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>;
398#if !SBEPP_HAS_BYTESWAP
401# ifndef __has_builtin
402# define __has_builtin(x) 0
405# if defined(_MSC_VER) && (!defined(__clang__) || defined(__c2__))
409inline std::uint64_t byteswap(std::uint64_t v)
noexcept
411 return _byteswap_uint64(v);
414inline std::uint32_t byteswap(std::uint32_t v)
noexcept
416 return _byteswap_ulong(v);
419inline std::uint16_t byteswap(std::uint16_t v)
noexcept
421 return _byteswap_ushort(v);
425 defined(__clang__) && __has_builtin(__builtin_bswap32) \
426 && __has_builtin(__builtin_bswap64)) \
427 || (defined(__GNUC__) \
428 && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
430# if(defined(__clang__) && __has_builtin(__builtin_bswap16)) \
431 || (defined(__GNUC__) \
432 && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
434inline std::uint16_t byteswap(std::uint16_t v)
noexcept
436 return __builtin_bswap16(v);
441inline std::uint16_t byteswap(std::uint16_t v)
noexcept
443 return __builtin_bswap32(v) << 16;
448inline std::uint64_t byteswap(std::uint64_t v)
noexcept
450 return __builtin_bswap64(v);
453inline std::uint32_t byteswap(std::uint32_t v)
noexcept
455 return __builtin_bswap32(v);
460constexpr std::uint64_t byteswap(std::uint64_t v)
noexcept
462 return ((v & UINT64_C(0x00000000000000FF)) << 56)
463 | ((v & UINT64_C(0x000000000000FF00)) << 40)
464 | ((v & UINT64_C(0x0000000000FF0000)) << 24)
465 | ((v & UINT64_C(0x00000000FF000000)) << 8)
466 | ((v & UINT64_C(0x000000FF00000000)) >> 8)
467 | ((v & UINT64_C(0x0000FF0000000000)) >> 24)
468 | ((v & UINT64_C(0x00FF000000000000)) >> 40)
469 | ((v & UINT64_C(0xFF00000000000000)) >> 56);
472constexpr std::uint32_t byteswap(std::uint32_t v)
noexcept
474 return ((v & UINT32_C(0x000000FF)) << 24)
475 | ((v & UINT32_C(0x0000FF00)) << 8)
476 | ((v & UINT32_C(0x00FF0000)) >> 8)
477 | ((v & UINT32_C(0xFF000000)) >> 24);
480constexpr std::uint16_t byteswap(std::uint16_t v)
noexcept
482 return ((v & UINT16_C(0x00FF)) << 8) | ((v & UINT16_C(0xFF00)) >> 8);
489struct fp_underlying_type;
492using fp_underlying_type_t =
typename fp_underlying_type<T>::type;
495struct fp_underlying_type<float>
497 using type = std::uint32_t;
501struct fp_underlying_type<double>
503 using type = std::uint64_t;
510constexpr enable_if_t<
sizeof(T) == 1, T> byteswap(T value)
noexcept
517 enable_if_t<!std::is_floating_point<T>::value && (
sizeof(T) != 1), T>
518 byteswap(T value)
noexcept
520#if SBEPP_HAS_BYTESWAP
523 return static_cast<T
>(std::byteswap(
524 static_cast<typename std::make_unsigned<T>::type
>(value)));
526 return static_cast<T
>(
527 byteswap(
static_cast<typename std::make_unsigned<T>::type
>(value)));
532enable_if_t<std::is_floating_point<T>::value, T> byteswap(T value)
noexcept
534 fp_underlying_type_t<T> underlying{};
535 std::memcpy(&underlying, &value,
sizeof(underlying));
536 underlying = byteswap(underlying);
538 std::memcpy(&value, &underlying,
sizeof(underlying));
543template<
typename T, endian E,
typename Byte>
544SBEPP_CPP20_CONSTEXPR T get_primitive(
const Byte* ptr)
547 std::array<Byte,
sizeof(T)> arr;
550 std::copy(ptr, ptr +
sizeof(T), std::begin(arr));
554 std::reverse_copy(ptr, ptr +
sizeof(T), std::begin(arr));
556 return std::bit_cast<T>(arr);
561 std::memcpy(&res, ptr,
sizeof(T));
568 return byteswap(res);
573template<endian E,
typename T,
typename Byte>
574SBEPP_CPP20_CONSTEXPR
void set_primitive(Byte* ptr, T value)
577 auto arr = std::bit_cast<std::array<Byte,
sizeof(T)>>(value);
580 std::copy(std::begin(arr), std::end(arr), ptr);
584 std::reverse_copy(std::begin(arr), std::end(arr), ptr);
591 value = byteswap(value);
593 std::memcpy(ptr, &value,
sizeof(T));
597struct fill_message_header_tag
599 explicit fill_message_header_tag() =
default;
602struct fill_group_header_tag
604 explicit fill_group_header_tag() =
default;
609 explicit size_bytes_tag() =
default;
614 explicit addressof_tag() =
default;
619 explicit end_ptr_tag() =
default;
624 explicit get_header_tag() =
default;
627struct get_block_length_tag
629 explicit get_block_length_tag() =
default;
634 explicit get_bit_tag() =
default;
639 explicit set_bit_tag() =
default;
644 explicit get_level_tag() =
default;
649 explicit visit_tag() =
default;
652struct visit_children_tag
654 explicit visit_children_tag() =
default;
657struct enum_to_str_tag
659 explicit enum_to_str_tag() =
default;
664 explicit visit_set_tag() =
default;
667template<
typename T,
typename U, endian E,
typename View>
668SBEPP_CPP20_CONSTEXPR T
669 get_value(
const View view,
const std::size_t offset)
noexcept
672 view(addressof_tag{}), view(end_ptr_tag{}), offset,
sizeof(U));
673 return T{get_primitive<U, E>(view(addressof_tag{}) + offset)};
676template<endian E,
typename T,
typename View>
677SBEPP_CPP20_CONSTEXPR
void
678 set_value(
const View view,
const std::size_t offset,
const T value)
noexcept
681 view(addressof_tag{}), view(end_ptr_tag{}), offset,
sizeof(T));
682 set_primitive<E>(view(addressof_tag{}) + offset, value);
685template<
typename Res,
typename View>
686SBEPP_CPP20_CONSTEXPR Res
687 get_static_field_view(
const View view,
const std::size_t offset)
noexcept
689 SBEPP_SIZE_CHECK(view(addressof_tag{}), view(end_ptr_tag{}), offset, 0);
690 return {view(addressof_tag{}) + offset, view(end_ptr_tag{})};
693template<
typename Group,
typename View>
694SBEPP_CPP20_CONSTEXPR Group
695 get_first_dynamic_field_view(
const View view)
noexcept
698 view(get_level_tag{}) + view(get_block_length_tag{}),
699 view(end_ptr_tag{})};
702template<
typename Group,
typename View,
typename Prev>
703SBEPP_CPP20_CONSTEXPR Group
704 get_dynamic_field_view(
const View view,
const Prev prev)
noexcept
707 prev(addressof_tag{}) + prev(size_bytes_tag{}), view(end_ptr_tag{})};
712template<
typename Byte>
716 static_assert(
sizeof(Byte) == 1,
"Byte must represent a single byte");
718 template<
typename Byte2>
725 SBEPP_CPP14_CONSTEXPR
byte_range(Byte* begin, Byte* end) noexcept
727#if SBEPP_SIZE_CHECKS_ENABLED
736 constexpr byte_range(Byte* ptr,
const std::size_t size) noexcept
742 template<
typename Byte2,
typename = enable_if_convertible_t<Byte2, Byte>>
746#if SBEPP_SIZE_CHECKS_ENABLED
753 constexpr Byte* operator()(addressof_tag)
const noexcept
758 constexpr Byte* operator()(end_ptr_tag)
const noexcept
760#if SBEPP_SIZE_CHECKS_ENABLED
769#if SBEPP_SIZE_CHECKS_ENABLED
781template<
typename Byte>
796 using result_type = T;
810 typename = detail::enable_if_convertible_t<Byte2, Byte>>
826 typename = detail::enable_if_convertible_t<Byte2, Byte>>
839 SBEPP_CPP14_CONSTEXPR Byte*&
pointer() noexcept
849 SBEPP_CPP14_CONSTEXPR Byte*
pointer() const noexcept
854 template<
typename T,
typename U, endian E,
typename View>
855 SBEPP_CPP20_CONSTEXPR T get_value(
857 const std::size_t offset,
858 const std::size_t absolute_offset)
noexcept
861 ((view(detail::addressof_tag{}) + absolute_offset)
863 &&
"Wrong cursor value");
864 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(U));
865 T res{detail::get_primitive<U, E>(ptr + offset)};
866 ptr += offset +
sizeof(U);
870 template<endian E,
typename T,
typename View>
871 SBEPP_CPP20_CONSTEXPR
void set_value(
873 const std::size_t offset,
874 const std::size_t absolute_offset,
875 const T value)
noexcept
878 ((view(detail::addressof_tag{}) + absolute_offset)
880 &&
"Wrong cursor value");
881 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(T));
882 detail::set_primitive<E>(ptr + offset, value);
883 ptr += offset +
sizeof(T);
886 template<
typename T,
typename U, endian E,
typename View>
887 SBEPP_CPP20_CONSTEXPR T get_last_value(
889 const std::size_t offset,
890 const std::size_t absolute_offset)
noexcept
893 ((view(detail::addressof_tag{}) + absolute_offset)
895 &&
"Wrong cursor value");
896 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(U));
897 auto res = T{detail::get_primitive<U, E>(ptr + offset)};
898 ptr = view(detail::get_level_tag{})
899 + view(detail::get_block_length_tag{});
903 template<endian E,
typename T,
typename View>
904 SBEPP_CPP20_CONSTEXPR
void set_last_value(
906 const std::size_t offset,
907 const std::size_t absolute_offset,
908 const T value)
noexcept
911 ((view(detail::addressof_tag{}) + absolute_offset)
913 &&
"Wrong cursor value");
914 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(T));
915 detail::set_primitive<E>(ptr + offset, value);
916 ptr = view(detail::get_level_tag{})
917 + view(detail::get_block_length_tag{});
920 template<
typename Res,
typename View>
921 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
923 const std::size_t offset,
924 const std::size_t absolute_offset)
noexcept
927 ((view(detail::addressof_tag{}) + absolute_offset)
929 &&
"Wrong cursor value");
930 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, 0);
931 Res res{ptr + offset, view(detail::end_ptr_tag{})};
932 ptr += offset + res(detail::size_bytes_tag{});
936 template<
typename Res,
typename View>
937 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
939 const std::size_t offset,
940 const std::size_t absolute_offset)
noexcept
943 ((view(detail::addressof_tag{}) + absolute_offset)
945 &&
"Wrong cursor value");
946 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, 0);
947 Res res{ptr + offset, view(detail::end_ptr_tag{})};
948 ptr = view(detail::get_level_tag{})
949 + view(detail::get_block_length_tag{});
953 template<
typename ResView,
typename View>
954 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
956 ptr = view(detail::get_level_tag{})
957 + view(detail::get_block_length_tag{});
958 ResView g{ptr, view(detail::end_ptr_tag{})};
959 ptr += g(detail::get_header_tag{})(detail::size_bytes_tag{});
964 template<
typename ResView,
typename View>
965 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
967 ptr = view(detail::get_level_tag{})
968 + view(detail::get_block_length_tag{});
969 ResView d{ptr, view(detail::end_ptr_tag{})};
970 ptr += d(detail::size_bytes_tag{});
975 template<
typename ResView,
typename View,
typename Getter>
976 SBEPP_CPP20_CONSTEXPR ResView
977 get_group_view(
const View view, Getter&& getter)
noexcept
980 (getter()(detail::addressof_tag{}) == ptr) &&
"Wrong cursor value");
981 ResView res{ptr, view(detail::end_ptr_tag{})};
982 auto header = res(detail::get_header_tag{});
983 ptr += header(detail::size_bytes_tag{});
987 template<
typename ResView,
typename View,
typename Getter>
988 SBEPP_CPP20_CONSTEXPR ResView
989 get_data_view(
const View view, Getter&& getter)
noexcept
992 (getter()(detail::addressof_tag{}) == ptr) &&
"Wrong cursor value");
993 ResView res{ptr, view(detail::end_ptr_tag{})};
994 ptr += res(detail::size_bytes_tag{});
1000 friend class cursor;
1007template<
typename Byte>
1008class init_cursor_wrapper
1011 using byte_type = Byte;
1013 template<
typename T>
1014 using result_type = T;
1016 init_cursor_wrapper() =
default;
1023 template<
typename T,
typename U, endian E,
typename View>
1024 SBEPP_CPP20_CONSTEXPR T get_value(
1027 const std::size_t absolute_offset)
noexcept
1030 view(addressof_tag{}),
1031 view(end_ptr_tag{}),
1034 T res{get_primitive<U, E>(view(addressof_tag{}) + absolute_offset)};
1035 cursor->pointer() = view(addressof_tag{}) + absolute_offset +
sizeof(U);
1039 template<endian E,
typename T,
typename View>
1040 SBEPP_CPP20_CONSTEXPR
void set_value(
1043 const std::size_t absolute_offset,
1044 const T value)
noexcept
1047 view(addressof_tag{}),
1048 view(end_ptr_tag{}),
1051 set_primitive<E>(view(addressof_tag{}) + absolute_offset, value);
1052 cursor->pointer() = view(addressof_tag{}) + absolute_offset +
sizeof(T);
1055 template<
typename T,
typename U, endian E,
typename View>
1056 SBEPP_CPP20_CONSTEXPR T get_last_value(
1059 const std::size_t absolute_offset)
noexcept
1062 view(addressof_tag{}),
1063 view(end_ptr_tag{}),
1066 T res{get_primitive<U, E>(view(addressof_tag{}) + absolute_offset)};
1068 view(get_level_tag{}) + view(get_block_length_tag{});
1072 template<endian E,
typename T,
typename View>
1073 SBEPP_CPP20_CONSTEXPR
void set_last_value(
1076 const std::size_t absolute_offset,
1077 const T value)
noexcept
1080 view(addressof_tag{}),
1081 view(end_ptr_tag{}),
1084 set_primitive<E>(view(addressof_tag{}) + absolute_offset, value);
1086 view(get_level_tag{}) + view(get_block_length_tag{});
1089 template<
typename Res,
typename View>
1090 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
1093 const std::size_t absolute_offset)
noexcept
1096 view(addressof_tag{}), view(end_ptr_tag{}), absolute_offset, 0);
1097 Res res{view(addressof_tag{}) + absolute_offset, view(end_ptr_tag{})};
1098 cursor->pointer() = res(addressof_tag{}) + res(size_bytes_tag{});
1102 template<
typename Res,
typename View>
1103 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
1106 const std::size_t absolute_offset)
noexcept
1109 view(addressof_tag{}), view(end_ptr_tag{}), absolute_offset, 0);
1110 Res res{view(addressof_tag{}) + absolute_offset, view(end_ptr_tag{})};
1112 view(get_level_tag{}) + view(get_block_length_tag{});
1116 template<
typename ResView,
typename View>
1117 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
1119 return cursor->template get_first_group_view<ResView>(view);
1122 template<
typename ResView,
typename View>
1123 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
1125 return cursor->template get_first_data_view<ResView>(view);
1128 template<
typename ResView,
typename View,
typename Getter>
1129 SBEPP_CPP20_CONSTEXPR ResView
1130 get_group_view(
const View , Getter&& getter)
noexcept
1132 auto res = getter();
1133 auto header = res(get_header_tag{});
1134 cursor->pointer() = res(addressof_tag{}) + header(size_bytes_tag{});
1138 template<
typename ResView,
typename View,
typename Getter>
1139 SBEPP_CPP20_CONSTEXPR ResView
1140 get_data_view(
const View , Getter&& getter)
noexcept
1142 auto res = getter();
1143 cursor->pointer() = res(addressof_tag{}) + res(size_bytes_tag{});
1151template<
typename Byte>
1152class init_dont_move_cursor_wrapper
1155 using byte_type = Byte;
1157 template<
typename T>
1158 using result_type = T;
1160 init_dont_move_cursor_wrapper() =
default;
1162 explicit constexpr init_dont_move_cursor_wrapper(
1168 template<
typename T,
typename U, endian E,
typename View>
1169 SBEPP_CPP20_CONSTEXPR T get_value(
1171 const std::size_t offset,
1172 const std::size_t absolute_offset)
noexcept
1175 view(addressof_tag{}),
1176 view(end_ptr_tag{}),
1179 cursor->pointer() = view(addressof_tag{}) + absolute_offset - offset;
1180 return T{get_primitive<U, E>(view(addressof_tag{}) + absolute_offset)};
1183 template<endian E,
typename T,
typename View>
1184 SBEPP_CPP20_CONSTEXPR
void set_value(
1186 const std::size_t offset,
1187 const std::size_t absolute_offset,
1188 const T value)
noexcept
1191 view(addressof_tag{}),
1192 view(end_ptr_tag{}),
1195 cursor->pointer() = view(addressof_tag{}) + absolute_offset - offset;
1196 set_primitive<E>(view(addressof_tag{}) + absolute_offset, value);
1199 template<
typename T,
typename U, endian E,
typename View>
1200 SBEPP_CPP20_CONSTEXPR T get_last_value(
1202 const std::size_t offset,
1203 const std::size_t absolute_offset)
noexcept
1205 return get_value<T, U, E>(view, offset, absolute_offset);
1208 template<endian E,
typename T,
typename View>
1209 SBEPP_CPP20_CONSTEXPR
void set_last_value(
1211 const std::size_t offset,
1212 const std::size_t absolute_offset,
1213 const T value)
noexcept
1215 return set_value<E>(view, offset, absolute_offset, value);
1218 template<
typename Res,
typename View>
1219 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
1221 const std::size_t offset,
1222 const std::size_t absolute_offset)
noexcept
1225 view(addressof_tag{}), view(end_ptr_tag{}), absolute_offset, 0);
1226 cursor->pointer() = view(addressof_tag{}) + absolute_offset - offset;
1227 return {view(addressof_tag{}) + absolute_offset, view(end_ptr_tag{})};
1230 template<
typename Res,
typename View>
1231 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
1233 const std::size_t offset,
1234 const std::size_t absolute_offset)
noexcept
1236 return get_static_field_view<Res>(view, offset, absolute_offset);
1239 template<
typename ResView,
typename View>
1240 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
1243 view(get_level_tag{}) + view(get_block_length_tag{});
1244 ResView g{cursor->pointer(), view(end_ptr_tag{})};
1249 template<
typename ResView,
typename View>
1250 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
1253 view(get_level_tag{}) + view(get_block_length_tag{});
1254 ResView d{cursor->pointer(), view(end_ptr_tag{})};
1259 template<
typename ResView,
typename View,
typename Getter>
1260 SBEPP_CPP20_CONSTEXPR ResView
1261 get_group_view(
const View , Getter&& getter)
noexcept
1263 auto res = getter();
1264 cursor->pointer() = res(addressof_tag{});
1268 template<
typename ResView,
typename View,
typename Getter>
1269 SBEPP_CPP20_CONSTEXPR ResView
1270 get_data_view(
const View , Getter&& getter)
noexcept
1272 auto res = getter();
1273 cursor->pointer() = res(addressof_tag{});
1281template<
typename Byte>
1282class dont_move_cursor_wrapper
1285 using byte_type = Byte;
1287 template<
typename T>
1288 using result_type = T;
1290 dont_move_cursor_wrapper() =
default;
1297 template<
typename T,
typename U, endian E,
typename View>
1298 SBEPP_CPP20_CONSTEXPR T get_value(
1300 const std::size_t offset,
1301 const std::size_t absolute_offset)
noexcept
1304 ((view(detail::addressof_tag{}) + absolute_offset)
1305 == (cursor->pointer() + offset))
1306 &&
"Wrong cursor value");
1308 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1309 return T{get_primitive<U, E>(cursor->pointer() + offset)};
1312 template<endian E,
typename T,
typename View>
1313 SBEPP_CPP20_CONSTEXPR
void set_value(
1315 const std::size_t offset,
1316 const std::size_t absolute_offset,
1317 const T value)
noexcept
1320 ((view(detail::addressof_tag{}) + absolute_offset)
1321 == (cursor->pointer() + offset))
1322 &&
"Wrong cursor value");
1324 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(T));
1325 set_primitive<E>(cursor->pointer() + offset, value);
1328 template<
typename T,
typename U, endian E,
typename View>
1329 SBEPP_CPP20_CONSTEXPR T get_last_value(
1331 const std::size_t offset,
1332 const std::size_t absolute_offset)
noexcept
1335 ((view(detail::addressof_tag{}) + absolute_offset)
1336 == (cursor->pointer() + offset))
1337 &&
"Wrong cursor value");
1339 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1340 return T{get_primitive<U, E>(cursor->pointer() + offset)};
1343 template<endian E,
typename T,
typename View>
1344 SBEPP_CPP20_CONSTEXPR
void set_last_value(
1346 const std::size_t offset,
1347 const std::size_t absolute_offset,
1348 const T value)
noexcept
1351 ((view(detail::addressof_tag{}) + absolute_offset)
1352 == (cursor->pointer() + offset))
1353 &&
"Wrong cursor value");
1355 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(T));
1356 set_primitive<E>(cursor->pointer() + offset, value);
1359 template<
typename Res,
typename View>
1360 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
1362 const std::size_t offset,
1363 const std::size_t absolute_offset)
noexcept
1366 ((view(detail::addressof_tag{}) + absolute_offset)
1367 == (cursor->pointer() + offset))
1368 &&
"Wrong cursor value");
1369 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1370 return {cursor->pointer() + offset, view(end_ptr_tag{})};
1373 template<
typename Res,
typename View>
1374 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
1376 const std::size_t offset,
1377 const std::size_t absolute_offset)
noexcept
1380 ((view(detail::addressof_tag{}) + absolute_offset)
1381 == (cursor->pointer() + offset))
1382 &&
"Wrong cursor value");
1383 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1384 return {cursor->pointer() + offset, view(end_ptr_tag{})};
1387 template<
typename ResView,
typename View>
1388 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
1391 view(get_level_tag{}) + view(get_block_length_tag{});
1392 ResView g{cursor->pointer(), view(end_ptr_tag{})};
1397 template<
typename ResView,
typename View>
1398 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
1401 view(get_level_tag{}) + view(get_block_length_tag{});
1402 ResView d{cursor->pointer(), view(end_ptr_tag{})};
1407 template<
typename ResView,
typename View,
typename Getter>
1408 SBEPP_CPP20_CONSTEXPR ResView
1409 get_group_view(
const View view, Getter&& getter)
noexcept
1412 (getter()(detail::addressof_tag{}) == cursor->pointer())
1413 &&
"Wrong cursor value");
1414 return {cursor->pointer(), view(end_ptr_tag{})};
1417 template<
typename ResView,
typename View,
typename Getter>
1418 SBEPP_CPP20_CONSTEXPR ResView
1419 get_data_view(
const View view, Getter&& getter)
noexcept
1422 (getter()(detail::addressof_tag{}) == cursor->pointer())
1423 &&
"Wrong cursor value");
1424 return {cursor->pointer(), view(end_ptr_tag{})};
1431template<
typename Byte>
1432class skip_cursor_wrapper
1435 using byte_type = Byte;
1437 template<
typename T>
1438 using result_type = void;
1440 skip_cursor_wrapper() =
default;
1447 template<
typename T,
typename U, endian E,
typename View>
1448 SBEPP_CPP20_CONSTEXPR
void get_value(
1450 const std::size_t offset,
1451 const std::size_t absolute_offset)
noexcept
1454 ((view(detail::addressof_tag{}) + absolute_offset)
1455 == (cursor->pointer() + offset))
1456 &&
"Wrong cursor value");
1458 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1459 cursor->pointer() += offset +
sizeof(U);
1462 template<
typename T,
typename U, endian E,
typename View>
1463 SBEPP_CPP20_CONSTEXPR
void get_last_value(
1465 const std::size_t offset,
1466 const std::size_t absolute_offset)
noexcept
1469 ((view(detail::addressof_tag{}) + absolute_offset)
1470 == (cursor->pointer() + offset))
1471 &&
"Wrong cursor value");
1473 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1475 view(get_level_tag{}) + view(get_block_length_tag{});
1478 template<
typename Res,
typename View>
1479 SBEPP_CPP20_CONSTEXPR
void get_static_field_view(
1481 const std::size_t offset,
1482 const std::size_t absolute_offset)
noexcept
1485 ((view(detail::addressof_tag{}) + absolute_offset)
1486 == (cursor->pointer() + offset))
1487 &&
"Wrong cursor value");
1488 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1489 Res res{cursor->pointer(), view(end_ptr_tag{})};
1490 cursor->pointer() += offset + res(size_bytes_tag{});
1493 template<
typename Res,
typename View>
1494 SBEPP_CPP20_CONSTEXPR
void get_last_static_field_view(
1496 const std::size_t offset,
1497 const std::size_t absolute_offset)
noexcept
1500 ((view(detail::addressof_tag{}) + absolute_offset)
1501 == (cursor->pointer() + offset))
1502 &&
"Wrong cursor value");
1503 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1505 view(get_level_tag{}) + view(get_block_length_tag{});
1508 template<
typename ResView,
typename View>
1509 SBEPP_CPP20_CONSTEXPR
void get_first_group_view(
const View view)
noexcept
1512 view(get_level_tag{}) + view(get_block_length_tag{});
1513 ResView g{cursor->pointer(), view(end_ptr_tag{})};
1514 cursor->pointer() += g(size_bytes_tag{});
1517 template<
typename ResView,
typename View>
1518 SBEPP_CPP20_CONSTEXPR
void get_first_data_view(
const View view)
noexcept
1521 view(get_level_tag{}) + view(get_block_length_tag{});
1522 ResView d{cursor->pointer(), view(end_ptr_tag{})};
1523 cursor->pointer() += d(size_bytes_tag{});
1526 template<
typename ResView,
typename View,
typename Getter>
1527 SBEPP_CPP20_CONSTEXPR
void
1528 get_group_view(
const View view, Getter&& getter)
noexcept
1531 (getter()(detail::addressof_tag{}) == cursor->pointer())
1532 &&
"Wrong cursor value");
1533 ResView res{cursor->pointer(), view(end_ptr_tag{})};
1534 cursor->pointer() += res(size_bytes_tag{});
1537 template<
typename ResView,
typename View,
typename Getter>
1538 SBEPP_CPP20_CONSTEXPR
void
1539 get_data_view(
const View view, Getter&& getter)
noexcept
1542 (getter()(detail::addressof_tag{}) == cursor->pointer())
1543 &&
"Wrong cursor value");
1544 ResView res{cursor->pointer(), view(end_ptr_tag{})};
1545 cursor->pointer() += res(size_bytes_tag{});
1552template<
typename Cursor,
typename T>
1553using cursor_result_type_t =
1554 typename remove_reference_t<Cursor>::template result_type<T>;
1556template<
typename Cursor>
1557using cursor_byte_type_t =
typename remove_reference_t<Cursor>::byte_type;
1559template<
typename MessageByte,
typename CursorByte>
1560using enable_if_cursor_compatible_t =
1561 enable_if_convertible_t<MessageByte, CursorByte>;
1563template<
typename MessageByte,
typename CursorByte>
1564using enable_if_cursor_writeable_t = enable_if_t<
1565 std::is_convertible<MessageByte*, CursorByte*>::value
1566 && !std::is_const<MessageByte>::value && !std::is_const<CursorByte>::value>;
1582 return v(detail::size_bytes_tag{});
1594template<
typename T,
typename Byte>
1597 return v(detail::size_bytes_tag{}, c);
1607constexpr auto get_header(T v)
noexcept ->
decltype(v(detail::get_header_tag{}))
1609 return v(detail::get_header_tag{});
1619constexpr auto addressof(T v)
noexcept ->
decltype(v(detail::addressof_tag{}))
1621 return v(detail::addressof_tag{});
1629template<
typename View>
1634 std::declval<View>()))>
::type;
1638template<
typename View>
1664template<
typename Byte>
1667 return detail::init_cursor_wrapper<Byte>{c};
1692template<
typename Byte>
1693constexpr detail::dont_move_cursor_wrapper<Byte>
1696 return detail::dont_move_cursor_wrapper<Byte>{c};
1706template<
typename Byte>
1707constexpr detail::init_dont_move_cursor_wrapper<Byte>
1710 return detail::init_dont_move_cursor_wrapper<Byte>{c};
1727template<
typename Byte>
1730 return detail::skip_cursor_wrapper<Byte>{c};
1738template<
typename Byte>
1747template<
typename Byte,
typename Header>
1754 SBEPP_CPP14_CONSTEXPR Header operator()(get_header_tag)
const noexcept
1756 Header header{(*this)(addressof_tag{}), (*
this)(end_ptr_tag{})};
1758 (*
this)(addressof_tag{}),
1759 (*
this)(end_ptr_tag{}),
1765 SBEPP_CPP14_CONSTEXPR Byte* operator()(get_level_tag)
const noexcept
1767 auto header = (*this)(get_header_tag{});
1768 return header(addressof_tag{}) + header(size_bytes_tag{});
1771 constexpr typename std::decay<
1772 decltype(std::declval<Header>().blockLength().value())>::type
1773 operator()(get_block_length_tag)
const noexcept
1775 return operator()(get_header_tag{}).blockLength().value();
1780 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
1781 SBEPP_CPP20_CONSTEXPR std::size_t
1784 return c.
pointer() - (*this)(addressof_tag{});
1789template<
typename Byte,
typename BlockLengthType>
1795 template<
typename Byte2,
typename BlockLengthType2>
1803 Byte* ptr, Byte* end, BlockLengthType block_length) noexcept
1811 const std::size_t size,
1812 const BlockLengthType block_length) noexcept
1818 template<
typename Byte2,
typename = enable_if_convertible_t<Byte2, Byte>>
1820 cursor<Byte2>& c, Byte* end_ptr, BlockLengthType block_length) noexcept
1821 :
entry_base{c.pointer(), end_ptr, block_length}
1830 template<
typename Byte2,
typename = enable_if_convertible_t<Byte2, Byte>>
1837 constexpr BlockLengthType operator()(get_block_length_tag)
const noexcept
1839 return block_length;
1842 constexpr Byte* operator()(get_level_tag)
const noexcept
1844 return (*
this)(addressof_tag{});
1848 BlockLengthType block_length{};
1851template<
typename Entry>
1855 explicit constexpr arrow_proxy(Entry entry) noexcept : entry{entry}
1859 constexpr const Entry* operator->() const noexcept
1872 typename DifferenceType,
1873 typename BlockLengthType>
1874class forward_iterator
1877 using iterator_category = std::forward_iterator_tag;
1878 using value_type = ValueType;
1879 using reference = value_type;
1880 using difference_type = DifferenceType;
1881 using pointer = arrow_proxy<value_type>;
1883 forward_iterator() =
default;
1885 SBEPP_CPP14_CONSTEXPR forward_iterator(
1887 const IndexType index,
1888 const BlockLengthType block_length,
1892 block_length{block_length}
1893#if SBEPP_SIZE_CHECKS_ENABLED
1901 constexpr reference operator*() const noexcept
1903#if SBEPP_SIZE_CHECKS_ENABLED
1904 return {ptr, end, block_length};
1906 return {ptr,
nullptr, block_length};
1910 constexpr pointer operator->() const noexcept
1912 return pointer{operator*()};
1915 SBEPP_CPP14_CONSTEXPR forward_iterator& operator++() noexcept
1923 SBEPP_CPP14_CONSTEXPR forward_iterator operator++(
int)
noexcept
1930 friend constexpr bool operator==(
1931 const forward_iterator& lhs,
const forward_iterator& rhs)
noexcept
1933 return lhs.index == rhs.index;
1936 friend constexpr bool operator!=(
1937 const forward_iterator& lhs,
const forward_iterator& rhs)
noexcept
1939 return lhs.index != rhs.index;
1945 BlockLengthType block_length{};
1946#if SBEPP_SIZE_CHECKS_ENABLED
1954 typename BlockLengthType,
1955 typename DifferenceType,
1957class random_access_iterator
1960 using iterator_category = std::random_access_iterator_tag;
1961 using value_type = ValueType;
1962 using reference = value_type;
1963 using difference_type = DifferenceType;
1964 using pointer = arrow_proxy<value_type>;
1966 random_access_iterator() =
default;
1968 SBEPP_CPP14_CONSTEXPR random_access_iterator(
1970 const BlockLengthType block_length,
1971 const IndexType index,
1974 block_length{block_length},
1976#if SBEPP_SIZE_CHECKS_ENABLED
1984 constexpr reference operator*() const noexcept
1986#if SBEPP_SIZE_CHECKS_ENABLED
1987 return {ptr, end, block_length};
1989 return {ptr,
nullptr, block_length};
1993 constexpr pointer operator->() const noexcept
1995 return pointer{operator*()};
1998 SBEPP_CPP14_CONSTEXPR random_access_iterator& operator++() noexcept
2000 SBEPP_SIZE_CHECK(ptr, end, 0, block_length);
2001 ptr += block_length;
2006 SBEPP_CPP14_CONSTEXPR random_access_iterator operator++(
int)
noexcept
2013 SBEPP_CPP14_CONSTEXPR random_access_iterator& operator--() noexcept
2015 ptr -= block_length;
2020 SBEPP_CPP14_CONSTEXPR random_access_iterator operator--(
int)
noexcept
2027 SBEPP_CPP14_CONSTEXPR random_access_iterator&
2028 operator+=(difference_type n)
noexcept
2030 ptr += n * block_length;
2035 SBEPP_CPP14_CONSTEXPR random_access_iterator
2036 operator+(difference_type n)
const noexcept
2042 friend constexpr random_access_iterator
2043 operator+(difference_type n,
const random_access_iterator& it)
noexcept
2048 SBEPP_CPP14_CONSTEXPR random_access_iterator&
2049 operator-=(difference_type n)
noexcept
2054 SBEPP_CPP14_CONSTEXPR random_access_iterator
2055 operator-(difference_type n)
const noexcept
2061 constexpr difference_type
2062 operator-(
const random_access_iterator& rhs)
const noexcept
2064 return index - rhs.index;
2067 constexpr reference operator[](difference_type n)
const noexcept
2069 return *(*
this + n);
2072 friend constexpr bool operator==(
2073 const random_access_iterator& lhs,
2074 const random_access_iterator& rhs)
noexcept
2076 return lhs.index == rhs.index;
2079 friend constexpr bool operator!=(
2080 const random_access_iterator& lhs,
2081 const random_access_iterator& rhs)
noexcept
2083 return lhs.index != rhs.index;
2086 friend constexpr bool operator<(
2087 const random_access_iterator& lhs,
2088 const random_access_iterator& rhs)
noexcept
2090 return lhs.index < rhs.index;
2093 friend constexpr bool operator<=(
2094 const random_access_iterator& lhs,
2095 const random_access_iterator& rhs)
noexcept
2097 return lhs.index <= rhs.index;
2100 friend constexpr bool operator>(
2101 const random_access_iterator& lhs,
2102 const random_access_iterator& rhs)
noexcept
2104 return lhs.index > rhs.index;
2107 friend constexpr bool operator>=(
2108 const random_access_iterator& lhs,
2109 const random_access_iterator& rhs)
noexcept
2111 return lhs.index >= rhs.index;
2116 BlockLengthType block_length{};
2120#if SBEPP_SIZE_CHECKS_ENABLED
2128 typename CursorType,
2129 typename BlockLengthType,
2134 using iterator_category = std::input_iterator_tag;
2135 using value_type = ValueType;
2136 using reference = value_type;
2137 using difference_type =
typename std::make_signed<IndexType>::type;
2138 using pointer = arrow_proxy<value_type>;
2140 input_iterator() =
default;
2142 SBEPP_CPP14_CONSTEXPR input_iterator(
2143 const IndexType index,
2145 BlockLengthType block_length,
2149 block_length{block_length}
2150#if SBEPP_SIZE_CHECKS_ENABLED
2158 constexpr reference operator*() const noexcept
2160#if SBEPP_SIZE_CHECKS_ENABLED
2161 return {*cursor, end, block_length};
2163 return {*cursor,
nullptr, block_length};
2167 constexpr pointer operator->() const noexcept
2169 return pointer{operator*()};
2172 SBEPP_CPP14_CONSTEXPR input_iterator& operator++() noexcept
2178 SBEPP_CPP14_CONSTEXPR input_iterator operator++(
int)
noexcept
2185 friend constexpr bool operator==(
2186 const input_iterator& lhs,
const input_iterator& rhs)
noexcept
2188 return lhs.index == rhs.index;
2191 friend constexpr bool operator!=(
2192 const input_iterator& lhs,
const input_iterator& rhs)
noexcept
2194 return lhs.index != rhs.index;
2199 CursorType* cursor{};
2200 BlockLengthType block_length{};
2201#if SBEPP_SIZE_CHECKS_ENABLED
2209 typename CursorType,
2210 typename BlockLengthType,
2215 SBEPP_CPP14_CONSTEXPR cursor_range(
2217 BlockLengthType block_length,
2219 IndexType start_pos,
2220 IndexType length) noexcept
2222 block_length{block_length},
2223 start_pos{start_pos},
2224#if SBEPP_SIZE_CHECKS_ENABLED
2233 input_iterator<ValueType, IndexType, CursorType, BlockLengthType, Byte>;
2235 constexpr iterator begin() const noexcept
2237#if SBEPP_SIZE_CHECKS_ENABLED
2238 return {start_pos, cursor, block_length, end_ptr};
2240 return {start_pos, cursor, block_length,
nullptr};
2244 constexpr iterator end() const noexcept
2246#if SBEPP_SIZE_CHECKS_ENABLED
2248 static_cast<IndexType
>(start_pos + size()),
2254 static_cast<IndexType
>(start_pos + size()),
2261 constexpr IndexType size() const noexcept
2267 CursorType* cursor{};
2268 BlockLengthType block_length{};
2269 IndexType start_pos{};
2270#if SBEPP_SIZE_CHECKS_ENABLED
2277template<
typename Byte,
typename Entry,
typename Dimension>
2287 decltype(std::declval<Dimension>().numInGroup())>::type;
2297 typename std::decay<
2298 decltype(std::declval<Dimension>().blockLength().value())>::type,
2305 SBEPP_CPP14_CONSTEXPR Dimension operator()(get_header_tag)
const noexcept
2307 Dimension header{(*this)(addressof_tag{}), (*
this)(end_ptr_tag{})};
2309 (*
this)(addressof_tag{}),
2310 (*
this)(end_ptr_tag{}),
2316 SBEPP_CPP20_CONSTEXPR std::size_t operator()(size_bytes_tag)
const noexcept
2318 auto dimension = (*this)(get_header_tag{});
2320 + dimension.numInGroup().value()
2321 * dimension.blockLength().value();
2327 return (*
this)(get_header_tag{}).numInGroup();
2339 (*this)(get_header_tag{}).numInGroup(count);
2343 SBEPP_CPP17_NODISCARD SBEPP_CPP20_CONSTEXPR
bool empty() const noexcept
2351 return sbe_size_type::max_value();
2357 auto dimension = (*this)(get_header_tag{});
2360 dimension.blockLength().value(),
2362 (*this)(end_ptr_tag{})};
2369 (*this)(addressof_tag{}) + (*
this)(size_bytes_tag{}),
2370 (*
this)(get_header_tag{}).blockLength().value(),
2372 (*this)(end_ptr_tag{})};
2379 SBEPP_ASSERT(pos <
size());
2380 return *(
begin() + pos);
2387 SBEPP_ASSERT(!
empty());
2395 SBEPP_ASSERT(!
empty());
2401 SBEPP_CPP14_CONSTEXPR
void clear() const noexcept
2407 template<
typename Byte2>
2412 typename std::decay<
2413 decltype(std::declval<Dimension>().blockLength().value())>::type,
2419 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2425 (*this)(get_header_tag{}).blockLength().value(),
2426 (*this)(end_ptr_tag{}),
2435 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2436 SBEPP_CPP20_CONSTEXPR cursor_range_t<Byte2>
2439 SBEPP_ASSERT(pos <
size());
2443 (*this)(get_header_tag{}).blockLength().value(),
2444 (*this)(end_ptr_tag{}),
2454 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2460 SBEPP_ASSERT(pos <
size());
2461 SBEPP_ASSERT(count <= (
size() - pos));
2465 (*this)(get_header_tag{}).blockLength().value(),
2466 (*this)(end_ptr_tag{}),
2472 template<
typename Byte2>
2478 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2488 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2489 SBEPP_CPP20_CONSTEXPR cursor_iterator<Byte2>
2495 template<
typename Visitor,
typename Cursor>
2496 SBEPP_CPP14_CONSTEXPR
bool
2497 operator()(visit_children_tag, Visitor& v, Cursor& c)
2499 for(
const auto entry : this->cursor_range(c))
2501 if(v.on_entry(entry, c))
2511template<
typename Byte,
typename Entry,
typename Dimension>
2521 decltype(std::declval<Dimension>().numInGroup())>::type;
2534 typename std::decay<
2535 decltype(std::declval<Dimension>().blockLength().value())>::type>;
2540 SBEPP_CPP14_CONSTEXPR Dimension operator()(get_header_tag)
const noexcept
2542 Dimension header{(*this)(addressof_tag{}), (*
this)(end_ptr_tag{})};
2544 (*
this)(addressof_tag{}),
2545 (*
this)(end_ptr_tag{}),
2551 SBEPP_CPP20_CONSTEXPR std::size_t operator()(size_bytes_tag)
const noexcept
2554 for(
const auto entry : *this)
2565 return (*
this)(get_header_tag{}).numInGroup();
2577 (*this)(get_header_tag{}).numInGroup(count);
2581 SBEPP_CPP17_NODISCARD SBEPP_CPP20_CONSTEXPR
bool empty() const noexcept
2589 return sbe_size_type::max_value();
2595 auto dimension = (*this)(get_header_tag{});
2599 dimension.blockLength().value(),
2600 (*this)(end_ptr_tag{})};
2608 (*this)(get_header_tag{}).numInGroup().value(),
2609 (*this)(get_header_tag{}).blockLength().value(),
2610 (*this)(end_ptr_tag{})};
2617 SBEPP_ASSERT(!
empty());
2623 SBEPP_CPP14_CONSTEXPR
void clear() const noexcept
2629 template<
typename Byte2>
2634 typename std::decay<
2635 decltype(std::declval<Dimension>().blockLength().value())>::type,
2641 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2647 (*this)(get_header_tag{}).blockLength().value(),
2648 (*this)(end_ptr_tag{}),
2657 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2658 SBEPP_CPP20_CONSTEXPR cursor_range_t<Byte2>
2661 SBEPP_ASSERT(pos <
size());
2665 (*this)(get_header_tag{}).blockLength().value(),
2666 (*this)(end_ptr_tag{}),
2676 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2682 SBEPP_ASSERT(pos <
size());
2683 SBEPP_ASSERT(count <= (
size() - pos));
2687 (*this)(get_header_tag{}).blockLength().value(),
2688 (*this)(end_ptr_tag{}),
2694 template<
typename Byte2>
2700 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2710 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2711 SBEPP_CPP20_CONSTEXPR cursor_iterator<Byte2>
2717 template<
typename Visitor,
typename Cursor>
2718 SBEPP_CPP14_CONSTEXPR
bool
2719 operator()(visit_children_tag, Visitor& v, Cursor& c)
2721 for(
const auto entry : this->cursor_range(c))
2723 if(v.on_entry(entry, c))
2761 return bits & (1 << n);
2764 SBEPP_CPP14_CONSTEXPR
void
2765 operator()(set_bit_tag,
const choice_index_t n,
const bool b)
noexcept
2767 bits = ((bits & ~(1 << n)) | (b << n));
2771 constexpr friend bool
2774 return *lhs == *rhs;
2778 constexpr friend bool
2781 return *lhs != *rhs;
2788template<
typename View,
typename =
void_t<>>
2789struct has_get_header : std::false_type
2793template<
typename View>
2794struct has_get_header<
2796 void_t<decltype(
sbepp::
get_header(std::declval<View>()))>> : std::true_type
2802 typename = detail::enable_if_t<detail::has_get_header<View>::value>>
2803constexpr std::size_t get_header_size(View view)
noexcept
2810 typename = detail::enable_if_t<!detail::has_get_header<View>::value>,
2812constexpr std::size_t get_header_size(View)
noexcept
2825template<
typename Enum>
2826constexpr typename std::underlying_type<Enum>::type
2829 return static_cast<typename std::underlying_type<Enum>::type
>(e);
2845template<
typename View>
2867template<
typename View>
2868SBEPP_CPP14_CONSTEXPR cursor<typename std::add_const<byte_type_t<View>>::type>
2909template<
typename From,
typename To>
2910struct copy_cv_qualifiers
2912 using copy_const_t =
typename std::
2913 conditional<std::is_const<From>::value,
const To, To>::type;
2915 using type =
typename std::conditional<
2916 std::is_volatile<From>::value,
2917 volatile copy_const_t,
2918 copy_const_t>::type;
2921template<
typename From,
typename To>
2922using apply_cv_qualifiers_t =
typename copy_cv_qualifiers<From, To>::type;
2926using is_range = std::bool_constant<std::ranges::range<R>>;
2928template<
typename R,
typename =
void_t<>>
2929struct is_range : std::false_type
2937 decltype(std::begin(std::declval<R>())),
2938 decltype(std::end(std::declval<R>()))>> : std::true_type
2943constexpr bool is_constant_evaluated() noexcept
2948#if SBEPP_HAS_IS_CONSTANT_EVALUATED
2949 return std::is_constant_evaluated();
2955inline SBEPP_CPP20_CONSTEXPR std::size_t string_length(
const char* str)
noexcept
2957 if(is_constant_evaluated())
2959 std::size_t length{};
2961 for(; *str !=
'\0'; str++, length++)
2969 return std::strlen(str);
2980template<
typename Byte,
typename Value, std::
size_t N,
typename Tag>
3007 constexpr std::size_t operator()(detail::size_bytes_tag)
const noexcept
3016 SBEPP_ASSERT(pos <
size());
3038 (*
this)(detail::addressof_tag{}),
3039 (*
this)(detail::end_ptr_tag{}),
3042 return (
pointer)(*this)(detail::addressof_tag{});
3046 SBEPP_CPP17_NODISCARD
static constexpr bool empty() noexcept
3102 (*this)(detail::addressof_tag{}), (*
this)(detail::end_ptr_tag{})};
3111 SBEPP_CPP20_CONSTEXPR std::size_t
strlen() const noexcept
3113 if(is_constant_evaluated())
3115 return string_length(
data());
3119 const auto first_null =
static_cast<const value_type*
>(
3120 std::memchr(
data(),
'\0',
size()));
3123 return first_null -
data();
3136 SBEPP_CPP20_CONSTEXPR std::size_t
strlen_r() const noexcept
3138 const auto last_non_null = std::find_if(
3143 return value !=
'\0';
3159 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3163 SBEPP_ASSERT(str !=
nullptr);
3164 const auto length = string_length(str);
3165 SBEPP_ASSERT(length <=
size());
3166 const auto eos_pos = std::copy_n(str, length,
begin());
3167 pad(eos_mode, eos_pos);
3186 enable_if_t<!std::is_const<Byte>::value && is_range<R>::value>>
3191 pad(eos_mode, eos_pos);
3207 enable_if_t<!std::is_const<Byte>::value && is_range<R>::value>>
3211 auto res = std::ranges::copy(std::forward<R>(r),
begin()).out;
3213 auto res = std::copy(std::begin(r), std::end(r),
begin());
3215 SBEPP_ASSERT(res <=
end());
3224 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3238 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3242 SBEPP_ASSERT(count <=
size());
3243 return std::fill_n(
begin(), count, value);
3249 template<
typename InputIt,
typename = enable_if_writable_t<Byte, InputIt>>
3252 const auto last_out = std::copy(first, last,
begin());
3264 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3266 assign(std::initializer_list<value_type> ilist)
const noexcept
3268 SBEPP_ASSERT(ilist.size() <=
size());
3269 return assign(std::begin(ilist), std::end(ilist));
3273 SBEPP_CPP20_CONSTEXPR
void
3278 std::fill(eos_pos,
end(),
'\0');
3282 if(eos_pos !=
end())
3302template<
typename Byte,
typename Value,
typename Length, endian E>
3307 std::is_unsigned<typename Length::value_type>::value,
3308 "Length must be unsigned");
3336 return data_checked();
3361 SBEPP_ASSERT(!
empty());
3369 SBEPP_ASSERT(!
empty());
3382 return data_checked();
3389 SBEPP_ASSERT(pos <
size());
3390 return *(
data() + pos);
3396 return detail::get_value<size_type, size_type, E>(*
this, 0);
3406 SBEPP_CPP17_NODISCARD SBEPP_CPP20_CONSTEXPR
bool empty() const noexcept
3414 return sbe_size_type::max_value();
3418 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3419 SBEPP_CPP20_CONSTEXPR
void clear() const noexcept
3425 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3428 const auto old_size =
size();
3430 if(count > old_size)
3432 for(
auto i = old_size; i != count; i++)
3440 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3441 SBEPP_CPP20_CONSTEXPR
void
3444 const auto old_size =
size();
3446 if(count > old_size)
3448 for(
auto i = old_size; i != count; i++)
3456 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3457 SBEPP_CPP20_CONSTEXPR
void
3463 (*
this)(addressof_tag{}),
3464 (*
this)(end_ptr_tag{}),
3467 set_primitive<E>((*
this)(addressof_tag{}), count);
3471 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3474 const auto current_size =
size();
3476 (*this)[current_size] = value;
3480 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3483 SBEPP_ASSERT(!
empty());
3488 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3491 SBEPP_ASSERT(pos >=
begin() && pos <
end());
3492 std::copy(pos + 1,
end(), pos);
3498 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3502 SBEPP_ASSERT(first >=
begin() && last <
end());
3503 std::copy(last,
end(), first);
3509 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3513 SBEPP_ASSERT(pos >=
begin() && pos <=
end());
3514 const auto old_end =
end();
3516 std::copy_backward(pos, old_end,
end());
3522 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3526 SBEPP_ASSERT(pos >=
begin() && pos <=
end());
3527 const auto old_end =
end();
3529 std::copy_backward(pos, old_end,
end());
3530 std::fill_n(pos, count, value);
3537 typename = detail::enable_if_t<
3538 !std::is_const<Byte>::value
3539 && std::is_convertible<
3540 typename std::iterator_traits<InputIt>::iterator_category,
3541 std::input_iterator_tag>::value>>
3545 SBEPP_ASSERT(pos >=
begin() && pos <=
end());
3547 typename std::iterator_traits<InputIt>::iterator_category;
3548 return insert_impl(pos, first, last, category_t{});
3552 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3554 iterator pos, std::initializer_list<value_type> ilist)
const noexcept
3556 return insert(pos, std::begin(ilist), std::end(ilist));
3561 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3562 SBEPP_CPP20_CONSTEXPR
void
3566 std::fill_n(
begin(), count, value);
3571 template<
typename InputIt,
typename = enable_if_writable_t<Byte, InputIt>>
3572 SBEPP_CPP20_CONSTEXPR
void assign(InputIt first, InputIt last)
const
3574 auto begin = data_unchecked();
3575 const auto new_end = std::copy(first, last,
begin);
3581 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3582 SBEPP_CPP20_CONSTEXPR
void
3583 assign(std::initializer_list<value_type> ilist)
const noexcept
3586 (*
this)(detail::addressof_tag{}),
3587 (*
this)(detail::end_ptr_tag{}),
3590 assign(std::begin(ilist), std::end(ilist));
3603 (*this)(detail::addressof_tag{}), (*
this)(detail::end_ptr_tag{})};
3606 SBEPP_CPP20_CONSTEXPR std::size_t
3607 operator()(detail::size_bytes_tag)
const noexcept
3618 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3621 SBEPP_ASSERT(str !=
nullptr);
3622 const auto length = string_length(str);
3624 std::copy_n(str, length,
begin());
3637 enable_if_t<!std::is_const<Byte>::value && is_range<R>::value>>
3640 const auto begin = data_unchecked();
3642 const auto new_end = std::ranges::copy(std::forward<R>(r),
begin).out;
3644 const auto new_end = std::copy(std::begin(r), std::end(r),
begin);
3650 SBEPP_CPP14_CONSTEXPR
pointer data_checked() const noexcept
3653 (*
this)(detail::addressof_tag{}),
3654 (*
this)(detail::end_ptr_tag{}),
3657 return data_unchecked();
3660 SBEPP_CPP14_CONSTEXPR
pointer data_unchecked() const noexcept
3663 (*
this)(detail::addressof_tag{}),
3664 (*
this)(detail::end_ptr_tag{}),
3677 template<
typename It>
3678 SBEPP_CPP14_CONSTEXPR
iterator insert_impl(
3679 iterator pos, It first, It last, std::input_iterator_tag)
const
3682 for(; first != last; ++first, ++out)
3690 template<
typename It>
3691 SBEPP_CPP20_CONSTEXPR
iterator insert_impl(
3692 iterator pos, It first, It last, std::forward_iterator_tag)
const
3694 const auto in_size = std::distance(first, last);
3695 auto old_end =
end();
3697 std::copy_backward(pos, old_end,
end());
3698 std::copy(first, last, pos);
3725template<
typename T,
typename Derived>
3763 return (Derived::min_value() <= val) && (val <= Derived::max_value());
3775#if SBEPP_HAS_THREE_WAY_COMPARISON
3780 constexpr friend bool
3783 return *lhs == *rhs;
3787 constexpr friend bool
3790 return *lhs != *rhs;
3794 constexpr friend bool
3801 constexpr friend bool
3804 return *lhs <= *rhs;
3808 constexpr friend bool
3815 constexpr friend bool
3818 return *lhs >= *rhs;
3832template<
typename T,
typename Derived>
3876 return (Derived::min_value() <= val) && (val <= Derived::max_value());
3886 return default_value;
3892 return (val != Derived::null_value());
3896 constexpr explicit operator bool() const noexcept
3909 constexpr friend bool
3912 return *lhs == *rhs;
3921#if SBEPP_HAS_THREE_WAY_COMPARISON
3922 constexpr friend std::strong_ordering
3927 return *lhs <=> *rhs;
3929 return lhs.has_value() <=> rhs.has_value();
3934 constexpr friend bool
3937 return *lhs != *rhs;
3941 constexpr friend bool
3944 return rhs && (!lhs || (*lhs < *rhs));
3948 constexpr friend bool
3951 return !lhs || (rhs && (*lhs <= *rhs));
3955 constexpr friend bool
3958 return lhs && (!rhs || (*lhs > *rhs));
3962 constexpr friend bool
3965 return !rhs || (lhs && (*lhs >= *rhs));
3971 value_type val{Derived::null_value()};
3989template<
typename Message>
3991 ->
decltype(m(detail::fill_message_header_tag{}))
3993 return m(detail::fill_message_header_tag{});
4009template<
typename Group,
typename Size>
4011 ->
decltype(g(detail::fill_group_header_tag{}, num_in_group))
4013 return g(detail::fill_group_header_tag{}, num_in_group);
4048 template<
typename Byte>
4052 static constexpr const char*
name() noexcept;
4055 static constexpr const
char* description() noexcept;
4088 static constexpr const
char* semantic_type() noexcept;
4098 static constexpr const
char* character_encoding() noexcept;
4125 static constexpr const
char* semantic_version() noexcept;
4127 static constexpr
endian byte_order() noexcept;
4129 static constexpr const
char* description() noexcept;
4135 template<typename Byte>
4159 static constexpr const char*
name() noexcept;
4161 static constexpr const
char* description() noexcept;
4196 static constexpr const char*
name() noexcept;
4198 static constexpr const
char* description() noexcept;
4205 static constexpr ScopedEnumType value() noexcept;
4226 static constexpr const char*
name() noexcept;
4228 static constexpr const
char* description() noexcept;
4263 static constexpr const char*
name() noexcept;
4265 static constexpr const
char* description() noexcept;
4293 static constexpr const char*
name() noexcept;
4295 static constexpr const
char* description() noexcept;
4302 static constexpr const
char* semantic_type() noexcept;
4313 template<typename Byte>
4316 static constexpr std::
size_t size_bytes() noexcept;
4337 static constexpr const char*
name() noexcept;
4339 static constexpr const
char* description() noexcept;
4345 static constexpr const
char* semantic_type() noexcept;
4356 template<typename Byte>
4438 static constexpr std::
size_t size_bytes(...) noexcept;
4459 static constexpr const char*
name() noexcept;
4463 static constexpr const
char* description() noexcept;
4484 template<typename Byte>
4508 static constexpr const char*
name() noexcept;
4510 static constexpr const
char* description() noexcept;
4516 static constexpr const
char* semantic_type() noexcept;
4527 template<typename Byte>
4534 template<typename Byte>
4543 template<typename Byte>
4556 static constexpr std::
size_t
4557 size_bytes(const NumInGroupType num_in_group, ...) noexcept;
4578 static constexpr const char*
name() noexcept;
4582 static constexpr const
char* description() noexcept;
4593 template<typename Byte>
4605 static constexpr std::
size_t
4633template<
typename ValueType>
4637template<
typename ValueType>
4646template<
typename ValueType>
4649template<
typename Byte,
typename Value, std::
size_t N,
typename Tag>
4650struct traits_tag<detail::static_array_ref<Byte, Value, N, Tag>>
4656#define SBEPP_BUILT_IN_IMPL(NAME, TYPE, MIN, MAX, NULL) \
4659 class NAME##_t : public detail::required_base<TYPE, NAME##_t> \
4662 using detail::required_base<TYPE, NAME##_t>::required_base; \
4665 static constexpr value_type min_value() noexcept \
4671 static constexpr value_type max_value() noexcept \
4679 class NAME##_opt_t : public detail::optional_base<TYPE, NAME##_opt_t> \
4682 using detail::optional_base<TYPE, NAME##_opt_t>::optional_base; \
4685 static constexpr value_type min_value() noexcept \
4691 static constexpr value_type max_value() noexcept \
4697 static constexpr value_type null_value() noexcept \
4704 class type_traits<NAME##_t> \
4707 static constexpr const char* name() noexcept \
4712 static constexpr const char* description() noexcept \
4717 static constexpr field_presence presence() noexcept \
4719 return field_presence::required; \
4722 static constexpr TYPE min_value() noexcept \
4724 return NAME##_t::min_value(); \
4727 static constexpr TYPE max_value() noexcept \
4729 return NAME##_t::max_value(); \
4732 static constexpr length_t length() noexcept \
4737 static constexpr const char* semantic_type() noexcept \
4742 static constexpr version_t since_version() noexcept \
4747 using value_type = NAME##_t; \
4748 using primitive_type = value_type::value_type; \
4752 struct traits_tag<NAME##_t> \
4754 using type = NAME##_t; \
4758 class type_traits<NAME##_opt_t> \
4761 static constexpr const char* name() noexcept \
4766 static constexpr const char* description() noexcept \
4771 static constexpr field_presence presence() noexcept \
4773 return field_presence::optional; \
4776 static constexpr TYPE min_value() noexcept \
4778 return NAME##_opt_t::min_value(); \
4781 static constexpr TYPE max_value() noexcept \
4783 return NAME##_opt_t::max_value(); \
4786 static constexpr TYPE null_value() noexcept \
4788 return NAME##_opt_t::null_value(); \
4791 static constexpr length_t length() noexcept \
4796 static constexpr const char* semantic_type() noexcept \
4801 static constexpr version_t since_version() noexcept \
4806 using value_type = NAME##_opt_t; \
4807 using primitive_type = value_type::value_type; \
4811 struct traits_tag<NAME##_opt_t> \
4813 using type = NAME##_opt_t; \
4816SBEPP_BUILT_IN_IMPL(
char,
char, 0x20, 0x7E, 0);
4820 std::numeric_limits<std::int8_t>::min() + 1,
4821 std::numeric_limits<std::int8_t>::max(),
4822 std::numeric_limits<std::int8_t>::min());
4826 std::numeric_limits<std::uint8_t>::min(),
4827 std::numeric_limits<std::uint8_t>::max() - 1,
4828 std::numeric_limits<std::uint8_t>::max());
4832 std::numeric_limits<std::int16_t>::min() + 1,
4833 std::numeric_limits<std::int16_t>::max(),
4834 std::numeric_limits<std::int16_t>::min());
4838 std::numeric_limits<std::uint16_t>::min(),
4839 std::numeric_limits<std::uint16_t>::max() - 1,
4840 std::numeric_limits<std::uint16_t>::max());
4844 std::numeric_limits<std::int32_t>::min() + 1,
4845 std::numeric_limits<std::int32_t>::max(),
4846 std::numeric_limits<std::int32_t>::min());
4850 std::numeric_limits<std::uint32_t>::min(),
4851 std::numeric_limits<std::uint32_t>::max() - 1,
4852 std::numeric_limits<std::uint32_t>::max());
4856 std::numeric_limits<std::int64_t>::min() + 1,
4857 std::numeric_limits<std::int64_t>::max(),
4858 std::numeric_limits<std::int64_t>::min());
4862 std::numeric_limits<std::uint64_t>::min(),
4863 std::numeric_limits<std::uint64_t>::max() - 1,
4864 std::numeric_limits<std::uint64_t>::max());
4868 std::numeric_limits<float>::min(),
4869 std::numeric_limits<float>::max(),
4870 std::numeric_limits<float>::quiet_NaN());
4874 std::numeric_limits<double>::min(),
4875 std::numeric_limits<double>::max(),
4876 std::numeric_limits<double>::quiet_NaN());
4878#undef SBEPP_BUILT_IN_IMPL
4897template<
template<
typename>
class View,
typename Byte>
4898constexpr View<Byte>
make_view(Byte* ptr,
const std::size_t size)
noexcept
4921template<
template<
typename>
class View,
typename Byte>
4922constexpr View<typename std::add_const<Byte>::type>
4934struct unknown_enum_value_tag
4941template<
template<
typename...>
class Base,
typename Derived>
4942struct is_base_of_tmp_impl
4944 static constexpr std::false_type test(...);
4946 template<
typename... Ts>
4947 static constexpr std::true_type test(Base<Ts...>*);
4949 using type =
decltype(test(std::declval<Derived*>()));
4952template<
template<
typename...>
class Base,
typename Derived>
4953using is_base_of_tmp =
typename is_base_of_tmp_impl<Base, Derived>::type;
4955#if SBEPP_HAS_CONCEPTS
4956template<
typename Derived,
template<
typename...>
class Base>
4957concept derived_from_tmp = is_base_of_tmp<Base, Derived>::value;
4963template<
typename Derived>
4964struct is_array_type_impl
4966 static constexpr std::false_type test(...);
4968 template<
typename T1,
typename T2, std::
size_t N,
typename T3>
4969 static constexpr std::true_type
4970 test(detail::static_array_ref<T1, T2, N, T3>*);
4972 using type =
decltype(test(std::declval<Derived*>()));
4978using is_array_type =
typename detail::is_array_type_impl<T>::type;
4996using is_type = std::integral_constant<
5002template<
typename T,
typename =
void>
5003struct is_enum : std::false_type
5010 detail::void_t<decltype(tag_invoke(
5011 std::declval<detail::visit_tag>(),
5013 std::declval<int&>()))>> : std::true_type
5019using is_set = detail::is_base_of_tmp<detail::bitset_base, T>;
5023using is_composite = detail::is_base_of_tmp<detail::composite_base, T>;
5027using is_message = detail::is_base_of_tmp<detail::message_base, T>;
5031using is_flat_group = detail::is_base_of_tmp<detail::flat_group_base, T>;
5035using is_nested_group = detail::is_base_of_tmp<detail::nested_group_base, T>;
5039using is_group = std::integral_constant<
5045using is_group_entry = detail::is_base_of_tmp<detail::entry_base, T>;
5049template<
typename Derived>
5052 static constexpr std::false_type test(...);
5054 template<
typename T1,
typename T2,
typename T3, endian E>
5055 static constexpr std::true_type
5058 using type =
decltype(test(std::declval<Derived*>()));
5064using is_data =
typename detail::is_data_impl<T>::type;
5066#if SBEPP_HAS_INLINE_VARS
5120#if SBEPP_HAS_CONCEPTS
5139concept type = is_type_v<T>;
5147concept set = is_set_v<T>;
5155concept message = is_message_v<T>;
5167concept group = is_group_v<T>;
5171concept data = is_data_v<T>;
5177using is_visitable_view = std::integral_constant<
5179 is_message<T>::value || is_group<T>::value || is_group_entry<T>::value
5180 || is_composite<T>::value>;
5198 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5199SBEPP_CPP14_CONSTEXPR Visitor&&
5200 visit(View view, Cursor& c, Visitor&& visitor = {})
5202 view(detail::visit_tag{}, visitor, c);
5203 return std::forward<Visitor>(visitor);
5219 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5220SBEPP_CPP14_CONSTEXPR Visitor&&
visit(View view, Visitor&& visitor = {})
5223 return sbepp::visit(view, c, std::forward<Visitor>(visitor));
5226#ifndef SBEPP_DOXYGEN
5227template<
typename Visitor,
typename Set>
5228SBEPP_CPP14_CONSTEXPR detail::enable_if_t<is_set<Set>::value, Visitor&&>
5229 visit(Set s, Visitor&& visitor = {})
5231 s(detail::visit_tag{}, visitor);
5232 return std::forward<Visitor>(visitor);
5235template<
typename Visitor,
typename Enum>
5236SBEPP_CPP14_CONSTEXPR detail::enable_if_t<is_enum<Enum>::value, Visitor&&>
5237 visit(Enum e, Visitor&& visitor = {})
5239 tag_invoke(detail::visit_tag{}, e, visitor);
5240 return std::forward<Visitor>(visitor);
5261template<
typename Visitor,
typename Set>
5262SBEPP_CPP14_CONSTEXPR Visitor&&
visit(Set s, Visitor&& visitor = {});
5280template<
typename Visitor,
typename Enum>
5281SBEPP_CPP14_CONSTEXPR Visitor&&
visit(Enum e, Visitor&& visitor = {});
5300 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5301SBEPP_CPP14_CONSTEXPR Visitor&&
5304 view(detail::visit_children_tag{}, visitor, c);
5305 return std::forward<Visitor>(visitor);
5321 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5322SBEPP_CPP14_CONSTEXPR Visitor&&
5331class enum_to_string_visitor
5334 template<
typename Enum,
typename Tag>
5335 SBEPP_CPP14_CONSTEXPR
void on_enum_value(Enum , Tag)
noexcept
5340 template<
typename Enum>
5341 SBEPP_CPP14_CONSTEXPR
void
5344 name_value =
nullptr;
5347 constexpr const char* name() const noexcept
5353 const char* name_value;
5367template<typename E, typename = detail::enable_if_t<is_enum<E>::value>>
5368SBEPP_DEPRECATED
constexpr const char*
enum_to_string(
const E e)
noexcept
5370 return visit<detail::enum_to_string_visitor>(e).name();
5384template<
typename Set,
typename Visitor>
5385SBEPP_DEPRECATED
constexpr auto
5386 visit_set(
const Set s, Visitor&& visitor)
noexcept
5387 ->
decltype(s(detail::visit_set_tag{}, std::forward<Visitor>(visitor)))
5389 return s(detail::visit_set_tag{}, std::forward<Visitor>(visitor));
5394class size_bytes_checked_visitor
5397 constexpr explicit size_bytes_checked_visitor(
5398 const std::size_t size) noexcept
5403 template<
typename T,
typename Cursor,
typename Tag>
5404 SBEPP_CPP14_CONSTEXPR
void on_message(T m, Cursor& c, Tag)
noexcept
5408 if(!validate_and_subtract(header_size))
5413 if(!validate_and_subtract(*header.blockLength()))
5421 template<
typename T,
typename Cursor,
typename Tag>
5422 SBEPP_CPP14_CONSTEXPR
bool on_group(T g, Cursor& c, Tag)
noexcept
5426 if(!validate_and_subtract(header_size))
5431 const auto prev_block_length =
5432 set_group_block_length(*header.blockLength());
5434 set_group_block_length(prev_block_length);
5439 template<
typename T,
typename Cursor>
5440 SBEPP_CPP14_CONSTEXPR
bool on_entry(T e, Cursor& c)
noexcept
5442 if(!validate_and_subtract(group_block_length))
5450 template<
typename T,
typename Tag>
5451 SBEPP_CPP14_CONSTEXPR
bool on_data(T d, Tag)
noexcept
5457 template<
typename T,
typename Tag>
5458 constexpr bool on_field(T, Tag)
const noexcept
5463 constexpr bool is_valid() const noexcept
5469 SBEPP_CPP14_CONSTEXPR std::size_t
5470 set_group_block_length(
const std::size_t block_length)
noexcept
5472 auto prev = group_block_length;
5473 group_block_length = block_length;
5477 constexpr std::size_t get_size() const noexcept
5486 std::size_t group_block_length{};
5488 SBEPP_CPP14_CONSTEXPR
bool
5489 validate_and_subtract(
const std::size_t n)
noexcept
5506struct size_bytes_checked_result
5525template<
typename View>
5535 detail::size_bytes_checked_visitor visitor{size};
5538 if(visitor.is_valid())
5540 return {
true, size - visitor.get_size()};
5546#if SBEPP_HAS_RANGES && SBEPP_HAS_CONCEPTS
5548template<
typename Byte,
typename Value, std::
size_t N,
typename Tag>
5549inline constexpr bool std::ranges::enable_borrowed_range<
5552template<
typename Byte,
typename Value,
typename Length, sbepp::endian E>
5553inline constexpr bool std::ranges::enable_borrowed_range<
5556template<sbepp::detail::derived_from_tmp<sbepp::detail::flat_group_base> T>
5557inline constexpr bool std::ranges::enable_borrowed_range<T> =
true;
5559template<sbepp::detail::derived_from_tmp<sbepp::detail::nested_group_base> T>
5560inline constexpr bool std::ranges::enable_borrowed_range<T> =
true;
5563#undef SBEPP_CPP17_INLINE_VAR
5564#undef SBEPP_DEPRECATED
5565#undef SBEPP_CPLUSPLUS
Provides various traits/attributes of a <composite> element.
Definition sbepp.hpp:4290
CompositeType< Byte > value_type
Representation type.
Definition sbepp.hpp:4314
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:783
constexpr Byte * pointer() const noexcept
access underlying pointer
Definition sbepp.hpp:849
constexpr cursor(cursor< Byte2 > other) noexcept
Construct from another cursor. Enabled only if Byte2* is convertible to Byte*.
Definition sbepp.hpp:812
Byte byte_type
same as Byte
Definition sbepp.hpp:786
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:839
constexpr cursor & operator=(cursor< Byte2 > other) noexcept
Assign from another cursor. Enabled only if Byte2* is convertible to Byte
Definition sbepp.hpp:827
Provides various traits/attributes of a <data> element.
Definition sbepp.hpp:4575
static constexpr const char * name() noexcept
Returns name attribute.
DataType value_type
Representation type.
Definition sbepp.hpp:4594
LengthTypeTag length_type_tag
length_type tag
Definition sbepp.hpp:4598
LengthType length_type
Length type.
Definition sbepp.hpp:4596
Base class for bitsets.
Definition sbepp.hpp:2736
constexpr T operator*() const noexcept
Returns underlying value.
Definition sbepp.hpp:2753
constexpr friend bool operator==(const bitset_base &lhs, const bitset_base &rhs) noexcept
Tests if underlying values are equal.
Definition sbepp.hpp:2772
constexpr T & operator*() noexcept
Returns reference to underlying value.
Definition sbepp.hpp:2747
constexpr bitset_base(T value) noexcept
Constructs from given value.
Definition sbepp.hpp:2742
constexpr friend bool operator!=(const bitset_base &lhs, const bitset_base &rhs) noexcept
Tests if underlying values are not equal.
Definition sbepp.hpp:2779
bitset_base()=default
Default constructs underlying value to 0
Base class for all reference semantics types.
Definition sbepp.hpp:714
constexpr byte_range(Byte *ptr, const std::size_t size) noexcept
Constructs from pointer and size.
Definition sbepp.hpp:736
constexpr byte_range(const byte_range< Byte2 > &other) noexcept
Copy constructor. Available if Byte2* is convertible to Byte*
Definition sbepp.hpp:744
byte_range()=default
Initializes to nullptr
constexpr byte_range(Byte *begin, Byte *end) noexcept
Constructs from a pair of pointers.
Definition sbepp.hpp:725
Base class for composites.
Definition sbepp.hpp:1740
Represents reference to dynamic arrays used for <data> elements.
Definition sbepp.hpp:3304
constexpr sbe_size_type sbe_size() const noexcept
Returns SBE size representation.
Definition sbepp.hpp:3394
pointer iterator
iterator type. Satisfies std::random_access_iterator
Definition sbepp.hpp:3326
std::reverse_iterator< iterator > reverse_iterator
reverse iterator type
Definition sbepp.hpp:3328
constexpr iterator insert(iterator pos, std::initializer_list< value_type > ilist) const noexcept
Inserts elements from ilist before pos
Definition sbepp.hpp:3553
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator to the end.
Definition sbepp.hpp:3352
static constexpr size_type max_size() noexcept
Returns max value of SBE length representation.
Definition sbepp.hpp:3412
constexpr iterator erase(iterator first, iterator last) const noexcept
Erases elements in [first; last) range.
Definition sbepp.hpp:3500
constexpr void assign_string(const char *str) const noexcept
Assigns null-terminated string.
Definition sbepp.hpp:3619
constexpr iterator insert(iterator pos, InputIt first, InputIt last) const
Inserts elements from [first; last) range before pos
Definition sbepp.hpp:3543
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:3583
constexpr reference back() const noexcept
Access the last element.
Definition sbepp.hpp:3367
constexpr void resize(size_type count, sbepp::default_init_t) const noexcept
Sets size to count, default initializes new elements.
Definition sbepp.hpp:3458
element_type * pointer
element pointer type
Definition sbepp.hpp:3324
constexpr void push_back(value_type value) const noexcept
Adds new element to the end.
Definition sbepp.hpp:3472
constexpr iterator insert(iterator pos, const value_type value) const noexcept
Inserts value before pos
Definition sbepp.hpp:3511
constexpr reference operator[](size_type pos) const noexcept
Access element at pos
Definition sbepp.hpp:3387
constexpr void resize(size_type count) const noexcept
Sets size to count, value initializes new elements.
Definition sbepp.hpp:3426
constexpr reference front() const noexcept
Access the first element.
Definition sbepp.hpp:3359
std::ptrdiff_t difference_type
std::ptrdiff_t
Definition sbepp.hpp:3320
constexpr void pop_back() const noexcept
Removes the last element.
Definition sbepp.hpp:3481
Value value_type
same as Value
Definition sbepp.hpp:3314
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:3600
detail::apply_cv_qualifiers_t< Byte, Value > element_type
final element type. value_type with the same cv-qualifiers as Byte
Definition sbepp.hpp:3312
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:3334
constexpr void assign_range(R &&r) const
Assigns range.
Definition sbepp.hpp:3638
constexpr iterator insert(iterator pos, size_type count, const value_type value) const noexcept
Inserts count copies of value before pos
Definition sbepp.hpp:3523
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:3563
constexpr pointer data() const noexcept
Direct access to the underlying array.
Definition sbepp.hpp:3380
constexpr iterator erase(iterator pos) const noexcept
Erases element at pos
Definition sbepp.hpp:3489
constexpr void clear() const noexcept
Sets size to 0.
Definition sbepp.hpp:3419
constexpr bool empty() const noexcept
Checks if size() != 0
Definition sbepp.hpp:3406
constexpr reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the beginning.
Definition sbepp.hpp:3346
constexpr void resize(size_type count, value_type value) const noexcept
Sets size to count, initializes new elements with value
Definition sbepp.hpp:3442
constexpr void assign(InputIt first, InputIt last) const
Replaces the contents of the container with the elements from [first; last) range.
Definition sbepp.hpp:3572
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:3340
constexpr size_type size() const noexcept
Returns raw size.
Definition sbepp.hpp:3400
typename sbe_size_type::value_type size_type
raw size type
Definition sbepp.hpp:3318
Length sbe_size_type
length SBE representation of data's encoding
Definition sbepp.hpp:3316
element_type & reference
element reference type
Definition sbepp.hpp:3322
Base class for group entries.
Definition sbepp.hpp:1791
constexpr entry_base(cursor< Byte2 > &c, Byte *end_ptr, BlockLengthType block_length) noexcept
Constructs from cursor.
Definition sbepp.hpp:1819
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:1831
constexpr entry_base(Byte *ptr, const std::size_t size, const BlockLengthType block_length) noexcept
Constructs from pointer and size.
Definition sbepp.hpp:1809
entry_base()=default
Constructs using nullptr
constexpr entry_base(Byte *ptr, Byte *end, BlockLengthType block_length) noexcept
Constructs from two pointers.
Definition sbepp.hpp:1802
Base class for a flat group.
Definition sbepp.hpp:2279
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:2294
constexpr void clear() const noexcept
Resizes to 0
Definition sbepp.hpp:2401
constexpr sbe_size_type sbe_size() const noexcept
Returns header's numInGroup
Definition sbepp.hpp:2325
typename cursor_range_t< Byte2 >::iterator cursor_iterator
cursor_range_t::iterator. Satisfies std::input_iterator
Definition sbepp.hpp:2473
constexpr reference front() const noexcept
Returns the first entry.
Definition sbepp.hpp:2385
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:2437
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:2408
typename std::decay< decltype(std::declval< Dimension >().numInGroup())>::type sbe_size_type
numInGroup value type
Definition sbepp.hpp:2286
Entry value_type
Entry type.
Definition sbepp.hpp:2282
constexpr reference operator[](size_type pos) const noexcept
Access group entry at pos
Definition sbepp.hpp:2377
constexpr size_type size() const noexcept
Returns raw size.
Definition sbepp.hpp:2331
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:2355
constexpr cursor_iterator< Byte2 > cursor_begin(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the beginning.
Definition sbepp.hpp:2480
constexpr cursor_range_t< Byte2 > cursor_range(cursor< Byte2 > &c) const noexcept
Returns cursor range to all group entries.
Definition sbepp.hpp:2421
constexpr bool empty() const noexcept
Checks if size() == 0
Definition sbepp.hpp:2343
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:2366
constexpr void resize(const size_type count) const noexcept
Sets numInGroup to count
Definition sbepp.hpp:2337
constexpr cursor_iterator< Byte2 > cursor_end(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the end.
Definition sbepp.hpp:2490
static constexpr size_type max_size() noexcept
Returns numInGroup's maxValue
Definition sbepp.hpp:2349
constexpr reference back() const noexcept
Returns the last entry.
Definition sbepp.hpp:2393
typename std::make_signed< size_type >::type difference_type
signed size_type
Definition sbepp.hpp:2291
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:2455
typename sbe_size_type::value_type size_type
Raw size type.
Definition sbepp.hpp:2289
value_type reference
value_type
Definition sbepp.hpp:2284
Base class for messages.
Definition sbepp.hpp:1749
Base class for a nested group.
Definition sbepp.hpp:2513
constexpr size_type size() const noexcept
Returns raw size.
Definition sbepp.hpp:2569
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:2604
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:2659
Entry value_type
entry type
Definition sbepp.hpp:2516
static constexpr size_type max_size() noexcept
Returns numInGroup's maxValue
Definition sbepp.hpp:2587
typename cursor_range_t< Byte2 >::iterator cursor_iterator
cursor_range_t::iterator. Satisfies std::input_iterator
Definition sbepp.hpp:2695
value_type reference
value_type
Definition sbepp.hpp:2518
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:2630
typename sbe_size_type::value_type size_type
raw size type
Definition sbepp.hpp:2523
typename std::make_signed< size_type >::type difference_type
signed size_type
Definition sbepp.hpp:2525
constexpr sbe_size_type sbe_size() const noexcept
Returns header's numInGroup
Definition sbepp.hpp:2563
constexpr void resize(const size_type count) const noexcept
Sets numInGroup to count
Definition sbepp.hpp:2575
constexpr reference front() const noexcept
Returns the first element.
Definition sbepp.hpp:2615
constexpr cursor_iterator< Byte2 > cursor_end(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the end.
Definition sbepp.hpp:2712
constexpr void clear() const noexcept
Resizes to 0
Definition sbepp.hpp:2623
constexpr cursor_iterator< Byte2 > cursor_begin(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the beginning.
Definition sbepp.hpp:2702
constexpr bool empty() const noexcept
Checks if size() == 0
Definition sbepp.hpp:2581
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:2529
constexpr cursor_range_t< Byte2 > cursor_range(cursor< Byte2 > &c) const noexcept
Returns cursor range to all group entries.
Definition sbepp.hpp:2643
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:2677
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:2593
typename std::decay< decltype(std::declval< Dimension >().numInGroup())>::type sbe_size_type
numInGroup value type
Definition sbepp.hpp:2520
Base class for optional types.
Definition sbepp.hpp:3834
constexpr value_type value() const noexcept
Returns underlying value.
Definition sbepp.hpp:3855
constexpr friend bool operator!=(const optional_base &lhs, const optional_base &rhs) noexcept
Tests if lhs is not equal to rhs
Definition sbepp.hpp:3935
constexpr optional_base(nullopt_t) noexcept
Constructs null object.
Definition sbepp.hpp:3844
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:3880
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:3963
T value_type
Underlying type.
Definition sbepp.hpp:3837
constexpr bool in_range() const noexcept
Checks if value is in [Derived::min_value(); Derived::max_value()] range.
Definition sbepp.hpp:3874
constexpr optional_base(value_type val) noexcept
Constructs object from given value.
Definition sbepp.hpp:3850
constexpr bool has_value() const noexcept
Checks if has value.
Definition sbepp.hpp:3890
constexpr friend bool operator>(const optional_base &lhs, const optional_base &rhs) noexcept
Tests if lhs is greater than rhs
Definition sbepp.hpp:3956
constexpr value_type operator*() const noexcept
Returns underlying value.
Definition sbepp.hpp:3867
constexpr value_type & operator*() noexcept
Returns reference to underlying value.
Definition sbepp.hpp:3861
constexpr friend bool operator==(const optional_base &lhs, const optional_base &rhs) noexcept
Tests if lhs is equal to rhs
Definition sbepp.hpp:3910
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:3727
constexpr friend bool operator>(const required_base &lhs, const required_base &rhs) noexcept
Tests if lhs is greater than rhs
Definition sbepp.hpp:3809
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:3816
constexpr value_type value() const noexcept
Returns underlying value.
Definition sbepp.hpp:3742
constexpr friend bool operator!=(const required_base &lhs, const required_base &rhs) noexcept
Tests if lhs is not equal to rhs
Definition sbepp.hpp:3788
constexpr value_type & operator*() noexcept
Returns reference to underlying value.
Definition sbepp.hpp:3748
constexpr friend bool operator==(const required_base &lhs, const required_base &rhs) noexcept
Tests if lhs is equal to rhs
Definition sbepp.hpp:3781
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:3761
T value_type
Underlying type.
Definition sbepp.hpp:3730
constexpr value_type operator*() const noexcept
Returns underlying value.
Definition sbepp.hpp:3754
constexpr required_base(value_type val) noexcept
Constructs from given value.
Definition sbepp.hpp:3737
Represents reference to fixed-size array.
Definition sbepp.hpp:2982
pointer iterator
iterator type. Satisfies std::random_access_iterator
Definition sbepp.hpp:2998
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator to the end.
Definition sbepp.hpp:3082
static constexpr bool empty() noexcept
Checks if size() != 0
Definition sbepp.hpp:3046
detail::apply_cv_qualifiers_t< Byte, Value > element_type
final element type. value_type with the same cv-qualifiers as Byte
Definition sbepp.hpp:2986
constexpr reference operator[](size_type pos) const noexcept
Access element at pos
Definition sbepp.hpp:3014
constexpr std::size_t strlen() const noexcept
Calculates string length from left to right.
Definition sbepp.hpp:3111
constexpr iterator assign_string(const char *str, const eos_null eos_mode=eos_null::all) const noexcept
Assigns null-terminated string.
Definition sbepp.hpp:3160
constexpr reference front() const noexcept
Access the first element.
Definition sbepp.hpp:3021
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:3064
static constexpr size_type size() noexcept
Returns N
Definition sbepp.hpp:3052
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:3099
constexpr iterator assign(std::initializer_list< value_type > ilist) const noexcept
Assigns initializer list to first elements.
Definition sbepp.hpp:3266
element_type & reference
element reference type
Definition sbepp.hpp:2994
std::reverse_iterator< iterator > reverse_iterator
reverse iterator type
Definition sbepp.hpp:3000
constexpr reference back() const noexcept
Access the last element.
Definition sbepp.hpp:3027
Value value_type
same as Value
Definition sbepp.hpp:2988
Tag tag
type tag
Definition sbepp.hpp:3002
element_type * pointer
element pointer type
Definition sbepp.hpp:2996
constexpr std::size_t strlen_r() const noexcept
Calculates string length from right to left.
Definition sbepp.hpp:3136
std::size_t size_type
std::size_t
Definition sbepp.hpp:2990
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:3070
constexpr iterator assign_string(R &&r, const eos_null eos_mode=eos_null::all) const
Assigns string represented by a range.
Definition sbepp.hpp:3188
constexpr void fill(const value_type value) const noexcept
Assigns value to all elements.
Definition sbepp.hpp:3225
constexpr iterator assign_range(R &&r) const
Assigns range.
Definition sbepp.hpp:3208
constexpr reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the beginning.
Definition sbepp.hpp:3076
constexpr iterator assign(InputIt first, InputIt last) const
Assigns elements from [first; last) range to first elements.
Definition sbepp.hpp:3250
static constexpr size_type max_size() noexcept
Returns size()
Definition sbepp.hpp:3058
std::ptrdiff_t difference_type
std::ptrdiff_t
Definition sbepp.hpp:2992
constexpr pointer data() const noexcept
Direct access to the underlying array.
Definition sbepp.hpp:3033
constexpr iterator assign(size_type count, const value_type value) const noexcept
Assigns value to first count elements.
Definition sbepp.hpp:3240
Provides various traits/attributes of an <enum> element.
Definition sbepp.hpp:4156
EncodingType encoding_type
Underlying type.
Definition sbepp.hpp:4163
static constexpr const char * name() noexcept
Returns name attribute.
ScopedEnumType value_type
Representation type.
Definition sbepp.hpp:4175
Provides various traits/attributes of a <validValue> element.
Definition sbepp.hpp:4193
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits/attributes of a <field> element.
Definition sbepp.hpp:4456
static constexpr const char * name() noexcept
Returns name attribute.
ValueType value_type
Representation type.
Definition sbepp.hpp:4478
TypeTag value_type_tag
value_type's tag. Not available for constants of numeric types
Definition sbepp.hpp:4487
Provides various traits/attributes of a <group> element.
Definition sbepp.hpp:4505
HeaderType< Byte > dimension_type
Group dimension composite type.
Definition sbepp.hpp:4535
HeaderTag dimension_type_tag
Dimension composite tag.
Definition sbepp.hpp:4537
GroupType< Byte > value_type
Representation type.
Definition sbepp.hpp:4528
EntryType< Byte > entry_type
Group entry type.
Definition sbepp.hpp:4544
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits/attributes of a <message> element.
Definition sbepp.hpp:4334
static constexpr const char * name() noexcept
Returns name attribute.
SchemaTag schema_tag
Schema tag.
Definition sbepp.hpp:4359
MessageType< Byte > value_type
Representation type.
Definition sbepp.hpp:4357
Provides various traits/attributes of a <messageSchema> element.
Definition sbepp.hpp:4116
HeaderTypeTag header_type_tag
Message header composite tag. Can be used to access its traits.
Definition sbepp.hpp:4138
static constexpr const char * package() noexcept
Returns package attribute.
HeaderComposite< Byte > header_type
Message header composite type.
Definition sbepp.hpp:4136
Provides various traits/attributes of a <choice> element.
Definition sbepp.hpp:4260
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits/attributes of a <set> element.
Definition sbepp.hpp:4223
SetType value_type
Representation type.
Definition sbepp.hpp:4242
EncodingType encoding_type
Underlying type.
Definition sbepp.hpp:4235
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits and attributes of a <type> element.
Definition sbepp.hpp:4035
ValueType value_type
Representation type.
Definition sbepp.hpp:4041
PrimitiveType primitive_type
Underlying type.
Definition sbepp.hpp:4038
static constexpr const char * name() noexcept
Returns name attribute.
Concept for sbepp::is_array_type<T>::value
Definition sbepp.hpp:5122
Concept for sbepp::is_composite<T>::value
Definition sbepp.hpp:5150
Concept for sbepp::is_data<T>::value
Definition sbepp.hpp:5170
Concept for sbepp::is_enum<T>::value
Definition sbepp.hpp:5142
Concept for sbepp::is_flat_group<T>::value
Definition sbepp.hpp:5158
Concept for sbepp::is_group<T>::value
Definition sbepp.hpp:5166
Concept for sbepp::is_message<T>::value
Definition sbepp.hpp:5154
Concept for sbepp::is_nested_group<T>::value
Definition sbepp.hpp:5162
Concept for sbepp::is_non_array_type<T>::value
Definition sbepp.hpp:5134
Concept for sbepp::is_optional_type<T>::value
Definition sbepp.hpp:5130
Concept for sbepp::is_required_type<T>::value
Definition sbepp.hpp:5126
Concept for sbepp::is_set<T>::value
Definition sbepp.hpp:5146
Concept for sbepp::is_type<T>::value
Definition sbepp.hpp:5138
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:1728
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:1694
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:1665
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:1708
The main sbepp namespace.
Definition sbepp.hpp:232
constexpr auto is_composite_v
Shorthand for sbepp::is_composite<T>::value
Definition sbepp.hpp:5096
constexpr auto is_required_type_v
Shorthand for sbepp::is_required_type<T>::value
Definition sbepp.hpp:5072
constexpr auto is_type_v
Shorthand for sbepp::is_type<T>::value
Definition sbepp.hpp:5084
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:2827
detail::is_base_of_tmp< detail::optional_base, T > is_optional_type
Checks if T is a non-array optional type.
Definition sbepp.hpp:4985
constexpr View< Byte > make_view(Byte *ptr, const std::size_t size) noexcept
Construct view from memory buffer.
Definition sbepp.hpp:4897
typename traits_tag< ValueType >::type traits_tag_t
Shorthand for sbepp::traits_tag<T>::type
Definition sbepp.hpp:4647
constexpr auto is_flat_group_v
Shorthand for sbepp::is_flat_group<T>::value
Definition sbepp.hpp:5104
eos_null
Represents number of null bytes that can be added after the end-of-string by detail::static_array_ref...
Definition sbepp.hpp:2895
@ 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:2846
constexpr auto get_header(T v) noexcept -> decltype(v(detail::get_header_tag{}))
Returns the header of a message/group.
Definition sbepp.hpp:1607
detail::is_base_of_tmp< detail::required_base, T > is_required_type
Checks if T is a non-array required type.
Definition sbepp.hpp:4981
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:5038
detail::is_base_of_tmp< detail::flat_group_base, T > is_flat_group
Checks if T is a flat group.
Definition sbepp.hpp:5030
constexpr auto is_array_type_v
Shorthand for sbepp::is_array_type<T>::value
Definition sbepp.hpp:5068
constexpr nullopt_t nullopt
Helper constant used to initialize optional types with null value.
Definition sbepp.hpp:3717
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:5301
constexpr auto is_enum_v
Shorthand for sbepp::is_enum<T>::value
Definition sbepp.hpp:5088
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:2869
constexpr auto fill_message_header(Message m) noexcept -> decltype(m(detail::fill_message_header_tag{}))
Fill message header.
Definition sbepp.hpp:3990
constexpr auto is_non_array_type_v
Shorthand for sbepp::is_non_array_type<T>::value
Definition sbepp.hpp:5080
constexpr Visitor && visit(View view, Cursor &c, Visitor &&visitor={})
Visit a view using given cursor.
Definition sbepp.hpp:5199
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:5063
typename byte_type< View >::type byte_type_t
Shortcut for byte_type<T>::type
Definition sbepp.hpp:1639
detail::is_base_of_tmp< detail::nested_group_base, T > is_nested_group
Checks if T is a nested group.
Definition sbepp.hpp:5034
constexpr const char * enum_to_string(const E e) noexcept
Converts enum to string.
Definition sbepp.hpp:5367
detail::is_base_of_tmp< detail::message_base, T > is_message
Checks if T is a message.
Definition sbepp.hpp:5026
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:4010
constexpr auto addressof(T v) noexcept -> decltype(v(detail::addressof_tag{}))
Returns pointer to the underlying data referenced by a view.
Definition sbepp.hpp:1619
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:1580
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:5018
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:4995
constexpr auto is_group_v
Shorthand for sbepp::is_group<T>::value
Definition sbepp.hpp:5112
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:5385
constexpr default_init_t default_init
helper to pass default_init_t to dynamic_array_ref::resize().
Definition sbepp.hpp:2890
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:4989
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:5076
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:5526
constexpr auto is_message_v
Shorthand for sbepp::is_message<T>::value
Definition sbepp.hpp:5100
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:5092
detail::is_base_of_tmp< detail::entry_base, T > is_group_entry
Checks if T is a group entry.
Definition sbepp.hpp:5044
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:5108
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:4922
constexpr auto is_data_v
Shorthand for sbepp::is_data<T>::value
Definition sbepp.hpp:5116
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:4977
detail::is_base_of_tmp< detail::composite_base, T > is_composite
Checks if T is a composite.
Definition sbepp.hpp:5022
#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:1631
typename std::remove_pointer< decltype(sbepp::addressof( std::declval< View >()))>::type type
holds View's byte type
Definition sbepp.hpp:1633
tag for dynamic_array_ref::resize(). Used to skip value initialization.
Definition sbepp.hpp:2881
Checks if T is an enumeration.
Definition sbepp.hpp:5003
Tag type used to initialize optional types with null value.
Definition sbepp.hpp:3706
Result type of size_bytes_checked
Definition sbepp.hpp:5506
Maps representation type to its tag.
Definition sbepp.hpp:4639
Tag type
Tag to access ValueType's traits.
Definition sbepp.hpp:4641
Tag for unknown enum values.
Definition sbepp.hpp:4934