Skip to content
GitLab
    • Explore Projects Groups Snippets
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • G gcc
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 39
    • Merge requests 39
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • gcc-mirror
  • gcc
  • Merge requests
  • !31

Add <span> header

  • Review changes

  • Download
  • Email patches
  • Plain diff
Closed Administrator requested to merge github/fork/chorman0773/master into master 6 years ago
  • Overview 2
  • Commits 2
  • Pipelines 0
  • Changes 1

Created by: chorman0773

Implements <span> from C++2a. This header provides std::span and all associated features in <span> as described by https://en.cppreference.com/w/cpp/header/span. The Pull Request is intended to add these to libstd++ which is currently not provided by GCC. This header comes with the guarentee that it follows the specification described in the above resource. It is not guarenteed to be Complient with the latest version of the C++2a standard working draft, or any later version, should the header and/or class specification change.

Compare
  • master (base)

and
  • latest version
    622ae82e
    2 commits, 2 years ago

1 file
+ 213
- 0

    Preferences

    File browser
    Compare changes
libstdc++-v3/include/std/span 0 → 100644
+ 213
- 0
  • View file @ 622ae82e

//<span> C++
//Pull Request Header for <span> (C++2a)
//(c) 2018 Connor Horman
//This library is free software;
//you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#ifndef __cxx__span_2018_09_13_09_56
#define __cxx__span_2018_09_13_09_56
#if __cplusplus <=201703
#pragma GCC warning "<span> is only availble when compiling for C++20/C++2a"
#else
#include <algorithm>
#include <bits/c++config>
#include <cstddef>
#include <type_traits>
#include <iterator>
#include <array>
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default){
_GLIBCXX_BEGIN_NAMESPACE_VERSION
const constexpr std::ptrdiff_t dynamic_extent{-1};
template<typename T,std::ptrdiff_t extent=dynamic_extent> struct span{
public:
using element_type = T;
using value_type = std::remove_cv_t<T>;
using index_type = std::ptrdiff_t;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using reference = T&;
using iterator = T*;
using const_iterator = T*;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
private:
pointer __ptr;
std::size_t __size;
public:
template<typename=std::enable_if_t<extent==0||extent==dynamic_extent>> constexpr span():__ptr(nullptr),__size(0){}
constexpr span(pointer in,index_type count):__ptr(in),__size(count){}
constexpr span(pointer first,pointer last):__ptr(first),__size(first-last){}
constexpr span(element_type(&arr)[extent])noexcept(true):__ptr(arr),__size(extent){}
constexpr span(std::array<value_type,extent>& arr,
std::enable_if_t<
std::is_convertible_v<std::remove_pointer_t<decltype(std::data(arr))>(*)[],
element_type(*)[]>,bool>=false))noexcept(true)
:__ptr(arr.data()),__size(extent){}
constexpr span(const std::array<value_type,extent>& arr,
std::enable_if_t<
std::is_convertible_v<std::remove_pointer_t<decltype(std::data(arr))>(*)[],
element_type(*)[]>,bool>=false))noexcept(true)
:__ptr(arr.data()),__size(extent){}
template<std::size_t N,typename=std::enable_if_t<extent==dynamic_extent>> constexpr span(element_type(&arr)[N])noexcept(true):__ptr(arr),__size(N){}
template<std::size_t N,typename=std::enable_if_t<extent==dynamic_extent>> constexpr span(std::array<value_type,N>& arr,
std::enable_if_t<
std::is_convertible_v<std::remove_pointer_t<decltype(std::data(arr))>(*)[],
element_type(*)[]>,bool>=false))noexcept(true)
:__ptr(arr.data()),__size(N){}
template<std::size_t N,typename=std::enable_if_t<extent==dynamic_extent>> constexpr span(const std::array<value_type,negation_v>& arr,
std::enable_if_t<
std::is_convertible_v<std::remove_pointer_t<decltype(std::data(arr))>(*)[],
element_type(*)[]>,bool>=false))noexcept(true)
:__ptr(arr.data()),__size(N){}
template<typename Container,
typename=void_t<decltype(std::data(std::declval<Container&>())),
decltype(std::size(std::declval<Container&>())),
std::enable_if_t<
std::is_convertible_v<std::remove_pointer_t<decltype(std::data(std::declval<Container&>()))>(*)[],
element_type(*)[]>>>> constexpr span(Container& c):__ptr(std::data(c)),__size(std::size(c)){}
template<typename Container,
typename=void_t<decltype(std::data(std::declval<const Container&>())),
decltype(std::size(std::declval<const Container&>())),
std::enable_if_t<
std::is_convertible_v<std::remove_pointer_t<decltype(std::data(std::declval<const Container&>()))>(*)[],
element_type(*)[]>>>> constexpr span(const Container& c):__ptr(std::data(c)),__size(std::size(c)){}
template<typename U,typename=std::enable_if_t<std::is_convertible_v<U(*)[],element_type(*)[]>>
constexpr span(const std::span<U,extent>& s)noexcept(true):__ptr(s.__ptr),__size(extent){}
template<typename U,size_t N,typename=std::enable_if_t<(extent==dynamic_extent)&&std::is_convertible_v<U(*)[],element_type(*)[]>>
constexpr span(const std::span<U,N>& s)noexcept(true):__ptr(s.__ptr),__size(N){}
constexpr span(const span&)noexcept(true)=default;
constexpr span& operator=(const span&)noexcept(true)=default;
constexpr pointer data()const noexcept(true){
return __ptr;
}
constexpr reference operator[](index_type idx)const{
return __ptr[idx];
}
constexpr reference operator()(index_type idx)const{
return __ptr[idx];
}
constexpr index_type size()const noexcept(true){
return extent==dynamic_extent?__size:extent;
}
constexpr index_type size_bytes()const noexcept(true){
return size()*sizeof(T);
}
constexpr bool empty()const noexcept(true){
return __size==0;
}
constexpr iterator begin()const noexcept(true){
return __ptr;
}
constexpr iterator end()const noexcept(true){
return __ptr+__size;
}
constexpr const_iterator cbegin()const noexcept(true){
return __ptr;
}
constexpr const_iterator cend()const noexcept(true){
return __ptr+__size;
}
constexpr reverse_iterator rbegin()const noexcept(true){
return std::make_reverse_iterator(end());
}
constexpr reverse_iterator rend()const noexcept(true){
return std::make_reverse_iteratr(begin());
}
constexpr const_reverse_iterator crbegin()const noexcept(true){
return std::make_reverse_iterator(cend());
}
constexpr const_reverse_iterator crend()const noexcept(true){
return std::make_reverse_iterator(cbegin());
}
template<std::ptrdiff_t Count> constexpr span<T,Count> first()const{
return span<T,Count>(__ptr,Count);
}
constexpr span<T,dynamic_extent> first(std::ptrdiff_t Count)const{
return span<T,dynamic_extent>(__ptr,Count);
}
template<std::ptrdiff_t Count> constexpr span<T,Count> last()const{
const std::size_t n = __size-Count;
return span<T,Count>(__ptr+n,Count);
}
constexpr span<T,dynamic_extent> last(std::ptrdiff_t Count)const{
const std::size_t n = __size-Count;
return span<T,dynamic_extent>(__ptr+n,Count);
}
template<std::ptrdiff_t Offset,std::ptrdiff_t Count,
std::ptrdiff_t NExtent=(Count!=dynamic_extent)?Count:(extent!=dynamic_extent?extent-Offset:dynamic_extent)> constexpr
constexpr span<T,NExtent>
subspan(){
return span<T,NExtent>(__ptr+std::size_t(Offset),Count!=dynamic_extent?Count:__size-Offset);
}
constexpr span<T,dynamic_extent> subspan(std::ptrdiff_t Offset,std::ptrdiff_t Count){
return span<T,dynamic_extent>(__ptr+std::size_t(Offset),Count!=dynamic_extent?Count:__size-Offset);
}
};
template<typename T,std::ptrdiff_t Extent1,typename U,std::ptrdiff_t Extent2>
constexpr bool operator==(const span<T,Extent1>& l1,const span<T,Extent2>& l2){
return std::equal(l1.begin(),l1.end(),l2.begin(),l2.end());
}
template<typename T,std::ptrdiff_t Extent1,typename U,std::ptrdiff_t Extent2>
constexpr bool operator!=(const span<T,Extent1>& l1,const span<T,Extent2>& l2){
return !(l1==l2);
}
template<typename T,std::ptrdiff_t Extent1,typename U,std::ptrdiff_t Extent2>
constexpr bool operator<(const span<T,Extent1>& l1,const span<T,Extent2>& l2){
return std::lexicographical_compare(l1.begin(),l1.end(),l2.begin(),l2.end());
}
template<typename T,std::ptrdiff_t Extent1,typename U,std::ptrdiff_t Extent2>
constexpr bool operator<=(const span<T,Extent1>& l1,const span<T,Extent2>& l2){
return l1<l2||l1==l2;
}
template<typename T,std::ptrdiff_t Extent1,typename U,std::ptrdiff_t Extent2>
constexpr bool operator>(const span<T,Extent1>& l1,const span<T,Extent2>& l2){
return !(l1<=l2);
}
template<typename T,std::ptrdiff_t Extent1,typename U,std::ptrdiff_t Extent2>
constexpr bool operator>=(const span<T,Extent1>& l1,const span<T,Extent2>& l2){
return !(l1<l2);
}
template<typename T,std::ptrdiff_t Extent,std::ptrdiff_t S=Extent!=dynamic_extent?Extent*sizeof(T):std::dynamic_extent>
span<const std::byte,S> as_bytes(std::span<T,Extent> s){
return std::span<const std::byte,S>{reinterpret_cast<const std::byte*>(s.data()),s.size_bytes()};
}
template<typename T,std::ptrdiff_t Extent,std::ptrdiff_t S=Extent!=dynamic_extent?Extent*sizeof(T):std::dynamic_extent>
span<std::enable_if_t<!std::is_const_v<T>,std::byte>,S> as_writeable_byte(std::span<T,Extent> s){
return std::span<std::byte,S>{reinterpret_cast<const std::byte*>(s.data()),s.size_bytes()};
}
template<typename Container> span(Container&)->span<typename Container::value_type>;
template<typename Container> span(const Container&)->span<std::add_const_t<typename Container::value_type>>;
template<typename T,std::size_t N> span(T(&)[N])->span<T,N>;
template<typename T,std::size_t N> span(array<T,N>&)->span<T,N>;
template<typename T,std::size_t N> span(const array<T,N>&)->span<std::add_const_t<T>,N>;
_GLIBCXX_END_NAMESPACE_VERSION
}
#endif
#endif
0 Assignees
None
Assign to
0 Reviewers
None
Request review from
Labels
0
None
0
None
    Assign labels
  • Manage project labels

Milestone
No milestone
None
None
Time tracking
No estimate or time spent
Lock merge request
Unlocked
1
1 participant
Administrator
Reference: gcc-mirror/gcc!31
Source branch: github/fork/chorman0773/master

Menu

Explore Projects Groups Snippets