12#ifndef PRECICE_SPAN_HPP_INCLUDED
13#define PRECICE_SPAN_HPP_INCLUDED
23#ifndef PRECICE_SPAN_NO_EXCEPTIONS
25#if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND))
26#define PRECICE_SPAN_NO_EXCEPTIONS
30#ifndef PRECICE_SPAN_NO_EXCEPTIONS
37#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
38#define PRECICE_SPAN_HAVE_CPP17
41#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
42#define PRECICE_SPAN_HAVE_CPP14
48#if !defined(PRECICE_SPAN_THROW_ON_CONTRACT_VIOLATION) && \
49 !defined(PRECICE_SPAN_TERMINATE_ON_CONTRACT_VIOLATION) && \
50 !defined(PRECICE_SPAN_NO_CONTRACT_CHECKING)
51#if defined(NDEBUG) || !defined(PRECICE_SPAN_HAVE_CPP14)
52#define PRECICE_SPAN_NO_CONTRACT_CHECKING
54#define PRECICE_SPAN_TERMINATE_ON_CONTRACT_VIOLATION
58#if defined(PRECICE_SPAN_THROW_ON_CONTRACT_VIOLATION)
59struct contract_violation_error : std::logic_error {
60 explicit contract_violation_error(
const char* msg) : std::logic_error(msg)
64inline void contract_violation(
const char* msg)
66 throw contract_violation_error(msg);
69#elif defined(PRECICE_SPAN_TERMINATE_ON_CONTRACT_VIOLATION)
70[[noreturn]]
inline void contract_violation(
const char* )
76#if !defined(PRECICE_SPAN_NO_CONTRACT_CHECKING)
77#define PRECICE_SPAN_STRINGIFY(cond) #cond
78#define PRECICE_SPAN_EXPECT(cond) \
79 cond ? (void) 0 : contract_violation("Expected " PRECICE_SPAN_STRINGIFY(cond))
81#define PRECICE_SPAN_EXPECT(cond)
84#if defined(PRECICE_SPAN_HAVE_CPP17) || defined(__cpp_inline_variables)
85#define PRECICE_SPAN_INLINE_VAR inline
87#define PRECICE_SPAN_INLINE_VAR
90#if defined(PRECICE_SPAN_HAVE_CPP14) || \
91 (defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
92#define PRECICE_SPAN_HAVE_CPP14_CONSTEXPR
95#if defined(PRECICE_SPAN_HAVE_CPP14_CONSTEXPR)
96#define PRECICE_SPAN_CONSTEXPR14 constexpr
98#define PRECICE_SPAN_CONSTEXPR14
101#if defined(PRECICE_SPAN_HAVE_CPP14_CONSTEXPR) && \
102 (!defined(_MSC_VER) || _MSC_VER > 1900)
103#define PRECICE_SPAN_CONSTEXPR_ASSIGN constexpr
105#define PRECICE_SPAN_CONSTEXPR_ASSIGN
108#if defined(PRECICE_SPAN_NO_CONTRACT_CHECKING)
109#define PRECICE_SPAN_CONSTEXPR11 constexpr
111#define PRECICE_SPAN_CONSTEXPR11 PRECICE_SPAN_CONSTEXPR14
114#if defined(PRECICE_SPAN_HAVE_CPP17) || defined(__cpp_deduction_guides)
115#define PRECICE_SPAN_HAVE_DEDUCTION_GUIDES
118#if defined(PRECICE_SPAN_HAVE_CPP17) || defined(__cpp_lib_byte)
119#define PRECICE_SPAN_HAVE_STD_BYTE
122#if defined(PRECICE_SPAN_HAVE_CPP17) || defined(__cpp_lib_array_constexpr)
123#define PRECICE_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC
126#if defined(PRECICE_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC)
127#define PRECICE_SPAN_ARRAY_CONSTEXPR constexpr
129#define PRECICE_SPAN_ARRAY_CONSTEXPR
132#ifdef PRECICE_SPAN_HAVE_STD_BYTE
133using byte = std::byte;
138#if defined(PRECICE_SPAN_HAVE_CPP17)
139#define PRECICE_SPAN_NODISCARD [[nodiscard]]
141#define PRECICE_SPAN_NODISCARD
146template <
typename ElementType, std::
size_t Extent = dynamic_extent>
151template <
typename E, std::
size_t S>
160 static constexpr std::size_t
size = S;
176#if defined(PRECICE_SPAN_HAVE_CPP17) || \
177 defined(__cpp_lib_nonmember_container_access)
182constexpr auto size(
const C& c) ->
decltype(c.size())
187template <
class T, std::
size_t N>
188constexpr std::size_t
size(
const T (&)[N])
noexcept
194constexpr auto data(C& c) ->
decltype(c.data())
200constexpr auto data(
const C& c) ->
decltype(c.data())
205template <
class T, std::
size_t N>
206constexpr T*
data(T (&array)[N])
noexcept
212constexpr const E*
data(std::initializer_list<E> il)
noexcept
218#if defined(PRECICE_SPAN_HAVE_CPP17) || defined(__cpp_lib_void_t)
221template <
typename...>
227 typename std::remove_cv<typename std::remove_reference<T>::type>::type;
232template <
typename T, std::
size_t S>
238template <
typename T, std::
size_t N>
241template <
typename,
typename =
void>
246 decltype(detail::data(std::declval<T>()))>>
249template <
typename C,
typename U = uncvref_t<C>>
259template <
typename,
typename,
typename =
void>
262template <
typename T,
typename E>
265 typename
std::enable_if<
267 typename std::remove_cv<decltype(detail::data(std::declval<T>()))>::type,
270 remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[],
275template <
typename,
typename =
size_t>
283template <
typename ElementType, std::
size_t Extent>
285 static_assert(std::is_object<ElementType>::value,
286 "A span's ElementType must be an object type (not a "
287 "reference type or void)");
289 "A span's ElementType must be a complete type (not a forward "
291 static_assert(!std::is_abstract<ElementType>::value,
292 "A span's ElementType cannot be an abstract class type");
299 using value_type =
typename std::remove_cv<ElementType>::type;
313 std::size_t E = Extent,
314 typename std::enable_if<(E ==
dynamic_extent || E <= 0), int>::type = 0>
325 :
storage_(first_elem, last_elem - first_elem)
328 last_elem - first_elem ==
329 static_cast<std::ptrdiff_t
>(
extent));
332 template <std::size_t N, std::size_t E = Extent,
333 typename std::enable_if<
341 template <
typename T, std::size_t N, std::size_t E = Extent,
342 typename std::enable_if<
345 std::array<T, N>&, ElementType>::value,
351 template <
typename T, std::size_t N, std::size_t E = Extent,
352 typename std::enable_if<
355 const std::array<T, N>&, ElementType>::value,
362 typename Container, std::size_t E = Extent,
363 typename std::enable_if<
366 Container&, ElementType>::value,
368 constexpr span(Container& cont)
373 typename Container, std::size_t E = Extent,
374 typename std::enable_if<
377 const Container&, ElementType>::value,
379 constexpr span(
const Container& cont)
383 constexpr span(
const span& other)
noexcept =
default;
385 template <
typename OtherElementType, std::size_t OtherExtent,
386 typename std::enable_if<
388 Extent == OtherExtent) &&
389 std::is_convertible<OtherElementType (*)[],
390 ElementType (*)[]>::value,
393 :
storage_(other.data(), other.size())
399 operator=(const
span& other) noexcept = default;
404 std::
size_t E = Extent,
405 typename
std::enable_if<
415 template <std::
size_t Count>
419 return {
data(), Count};
422 template <std::
size_t Count>
426 return {
data() + (
size() - Count), Count};
429 template <std::
size_t Offset, std::
size_t Count = dynamic_extent>
436 template <std::
size_t Offset, std::
size_t Count = dynamic_extent>
441 return {
data() + Offset,
449 return {
data(), count};
456 return {
data() + (
size() - count), count};
464 return {
data() + offset,
485 return *(
data() + idx);
521#ifdef PRECICE_SPAN_HAVE_DEDUCTION_GUIDES
524template <
class T,
size_t N>
527template <
class T,
size_t N>
530template <
class T,
size_t N>
531span(
const std::array<T, N>&)->
span<
const T, N>;
533template <
class Container>
534span(Container&)->
span<
typename std::remove_reference<
535 decltype(*
detail::data(std::declval<Container&>()))>::type>;
537template <
class Container>
538span(
const Container&)->
span<
const typename Container::value_type>;
542template <
typename ElementType, std::
size_t Extent>
549template <
typename T, std::
size_t N>
555template <
typename T, std::
size_t N>
561template <
typename T, std::
size_t N>
568template <
typename Container>
569constexpr span<
typename std::remove_reference<
570 decltype(*
detail::data(std::declval<Container&>()))>::type>
576template <
typename Container>
583template <
typename ElementType, std::
size_t Extent>
585 :
sizeof(ElementType) * Extent)>
592 class ElementType,
size_t Extent,
593 typename std::enable_if<!std::is_const<ElementType>::value,
int>::type = 0>
595 :
sizeof(ElementType) * Extent)>
601template <std::
size_t N,
typename E, std::
size_t S>
611template <
typename ElementType,
size_t Extent>
612class tuple_size<
precice::span<ElementType, Extent>>
613 :
public integral_constant<size_t, Extent> {};
615template <
typename ElementType>
617 ElementType, precice::dynamic_extent>>;
619template <size_t I, typename ElementType, size_t Extent>
620class tuple_element<I, precice::span<ElementType, Extent>> {
A C++ 11 implementation of the non-owning C++20 std::span type.
PRECICE_SPAN_CONSTEXPR11 reference front() const
PRECICE_SPAN_CONSTEXPR11 span< element_type, dynamic_extent > subspan(size_type offset, size_type count=dynamic_extent) const
PRECICE_SPAN_ARRAY_CONSTEXPR reverse_iterator rbegin() const noexcept
std::reverse_iterator< iterator > reverse_iterator
PRECICE_SPAN_CONSTEXPR11 span< element_type, dynamic_extent > first(size_type count) const
constexpr pointer data() const noexcept
constexpr span(const span &other) noexcept=default
typename std::remove_cv< const char >::type value_type
PRECICE_SPAN_ARRAY_CONSTEXPR span(const std::array< T, N > &arr) noexcept
constexpr span(Container &cont)
PRECICE_SPAN_CONSTEXPR11 span< element_type, Count > first() const
PRECICE_SPAN_NODISCARD constexpr bool empty() const noexcept
PRECICE_SPAN_CONSTEXPR11 span< element_type, Count > last() const
static constexpr size_type extent
PRECICE_SPAN_ARRAY_CONSTEXPR reverse_iterator rend() const noexcept
std::ptrdiff_t difference_type
constexpr span(element_type(&arr)[N]) noexcept
PRECICE_SPAN_CONSTEXPR11 reference operator[](size_type idx) const
constexpr iterator begin() const noexcept
constexpr iterator end() const noexcept
const element_type & const_reference
constexpr span(const span< OtherElementType, OtherExtent > &other) noexcept
const element_type * const_pointer
PRECICE_SPAN_CONSTEXPR11 subspan_return_t< Offset, Count > subspan() const
constexpr span(const Container &cont)
PRECICE_SPAN_CONSTEXPR11 span(pointer ptr, size_type count)
constexpr size_type size_bytes() const noexcept
PRECICE_SPAN_CONSTEXPR11 span(pointer first_elem, pointer last_elem)
constexpr size_type size() const noexcept
constexpr span() noexcept
PRECICE_SPAN_ARRAY_CONSTEXPR span(std::array< T, N > &arr) noexcept
span< const char, Count !=dynamic_extent ? Count :(Extent !=dynamic_extent ? Extent - Offset :dynamic_extent)> subspan_return_t
PRECICE_SPAN_CONSTEXPR11 span< element_type, dynamic_extent > last(size_type count) const
PRECICE_SPAN_CONSTEXPR11 reference back() const
detail::span_storage< const char, Extent > storage_type
A C++ 11 implementation of the non-owning C++20 std::span type.
constexpr span() noexcept
typename std::remove_pointer< T >::type remove_pointer_t
constexpr auto size(const C &c) -> decltype(c.size())
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
constexpr auto data(C &c) -> decltype(c.data())
Main namespace of the precice library.
span< byte,((Extent==dynamic_extent) ? dynamic_extent :sizeof(ElementType) *Extent)> as_writable_bytes(span< ElementType, Extent > s) noexcept
span< const byte,((Extent==dynamic_extent) ? dynamic_extent :sizeof(ElementType) *Extent)> as_bytes(span< ElementType, Extent > s) noexcept
constexpr span< ElementType, Extent > make_span(span< ElementType, Extent > s) noexcept
constexpr auto get(span< E, S > s) -> decltype(s[N])
PRECICE_SPAN_INLINE_VAR constexpr std::size_t dynamic_extent
#define PRECICE_SPAN_NODISCARD
#define PRECICE_SPAN_CONSTEXPR11
#define PRECICE_SPAN_INLINE_VAR
#define PRECICE_SPAN_ARRAY_CONSTEXPR
#define PRECICE_SPAN_EXPECT(cond)
#define PRECICE_SPAN_CONSTEXPR_ASSIGN
static constexpr bool value
constexpr span_storage() noexcept=default
constexpr span_storage() noexcept=default
static constexpr std::size_t size