#pragma once #if !defined(BAD_APPLE_OS_SPAN_HPP_INCLUDED) #define BAD_APPLE_OS_SPAN_HPP_INCLUDED #include #include #include #include #include namespace std { inline constexpr size_t dynamic_extent = size_t(-1); template // TODO: use the extent? class span { public: using element_type = T; using value_type = remove_cv_t; using size_type = size_t; using difference_type = ptrdiff_t; using reference = element_type&; using const_reference = const element_type&; using pointer = element_type*; using const_pointer = const element_type*; using iterator = pointer; using const_iterator = const_pointer; static constexpr size_t extent = Extent; private: pointer _first = nullptr; pointer _last = nullptr; public: constexpr span() noexcept = default; constexpr span(const span&) noexcept = default; template explicit(extent != dynamic_extent) constexpr span(It first, size_type count) : _first(&*first), _last(&*(_first + count)) {} template explicit(extent != dynamic_extent) constexpr span(It first, It last) : _first(&*first), _last(&*last) {} template constexpr span(type_identity_t (&arr)[N]) noexcept : span(&arr[0], N) {} template constexpr span(array& arr) noexcept : span(&arr[0], N) {} template constexpr span(const array& arr) noexcept : span(&arr[0], N) {} explicit(Extent != dynamic_extent) constexpr span(initializer_list il) noexcept : span(il.begin(), il.size()) {} template explicit(extent != dynamic_extent && N != dynamic_extent) constexpr span(const span& source) noexcept : span(source.begin(), source.end()) {} constexpr span& operator=(const span&) noexcept = default; constexpr reference operator[](size_type idx) const { return _first[idx]; } constexpr iterator begin() const noexcept { return _first; } constexpr const_iterator cbegin() const noexcept { return _first; } constexpr iterator end() const noexcept { return _last; } constexpr const_iterator cend() const noexcept { return _last; } constexpr reference front() const { return *_first; } constexpr reference back() const { return *(_last - 1); } constexpr reference at(size_type pos) const { if (pos >= size()) { __ba_throw std::out_of_range(); } return (*this)[pos]; } constexpr pointer data() const noexcept { return _first; } constexpr size_type size() const noexcept { return _last - _first; } constexpr size_type size_bytes() const noexcept { return size() * sizeof(element_type); } constexpr bool empty() const noexcept { return size() == 0; } // TODO: subspans }; } #endif // !defined(BAD_APPLE_OS_SPAN_HPP_INCLUDED)