20#include <initializer_list>
26# define SBEPP_WARNINGS_OFF() \
27 _Pragma("clang diagnostic push"); \
28 _Pragma("clang diagnostic ignored \"-Wbraced-scalar-init\"")
29# define SBEPP_WARNINGS_ON() _Pragma("clang diagnostic pop")
31# define SBEPP_WARNINGS_OFF()
32# define SBEPP_WARNINGS_ON()
38# define SBEPP_CPLUSPLUS _MSVC_LANG
40# define SBEPP_CPLUSPLUS __cplusplus
44# if __has_include(<version>)
58#if !defined(SBEPP_HAS_THREE_WAY_COMPARISON) \
59 && defined(__cpp_impl_three_way_comparison) \
60 && defined(__cpp_lib_three_way_comparison)
61# if(__cpp_impl_three_way_comparison >= 201907L) \
62 && (__cpp_lib_three_way_comparison >= 201907L)
63# define SBEPP_HAS_THREE_WAY_COMPARISON 1
67#ifndef SBEPP_HAS_THREE_WAY_COMPARISON
68# define SBEPP_HAS_THREE_WAY_COMPARISON 0
72#if !defined(SBEPP_HAS_CONCEPTS) && defined(__cpp_concepts)
73# if(__cpp_concepts >= 201907L)
74# define SBEPP_HAS_CONCEPTS 1
77#ifndef SBEPP_HAS_CONCEPTS
78# define SBEPP_HAS_CONCEPTS 0
82#if !defined(SBEPP_HAS_INLINE_VARS) && defined(__cpp_inline_variables)
83# if(__cpp_inline_variables >= 201606L)
84# define SBEPP_HAS_INLINE_VARS 1
85# define SBEPP_CPP17_INLINE_VAR inline
88#ifndef SBEPP_CPP17_INLINE_VAR
89# define SBEPP_HAS_INLINE_VARS 0
90# define SBEPP_CPP17_INLINE_VAR
94#if !defined(SBEPP_HAS_ENDIAN) && defined(__cpp_lib_endian)
95# if(__cpp_lib_endian >= 201907L)
96# define SBEPP_HAS_ENDIAN 1
100#ifndef SBEPP_HAS_ENDIAN
101# define SBEPP_HAS_ENDIAN 0
105#if !defined(SBEPP_HAS_BITCAST) && defined(__cpp_lib_bit_cast)
106# if(__cpp_lib_bit_cast >= 201806L)
107# define SBEPP_HAS_BITCAST 1
111#ifndef SBEPP_HAS_BITCAST
112# define SBEPP_HAS_BITCAST 0
116#if !defined(SBEPP_HAS_BYTESWAP) && defined(__cpp_lib_byteswap)
117# if(__cpp_lib_byteswap >= 202110L)
118# define SBEPP_HAS_BYTESWAP 1
122#ifndef SBEPP_HAS_BYTESWAP
123# define SBEPP_HAS_BYTESWAP 0
127#if !defined(SBEPP_HAS_CONSTEXPR_ALGORITHMS) \
128 && defined(__cpp_lib_constexpr_algorithms)
129# if(__cpp_lib_constexpr_algorithms >= 201806L)
130# define SBEPP_HAS_CONSTEXPR_ALGORITHMS 1
133#ifndef SBEPP_HAS_CONSTEXPR_ALGORITHMS
134# define SBEPP_HAS_CONSTEXPR_ALGORITHMS 0
137#ifdef __has_cpp_attribute
139# if __has_cpp_attribute(nodiscard) \
140 && !(defined(__clang__) && (SBEPP_CPLUSPLUS < 201703L))
141# define SBEPP_CPP17_NODISCARD [[nodiscard]]
144# if __has_cpp_attribute(deprecated) \
145 && !(defined(__clang__) && (SBEPP_CPLUSPLUS < 201402L))
146# define SBEPP_DEPRECATED [[deprecated]]
150#ifndef SBEPP_CPP17_NODISCARD
151# define SBEPP_CPP17_NODISCARD
154#ifndef SBEPP_DEPRECATED
155# if defined(__GNUC__) || defined(__clang__)
156# define SBEPP_DEPRECATED __attribute__((deprecated))
157# elif defined(_MSC_VER)
158# define SBEPP_DEPRECATED __declspec(deprecated)
160# define SBEPP_DEPRECATED
165#if SBEPP_HAS_BITCAST && SBEPP_HAS_CONSTEXPR_ALGORITHMS
166# define SBEPP_HAS_CONSTEXPR_ACCESSORS 1
168# define SBEPP_HAS_CONSTEXPR_ACCESSORS 0
171#if SBEPP_HAS_CONSTEXPR_ACCESSORS
173# define SBEPP_CPP20_CONSTEXPR constexpr
175# define SBEPP_CPP20_CONSTEXPR
178#ifdef __cpp_constexpr
179# if(__cpp_constexpr >= 201304L)
180# define SBEPP_CPP14_CONSTEXPR constexpr
183# if(SBEPP_CPLUSPLUS >= 201402L)
184# define SBEPP_CPP14_CONSTEXPR constexpr
187#ifndef SBEPP_CPP14_CONSTEXPR
188# define SBEPP_CPP14_CONSTEXPR
192#if !defined(SBEPP_HAS_RANGES) && defined(__cpp_lib_ranges)
193# if(__cpp_lib_ranges >= 201911L)
194# define SBEPP_HAS_RANGES 1
198#ifndef SBEPP_HAS_RANGES
199# define SBEPP_HAS_RANGES 0
204#if !defined(SBEPP_HAS_IS_CONSTANT_EVALUATED) \
205 && defined(__cpp_lib_is_constant_evaluated) \
206 && (__cpp_lib_is_constant_evaluated >= 201811L)
207# define SBEPP_HAS_IS_CONSTANT_EVALUATED 1
209#ifndef SBEPP_HAS_IS_CONSTANT_EVALUATED
210# define SBEPP_HAS_IS_CONSTANT_EVALUATED 0
217# define SBEPP_DISABLE_ASSERTS
223# define SBEPP_ASSERT_HANDLER
229# define SBEPP_ENABLE_ASSERTS_WITH_HANDLER
244 char const* expr,
char const* function,
char const* file,
long line);
248#ifdef SBEPP_DISABLE_ASSERTS
249# define SBEPP_SIZE_CHECKS_ENABLED 0
250# define SBEPP_ASSERT(expr) ((void)0)
251#elif defined(SBEPP_ASSERT_HANDLER) \
252 || defined(SBEPP_ENABLE_ASSERTS_WITH_HANDLER)
253# if !defined(NDEBUG) || defined(SBEPP_ENABLE_ASSERTS_WITH_HANDLER)
258 char const* expr,
char const* function,
char const* file,
long line);
261# define SBEPP_SIZE_CHECKS_ENABLED 1
262# define SBEPP_ASSERT(expr) \
263 (static_cast<bool>(expr) \
265 : ::sbepp::assertion_failed( \
266 #expr, __func__, __FILE__, __LINE__))
268# define SBEPP_SIZE_CHECKS_ENABLED 0
269# define SBEPP_ASSERT(expr) ((void)0)
274# define SBEPP_SIZE_CHECKS_ENABLED 0
276# define SBEPP_SIZE_CHECKS_ENABLED 1
278# define SBEPP_ASSERT(expr) assert(expr)
281#define SBEPP_SIZE_CHECK(begin, end, offset, size) \
284 && (((offset) + (size)) <= static_cast<std::size_t>((end) - (begin))))
327# define SBEPP_BYTE_ORDER
345#elif SBEPP_HAS_ENDIAN
346using endian = std::endian;
351# if defined(_WIN32) || defined(WIN32)
355# elif defined(__BYTE_ORDER__)
356 little = __ORDER_LITTLE_ENDIAN__,
357 big = __ORDER_BIG_ENDIAN__,
359# elif defined(SBEPP_BYTE_ORDER)
364# error "Byte order cannot be detected.\
365 Define SBEPP_BYTE_ORDER to 'little' or 'big'"
372 "Mixed-endian is not supported");
379template<
bool B,
typename T =
void>
380using enable_if_t =
typename std::enable_if<B, T>::type;
383using remove_cv_t =
typename std::remove_cv<T>::type;
386using remove_reference_t =
typename std::remove_reference<T>::type;
388template<
typename ByteFrom,
typename ByteTo>
389using enable_if_convertible_t =
390 enable_if_t<std::is_convertible<ByteFrom*, ByteTo*>::value>;
392template<
typename Byte,
typename T =
void>
393using enable_if_writable_t = enable_if_t<!std::is_const<Byte>::value, T>;
398template<typename T, typename = enable_if_t<!std::is_floating_point<T>::value>>
399constexpr typename std::make_unsigned<T>::type to_unsigned(T v)
noexcept
401 return static_cast<typename std::make_unsigned<T>::type
>(v);
404inline std::uint64_t to_unsigned(
double v)
noexcept
407 std::memcpy(&res, &v,
sizeof(res));
411inline std::uint32_t to_unsigned(
float v)
noexcept
414 std::memcpy(&res, &v,
sizeof(res));
422 operator()(
typename std::make_unsigned<To>::type from)
const noexcept
424 return static_cast<To
>(from);
429struct from_unsigned<double>
431 double operator()(std::uint64_t from)
const noexcept
434 std::memcpy(&res, &from,
sizeof(res));
440struct from_unsigned<float>
442 float operator()(std::uint32_t from)
const noexcept
445 std::memcpy(&res, &from,
sizeof(res));
452# define __has_builtin(x) 0
455#if SBEPP_HAS_BYTESWAP
465T byteswap(T)
noexcept;
467# if defined(_MSC_VER) && (!defined(__clang__) || defined(__c2__))
471inline std::uint64_t byteswap(std::uint64_t v)
noexcept
473 return _byteswap_uint64(v);
476inline std::uint32_t byteswap(std::uint32_t v)
noexcept
478 return _byteswap_ulong(v);
481inline std::uint16_t byteswap(std::uint16_t v)
noexcept
483 return _byteswap_ushort(v);
487 defined(__clang__) && __has_builtin(__builtin_bswap32) \
488 && __has_builtin(__builtin_bswap64)) \
489 || (defined(__GNUC__) \
490 && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
492# if(defined(__clang__) && __has_builtin(__builtin_bswap16)) \
493 || (defined(__GNUC__) \
494 && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
496inline std::uint16_t byteswap(std::uint16_t v)
noexcept
498 return __builtin_bswap16(v);
503inline std::uint16_t byteswap(std::uint16_t v)
noexcept
505 return __builtin_bswap32(v) << 16;
510inline std::uint64_t byteswap(std::uint64_t v)
noexcept
512 return __builtin_bswap64(v);
515inline std::uint32_t byteswap(std::uint32_t v)
noexcept
517 return __builtin_bswap32(v);
522constexpr std::uint64_t byteswap(std::uint64_t v)
noexcept
524 return ((v & UINT64_C(0x00000000000000FF)) << 56)
525 | ((v & UINT64_C(0x000000000000FF00)) << 40)
526 | ((v & UINT64_C(0x0000000000FF0000)) << 24)
527 | ((v & UINT64_C(0x00000000FF000000)) << 8)
528 | ((v & UINT64_C(0x000000FF00000000)) >> 8)
529 | ((v & UINT64_C(0x0000FF0000000000)) >> 24)
530 | ((v & UINT64_C(0x00FF000000000000)) >> 40)
531 | ((v & UINT64_C(0xFF00000000000000)) >> 56);
534constexpr std::uint32_t byteswap(std::uint32_t v)
noexcept
536 return ((v & UINT32_C(0x000000FF)) << 24)
537 | ((v & UINT32_C(0x0000FF00)) << 8)
538 | ((v & UINT32_C(0x00FF0000)) >> 8)
539 | ((v & UINT32_C(0xFF000000)) >> 24);
542constexpr std::uint16_t byteswap(std::uint16_t v)
noexcept
544 return ((v & UINT16_C(0x00FF)) << 8) | ((v & UINT16_C(0xFF00)) >> 8);
550template<
typename T, endian E,
typename Byte>
551SBEPP_CPP20_CONSTEXPR T get_primitive(
const Byte* ptr)
554 std::array<Byte,
sizeof(T)> arr;
557 std::copy(ptr, ptr +
sizeof(T), std::begin(arr));
561 std::reverse_copy(ptr, ptr +
sizeof(T), std::begin(arr));
563 return std::bit_cast<T>(arr);
568 std::memcpy(&res, ptr,
sizeof(T));
575 return from_unsigned<T>{}(byteswap(to_unsigned(res)));
580template<endian E,
typename T,
typename Byte>
581SBEPP_CPP20_CONSTEXPR
void set_primitive(Byte* ptr, T value)
584 auto arr = std::bit_cast<std::array<Byte,
sizeof(T)>>(value);
587 std::copy(std::begin(arr), std::end(arr), ptr);
591 std::reverse_copy(std::begin(arr), std::end(arr), ptr);
598 value = from_unsigned<T>{}(byteswap(to_unsigned(value)));
600 std::memcpy(ptr, &value,
sizeof(T));
604struct fill_message_header_tag
606 explicit fill_message_header_tag() =
default;
609struct fill_group_header_tag
611 explicit fill_group_header_tag() =
default;
616 explicit size_bytes_tag() =
default;
621 explicit addressof_tag() =
default;
626 explicit end_ptr_tag() =
default;
631 explicit get_header_tag() =
default;
634struct get_block_length_tag
636 explicit get_block_length_tag() =
default;
641 explicit get_bit_tag() =
default;
646 explicit set_bit_tag() =
default;
651 explicit get_level_tag() =
default;
656 explicit visit_tag() =
default;
659struct visit_children_tag
661 explicit visit_children_tag() =
default;
664struct enum_to_str_tag
666 explicit enum_to_str_tag() =
default;
671 explicit visit_set_tag() =
default;
674template<
typename T,
typename U, endian E,
typename View>
675SBEPP_CPP20_CONSTEXPR T
676 get_value(
const View view,
const std::size_t offset)
noexcept
679 view(addressof_tag{}), view(end_ptr_tag{}), offset,
sizeof(U));
680 return T{get_primitive<U, E>(view(addressof_tag{}) + offset)};
683template<endian E,
typename T,
typename View>
684SBEPP_CPP20_CONSTEXPR
void
685 set_value(
const View view,
const std::size_t offset,
const T value)
noexcept
688 view(addressof_tag{}), view(end_ptr_tag{}), offset,
sizeof(T));
689 set_primitive<E>(view(addressof_tag{}) + offset, value);
692template<
typename Res,
typename View>
693SBEPP_CPP20_CONSTEXPR Res
694 get_static_field_view(
const View view,
const std::size_t offset)
noexcept
696 SBEPP_SIZE_CHECK(view(addressof_tag{}), view(end_ptr_tag{}), offset, 0);
697 return {view(addressof_tag{}) + offset, view(end_ptr_tag{})};
700template<
typename Group,
typename View>
701SBEPP_CPP20_CONSTEXPR Group
702 get_first_dynamic_field_view(
const View view)
noexcept
705 view(get_level_tag{}) + view(get_block_length_tag{}),
706 view(end_ptr_tag{})};
709template<
typename Group,
typename View,
typename Prev>
710SBEPP_CPP20_CONSTEXPR Group
711 get_dynamic_field_view(
const View view,
const Prev prev)
noexcept
714 prev(addressof_tag{}) + prev(size_bytes_tag{}), view(end_ptr_tag{})};
719template<
typename Byte>
723 static_assert(
sizeof(Byte) == 1,
"Byte must represent a single byte");
725 template<
typename Byte2>
732 SBEPP_CPP14_CONSTEXPR
byte_range(Byte* begin, Byte* end) noexcept
734#if SBEPP_SIZE_CHECKS_ENABLED
743 constexpr byte_range(Byte* ptr,
const std::size_t size) noexcept
749 template<
typename Byte2,
typename = enable_if_convertible_t<Byte2, Byte>>
753#if SBEPP_SIZE_CHECKS_ENABLED
760 constexpr Byte* operator()(addressof_tag)
const noexcept
765 constexpr Byte* operator()(end_ptr_tag)
const noexcept
767#if SBEPP_SIZE_CHECKS_ENABLED
776#if SBEPP_SIZE_CHECKS_ENABLED
788template<
typename Byte>
803 using result_type = T;
817 typename = detail::enable_if_convertible_t<Byte2, Byte>>
833 typename = detail::enable_if_convertible_t<Byte2, Byte>>
846 SBEPP_CPP14_CONSTEXPR Byte*&
pointer() noexcept
856 SBEPP_CPP14_CONSTEXPR Byte*
pointer() const noexcept
861 template<
typename T,
typename U, endian E,
typename View>
862 SBEPP_CPP20_CONSTEXPR T get_value(
864 const std::size_t offset,
865 const std::size_t )
noexcept
867 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(U));
868 T res{detail::get_primitive<U, E>(ptr + offset)};
869 ptr += offset +
sizeof(U);
873 template<endian E,
typename T,
typename View>
874 SBEPP_CPP20_CONSTEXPR
void set_value(
876 const std::size_t offset,
878 const T value)
noexcept
880 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(T));
881 detail::set_primitive<E>(ptr + offset, value);
882 ptr += offset +
sizeof(T);
885 template<
typename T,
typename U, endian E,
typename View>
886 SBEPP_CPP20_CONSTEXPR T get_last_value(
888 const std::size_t offset,
889 const std::size_t )
noexcept
891 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(U));
892 auto res = T{detail::get_primitive<U, E>(ptr + offset)};
893 ptr = view(detail::get_level_tag{})
894 + view(detail::get_block_length_tag{});
898 template<endian E,
typename T,
typename View>
899 SBEPP_CPP20_CONSTEXPR
void set_last_value(
901 const std::size_t offset,
903 const T value)
noexcept
905 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(T));
906 detail::set_primitive<E>(ptr + offset, value);
907 ptr = view(detail::get_level_tag{})
908 + view(detail::get_block_length_tag{});
911 template<
typename Res,
typename View>
912 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
914 const std::size_t offset,
915 const std::size_t )
noexcept
917 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, 0);
918 Res res{ptr + offset, view(detail::end_ptr_tag{})};
919 ptr += offset + res(detail::size_bytes_tag{});
923 template<
typename Res,
typename View>
924 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
926 const std::size_t offset,
927 const std::size_t )
noexcept
929 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, 0);
930 Res res{ptr + offset, view(detail::end_ptr_tag{})};
931 ptr = view(detail::get_level_tag{})
932 + view(detail::get_block_length_tag{});
936 template<
typename ResView,
typename View>
937 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
939 ptr = view(detail::get_level_tag{})
940 + view(detail::get_block_length_tag{});
941 ResView g{ptr, view(detail::end_ptr_tag{})};
942 ptr += g(detail::get_header_tag{})(detail::size_bytes_tag{});
947 template<
typename ResView,
typename View>
948 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
950 ptr = view(detail::get_level_tag{})
951 + view(detail::get_block_length_tag{});
952 ResView d{ptr, view(detail::end_ptr_tag{})};
953 ptr += d(detail::size_bytes_tag{});
958 template<
typename ResView,
typename View,
typename Getter>
959 SBEPP_CPP20_CONSTEXPR ResView
960 get_group_view(
const View view, Getter&& ) noexcept
962 ResView res{ptr, view(detail::end_ptr_tag{})};
963 auto header = res(detail::get_header_tag{});
964 ptr += header(detail::size_bytes_tag{});
968 template<
typename ResView,
typename View,
typename Getter>
969 SBEPP_CPP20_CONSTEXPR ResView
970 get_data_view(
const View view, Getter&& ) noexcept
972 ResView res{ptr, view(detail::end_ptr_tag{})};
973 ptr += res(detail::size_bytes_tag{});
986template<
typename Byte>
987class init_cursor_wrapper
990 using byte_type = Byte;
993 using result_type = T;
995 init_cursor_wrapper() =
default;
1002 template<
typename T,
typename U, endian E,
typename View>
1003 SBEPP_CPP20_CONSTEXPR T get_value(
1006 const std::size_t absolute_offset)
noexcept
1009 view(addressof_tag{}),
1010 view(end_ptr_tag{}),
1013 T res{get_primitive<U, E>(view(addressof_tag{}) + absolute_offset)};
1014 cursor->pointer() = view(addressof_tag{}) + absolute_offset +
sizeof(U);
1018 template<endian E,
typename T,
typename View>
1019 SBEPP_CPP20_CONSTEXPR
void set_value(
1022 const std::size_t absolute_offset,
1023 const T value)
noexcept
1026 view(addressof_tag{}),
1027 view(end_ptr_tag{}),
1030 set_primitive<E>(view(addressof_tag{}) + absolute_offset, value);
1031 cursor->pointer() = view(addressof_tag{}) + absolute_offset +
sizeof(T);
1034 template<
typename T,
typename U, endian E,
typename View>
1035 SBEPP_CPP20_CONSTEXPR T get_last_value(
1038 const std::size_t absolute_offset)
noexcept
1041 view(addressof_tag{}),
1042 view(end_ptr_tag{}),
1045 T res{get_primitive<U, E>(view(addressof_tag{}) + absolute_offset)};
1047 view(get_level_tag{}) + view(get_block_length_tag{});
1051 template<endian E,
typename T,
typename View>
1052 SBEPP_CPP20_CONSTEXPR
void set_last_value(
1055 const std::size_t absolute_offset,
1056 const T value)
noexcept
1059 view(addressof_tag{}),
1060 view(end_ptr_tag{}),
1063 set_primitive<E>(view(addressof_tag{}) + absolute_offset, value);
1065 view(get_level_tag{}) + view(get_block_length_tag{});
1068 template<
typename Res,
typename View>
1069 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
1072 const std::size_t absolute_offset)
noexcept
1075 view(addressof_tag{}), view(end_ptr_tag{}), absolute_offset, 0);
1076 Res res{view(addressof_tag{}) + absolute_offset, view(end_ptr_tag{})};
1077 cursor->pointer() = res(addressof_tag{}) + res(size_bytes_tag{});
1081 template<
typename Res,
typename View>
1082 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
1085 const std::size_t absolute_offset)
noexcept
1088 view(addressof_tag{}), view(end_ptr_tag{}), absolute_offset, 0);
1089 Res res{view(addressof_tag{}) + absolute_offset, view(end_ptr_tag{})};
1091 view(get_level_tag{}) + view(get_block_length_tag{});
1095 template<
typename ResView,
typename View>
1096 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
1098 return cursor->template get_first_group_view<ResView>(view);
1101 template<
typename ResView,
typename View>
1102 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
1104 return cursor->template get_first_data_view<ResView>(view);
1107 template<
typename ResView,
typename View,
typename Getter>
1108 SBEPP_CPP20_CONSTEXPR ResView
1109 get_group_view(
const View , Getter&& getter)
noexcept
1111 auto res = getter();
1112 auto header = res(get_header_tag{});
1113 cursor->pointer() = res(addressof_tag{}) + header(size_bytes_tag{});
1117 template<
typename ResView,
typename View,
typename Getter>
1118 SBEPP_CPP20_CONSTEXPR ResView
1119 get_data_view(
const View , Getter&& getter)
noexcept
1121 auto res = getter();
1122 cursor->pointer() = res(addressof_tag{}) + res(size_bytes_tag{});
1130template<
typename Byte>
1131class init_dont_move_cursor_wrapper
1134 using byte_type = Byte;
1136 template<
typename T>
1137 using result_type = T;
1139 init_dont_move_cursor_wrapper() =
default;
1141 explicit constexpr init_dont_move_cursor_wrapper(
1147 template<
typename T,
typename U, endian E,
typename View>
1148 SBEPP_CPP20_CONSTEXPR T get_value(
1150 const std::size_t offset,
1151 const std::size_t absolute_offset)
noexcept
1154 view(addressof_tag{}),
1155 view(end_ptr_tag{}),
1158 cursor->pointer() = view(addressof_tag{}) + absolute_offset - offset;
1159 return T{get_primitive<U, E>(view(addressof_tag{}) + absolute_offset)};
1162 template<endian E,
typename T,
typename View>
1163 SBEPP_CPP20_CONSTEXPR
void set_value(
1165 const std::size_t offset,
1166 const std::size_t absolute_offset,
1167 const T value)
noexcept
1170 view(addressof_tag{}),
1171 view(end_ptr_tag{}),
1174 cursor->pointer() = view(addressof_tag{}) + absolute_offset - offset;
1175 set_primitive<E>(view(addressof_tag{}) + absolute_offset, value);
1178 template<
typename T,
typename U, endian E,
typename View>
1179 SBEPP_CPP20_CONSTEXPR T get_last_value(
1181 const std::size_t offset,
1182 const std::size_t absolute_offset)
noexcept
1184 return get_value<T, U, E>(view, offset, absolute_offset);
1187 template<endian E,
typename T,
typename View>
1188 SBEPP_CPP20_CONSTEXPR
void set_last_value(
1190 const std::size_t offset,
1191 const std::size_t absolute_offset,
1192 const T value)
noexcept
1194 return set_value<E>(view, offset, absolute_offset, value);
1197 template<
typename Res,
typename View>
1198 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
1200 const std::size_t offset,
1201 const std::size_t absolute_offset)
noexcept
1204 view(addressof_tag{}), view(end_ptr_tag{}), absolute_offset, 0);
1205 cursor->pointer() = view(addressof_tag{}) + absolute_offset - offset;
1206 return {view(addressof_tag{}) + absolute_offset, view(end_ptr_tag{})};
1209 template<
typename Res,
typename View>
1210 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
1212 const std::size_t offset,
1213 const std::size_t absolute_offset)
noexcept
1215 return get_static_field_view<Res>(view, offset, absolute_offset);
1218 template<
typename ResView,
typename View>
1219 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
1222 view(get_level_tag{}) + view(get_block_length_tag{});
1223 ResView g{cursor->pointer(), view(end_ptr_tag{})};
1228 template<
typename ResView,
typename View>
1229 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
1232 view(get_level_tag{}) + view(get_block_length_tag{});
1233 ResView d{cursor->pointer(), view(end_ptr_tag{})};
1238 template<
typename ResView,
typename View,
typename Getter>
1239 SBEPP_CPP20_CONSTEXPR ResView
1240 get_group_view(
const View , Getter&& getter)
noexcept
1242 auto res = getter();
1243 cursor->pointer() = res(addressof_tag{});
1247 template<
typename ResView,
typename View,
typename Getter>
1248 SBEPP_CPP20_CONSTEXPR ResView
1249 get_data_view(
const View , Getter&& getter)
noexcept
1251 auto res = getter();
1252 cursor->pointer() = res(addressof_tag{});
1260template<
typename Byte>
1261class dont_move_cursor_wrapper
1264 using byte_type = Byte;
1266 template<
typename T>
1267 using result_type = T;
1269 dont_move_cursor_wrapper() =
default;
1276 template<
typename T,
typename U, endian E,
typename View>
1277 SBEPP_CPP20_CONSTEXPR T get_value(
1279 const std::size_t offset,
1280 const std::size_t )
noexcept
1283 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1284 return T{get_primitive<U, E>(cursor->pointer() + offset)};
1287 template<endian E,
typename T,
typename View>
1288 SBEPP_CPP20_CONSTEXPR
void set_value(
1290 const std::size_t offset,
1292 const T value)
noexcept
1295 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(T));
1296 set_primitive<E>(cursor->pointer() + offset, value);
1299 template<
typename T,
typename U, endian E,
typename View>
1300 SBEPP_CPP20_CONSTEXPR T get_last_value(
1302 const std::size_t offset,
1303 const std::size_t )
noexcept
1306 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1307 return T{get_primitive<U, E>(cursor->pointer() + offset)};
1310 template<endian E,
typename T,
typename View>
1311 SBEPP_CPP20_CONSTEXPR
void set_last_value(
1313 const std::size_t offset,
1315 const T value)
noexcept
1318 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(T));
1319 set_primitive<E>(cursor->pointer() + offset, value);
1322 template<
typename Res,
typename View>
1323 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
1325 const std::size_t offset,
1326 const std::size_t )
noexcept
1328 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1329 return {cursor->pointer() + offset, view(end_ptr_tag{})};
1332 template<
typename Res,
typename View>
1333 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
1335 const std::size_t offset,
1336 const std::size_t )
noexcept
1338 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1339 return {cursor->pointer() + offset, view(end_ptr_tag{})};
1342 template<
typename ResView,
typename View>
1343 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
1346 view(get_level_tag{}) + view(get_block_length_tag{});
1347 ResView g{cursor->pointer(), view(end_ptr_tag{})};
1352 template<
typename ResView,
typename View>
1353 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
1356 view(get_level_tag{}) + view(get_block_length_tag{});
1357 ResView d{cursor->pointer(), view(end_ptr_tag{})};
1362 template<
typename ResView,
typename View,
typename Getter>
1363 SBEPP_CPP20_CONSTEXPR ResView
1364 get_group_view(
const View view, Getter&& ) noexcept
1366 return {cursor->pointer(), view(end_ptr_tag{})};
1369 template<
typename ResView,
typename View,
typename Getter>
1370 SBEPP_CPP20_CONSTEXPR ResView
1371 get_data_view(
const View view, Getter&& ) noexcept
1373 return {cursor->pointer(), view(end_ptr_tag{})};
1380template<
typename Byte>
1381class skip_cursor_wrapper
1384 using byte_type = Byte;
1386 template<
typename T>
1387 using result_type = void;
1389 skip_cursor_wrapper() =
default;
1396 template<
typename T,
typename U, endian E,
typename View>
1397 SBEPP_CPP20_CONSTEXPR
void get_value(
1399 const std::size_t offset,
1400 const std::size_t )
noexcept
1403 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1404 cursor->pointer() += offset +
sizeof(U);
1407 template<
typename T,
typename U, endian E,
typename View>
1408 SBEPP_CPP20_CONSTEXPR
void get_last_value(
1410 const std::size_t offset,
1411 const std::size_t )
noexcept
1414 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1416 view(get_level_tag{}) + view(get_block_length_tag{});
1419 template<
typename Res,
typename View>
1420 SBEPP_CPP20_CONSTEXPR
void get_static_field_view(
1422 const std::size_t offset,
1423 const std::size_t )
noexcept
1425 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1426 Res res{cursor->pointer(), view(end_ptr_tag{})};
1427 cursor->pointer() += offset + res(size_bytes_tag{});
1430 template<
typename Res,
typename View>
1431 SBEPP_CPP20_CONSTEXPR
void get_last_static_field_view(
1433 const std::size_t offset,
1434 const std::size_t )
noexcept
1436 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1438 view(get_level_tag{}) + view(get_block_length_tag{});
1441 template<
typename ResView,
typename View>
1442 SBEPP_CPP20_CONSTEXPR
void get_first_group_view(
const View view)
noexcept
1445 view(get_level_tag{}) + view(get_block_length_tag{});
1446 ResView g{cursor->pointer(), view(end_ptr_tag{})};
1447 cursor->pointer() += g(size_bytes_tag{});
1450 template<
typename ResView,
typename View>
1451 SBEPP_CPP20_CONSTEXPR
void get_first_data_view(
const View view)
noexcept
1454 view(get_level_tag{}) + view(get_block_length_tag{});
1455 ResView d{cursor->pointer(), view(end_ptr_tag{})};
1456 cursor->pointer() += d(size_bytes_tag{});
1459 template<
typename ResView,
typename View,
typename Getter>
1460 SBEPP_CPP20_CONSTEXPR
void
1461 get_group_view(
const View view, Getter&& ) noexcept
1463 ResView res{cursor->pointer(), view(end_ptr_tag{})};
1464 cursor->pointer() += res(size_bytes_tag{});
1467 template<
typename ResView,
typename View,
typename Getter>
1468 SBEPP_CPP20_CONSTEXPR
void
1469 get_data_view(
const View view, Getter&& ) noexcept
1471 ResView res{cursor->pointer(), view(end_ptr_tag{})};
1472 cursor->pointer() += res(size_bytes_tag{});
1479template<
typename Cursor,
typename T>
1480using cursor_result_type_t =
1481 typename remove_reference_t<Cursor>::template result_type<T>;
1483template<
typename Cursor>
1484using cursor_byte_type_t =
typename remove_reference_t<Cursor>::byte_type;
1486template<
typename MessageByte,
typename CursorByte>
1487using enable_if_cursor_compatible_t =
1488 enable_if_convertible_t<MessageByte, CursorByte>;
1490template<
typename MessageByte,
typename CursorByte>
1491using enable_if_cursor_writeable_t = enable_if_t<
1492 std::is_convertible<MessageByte*, CursorByte*>::value
1493 && !std::is_const<MessageByte>::value && !std::is_const<CursorByte>::value>;
1509 return v(detail::size_bytes_tag{});
1521template<
typename T,
typename Byte>
1524 return v(detail::size_bytes_tag{}, c);
1534constexpr auto get_header(T v)
noexcept ->
decltype(v(detail::get_header_tag{}))
1536 return v(detail::get_header_tag{});
1546constexpr auto addressof(T v)
noexcept ->
decltype(v(detail::addressof_tag{}))
1548 return v(detail::addressof_tag{});
1556template<
typename View>
1561 std::declval<View>()))>
::type;
1565template<
typename View>
1591template<
typename Byte>
1594 return detail::init_cursor_wrapper<Byte>{c};
1619template<
typename Byte>
1620constexpr detail::dont_move_cursor_wrapper<Byte>
1623 return detail::dont_move_cursor_wrapper<Byte>{c};
1633template<
typename Byte>
1634constexpr detail::init_dont_move_cursor_wrapper<Byte>
1637 return detail::init_dont_move_cursor_wrapper<Byte>{c};
1654template<
typename Byte>
1657 return detail::skip_cursor_wrapper<Byte>{c};
1665template<
typename Byte>
1674template<
typename Byte,
typename Header>
1681 SBEPP_CPP14_CONSTEXPR Header operator()(get_header_tag)
const noexcept
1683 Header header{(*this)(addressof_tag{}), (*
this)(end_ptr_tag{})};
1685 (*
this)(addressof_tag{}),
1686 (*
this)(end_ptr_tag{}),
1692 SBEPP_CPP14_CONSTEXPR Byte* operator()(get_level_tag)
const noexcept
1694 auto header = (*this)(get_header_tag{});
1695 return header(addressof_tag{}) + header(size_bytes_tag{});
1698 constexpr typename std::decay<
1699 decltype(std::declval<Header>().blockLength().value())>::type
1700 operator()(get_block_length_tag)
const noexcept
1702 return operator()(get_header_tag{}).blockLength().value();
1707 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
1708 SBEPP_CPP20_CONSTEXPR std::size_t
1711 return c.
pointer() - (*this)(addressof_tag{});
1716template<
typename Byte,
typename BlockLengthType>
1722 template<
typename Byte2,
typename BlockLengthType2>
1730 Byte* ptr, Byte* end, BlockLengthType block_length) noexcept
1738 const std::size_t size,
1739 const BlockLengthType block_length) noexcept
1745 template<
typename Byte2,
typename = enable_if_convertible_t<Byte2, Byte>>
1747 cursor<Byte2>& c, Byte* end_ptr, BlockLengthType block_length) noexcept
1748 :
entry_base{c.pointer(), end_ptr, block_length}
1757 template<
typename Byte2,
typename = enable_if_convertible_t<Byte2, Byte>>
1764 constexpr BlockLengthType operator()(get_block_length_tag)
const noexcept
1766 return block_length;
1769 constexpr Byte* operator()(get_level_tag)
const noexcept
1771 return (*
this)(addressof_tag{});
1775 BlockLengthType block_length{};
1778template<
typename Entry>
1782 explicit constexpr arrow_proxy(Entry entry) noexcept : entry{entry}
1786 constexpr const Entry* operator->() const noexcept
1799 typename DifferenceType,
1800 typename BlockLengthType>
1801class forward_iterator
1804 using iterator_category = std::forward_iterator_tag;
1805 using value_type = ValueType;
1806 using reference = value_type;
1807 using difference_type = DifferenceType;
1808 using pointer = arrow_proxy<value_type>;
1810 forward_iterator() =
default;
1812 SBEPP_CPP14_CONSTEXPR forward_iterator(
1814 const IndexType index,
1815 const BlockLengthType block_length,
1819 block_length{block_length}
1820#if SBEPP_SIZE_CHECKS_ENABLED
1828 constexpr reference operator*() const noexcept
1830#if SBEPP_SIZE_CHECKS_ENABLED
1831 return {ptr, end, block_length};
1833 return {ptr,
nullptr, block_length};
1837 constexpr pointer operator->() const noexcept
1839 return pointer{operator*()};
1842 SBEPP_CPP14_CONSTEXPR forward_iterator& operator++() noexcept
1850 SBEPP_CPP14_CONSTEXPR forward_iterator operator++(
int)
noexcept
1857 friend constexpr bool operator==(
1858 const forward_iterator& lhs,
const forward_iterator& rhs)
noexcept
1860 return lhs.index == rhs.index;
1863 friend constexpr bool operator!=(
1864 const forward_iterator& lhs,
const forward_iterator& rhs)
noexcept
1866 return lhs.index != rhs.index;
1872 BlockLengthType block_length{};
1873#if SBEPP_SIZE_CHECKS_ENABLED
1881 typename BlockLengthType,
1882 typename DifferenceType,
1884class random_access_iterator
1887 using iterator_category = std::random_access_iterator_tag;
1888 using value_type = ValueType;
1889 using reference = value_type;
1890 using difference_type = DifferenceType;
1891 using pointer = arrow_proxy<value_type>;
1893 random_access_iterator() =
default;
1895 SBEPP_CPP14_CONSTEXPR random_access_iterator(
1897 const BlockLengthType block_length,
1898 const IndexType index,
1901 block_length{block_length},
1903#if SBEPP_SIZE_CHECKS_ENABLED
1911 constexpr reference operator*() const noexcept
1913#if SBEPP_SIZE_CHECKS_ENABLED
1914 return {ptr, end, block_length};
1916 return {ptr,
nullptr, block_length};
1920 constexpr pointer operator->() const noexcept
1922 return pointer{operator*()};
1925 SBEPP_CPP14_CONSTEXPR random_access_iterator& operator++() noexcept
1927 SBEPP_SIZE_CHECK(ptr, end, 0, block_length);
1928 ptr += block_length;
1933 SBEPP_CPP14_CONSTEXPR random_access_iterator operator++(
int)
noexcept
1940 SBEPP_CPP14_CONSTEXPR random_access_iterator& operator--() noexcept
1942 ptr -= block_length;
1947 SBEPP_CPP14_CONSTEXPR random_access_iterator operator--(
int)
noexcept
1954 SBEPP_CPP14_CONSTEXPR random_access_iterator&
1955 operator+=(difference_type n)
noexcept
1957 ptr += n * block_length;
1962 SBEPP_CPP14_CONSTEXPR random_access_iterator
1963 operator+(difference_type n)
const noexcept
1969 friend constexpr random_access_iterator
1970 operator+(difference_type n,
const random_access_iterator& it)
noexcept
1975 SBEPP_CPP14_CONSTEXPR random_access_iterator&
1976 operator-=(difference_type n)
noexcept
1981 SBEPP_CPP14_CONSTEXPR random_access_iterator
1982 operator-(difference_type n)
const noexcept
1988 constexpr difference_type
1989 operator-(
const random_access_iterator& rhs)
const noexcept
1991 return index - rhs.index;
1994 constexpr reference operator[](difference_type n)
const noexcept
1996 return *(*
this + n);
1999 friend constexpr bool operator==(
2000 const random_access_iterator& lhs,
2001 const random_access_iterator& rhs)
noexcept
2003 return lhs.index == rhs.index;
2006 friend constexpr bool operator!=(
2007 const random_access_iterator& lhs,
2008 const random_access_iterator& rhs)
noexcept
2010 return lhs.index != rhs.index;
2013 friend constexpr bool operator<(
2014 const random_access_iterator& lhs,
2015 const random_access_iterator& rhs)
noexcept
2017 return lhs.index < rhs.index;
2020 friend constexpr bool operator<=(
2021 const random_access_iterator& lhs,
2022 const random_access_iterator& rhs)
noexcept
2024 return lhs.index <= rhs.index;
2027 friend constexpr bool operator>(
2028 const random_access_iterator& lhs,
2029 const random_access_iterator& rhs)
noexcept
2031 return lhs.index > rhs.index;
2034 friend constexpr bool operator>=(
2035 const random_access_iterator& lhs,
2036 const random_access_iterator& rhs)
noexcept
2038 return lhs.index >= rhs.index;
2043 BlockLengthType block_length{};
2047#if SBEPP_SIZE_CHECKS_ENABLED
2055 typename CursorType,
2056 typename BlockLengthType,
2061 using iterator_category = std::input_iterator_tag;
2062 using value_type = ValueType;
2063 using reference = value_type;
2064 using difference_type =
typename std::make_signed<IndexType>::type;
2065 using pointer = arrow_proxy<value_type>;
2067 input_iterator() =
default;
2069 SBEPP_CPP14_CONSTEXPR input_iterator(
2070 const IndexType index,
2072 BlockLengthType block_length,
2076 block_length{block_length}
2077#if SBEPP_SIZE_CHECKS_ENABLED
2085 constexpr reference operator*() const noexcept
2087#if SBEPP_SIZE_CHECKS_ENABLED
2088 return {*cursor, end, block_length};
2090 return {*cursor,
nullptr, block_length};
2094 constexpr pointer operator->() const noexcept
2096 return pointer{operator*()};
2099 SBEPP_CPP14_CONSTEXPR input_iterator& operator++() noexcept
2105 SBEPP_CPP14_CONSTEXPR input_iterator operator++(
int)
noexcept
2112 friend constexpr bool operator==(
2113 const input_iterator& lhs,
const input_iterator& rhs)
noexcept
2115 return lhs.index == rhs.index;
2118 friend constexpr bool operator!=(
2119 const input_iterator& lhs,
const input_iterator& rhs)
noexcept
2121 return lhs.index != rhs.index;
2126 CursorType* cursor{};
2127 BlockLengthType block_length{};
2128#if SBEPP_SIZE_CHECKS_ENABLED
2136 typename CursorType,
2137 typename BlockLengthType,
2142 SBEPP_CPP14_CONSTEXPR cursor_range(
2144 BlockLengthType block_length,
2146 IndexType start_pos,
2147 IndexType length) noexcept
2149 block_length{block_length},
2150 start_pos{start_pos},
2151#if SBEPP_SIZE_CHECKS_ENABLED
2160 input_iterator<ValueType, IndexType, CursorType, BlockLengthType, Byte>;
2162 constexpr iterator begin() const noexcept
2164#if SBEPP_SIZE_CHECKS_ENABLED
2165 return {start_pos, cursor, block_length, end_ptr};
2167 return {start_pos, cursor, block_length,
nullptr};
2171 constexpr iterator end() const noexcept
2173#if SBEPP_SIZE_CHECKS_ENABLED
2175 static_cast<IndexType
>(start_pos + size()),
2181 static_cast<IndexType
>(start_pos + size()),
2188 constexpr IndexType size() const noexcept
2194 CursorType* cursor{};
2195 BlockLengthType block_length{};
2196 IndexType start_pos{};
2197#if SBEPP_SIZE_CHECKS_ENABLED
2204template<
typename Byte,
typename Entry,
typename Dimension>
2214 decltype(std::declval<Dimension>().numInGroup())>::type;
2224 typename std::decay<
2225 decltype(std::declval<Dimension>().blockLength().value())>::type,
2232 SBEPP_CPP14_CONSTEXPR Dimension operator()(get_header_tag)
const noexcept
2234 Dimension header{(*this)(addressof_tag{}), (*
this)(end_ptr_tag{})};
2236 (*
this)(addressof_tag{}),
2237 (*
this)(end_ptr_tag{}),
2243 SBEPP_CPP20_CONSTEXPR std::size_t operator()(size_bytes_tag)
const noexcept
2245 auto dimension = (*this)(get_header_tag{});
2247 + dimension.numInGroup().value()
2248 * dimension.blockLength().value();
2254 return (*
this)(get_header_tag{}).numInGroup();
2266 (*this)(get_header_tag{}).numInGroup(count);
2270 SBEPP_CPP17_NODISCARD SBEPP_CPP20_CONSTEXPR
bool empty() const noexcept
2278 return sbe_size_type::max_value();
2284 auto dimension = (*this)(get_header_tag{});
2287 dimension.blockLength().value(),
2289 (*this)(end_ptr_tag{})};
2296 (*this)(addressof_tag{}) + (*
this)(size_bytes_tag{}),
2297 (*
this)(get_header_tag{}).blockLength().value(),
2299 (*this)(end_ptr_tag{})};
2306 SBEPP_ASSERT(pos <
size());
2307 return *(
begin() + pos);
2314 SBEPP_ASSERT(!
empty());
2322 SBEPP_ASSERT(!
empty());
2328 SBEPP_CPP14_CONSTEXPR
void clear() const noexcept
2334 template<
typename Byte2>
2339 typename std::decay<
2340 decltype(std::declval<Dimension>().blockLength().value())>::type,
2346 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2352 (*this)(get_header_tag{}).blockLength().value(),
2353 (*this)(end_ptr_tag{}),
2362 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2363 SBEPP_CPP20_CONSTEXPR cursor_range_t<Byte2>
2366 SBEPP_ASSERT(pos <
size());
2370 (*this)(get_header_tag{}).blockLength().value(),
2371 (*this)(end_ptr_tag{}),
2381 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2387 SBEPP_ASSERT(pos <
size());
2388 SBEPP_ASSERT(count <= (
size() - pos));
2392 (*this)(get_header_tag{}).blockLength().value(),
2393 (*this)(end_ptr_tag{}),
2399 template<
typename Byte2>
2405 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2415 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2416 SBEPP_CPP20_CONSTEXPR cursor_iterator<Byte2>
2422 template<
typename Visitor,
typename Cursor>
2423 SBEPP_CPP14_CONSTEXPR
bool
2424 operator()(visit_children_tag, Visitor& v, Cursor& c)
2426 for(
const auto entry : this->cursor_range(c))
2428 if(v.template on_entry(entry, c))
2438template<
typename Byte,
typename Entry,
typename Dimension>
2448 decltype(std::declval<Dimension>().numInGroup())>::type;
2461 typename std::decay<
2462 decltype(std::declval<Dimension>().blockLength().value())>::type>;
2467 SBEPP_CPP14_CONSTEXPR Dimension operator()(get_header_tag)
const noexcept
2469 Dimension header{(*this)(addressof_tag{}), (*
this)(end_ptr_tag{})};
2471 (*
this)(addressof_tag{}),
2472 (*
this)(end_ptr_tag{}),
2478 SBEPP_CPP20_CONSTEXPR std::size_t operator()(size_bytes_tag)
const noexcept
2481 for(
const auto entry : *this)
2492 return (*
this)(get_header_tag{}).numInGroup();
2504 (*this)(get_header_tag{}).numInGroup(count);
2508 SBEPP_CPP17_NODISCARD SBEPP_CPP20_CONSTEXPR
bool empty() const noexcept
2516 return sbe_size_type::max_value();
2522 auto dimension = (*this)(get_header_tag{});
2526 dimension.blockLength().value(),
2527 (*this)(end_ptr_tag{})};
2535 (*this)(get_header_tag{}).numInGroup().value(),
2536 (*this)(get_header_tag{}).blockLength().value(),
2537 (*this)(end_ptr_tag{})};
2544 SBEPP_ASSERT(!
empty());
2550 SBEPP_CPP14_CONSTEXPR
void clear() const noexcept
2556 template<
typename Byte2>
2561 typename std::decay<
2562 decltype(std::declval<Dimension>().blockLength().value())>::type,
2568 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2574 (*this)(get_header_tag{}).blockLength().value(),
2575 (*this)(end_ptr_tag{}),
2584 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2585 SBEPP_CPP20_CONSTEXPR cursor_range_t<Byte2>
2588 SBEPP_ASSERT(pos <
size());
2592 (*this)(get_header_tag{}).blockLength().value(),
2593 (*this)(end_ptr_tag{}),
2603 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2609 SBEPP_ASSERT(pos <
size());
2610 SBEPP_ASSERT(count <= (
size() - pos));
2614 (*this)(get_header_tag{}).blockLength().value(),
2615 (*this)(end_ptr_tag{}),
2621 template<
typename Byte2>
2627 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2637 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2638 SBEPP_CPP20_CONSTEXPR cursor_iterator<Byte2>
2644 template<
typename Visitor,
typename Cursor>
2645 SBEPP_CPP14_CONSTEXPR
bool
2646 operator()(visit_children_tag, Visitor& v, Cursor& c)
2648 for(
const auto entry : this->cursor_range(c))
2650 if(v.template on_entry(entry, c))
2688 return bits & (1 << n);
2691 SBEPP_CPP14_CONSTEXPR
void
2692 operator()(set_bit_tag,
const choice_index_t n,
const bool b)
noexcept
2694 bits = ((bits & ~(1 << n)) | (b << n));
2698 constexpr friend bool
2701 return *lhs == *rhs;
2705 constexpr friend bool
2708 return *lhs != *rhs;
2715template<
typename View,
typename =
void_t<>>
2716struct has_get_header : std::false_type
2720template<
typename View>
2721struct has_get_header<
2723 void_t<decltype(
sbepp::
get_header(std::declval<View>()))>> : std::true_type
2729 typename = detail::enable_if_t<detail::has_get_header<View>::value>>
2730constexpr std::size_t get_header_size(View view)
noexcept
2737 typename = detail::enable_if_t<!detail::has_get_header<View>::value>,
2739constexpr std::size_t get_header_size(View)
noexcept
2752template<
typename Enum>
2753constexpr typename std::underlying_type<Enum>::type
2756 return static_cast<typename std::underlying_type<Enum>::type
>(e);
2772template<
typename View>
2794template<
typename View>
2795SBEPP_CPP14_CONSTEXPR cursor<typename std::add_const<byte_type_t<View>>::type>
2836template<
typename From,
typename To>
2837struct copy_cv_qualifiers
2839 using copy_const_t =
typename std::
2840 conditional<std::is_const<From>::value,
const To, To>::type;
2842 using type =
typename std::conditional<
2843 std::is_volatile<From>::value,
2844 volatile copy_const_t,
2845 copy_const_t>::type;
2848template<
typename From,
typename To>
2849using apply_cv_qualifiers_t =
typename copy_cv_qualifiers<From, To>::type;
2853using is_range = std::bool_constant<std::ranges::range<R>>;
2855template<
typename R,
typename =
void_t<>>
2856struct is_range : std::false_type
2864 decltype(std::begin(std::declval<R>())),
2865 decltype(std::end(std::declval<R>()))>> : std::true_type
2870constexpr bool is_constant_evaluated() noexcept
2875#if SBEPP_HAS_IS_CONSTANT_EVALUATED
2876 return std::is_constant_evaluated();
2882inline SBEPP_CPP20_CONSTEXPR std::size_t string_length(
const char* str)
noexcept
2884 if(is_constant_evaluated())
2886 std::size_t length{};
2888 for(; *str !=
'\0'; str++, length++)
2896 return std::strlen(str);
2907template<
typename Byte,
typename Value, std::
size_t N,
typename Tag>
2934 constexpr std::size_t operator()(detail::size_bytes_tag)
const noexcept
2943 SBEPP_ASSERT(pos <
size());
2965 (*
this)(detail::addressof_tag{}),
2966 (*
this)(detail::end_ptr_tag{}),
2969 return (
pointer)(*this)(detail::addressof_tag{});
2973 SBEPP_CPP17_NODISCARD
static constexpr bool empty() noexcept
3029 (*this)(detail::addressof_tag{}), (*
this)(detail::end_ptr_tag{})};
3038 SBEPP_CPP20_CONSTEXPR std::size_t
strlen() const noexcept
3040 if(is_constant_evaluated())
3042 return string_length(
data());
3046 const auto first_null =
static_cast<const value_type*
>(
3047 std::memchr(
data(),
'\0',
size()));
3050 return first_null -
data();
3063 SBEPP_CPP20_CONSTEXPR std::size_t
strlen_r() const noexcept
3065 const auto last_non_null = std::find_if(
3070 return value !=
'\0';
3086 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3090 SBEPP_ASSERT(str !=
nullptr);
3091 const auto length = string_length(str);
3092 SBEPP_ASSERT(length <=
size());
3093 const auto eos_pos = std::copy_n(str, length,
begin());
3094 pad(eos_mode, eos_pos);
3113 enable_if_t<!std::is_const<Byte>::value && is_range<R>::value>>
3118 pad(eos_mode, eos_pos);
3134 enable_if_t<!std::is_const<Byte>::value && is_range<R>::value>>
3138 auto res = std::ranges::copy(std::forward<R>(r),
begin()).out;
3140 auto res = std::copy(std::begin(r), std::end(r),
begin());
3142 SBEPP_ASSERT(res <=
end());
3151 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3165 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3169 SBEPP_ASSERT(count <=
size());
3170 return std::fill_n(
begin(), count, value);
3176 template<
typename InputIt,
typename = enable_if_writable_t<Byte, InputIt>>
3179 const auto last_out = std::copy(first, last,
begin());
3191 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3193 assign(std::initializer_list<value_type> ilist)
const noexcept
3195 SBEPP_ASSERT(ilist.size() <=
size());
3196 return assign(std::begin(ilist), std::end(ilist));
3200 SBEPP_CPP20_CONSTEXPR
void
3205 std::fill(eos_pos,
end(),
'\0');
3209 if(eos_pos !=
end())
3229template<
typename Byte,
typename Value,
typename Length, endian E>
3234 std::is_unsigned<typename Length::value_type>::value,
3235 "Length must be unsigned");
3263 return data_checked();
3288 SBEPP_ASSERT(!
empty());
3296 SBEPP_ASSERT(!
empty());
3309 return data_checked();
3316 SBEPP_ASSERT(pos <
size());
3317 return *(
data() + pos);
3323 return detail::get_value<size_type, size_type, E>(*
this, 0);
3333 SBEPP_CPP17_NODISCARD SBEPP_CPP20_CONSTEXPR
bool empty() const noexcept
3341 return sbe_size_type::max_value();
3345 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3346 SBEPP_CPP20_CONSTEXPR
void clear() const noexcept
3352 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3355 const auto old_size =
size();
3357 if(count > old_size)
3359 for(
auto i = old_size; i != count; i++)
3367 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3368 SBEPP_CPP20_CONSTEXPR
void
3371 const auto old_size =
size();
3373 if(count > old_size)
3375 for(
auto i = old_size; i != count; i++)
3383 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3384 SBEPP_CPP20_CONSTEXPR
void
3390 (*
this)(addressof_tag{}),
3391 (*
this)(end_ptr_tag{}),
3394 set_primitive<E>((*
this)(addressof_tag{}), count);
3398 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3401 const auto current_size =
size();
3403 (*this)[current_size] = value;
3407 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3410 SBEPP_ASSERT(!
empty());
3415 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3418 SBEPP_ASSERT(pos >=
begin() && pos <
end());
3419 std::copy(pos + 1,
end(), pos);
3425 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3429 SBEPP_ASSERT(first >=
begin() && last <
end());
3430 std::copy(last,
end(), first);
3436 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3440 SBEPP_ASSERT(pos >=
begin() && pos <=
end());
3441 const auto old_end =
end();
3443 std::copy_backward(pos, old_end,
end());
3449 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3453 SBEPP_ASSERT(pos >=
begin() && pos <=
end());
3454 const auto old_end =
end();
3456 std::copy_backward(pos, old_end,
end());
3457 std::fill_n(pos, count, value);
3464 typename = detail::enable_if_t<
3465 !std::is_const<Byte>::value
3466 && std::is_convertible<
3467 typename std::iterator_traits<InputIt>::iterator_category,
3468 std::input_iterator_tag>::value>>
3472 SBEPP_ASSERT(pos >=
begin() && pos <=
end());
3474 typename std::iterator_traits<InputIt>::iterator_category;
3475 return insert_impl(pos, first, last, category_t{});
3479 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3481 iterator pos, std::initializer_list<value_type> ilist)
const noexcept
3483 return insert(pos, std::begin(ilist), std::end(ilist));
3488 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3489 SBEPP_CPP20_CONSTEXPR
void
3493 std::fill_n(
begin(), count, value);
3498 template<
typename InputIt,
typename = enable_if_writable_t<Byte, InputIt>>
3499 SBEPP_CPP20_CONSTEXPR
void assign(InputIt first, InputIt last)
const
3501 auto begin = data_unchecked();
3502 const auto new_end = std::copy(first, last,
begin);
3508 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3509 SBEPP_CPP20_CONSTEXPR
void
3510 assign(std::initializer_list<value_type> ilist)
const noexcept
3513 (*
this)(detail::addressof_tag{}),
3514 (*
this)(detail::end_ptr_tag{}),
3517 assign(std::begin(ilist), std::end(ilist));
3530 (*this)(detail::addressof_tag{}), (*
this)(detail::end_ptr_tag{})};
3533 SBEPP_CPP20_CONSTEXPR std::size_t
3534 operator()(detail::size_bytes_tag)
const noexcept
3545 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3548 SBEPP_ASSERT(str !=
nullptr);
3549 const auto length = string_length(str);
3551 std::copy_n(str, length,
begin());
3564 enable_if_t<!std::is_const<Byte>::value && is_range<R>::value>>
3567 const auto begin = data_unchecked();
3569 const auto new_end = std::ranges::copy(std::forward<R>(r),
begin).out;
3571 const auto new_end = std::copy(std::begin(r), std::end(r),
begin);
3577 SBEPP_CPP14_CONSTEXPR
pointer data_checked() const noexcept
3580 (*
this)(detail::addressof_tag{}),
3581 (*
this)(detail::end_ptr_tag{}),
3584 return data_unchecked();
3587 SBEPP_CPP14_CONSTEXPR
pointer data_unchecked() const noexcept
3590 (*
this)(detail::addressof_tag{}),
3591 (*
this)(detail::end_ptr_tag{}),
3604 template<
typename It>
3605 SBEPP_CPP14_CONSTEXPR
iterator insert_impl(
3606 iterator pos, It first, It last, std::input_iterator_tag)
const
3609 for(; first != last; ++first, ++out)
3617 template<
typename It>
3618 SBEPP_CPP20_CONSTEXPR
iterator insert_impl(
3619 iterator pos, It first, It last, std::forward_iterator_tag)
const
3621 const auto in_size = std::distance(first, last);
3622 auto old_end =
end();
3624 std::copy_backward(pos, old_end,
end());
3625 std::copy(first, last, pos);
3652template<
typename T,
typename Derived>
3690 return (Derived::min_value() <= val) && (val <= Derived::max_value());
3702#if SBEPP_HAS_THREE_WAY_COMPARISON
3707 constexpr friend bool
3710 return *lhs == *rhs;
3714 constexpr friend bool
3717 return *lhs != *rhs;
3721 constexpr friend bool
3728 constexpr friend bool
3731 return *lhs <= *rhs;
3735 constexpr friend bool
3742 constexpr friend bool
3745 return *lhs >= *rhs;
3759template<
typename T,
typename Derived>
3803 return (Derived::min_value() <= val) && (val <= Derived::max_value());
3813 return default_value;
3819 return (val != Derived::null_value());
3823 constexpr explicit operator bool() const noexcept
3836 constexpr friend bool
3839 return *lhs == *rhs;
3848#if SBEPP_HAS_THREE_WAY_COMPARISON
3849 constexpr friend std::strong_ordering
3854 return *lhs <=> *rhs;
3856 return lhs.has_value() <=> rhs.has_value();
3861 constexpr friend bool
3864 return *lhs != *rhs;
3868 constexpr friend bool
3871 return rhs && (!lhs || (*lhs < *rhs));
3875 constexpr friend bool
3878 return !lhs || (rhs && (*lhs <= *rhs));
3882 constexpr friend bool
3885 return lhs && (!rhs || (*lhs > *rhs));
3889 constexpr friend bool
3892 return !rhs || (lhs && (*lhs >= *rhs));
3898 value_type val{Derived::null_value()};
3916template<
typename Message>
3918 ->
decltype(m(detail::fill_message_header_tag{}))
3920 return m(detail::fill_message_header_tag{});
3936template<
typename Group,
typename Size>
3938 ->
decltype(g(detail::fill_group_header_tag{}, num_in_group))
3940 return g(detail::fill_group_header_tag{}, num_in_group);
3975 template<
typename Byte>
3979 static constexpr const char*
name() noexcept;
3982 static constexpr const
char* description() noexcept;
4015 static constexpr const
char* semantic_type() noexcept;
4025 static constexpr const
char* character_encoding() noexcept;
4052 static constexpr const
char* semantic_version() noexcept;
4054 static constexpr
endian byte_order() noexcept;
4056 static constexpr const
char* description() noexcept;
4062 template<typename Byte>
4086 static constexpr const char*
name() noexcept;
4088 static constexpr const
char* description() noexcept;
4123 static constexpr const char*
name() noexcept;
4125 static constexpr const
char* description() noexcept;
4132 static constexpr ScopedEnumType value() noexcept;
4153 static constexpr const char*
name() noexcept;
4155 static constexpr const
char* description() noexcept;
4190 static constexpr const char*
name() noexcept;
4192 static constexpr const
char* description() noexcept;
4220 static constexpr const char*
name() noexcept;
4222 static constexpr const
char* description() noexcept;
4229 static constexpr const
char* semantic_type() noexcept;
4240 template<typename Byte>
4243 static constexpr std::
size_t size_bytes() noexcept;
4264 static constexpr const char*
name() noexcept;
4266 static constexpr const
char* description() noexcept;
4272 static constexpr const
char* semantic_type() noexcept;
4283 template<typename Byte>
4365 static constexpr std::
size_t size_bytes(...) noexcept;
4386 static constexpr const char*
name() noexcept;
4390 static constexpr const
char* description() noexcept;
4411 template<typename Byte>
4435 static constexpr const char*
name() noexcept;
4437 static constexpr const
char* description() noexcept;
4443 static constexpr const
char* semantic_type() noexcept;
4454 template<typename Byte>
4461 template<typename Byte>
4470 template<typename Byte>
4483 static constexpr std::
size_t
4484 size_bytes(const NumInGroupType num_in_group, ...) noexcept;
4505 static constexpr const char*
name() noexcept;
4509 static constexpr const
char* description() noexcept;
4520 template<typename Byte>
4532 static constexpr std::
size_t
4560template<
typename ValueType>
4564template<
typename ValueType>
4573template<
typename ValueType>
4576template<
typename Byte,
typename Value, std::
size_t N,
typename Tag>
4577struct traits_tag<detail::static_array_ref<Byte, Value, N, Tag>>
4583#define SBEPP_BUILT_IN_IMPL(NAME, TYPE, MIN, MAX, NULL) \
4586 class NAME##_t : public detail::required_base<TYPE, NAME##_t> \
4589 using detail::required_base<TYPE, NAME##_t>::required_base; \
4592 static constexpr value_type min_value() noexcept \
4598 static constexpr value_type max_value() noexcept \
4606 class NAME##_opt_t : public detail::optional_base<TYPE, NAME##_opt_t> \
4609 using detail::optional_base<TYPE, NAME##_opt_t>::optional_base; \
4612 static constexpr value_type min_value() noexcept \
4618 static constexpr value_type max_value() noexcept \
4624 static constexpr value_type null_value() noexcept \
4631 class type_traits<NAME##_t> \
4634 static constexpr const char* name() noexcept \
4639 static constexpr const char* description() noexcept \
4644 static constexpr field_presence presence() noexcept \
4646 return field_presence::required; \
4649 static constexpr TYPE min_value() noexcept \
4651 return NAME##_t::min_value(); \
4654 static constexpr TYPE max_value() noexcept \
4656 return NAME##_t::max_value(); \
4659 static constexpr length_t length() noexcept \
4664 static constexpr const char* semantic_type() noexcept \
4669 static constexpr version_t since_version() noexcept \
4674 using value_type = NAME##_t; \
4675 using primitive_type = value_type::value_type; \
4679 struct traits_tag<NAME##_t> \
4681 using type = NAME##_t; \
4685 class type_traits<NAME##_opt_t> \
4688 static constexpr const char* name() noexcept \
4693 static constexpr const char* description() noexcept \
4698 static constexpr field_presence presence() noexcept \
4700 return field_presence::optional; \
4703 static constexpr TYPE min_value() noexcept \
4705 return NAME##_opt_t::min_value(); \
4708 static constexpr TYPE max_value() noexcept \
4710 return NAME##_opt_t::max_value(); \
4713 static constexpr TYPE null_value() noexcept \
4715 return NAME##_opt_t::null_value(); \
4718 static constexpr length_t length() noexcept \
4723 static constexpr const char* semantic_type() noexcept \
4728 static constexpr version_t since_version() noexcept \
4733 using value_type = NAME##_opt_t; \
4734 using primitive_type = value_type::value_type; \
4738 struct traits_tag<NAME##_opt_t> \
4740 using type = NAME##_opt_t; \
4743SBEPP_BUILT_IN_IMPL(
char,
char, 0x20, 0x7E, 0);
4747 std::numeric_limits<std::int8_t>::min() + 1,
4748 std::numeric_limits<std::int8_t>::max(),
4749 std::numeric_limits<std::int8_t>::min());
4753 std::numeric_limits<std::uint8_t>::min(),
4754 std::numeric_limits<std::uint8_t>::max() - 1,
4755 std::numeric_limits<std::uint8_t>::max());
4759 std::numeric_limits<std::int16_t>::min() + 1,
4760 std::numeric_limits<std::int16_t>::max(),
4761 std::numeric_limits<std::int16_t>::min());
4765 std::numeric_limits<std::uint16_t>::min(),
4766 std::numeric_limits<std::uint16_t>::max() - 1,
4767 std::numeric_limits<std::uint16_t>::max());
4771 std::numeric_limits<std::int32_t>::min() + 1,
4772 std::numeric_limits<std::int32_t>::max(),
4773 std::numeric_limits<std::int32_t>::min());
4777 std::numeric_limits<std::uint32_t>::min(),
4778 std::numeric_limits<std::uint32_t>::max() - 1,
4779 std::numeric_limits<std::uint32_t>::max());
4783 std::numeric_limits<std::int64_t>::min() + 1,
4784 std::numeric_limits<std::int64_t>::max(),
4785 std::numeric_limits<std::int64_t>::min());
4789 std::numeric_limits<std::uint64_t>::min(),
4790 std::numeric_limits<std::uint64_t>::max() - 1,
4791 std::numeric_limits<std::uint64_t>::max());
4795 std::numeric_limits<float>::min(),
4796 std::numeric_limits<float>::max(),
4797 std::numeric_limits<float>::quiet_NaN());
4801 std::numeric_limits<double>::min(),
4802 std::numeric_limits<double>::max(),
4803 std::numeric_limits<double>::quiet_NaN());
4805#undef SBEPP_BUILT_IN_IMPL
4824template<
template<
typename>
class View,
typename Byte>
4825constexpr View<Byte>
make_view(Byte* ptr,
const std::size_t size)
noexcept
4848template<
template<
typename>
class View,
typename Byte>
4849constexpr View<typename std::add_const<Byte>::type>
4861struct unknown_enum_value_tag
4868template<
template<
typename...>
class Base,
typename Derived>
4869struct is_base_of_tmp_impl
4871 static constexpr std::false_type test(...);
4873 template<
typename... Ts>
4874 static constexpr std::true_type test(Base<Ts...>*);
4876 using type =
decltype(test(std::declval<Derived*>()));
4879template<
template<
typename...>
class Base,
typename Derived>
4880using is_base_of_tmp =
typename is_base_of_tmp_impl<Base, Derived>::type;
4882#if SBEPP_HAS_CONCEPTS
4883template<
typename Derived,
template<
typename...>
class Base>
4884concept derived_from_tmp = is_base_of_tmp<Base, Derived>::value;
4890template<
typename Derived>
4891struct is_array_type_impl
4893 static constexpr std::false_type test(...);
4895 template<
typename T1,
typename T2, std::
size_t N,
typename T3>
4896 static constexpr std::true_type
4897 test(detail::static_array_ref<T1, T2, N, T3>*);
4899 using type =
decltype(test(std::declval<Derived*>()));
4905using is_array_type =
typename detail::is_array_type_impl<T>::type;
4923using is_type = std::integral_constant<
4929template<
typename T,
typename =
void>
4930struct is_enum : std::false_type
4937 detail::void_t<decltype(tag_invoke(
4938 std::declval<detail::visit_tag>(),
4940 std::declval<int&>()))>> : std::true_type
4946using is_set = detail::is_base_of_tmp<detail::bitset_base, T>;
4950using is_composite = detail::is_base_of_tmp<detail::composite_base, T>;
4954using is_message = detail::is_base_of_tmp<detail::message_base, T>;
4958using is_flat_group = detail::is_base_of_tmp<detail::flat_group_base, T>;
4962using is_nested_group = detail::is_base_of_tmp<detail::nested_group_base, T>;
4966using is_group = std::integral_constant<
4972using is_group_entry = detail::is_base_of_tmp<detail::entry_base, T>;
4976template<
typename Derived>
4979 static constexpr std::false_type test(...);
4981 template<
typename T1,
typename T2,
typename T3, endian E>
4982 static constexpr std::true_type
4985 using type =
decltype(test(std::declval<Derived*>()));
4991using is_data =
typename detail::is_data_impl<T>::type;
4993#if SBEPP_HAS_INLINE_VARS
5047#if SBEPP_HAS_CONCEPTS
5066concept type = is_type_v<T>;
5074concept set = is_set_v<T>;
5082concept message = is_message_v<T>;
5094concept group = is_group_v<T>;
5098concept data = is_data_v<T>;
5104using is_visitable_view = std::integral_constant<
5106 is_message<T>::value || is_group<T>::value || is_group_entry<T>::value
5107 || is_composite<T>::value>;
5125 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5126SBEPP_CPP14_CONSTEXPR Visitor&&
5127 visit(View view, Cursor& c, Visitor&& visitor = {})
5129 view(detail::visit_tag{}, visitor, c);
5130 return std::forward<Visitor>(visitor);
5146 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5147SBEPP_CPP14_CONSTEXPR Visitor&&
visit(View view, Visitor&& visitor = {})
5150 return sbepp::visit(view, c, std::forward<Visitor>(visitor));
5153#ifndef SBEPP_DOXYGEN
5154template<
typename Visitor,
typename Set>
5155SBEPP_CPP14_CONSTEXPR detail::enable_if_t<is_set<Set>::value, Visitor&&>
5156 visit(Set s, Visitor&& visitor = {})
5158 s(detail::visit_tag{}, visitor);
5159 return std::forward<Visitor>(visitor);
5162template<
typename Visitor,
typename Enum>
5163SBEPP_CPP14_CONSTEXPR detail::enable_if_t<is_enum<Enum>::value, Visitor&&>
5164 visit(Enum e, Visitor&& visitor = {})
5166 tag_invoke(detail::visit_tag{}, e, visitor);
5167 return std::forward<Visitor>(visitor);
5188template<
typename Visitor,
typename Set>
5189SBEPP_CPP14_CONSTEXPR Visitor&&
visit(Set s, Visitor&& visitor = {});
5207template<
typename Visitor,
typename Enum>
5208SBEPP_CPP14_CONSTEXPR Visitor&&
visit(Enum e, Visitor&& visitor = {});
5227 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5228SBEPP_CPP14_CONSTEXPR Visitor&&
5231 view(detail::visit_children_tag{}, visitor, c);
5232 return std::forward<Visitor>(visitor);
5248 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5249SBEPP_CPP14_CONSTEXPR Visitor&&
5258class enum_to_string_visitor
5261 template<
typename Enum,
typename Tag>
5262 SBEPP_CPP14_CONSTEXPR
void on_enum_value(Enum , Tag)
noexcept
5267 template<
typename Enum>
5268 SBEPP_CPP14_CONSTEXPR
void
5271 name_value =
nullptr;
5274 constexpr const char* name() const noexcept
5280 const char* name_value;
5294template<typename E, typename = detail::enable_if_t<is_enum<E>::value>>
5295SBEPP_DEPRECATED
constexpr const char*
enum_to_string(
const E e)
noexcept
5297 return visit<detail::enum_to_string_visitor>(e).name();
5311template<
typename Set,
typename Visitor>
5312SBEPP_DEPRECATED
constexpr auto
5313 visit_set(
const Set s, Visitor&& visitor)
noexcept
5314 ->
decltype(s(detail::visit_set_tag{}, std::forward<Visitor>(visitor)))
5316 return s(detail::visit_set_tag{}, std::forward<Visitor>(visitor));
5321class size_bytes_checked_visitor
5324 constexpr explicit size_bytes_checked_visitor(
5325 const std::size_t size) noexcept
5330 template<
typename T,
typename Cursor,
typename Tag>
5331 SBEPP_CPP14_CONSTEXPR
void on_message(T m, Cursor& c, Tag)
noexcept
5335 if(!validate_and_subtract(header_size))
5340 if(!validate_and_subtract(*header.blockLength()))
5348 template<
typename T,
typename Cursor,
typename Tag>
5349 SBEPP_CPP14_CONSTEXPR
bool on_group(T g, Cursor& c, Tag)
noexcept
5353 if(!validate_and_subtract(header_size))
5358 const auto prev_block_length =
5359 set_group_block_length(*header.blockLength());
5361 set_group_block_length(prev_block_length);
5366 template<
typename T,
typename Cursor>
5367 SBEPP_CPP14_CONSTEXPR
bool on_entry(T e, Cursor& c)
noexcept
5369 if(!validate_and_subtract(group_block_length))
5377 template<
typename T,
typename Tag>
5378 SBEPP_CPP14_CONSTEXPR
bool on_data(T d, Tag)
noexcept
5384 template<
typename T,
typename Tag>
5385 constexpr bool on_field(T, Tag)
const noexcept
5390 constexpr bool is_valid() const noexcept
5396 SBEPP_CPP14_CONSTEXPR std::size_t
5397 set_group_block_length(
const std::size_t block_length)
noexcept
5399 auto prev = group_block_length;
5400 group_block_length = block_length;
5404 constexpr std::size_t get_size() const noexcept
5413 std::size_t group_block_length{};
5415 SBEPP_CPP14_CONSTEXPR
bool
5416 validate_and_subtract(
const std::size_t n)
noexcept
5433struct size_bytes_checked_result
5452template<
typename View>
5462 detail::size_bytes_checked_visitor visitor{size};
5465 if(visitor.is_valid())
5467 return {
true, size - visitor.get_size()};
5473#if SBEPP_HAS_RANGES && SBEPP_HAS_CONCEPTS
5475template<
typename Byte,
typename Value, std::
size_t N,
typename Tag>
5476inline constexpr bool std::ranges::enable_borrowed_range<
5479template<
typename Byte,
typename Value,
typename Length, sbepp::endian E>
5480inline constexpr bool std::ranges::enable_borrowed_range<
5483template<sbepp::detail::derived_from_tmp<sbepp::detail::flat_group_base> T>
5484inline constexpr bool std::ranges::enable_borrowed_range<T> =
true;
5486template<sbepp::detail::derived_from_tmp<sbepp::detail::nested_group_base> T>
5487inline constexpr bool std::ranges::enable_borrowed_range<T> =
true;
5490#undef SBEPP_CPP17_INLINE_VAR
5491#undef SBEPP_DEPRECATED
5492#undef SBEPP_CPLUSPLUS
Provides various traits/attributes of a <composite> element.
Definition sbepp.hpp:4217
CompositeType< Byte > value_type
Representation type.
Definition sbepp.hpp:4241
static constexpr const char * name() noexcept
Returns name attribute.
Represents cursor which is used in cursor-based API. Clients should not use undocumented methods.
Definition sbepp.hpp:790
constexpr Byte * pointer() const noexcept
access underlying pointer
Definition sbepp.hpp:856
constexpr cursor(cursor< Byte2 > other) noexcept
Construct from another cursor. Enabled only if Byte2* is convertible to Byte*.
Definition sbepp.hpp:819
Byte byte_type
same as Byte
Definition sbepp.hpp:793
cursor()=default
Construct a new cursor object initialized with nullptr
constexpr Byte *& pointer() noexcept
access underlying pointer. Might be useful in rare cases to initialize cursor with a particular value...
Definition sbepp.hpp:846
constexpr cursor & operator=(cursor< Byte2 > other) noexcept
Assign from another cursor. Enabled only if Byte2* is convertible to Byte
Definition sbepp.hpp:834
Provides various traits/attributes of a <data> element.
Definition sbepp.hpp:4502
static constexpr const char * name() noexcept
Returns name attribute.
DataType value_type
Representation type.
Definition sbepp.hpp:4521
LengthTypeTag length_type_tag
length_type tag
Definition sbepp.hpp:4525
LengthType length_type
Length type.
Definition sbepp.hpp:4523
Base class for bitsets.
Definition sbepp.hpp:2663
constexpr T operator*() const noexcept
Returns underlying value.
Definition sbepp.hpp:2680
constexpr friend bool operator==(const bitset_base &lhs, const bitset_base &rhs) noexcept
Tests if underlying values are equal.
Definition sbepp.hpp:2699
constexpr T & operator*() noexcept
Returns reference to underlying value.
Definition sbepp.hpp:2674
constexpr bitset_base(T value) noexcept
Constructs from given value.
Definition sbepp.hpp:2669
constexpr friend bool operator!=(const bitset_base &lhs, const bitset_base &rhs) noexcept
Tests if underlying values are not equal.
Definition sbepp.hpp:2706
bitset_base()=default
Default constructs underlying value to 0
Base class for all reference semantics types.
Definition sbepp.hpp:721
constexpr byte_range(Byte *ptr, const std::size_t size) noexcept
Constructs from pointer and size.
Definition sbepp.hpp:743
constexpr byte_range(const byte_range< Byte2 > &other) noexcept
Copy constructor. Available if Byte2* is convertible to Byte*
Definition sbepp.hpp:751
byte_range()=default
Initializes to nullptr
constexpr byte_range(Byte *begin, Byte *end) noexcept
Constructs from a pair of pointers.
Definition sbepp.hpp:732
Base class for composites.
Definition sbepp.hpp:1667
Represents reference to dynamic arrays used for <data> elements.
Definition sbepp.hpp:3231
constexpr sbe_size_type sbe_size() const noexcept
Returns SBE size representation.
Definition sbepp.hpp:3321
pointer iterator
iterator type. Satisfies std::random_access_iterator
Definition sbepp.hpp:3253
std::reverse_iterator< iterator > reverse_iterator
reverse iterator type
Definition sbepp.hpp:3255
constexpr iterator insert(iterator pos, std::initializer_list< value_type > ilist) const noexcept
Inserts elements from ilist before pos
Definition sbepp.hpp:3480
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator to the end.
Definition sbepp.hpp:3279
static constexpr size_type max_size() noexcept
Returns max value of SBE length representation.
Definition sbepp.hpp:3339
constexpr iterator erase(iterator first, iterator last) const noexcept
Erases elements in [first; last) range.
Definition sbepp.hpp:3427
constexpr void assign_string(const char *str) const noexcept
Assigns null-terminated string.
Definition sbepp.hpp:3546
constexpr iterator insert(iterator pos, InputIt first, InputIt last) const
Inserts elements from [first; last) range before pos
Definition sbepp.hpp:3470
constexpr void assign(std::initializer_list< value_type > ilist) const noexcept
Replaces the contents of the container with the elements from ilist
Definition sbepp.hpp:3510
constexpr reference back() const noexcept
Access the last element.
Definition sbepp.hpp:3294
constexpr void resize(size_type count, sbepp::default_init_t) const noexcept
Sets size to count, default initializes new elements.
Definition sbepp.hpp:3385
element_type * pointer
element pointer type
Definition sbepp.hpp:3251
constexpr void push_back(value_type value) const noexcept
Adds new element to the end.
Definition sbepp.hpp:3399
constexpr iterator insert(iterator pos, const value_type value) const noexcept
Inserts value before pos
Definition sbepp.hpp:3438
constexpr reference operator[](size_type pos) const noexcept
Access element at pos
Definition sbepp.hpp:3314
constexpr void resize(size_type count) const noexcept
Sets size to count, value initializes new elements.
Definition sbepp.hpp:3353
constexpr reference front() const noexcept
Access the first element.
Definition sbepp.hpp:3286
std::ptrdiff_t difference_type
std::ptrdiff_t
Definition sbepp.hpp:3247
constexpr void pop_back() const noexcept
Removes the last element.
Definition sbepp.hpp:3408
Value value_type
same as Value
Definition sbepp.hpp:3241
constexpr dynamic_array_ref< Byte, detail::remove_cv_t< Byte >, Length, E > raw() const noexcept
Returns dynamic_array_ref<Byte, Byte, Length, E>.
Definition sbepp.hpp:3527
detail::apply_cv_qualifiers_t< Byte, Value > element_type
final element type. value_type with the same cv-qualifiers as Byte
Definition sbepp.hpp:3239
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:3261
constexpr void assign_range(R &&r) const
Assigns range.
Definition sbepp.hpp:3565
constexpr iterator insert(iterator pos, size_type count, const value_type value) const noexcept
Inserts count copies of value before pos
Definition sbepp.hpp:3450
constexpr void assign(size_type count, const value_type value) const noexcept
Replaces the contents of the container with count copies of value
Definition sbepp.hpp:3490
constexpr pointer data() const noexcept
Direct access to the underlying array.
Definition sbepp.hpp:3307
constexpr iterator erase(iterator pos) const noexcept
Erases element at pos
Definition sbepp.hpp:3416
constexpr void clear() const noexcept
Sets size to 0.
Definition sbepp.hpp:3346
constexpr bool empty() const noexcept
Checks if size() != 0
Definition sbepp.hpp:3333
constexpr reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the beginning.
Definition sbepp.hpp:3273
constexpr void resize(size_type count, value_type value) const noexcept
Sets size to count, initializes new elements with value
Definition sbepp.hpp:3369
constexpr void assign(InputIt first, InputIt last) const
Replaces the contents of the container with the elements from [first; last) range.
Definition sbepp.hpp:3499
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:3267
constexpr size_type size() const noexcept
Returns raw size.
Definition sbepp.hpp:3327
typename sbe_size_type::value_type size_type
raw size type
Definition sbepp.hpp:3245
Length sbe_size_type
length SBE representation of data's encoding
Definition sbepp.hpp:3243
element_type & reference
element reference type
Definition sbepp.hpp:3249
Base class for group entries.
Definition sbepp.hpp:1718
constexpr entry_base(cursor< Byte2 > &c, Byte *end_ptr, BlockLengthType block_length) noexcept
Constructs from cursor.
Definition sbepp.hpp:1746
constexpr entry_base(const entry_base< Byte2, BlockLengthType > &other) noexcept
Constructs from entry_base of compatible byte type. Available if Byte2* is convertible to Byte*
Definition sbepp.hpp:1758
constexpr entry_base(Byte *ptr, const std::size_t size, const BlockLengthType block_length) noexcept
Constructs from pointer and size.
Definition sbepp.hpp:1736
entry_base()=default
Constructs using nullptr
constexpr entry_base(Byte *ptr, Byte *end, BlockLengthType block_length) noexcept
Constructs from two pointers.
Definition sbepp.hpp:1729
Base class for a flat group.
Definition sbepp.hpp:2206
random_access_iterator< Byte, Entry, typename std::decay< decltype(std::declval< Dimension >().blockLength().value())>::type, difference_type, size_type > iterator
Random access iterator to value_type. Satisfies std::random_access_iterator
Definition sbepp.hpp:2221
constexpr void clear() const noexcept
Resizes to 0
Definition sbepp.hpp:2328
constexpr sbe_size_type sbe_size() const noexcept
Returns header's numInGroup
Definition sbepp.hpp:2252
typename cursor_range_t< Byte2 >::iterator cursor_iterator
cursor_range_t::iterator. Satisfies std::input_iterator
Definition sbepp.hpp:2400
constexpr reference front() const noexcept
Returns the first entry.
Definition sbepp.hpp:2312
constexpr cursor_range_t< Byte2 > cursor_subrange(cursor< Byte2 > &c, const size_type pos) const noexcept
Returns cursor range to [pos; size()) entries.
Definition sbepp.hpp:2364
detail::cursor_range< value_type, size_type, cursor< Byte2 >, typename std::decay< decltype(std::declval< Dimension >().blockLength().value())>::type, Byte > cursor_range_t
Type of a cursor range. Satisfies std::ranges::input_range
Definition sbepp.hpp:2335
typename std::decay< decltype(std::declval< Dimension >().numInGroup())>::type sbe_size_type
numInGroup value type
Definition sbepp.hpp:2213
Entry value_type
Entry type.
Definition sbepp.hpp:2209
constexpr reference operator[](size_type pos) const noexcept
Access group entry at pos
Definition sbepp.hpp:2304
constexpr size_type size() const noexcept
Returns raw size.
Definition sbepp.hpp:2258
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:2282
constexpr cursor_iterator< Byte2 > cursor_begin(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the beginning.
Definition sbepp.hpp:2407
constexpr cursor_range_t< Byte2 > cursor_range(cursor< Byte2 > &c) const noexcept
Returns cursor range to all group entries.
Definition sbepp.hpp:2348
constexpr bool empty() const noexcept
Checks if size() == 0
Definition sbepp.hpp:2270
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:2293
constexpr void resize(const size_type count) const noexcept
Sets numInGroup to count
Definition sbepp.hpp:2264
constexpr cursor_iterator< Byte2 > cursor_end(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the end.
Definition sbepp.hpp:2417
static constexpr size_type max_size() noexcept
Returns numInGroup's maxValue
Definition sbepp.hpp:2276
constexpr reference back() const noexcept
Returns the last entry.
Definition sbepp.hpp:2320
typename std::make_signed< size_type >::type difference_type
signed size_type
Definition sbepp.hpp:2218
constexpr cursor_range_t< Byte2 > cursor_subrange(cursor< Byte2 > &c, const size_type pos, const size_type count) const noexcept
Returns cursor range to [pos; pos+count) entries.
Definition sbepp.hpp:2382
typename sbe_size_type::value_type size_type
Raw size type.
Definition sbepp.hpp:2216
value_type reference
value_type
Definition sbepp.hpp:2211
Base class for messages.
Definition sbepp.hpp:1676
Base class for a nested group.
Definition sbepp.hpp:2440
constexpr size_type size() const noexcept
Returns raw size.
Definition sbepp.hpp:2496
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:2531
constexpr cursor_range_t< Byte2 > cursor_subrange(cursor< Byte2 > &c, const size_type pos) const noexcept
Returns cursor range to [pos; size()) entries.
Definition sbepp.hpp:2586
Entry value_type
entry type
Definition sbepp.hpp:2443
static constexpr size_type max_size() noexcept
Returns numInGroup's maxValue
Definition sbepp.hpp:2514
typename cursor_range_t< Byte2 >::iterator cursor_iterator
cursor_range_t::iterator. Satisfies std::input_iterator
Definition sbepp.hpp:2622
value_type reference
value_type
Definition sbepp.hpp:2445
detail::cursor_range< value_type, size_type, cursor< Byte2 >, typename std::decay< decltype(std::declval< Dimension >().blockLength().value())>::type, Byte > cursor_range_t
Type of a cursor range. Satisfies std::ranges::input_range
Definition sbepp.hpp:2557
typename sbe_size_type::value_type size_type
raw size type
Definition sbepp.hpp:2450
typename std::make_signed< size_type >::type difference_type
signed size_type
Definition sbepp.hpp:2452
constexpr sbe_size_type sbe_size() const noexcept
Returns header's numInGroup
Definition sbepp.hpp:2490
constexpr void resize(const size_type count) const noexcept
Sets numInGroup to count
Definition sbepp.hpp:2502
constexpr reference front() const noexcept
Returns the first element.
Definition sbepp.hpp:2542
constexpr cursor_iterator< Byte2 > cursor_end(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the end.
Definition sbepp.hpp:2639
constexpr void clear() const noexcept
Resizes to 0
Definition sbepp.hpp:2550
constexpr cursor_iterator< Byte2 > cursor_begin(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the beginning.
Definition sbepp.hpp:2629
constexpr bool empty() const noexcept
Checks if size() == 0
Definition sbepp.hpp:2508
forward_iterator< Byte, Entry, size_type, difference_type, typename std::decay< decltype(std::declval< Dimension >().blockLength().value())>::type > iterator
Forward iterator to value_type. Satisfies std::forward_iterator
Definition sbepp.hpp:2456
constexpr cursor_range_t< Byte2 > cursor_range(cursor< Byte2 > &c) const noexcept
Returns cursor range to all group entries.
Definition sbepp.hpp:2570
constexpr cursor_range_t< Byte2 > cursor_subrange(cursor< Byte2 > &c, const size_type pos, const size_type count) const noexcept
Returns cursor range to [pos; pos+count) entries.
Definition sbepp.hpp:2604
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:2520
typename std::decay< decltype(std::declval< Dimension >().numInGroup())>::type sbe_size_type
numInGroup value type
Definition sbepp.hpp:2447
Base class for optional types.
Definition sbepp.hpp:3761
constexpr value_type value() const noexcept
Returns underlying value.
Definition sbepp.hpp:3782
constexpr friend bool operator!=(const optional_base &lhs, const optional_base &rhs) noexcept
Tests if lhs is not equal to rhs
Definition sbepp.hpp:3862
constexpr optional_base(nullopt_t) noexcept
Constructs null object.
Definition sbepp.hpp:3771
optional_base()=default
Constructs null object.
constexpr value_type value_or(T default_value) const noexcept
Returns value if not null, default_value otherwise.
Definition sbepp.hpp:3807
constexpr friend bool operator>=(const optional_base &lhs, const optional_base &rhs) noexcept
Tests if lhs is greater than or equal to rhs
Definition sbepp.hpp:3890
T value_type
Underlying type.
Definition sbepp.hpp:3764
constexpr bool in_range() const noexcept
Checks if value is in [Derived::min_value(); Derived::max_value()] range.
Definition sbepp.hpp:3801
constexpr optional_base(value_type val) noexcept
Constructs object from given value.
Definition sbepp.hpp:3777
constexpr bool has_value() const noexcept
Checks if has value.
Definition sbepp.hpp:3817
constexpr friend bool operator>(const optional_base &lhs, const optional_base &rhs) noexcept
Tests if lhs is greater than rhs
Definition sbepp.hpp:3883
constexpr value_type operator*() const noexcept
Returns underlying value.
Definition sbepp.hpp:3794
constexpr value_type & operator*() noexcept
Returns reference to underlying value.
Definition sbepp.hpp:3788
constexpr friend bool operator==(const optional_base &lhs, const optional_base &rhs) noexcept
Tests if lhs is equal to rhs
Definition sbepp.hpp:3837
constexpr friend std::strong_ordering operator<=>(const optional_base &lhs, const optional_base &rhs) noexcept
Available only if SBEPP_HAS_THREE_WAY_COMPARISON == 1.
Base class for required types.
Definition sbepp.hpp:3654
constexpr friend bool operator>(const required_base &lhs, const required_base &rhs) noexcept
Tests if lhs is greater than rhs
Definition sbepp.hpp:3736
constexpr friend bool operator>=(const required_base &lhs, const required_base &rhs) noexcept
Tests if lhs is greater than or equal to rhs
Definition sbepp.hpp:3743
constexpr value_type value() const noexcept
Returns underlying value.
Definition sbepp.hpp:3669
constexpr friend bool operator!=(const required_base &lhs, const required_base &rhs) noexcept
Tests if lhs is not equal to rhs
Definition sbepp.hpp:3715
constexpr value_type & operator*() noexcept
Returns reference to underlying value.
Definition sbepp.hpp:3675
constexpr friend bool operator==(const required_base &lhs, const required_base &rhs) noexcept
Tests if lhs is equal to rhs
Definition sbepp.hpp:3708
required_base()=default
Default constructor. Constructs value-initialized object.
constexpr bool in_range() const noexcept
Checks if value is in [Derived::min_value(); Derived::max_value()] range.
Definition sbepp.hpp:3688
T value_type
Underlying type.
Definition sbepp.hpp:3657
constexpr value_type operator*() const noexcept
Returns underlying value.
Definition sbepp.hpp:3681
constexpr required_base(value_type val) noexcept
Constructs from given value.
Definition sbepp.hpp:3664
Represents reference to fixed-size array.
Definition sbepp.hpp:2909
pointer iterator
iterator type. Satisfies std::random_access_iterator
Definition sbepp.hpp:2925
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator to the end.
Definition sbepp.hpp:3009
static constexpr bool empty() noexcept
Checks if size() != 0
Definition sbepp.hpp:2973
detail::apply_cv_qualifiers_t< Byte, Value > element_type
final element type. value_type with the same cv-qualifiers as Byte
Definition sbepp.hpp:2913
constexpr reference operator[](size_type pos) const noexcept
Access element at pos
Definition sbepp.hpp:2941
constexpr std::size_t strlen() const noexcept
Calculates string length from left to right.
Definition sbepp.hpp:3038
constexpr iterator assign_string(const char *str, const eos_null eos_mode=eos_null::all) const noexcept
Assigns null-terminated string.
Definition sbepp.hpp:3087
constexpr reference front() const noexcept
Access the first element.
Definition sbepp.hpp:2948
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:2991
static constexpr size_type size() noexcept
Returns N
Definition sbepp.hpp:2979
constexpr static_array_ref< Byte, detail::remove_cv_t< Byte >, N, Tag > raw() const noexcept
Returns static_array_ref<Byte, Byte, N, Tag>.
Definition sbepp.hpp:3026
constexpr iterator assign(std::initializer_list< value_type > ilist) const noexcept
Assigns initializer list to first elements.
Definition sbepp.hpp:3193
element_type & reference
element reference type
Definition sbepp.hpp:2921
std::reverse_iterator< iterator > reverse_iterator
reverse iterator type
Definition sbepp.hpp:2927
constexpr reference back() const noexcept
Access the last element.
Definition sbepp.hpp:2954
Value value_type
same as Value
Definition sbepp.hpp:2915
Tag tag
type tag
Definition sbepp.hpp:2929
element_type * pointer
element pointer type
Definition sbepp.hpp:2923
constexpr std::size_t strlen_r() const noexcept
Calculates string length from right to left.
Definition sbepp.hpp:3063
std::size_t size_type
std::size_t
Definition sbepp.hpp:2917
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:2997
constexpr iterator assign_string(R &&r, const eos_null eos_mode=eos_null::all) const
Assigns string represented by a range.
Definition sbepp.hpp:3115
constexpr void fill(const value_type value) const noexcept
Assigns value to all elements.
Definition sbepp.hpp:3152
constexpr iterator assign_range(R &&r) const
Assigns range.
Definition sbepp.hpp:3135
constexpr reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the beginning.
Definition sbepp.hpp:3003
constexpr iterator assign(InputIt first, InputIt last) const
Assigns elements from [first; last) range to first elements.
Definition sbepp.hpp:3177
static constexpr size_type max_size() noexcept
Returns size()
Definition sbepp.hpp:2985
std::ptrdiff_t difference_type
std::ptrdiff_t
Definition sbepp.hpp:2919
constexpr pointer data() const noexcept
Direct access to the underlying array.
Definition sbepp.hpp:2960
constexpr iterator assign(size_type count, const value_type value) const noexcept
Assigns value to first count elements.
Definition sbepp.hpp:3167
Provides various traits/attributes of an <enum> element.
Definition sbepp.hpp:4083
EncodingType encoding_type
Underlying type.
Definition sbepp.hpp:4090
static constexpr const char * name() noexcept
Returns name attribute.
ScopedEnumType value_type
Representation type.
Definition sbepp.hpp:4102
Provides various traits/attributes of a <validValue> element.
Definition sbepp.hpp:4120
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits/attributes of a <field> element.
Definition sbepp.hpp:4383
static constexpr const char * name() noexcept
Returns name attribute.
ValueType value_type
Representation type.
Definition sbepp.hpp:4405
TypeTag value_type_tag
value_type's tag. Not available for constants of numeric types
Definition sbepp.hpp:4414
Provides various traits/attributes of a <group> element.
Definition sbepp.hpp:4432
HeaderType< Byte > dimension_type
Group dimension composite type.
Definition sbepp.hpp:4462
HeaderTag dimension_type_tag
Dimension composite tag.
Definition sbepp.hpp:4464
GroupType< Byte > value_type
Representation type.
Definition sbepp.hpp:4455
EntryType< Byte > entry_type
Group entry type.
Definition sbepp.hpp:4471
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits/attributes of a <message> element.
Definition sbepp.hpp:4261
static constexpr const char * name() noexcept
Returns name attribute.
SchemaTag schema_tag
Schema tag.
Definition sbepp.hpp:4286
MessageType< Byte > value_type
Representation type.
Definition sbepp.hpp:4284
Provides various traits/attributes of a <messageSchema> element.
Definition sbepp.hpp:4043
HeaderTypeTag header_type_tag
Message header composite tag. Can be used to access its traits.
Definition sbepp.hpp:4065
static constexpr const char * package() noexcept
Returns package attribute.
HeaderComposite< Byte > header_type
Message header composite type.
Definition sbepp.hpp:4063
Provides various traits/attributes of a <choice> element.
Definition sbepp.hpp:4187
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits/attributes of a <set> element.
Definition sbepp.hpp:4150
SetType value_type
Representation type.
Definition sbepp.hpp:4169
EncodingType encoding_type
Underlying type.
Definition sbepp.hpp:4162
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits and attributes of a <type> element.
Definition sbepp.hpp:3962
ValueType value_type
Representation type.
Definition sbepp.hpp:3968
PrimitiveType primitive_type
Underlying type.
Definition sbepp.hpp:3965
static constexpr const char * name() noexcept
Returns name attribute.
Concept for sbepp::is_array_type<T>::value
Definition sbepp.hpp:5049
Concept for sbepp::is_composite<T>::value
Definition sbepp.hpp:5077
Concept for sbepp::is_data<T>::value
Definition sbepp.hpp:5097
Concept for sbepp::is_enum<T>::value
Definition sbepp.hpp:5069
Concept for sbepp::is_flat_group<T>::value
Definition sbepp.hpp:5085
Concept for sbepp::is_group<T>::value
Definition sbepp.hpp:5093
Concept for sbepp::is_message<T>::value
Definition sbepp.hpp:5081
Concept for sbepp::is_nested_group<T>::value
Definition sbepp.hpp:5089
Concept for sbepp::is_non_array_type<T>::value
Definition sbepp.hpp:5061
Concept for sbepp::is_optional_type<T>::value
Definition sbepp.hpp:5057
Concept for sbepp::is_required_type<T>::value
Definition sbepp.hpp:5053
Concept for sbepp::is_set<T>::value
Definition sbepp.hpp:5073
Concept for sbepp::is_type<T>::value
Definition sbepp.hpp:5065
constexpr detail::skip_cursor_wrapper< Byte > skip(cursor< Byte > &c) noexcept
Returns a wrapper which moves the cursor to the end of field/group/data without returning the accesse...
Definition sbepp.hpp:1655
constexpr detail::dont_move_cursor_wrapper< Byte > dont_move(cursor< Byte > &c) noexcept
Returns a wrapper which doesn't advance the cursor when it's used.
Definition sbepp.hpp:1621
constexpr detail::init_cursor_wrapper< Byte > init(cursor< Byte > &c) noexcept
Returns a wrapper which will initialize the cursor when it's used and advance after the usage.
Definition sbepp.hpp:1592
constexpr detail::init_dont_move_cursor_wrapper< Byte > init_dont_move(cursor< Byte > &c) noexcept
Returns a wrapper which initializes the cursor but doesn't move it. Behaves like a combination of ini...
Definition sbepp.hpp:1635
The main sbepp namespace.
Definition sbepp.hpp:232
constexpr auto is_composite_v
Shorthand for sbepp::is_composite<T>::value
Definition sbepp.hpp:5023
constexpr auto is_required_type_v
Shorthand for sbepp::is_required_type<T>::value
Definition sbepp.hpp:4999
constexpr auto is_type_v
Shorthand for sbepp::is_type<T>::value
Definition sbepp.hpp:5011
constexpr std::underlying_type< Enum >::type to_underlying(Enum e) noexcept
Converts an enumeration to its underlying type. Equivalent to C++23 std::to_underlying()
Definition sbepp.hpp:2754
detail::is_base_of_tmp< detail::optional_base, T > is_optional_type
Checks if T is a non-array optional type.
Definition sbepp.hpp:4912
constexpr View< Byte > make_view(Byte *ptr, const std::size_t size) noexcept
Construct view from memory buffer.
Definition sbepp.hpp:4824
typename traits_tag< ValueType >::type traits_tag_t
Shorthand for sbepp::traits_tag<T>::type
Definition sbepp.hpp:4574
constexpr auto is_flat_group_v
Shorthand for sbepp::is_flat_group<T>::value
Definition sbepp.hpp:5031
eos_null
Represents number of null bytes that can be added after the end-of-string by detail::static_array_ref...
Definition sbepp.hpp:2822
@ all
All bytes after the last string character will be set to null.
constexpr cursor< byte_type_t< View > > init_cursor(View view) noexcept
Initializes cursor from a message/group view with the same byte type.
Definition sbepp.hpp:2773
constexpr auto get_header(T v) noexcept -> decltype(v(detail::get_header_tag{}))
Returns the header of a message/group.
Definition sbepp.hpp:1534
detail::is_base_of_tmp< detail::required_base, T > is_required_type
Checks if T is a non-array required type.
Definition sbepp.hpp:4908
std::integral_constant< bool, is_flat_group< T >::value||is_nested_group< T >::value > is_group
Checks if T is a group of any kind.
Definition sbepp.hpp:4965
detail::is_base_of_tmp< detail::flat_group_base, T > is_flat_group
Checks if T is a flat group.
Definition sbepp.hpp:4957
constexpr auto is_array_type_v
Shorthand for sbepp::is_array_type<T>::value
Definition sbepp.hpp:4995
constexpr nullopt_t nullopt
Helper constant used to initialize optional types with null value.
Definition sbepp.hpp:3644
field_presence
Represents presence trait value type, e.g. type_traits::presence()
Definition sbepp.hpp:313
@ constant
field is constant
@ required
field is required
@ optional
field is optional
constexpr Visitor && visit_children(View view, Cursor &c, Visitor &&visitor={})
Visit view's children using provided cursor.
Definition sbepp.hpp:5228
constexpr auto is_enum_v
Shorthand for sbepp::is_enum<T>::value
Definition sbepp.hpp:5015
constexpr cursor< typename std::add_const< byte_type_t< View > >::type > init_const_cursor(View view) noexcept
Initializes cursor from a message/group view with const byte type.
Definition sbepp.hpp:2796
constexpr auto fill_message_header(Message m) noexcept -> decltype(m(detail::fill_message_header_tag{}))
Fill message header.
Definition sbepp.hpp:3917
constexpr auto is_non_array_type_v
Shorthand for sbepp::is_non_array_type<T>::value
Definition sbepp.hpp:5007
constexpr Visitor && visit(View view, Cursor &c, Visitor &&visitor={})
Visit a view using given cursor.
Definition sbepp.hpp:5126
std::uint8_t choice_index_t
Represents set_choice_traits::index() value type.
Definition sbepp.hpp:308
typename detail::is_data_impl< T >::type is_data
Checks if T is a data.
Definition sbepp.hpp:4990
typename byte_type< View >::type byte_type_t
Shortcut for byte_type<T>::type
Definition sbepp.hpp:1566
detail::is_base_of_tmp< detail::nested_group_base, T > is_nested_group
Checks if T is a nested group.
Definition sbepp.hpp:4961
constexpr const char * enum_to_string(const E e) noexcept
Converts enum to string.
Definition sbepp.hpp:5294
detail::is_base_of_tmp< detail::message_base, T > is_message
Checks if T is a message.
Definition sbepp.hpp:4953
constexpr auto fill_group_header(Group g, Size num_in_group) noexcept -> decltype(g(detail::fill_group_header_tag{}, num_in_group))
Fill group header.
Definition sbepp.hpp:3937
constexpr auto addressof(T v) noexcept -> decltype(v(detail::addressof_tag{}))
Returns pointer to the underlying data referenced by a view.
Definition sbepp.hpp:1546
std::uint64_t offset_t
Represents offset trait value type, e.g. type_traits::offset()
Definition sbepp.hpp:294
std::uint32_t message_id_t
Represents message_traits::id() value type.
Definition sbepp.hpp:301
void assertion_failed(char const *expr, char const *function, char const *file, long line)
When SBEPP_ASSERT_HANDLER or SBEPP_ENABLE_ASSERTS_WITH_HANDLER is defined, this function is called fo...
constexpr std::size_t size_bytes(T v) noexcept
Returns the size of the underlying data represented by message/group/entry/data/composite view,...
Definition sbepp.hpp:1507
std::uint64_t version_t
Represents version trait value type, e.g. type_traits::since_version()
Definition sbepp.hpp:297
detail::is_base_of_tmp< detail::bitset_base, T > is_set
Checks if T is a set.
Definition sbepp.hpp:4945
std::integral_constant< bool, is_required_type< T >::value||is_optional_type< T >::value||is_array_type< T >::value > is_type
Checks if T is a type of any kind.
Definition sbepp.hpp:4922
constexpr auto is_group_v
Shorthand for sbepp::is_group<T>::value
Definition sbepp.hpp:5039
constexpr auto visit_set(const Set s, Visitor &&visitor) noexcept -> decltype(s(detail::visit_set_tag{}, std::forward< Visitor >(visitor)))
Visits set choices in order of their declaration.
Definition sbepp.hpp:5312
constexpr default_init_t default_init
helper to pass default_init_t to dynamic_array_ref::resize().
Definition sbepp.hpp:2817
std::integral_constant< bool, is_required_type< T >::value||is_optional_type< T >::value > is_non_array_type
Checks if T is a non-array type.
Definition sbepp.hpp:4916
std::uint16_t member_id_t
Represents id trait value type, e.g. field_traits::id()
Definition sbepp.hpp:306
constexpr auto is_optional_type_v
Shorthand for sbepp::is_optional_type<T>::value
Definition sbepp.hpp:5003
std::uint64_t length_t
Represents type_traits::length() value type.
Definition sbepp.hpp:290
constexpr size_bytes_checked_result size_bytes_checked(View view, std::size_t size) noexcept
Calculate view size with additional safety checks.
Definition sbepp.hpp:5453
constexpr auto is_message_v
Shorthand for sbepp::is_message<T>::value
Definition sbepp.hpp:5027
std::uint64_t block_length_t
Represents block_length trait value type, e.g. message_traits::block_length()
Definition sbepp.hpp:304
constexpr auto is_set_v
Shorthand for sbepp::is_set<T>::value
Definition sbepp.hpp:5019
detail::is_base_of_tmp< detail::entry_base, T > is_group_entry
Checks if T is a group entry.
Definition sbepp.hpp:4971
std::uint32_t schema_id_t
Represents schema_traits::id() value type.
Definition sbepp.hpp:299
constexpr auto is_nested_group_v
Shorthand for sbepp::is_nested_group<T>::value
Definition sbepp.hpp:5035
constexpr View< typename std::add_const< Byte >::type > make_const_view(Byte *ptr, const std::size_t size) noexcept
Construct read-only view from memory buffer.
Definition sbepp.hpp:4849
constexpr auto is_data_v
Shorthand for sbepp::is_data<T>::value
Definition sbepp.hpp:5043
endian
Represents schema_traits::byte_order() value type. When SBEPP_HAS_ENDIAN is 1, it's just an alias to ...
Definition sbepp.hpp:337
@ native
current platform endianness
typename detail::is_array_type_impl< T >::type is_array_type
Checks is T is an array type.
Definition sbepp.hpp:4904
detail::is_base_of_tmp< detail::composite_base, T > is_composite
Checks if T is a composite.
Definition sbepp.hpp:4949
#define SBEPP_BYTE_ORDER
Must be defined to either little or big when native endianness cannot be detected automatically.
Definition sbepp.hpp:327
Trait to get view's byte type.
Definition sbepp.hpp:1558
typename std::remove_pointer< decltype(sbepp::addressof( std::declval< View >()))>::type type
holds View's byte type
Definition sbepp.hpp:1560
tag for dynamic_array_ref::resize(). Used to skip value initialization.
Definition sbepp.hpp:2808
Checks if T is an enumeration.
Definition sbepp.hpp:4930
Tag type used to initialize optional types with null value.
Definition sbepp.hpp:3633
Result type of size_bytes_checked
Definition sbepp.hpp:5433
Maps representation type to its tag.
Definition sbepp.hpp:4566
Tag type
Tag to access ValueType's traits.
Definition sbepp.hpp:4568
Tag for unknown enum values.
Definition sbepp.hpp:4861