20#include <initializer_list>
26# define SBEPP_WARNINGS_OFF() \
27 _Pragma("clang diagnostic push"); \
28 _Pragma("clang diagnostic ignored \"-Wbraced-scalar-init\"")
29# define SBEPP_WARNINGS_ON() _Pragma("clang diagnostic pop")
31# define SBEPP_WARNINGS_OFF()
32# define SBEPP_WARNINGS_ON()
38# define SBEPP_CPLUSPLUS _MSVC_LANG
40# define SBEPP_CPLUSPLUS __cplusplus
44# if __has_include(<version>)
58#if !defined(SBEPP_HAS_THREE_WAY_COMPARISON) \
59 && defined(__cpp_impl_three_way_comparison) \
60 && defined(__cpp_lib_three_way_comparison)
61# if(__cpp_impl_three_way_comparison >= 201907L) \
62 && (__cpp_lib_three_way_comparison >= 201907L)
63# define SBEPP_HAS_THREE_WAY_COMPARISON 1
67#ifndef SBEPP_HAS_THREE_WAY_COMPARISON
68# define SBEPP_HAS_THREE_WAY_COMPARISON 0
72#if !defined(SBEPP_HAS_CONCEPTS) && defined(__cpp_concepts)
73# if(__cpp_concepts >= 201907L)
74# define SBEPP_HAS_CONCEPTS 1
77#ifndef SBEPP_HAS_CONCEPTS
78# define SBEPP_HAS_CONCEPTS 0
82#if !defined(SBEPP_HAS_INLINE_VARS) && defined(__cpp_inline_variables)
83# if(__cpp_inline_variables >= 201606L)
84# define SBEPP_HAS_INLINE_VARS 1
85# define SBEPP_CPP17_INLINE_VAR inline
88#ifndef SBEPP_CPP17_INLINE_VAR
89# define SBEPP_HAS_INLINE_VARS 0
90# define SBEPP_CPP17_INLINE_VAR
94#if !defined(SBEPP_HAS_ENDIAN) && defined(__cpp_lib_endian)
95# if(__cpp_lib_endian >= 201907L)
96# define SBEPP_HAS_ENDIAN 1
100#ifndef SBEPP_HAS_ENDIAN
101# define SBEPP_HAS_ENDIAN 0
105#if !defined(SBEPP_HAS_BITCAST) && defined(__cpp_lib_bit_cast)
106# if(__cpp_lib_bit_cast >= 201806L)
107# define SBEPP_HAS_BITCAST 1
111#ifndef SBEPP_HAS_BITCAST
112# define SBEPP_HAS_BITCAST 0
116#if !defined(SBEPP_HAS_BYTESWAP) && defined(__cpp_lib_byteswap)
117# if(__cpp_lib_byteswap >= 202110L)
118# define SBEPP_HAS_BYTESWAP 1
122#ifndef SBEPP_HAS_BYTESWAP
123# define SBEPP_HAS_BYTESWAP 0
127#if !defined(SBEPP_HAS_CONSTEXPR_ALGORITHMS) \
128 && defined(__cpp_lib_constexpr_algorithms)
129# if(__cpp_lib_constexpr_algorithms >= 201806L)
130# define SBEPP_HAS_CONSTEXPR_ALGORITHMS 1
133#ifndef SBEPP_HAS_CONSTEXPR_ALGORITHMS
134# define SBEPP_HAS_CONSTEXPR_ALGORITHMS 0
137#ifdef __has_cpp_attribute
139# if __has_cpp_attribute(nodiscard) \
140 && !(defined(__clang__) && (SBEPP_CPLUSPLUS < 201703L))
141# define SBEPP_CPP17_NODISCARD [[nodiscard]]
144# if __has_cpp_attribute(deprecated) \
145 && !(defined(__clang__) && (SBEPP_CPLUSPLUS < 201402L))
146# define SBEPP_DEPRECATED [[deprecated]]
150#ifndef SBEPP_CPP17_NODISCARD
151# define SBEPP_CPP17_NODISCARD
154#ifndef SBEPP_DEPRECATED
155# if defined(__GNUC__) || defined(__clang__)
156# define SBEPP_DEPRECATED __attribute__((deprecated))
157# elif defined(_MSC_VER)
158# define SBEPP_DEPRECATED __declspec(deprecated)
160# define SBEPP_DEPRECATED
165#if SBEPP_HAS_BITCAST && SBEPP_HAS_CONSTEXPR_ALGORITHMS
166# define SBEPP_HAS_CONSTEXPR_ACCESSORS 1
168# define SBEPP_HAS_CONSTEXPR_ACCESSORS 0
171#if SBEPP_HAS_CONSTEXPR_ACCESSORS
173# define SBEPP_CPP20_CONSTEXPR constexpr
175# define SBEPP_CPP20_CONSTEXPR
178#ifdef __cpp_constexpr
179# if(__cpp_constexpr >= 201304L)
180# define SBEPP_CPP14_CONSTEXPR constexpr
183# if(SBEPP_CPLUSPLUS >= 201402L)
184# define SBEPP_CPP14_CONSTEXPR constexpr
187#ifndef SBEPP_CPP14_CONSTEXPR
188# define SBEPP_CPP14_CONSTEXPR
192#if !defined(SBEPP_HAS_RANGES) && defined(__cpp_lib_ranges)
193# if(__cpp_lib_ranges >= 201911L)
194# define SBEPP_HAS_RANGES 1
198#ifndef SBEPP_HAS_RANGES
199# define SBEPP_HAS_RANGES 0
204#if !defined(SBEPP_HAS_IS_CONSTANT_EVALUATED) \
205 && defined(__cpp_lib_is_constant_evaluated) \
206 && (__cpp_lib_is_constant_evaluated >= 201811L)
207# define SBEPP_HAS_IS_CONSTANT_EVALUATED 1
209#ifndef SBEPP_HAS_IS_CONSTANT_EVALUATED
210# define SBEPP_HAS_IS_CONSTANT_EVALUATED 0
217# define SBEPP_DISABLE_ASSERTS
223# define SBEPP_ASSERT_HANDLER
229# define SBEPP_ENABLE_ASSERTS_WITH_HANDLER
244 char const* expr,
char const* function,
char const* file,
long line);
248#ifdef SBEPP_DISABLE_ASSERTS
249# define SBEPP_SIZE_CHECKS_ENABLED 0
250# define SBEPP_ASSERT(expr) ((void)0)
251#elif defined(SBEPP_ASSERT_HANDLER) \
252 || defined(SBEPP_ENABLE_ASSERTS_WITH_HANDLER)
253# if !defined(NDEBUG) || defined(SBEPP_ENABLE_ASSERTS_WITH_HANDLER)
258 char const* expr,
char const* function,
char const* file,
long line);
261# define SBEPP_SIZE_CHECKS_ENABLED 1
262# define SBEPP_ASSERT(expr) \
263 (static_cast<bool>(expr) \
265 : ::sbepp::assertion_failed( \
266 #expr, __func__, __FILE__, __LINE__))
268# define SBEPP_SIZE_CHECKS_ENABLED 0
269# define SBEPP_ASSERT(expr) ((void)0)
274# define SBEPP_SIZE_CHECKS_ENABLED 0
276# define SBEPP_SIZE_CHECKS_ENABLED 1
278# define SBEPP_ASSERT(expr) assert(expr)
281#define SBEPP_SIZE_CHECK(begin, end, offset, size) \
284 && (((offset) + (size)) <= static_cast<std::size_t>((end) - (begin))))
327# define SBEPP_BYTE_ORDER
345#elif SBEPP_HAS_ENDIAN
346using endian = std::endian;
351# if defined(_WIN32) || defined(WIN32)
355# elif defined(__BYTE_ORDER__)
356 little = __ORDER_LITTLE_ENDIAN__,
357 big = __ORDER_BIG_ENDIAN__,
359# elif defined(SBEPP_BYTE_ORDER)
364# error "Byte order cannot be detected.\
365 Define SBEPP_BYTE_ORDER to 'little' or 'big'"
372 "Mixed-endian is not supported");
379template<
bool B,
typename T =
void>
380using enable_if_t =
typename std::enable_if<B, T>::type;
383using remove_cv_t =
typename std::remove_cv<T>::type;
386using remove_reference_t =
typename std::remove_reference<T>::type;
388template<
typename ByteFrom,
typename ByteTo>
389using enable_if_convertible_t =
390 enable_if_t<std::is_convertible<ByteFrom*, ByteTo*>::value>;
392template<
typename Byte,
typename T =
void>
393using enable_if_writable_t = enable_if_t<!std::is_const<Byte>::value, T>;
398template<typename T, typename = enable_if_t<!std::is_floating_point<T>::value>>
399constexpr typename std::make_unsigned<T>::type to_unsigned(T v)
noexcept
401 return static_cast<typename std::make_unsigned<T>::type
>(v);
404inline std::uint64_t to_unsigned(
double v)
noexcept
407 std::memcpy(&res, &v,
sizeof(res));
411inline std::uint32_t to_unsigned(
float v)
noexcept
414 std::memcpy(&res, &v,
sizeof(res));
422 operator()(
typename std::make_unsigned<To>::type from)
const noexcept
424 return static_cast<To
>(from);
429struct from_unsigned<double>
431 double operator()(std::uint64_t from)
const noexcept
434 std::memcpy(&res, &from,
sizeof(res));
440struct from_unsigned<float>
442 float operator()(std::uint32_t from)
const noexcept
445 std::memcpy(&res, &from,
sizeof(res));
452# define __has_builtin(x) 0
455#if SBEPP_HAS_BYTESWAP
465T byteswap(T)
noexcept;
467# if defined(_MSC_VER) && (!defined(__clang__) || defined(__c2__))
471inline std::uint64_t byteswap(std::uint64_t v)
noexcept
473 return _byteswap_uint64(v);
476inline std::uint32_t byteswap(std::uint32_t v)
noexcept
478 return _byteswap_ulong(v);
481inline std::uint16_t byteswap(std::uint16_t v)
noexcept
483 return _byteswap_ushort(v);
487 defined(__clang__) && __has_builtin(__builtin_bswap32) \
488 && __has_builtin(__builtin_bswap64)) \
489 || (defined(__GNUC__) \
490 && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
492# if(defined(__clang__) && __has_builtin(__builtin_bswap16)) \
493 || (defined(__GNUC__) \
494 && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
496inline std::uint16_t byteswap(std::uint16_t v)
noexcept
498 return __builtin_bswap16(v);
503inline std::uint16_t byteswap(std::uint16_t v)
noexcept
505 return __builtin_bswap32(v) << 16;
510inline std::uint64_t byteswap(std::uint64_t v)
noexcept
512 return __builtin_bswap64(v);
515inline std::uint32_t byteswap(std::uint32_t v)
noexcept
517 return __builtin_bswap32(v);
522constexpr std::uint64_t byteswap(std::uint64_t v)
noexcept
524 return ((v & UINT64_C(0x00000000000000FF)) << 56)
525 | ((v & UINT64_C(0x000000000000FF00)) << 40)
526 | ((v & UINT64_C(0x0000000000FF0000)) << 24)
527 | ((v & UINT64_C(0x00000000FF000000)) << 8)
528 | ((v & UINT64_C(0x000000FF00000000)) >> 8)
529 | ((v & UINT64_C(0x0000FF0000000000)) >> 24)
530 | ((v & UINT64_C(0x00FF000000000000)) >> 40)
531 | ((v & UINT64_C(0xFF00000000000000)) >> 56);
534constexpr std::uint32_t byteswap(std::uint32_t v)
noexcept
536 return ((v & UINT32_C(0x000000FF)) << 24)
537 | ((v & UINT32_C(0x0000FF00)) << 8)
538 | ((v & UINT32_C(0x00FF0000)) >> 8)
539 | ((v & UINT32_C(0xFF000000)) >> 24);
542constexpr std::uint16_t byteswap(std::uint16_t v)
noexcept
544 return ((v & UINT16_C(0x00FF)) << 8) | ((v & UINT16_C(0xFF00)) >> 8);
550template<
typename T, endian E,
typename Byte>
551SBEPP_CPP20_CONSTEXPR T get_primitive(
const Byte* ptr)
554 std::array<Byte,
sizeof(T)> arr;
557 std::copy(ptr, ptr +
sizeof(T), std::begin(arr));
561 std::reverse_copy(ptr, ptr +
sizeof(T), std::begin(arr));
563 return std::bit_cast<T>(arr);
568 std::memcpy(&res, ptr,
sizeof(T));
575 return from_unsigned<T>{}(byteswap(to_unsigned(res)));
580template<endian E,
typename T,
typename Byte>
581SBEPP_CPP20_CONSTEXPR
void set_primitive(Byte* ptr, T value)
584 auto arr = std::bit_cast<std::array<Byte,
sizeof(T)>>(value);
587 std::copy(std::begin(arr), std::end(arr), ptr);
591 std::reverse_copy(std::begin(arr), std::end(arr), ptr);
598 value = from_unsigned<T>{}(byteswap(to_unsigned(value)));
600 std::memcpy(ptr, &value,
sizeof(T));
604struct fill_message_header_tag
606 explicit fill_message_header_tag() =
default;
609struct fill_group_header_tag
611 explicit fill_group_header_tag() =
default;
616 explicit size_bytes_tag() =
default;
621 explicit addressof_tag() =
default;
626 explicit end_ptr_tag() =
default;
631 explicit get_header_tag() =
default;
634struct get_block_length_tag
636 explicit get_block_length_tag() =
default;
641 explicit get_bit_tag() =
default;
646 explicit set_bit_tag() =
default;
651 explicit get_level_tag() =
default;
656 explicit visit_tag() =
default;
659struct visit_children_tag
661 explicit visit_children_tag() =
default;
664struct enum_to_str_tag
666 explicit enum_to_str_tag() =
default;
671 explicit visit_set_tag() =
default;
674template<
typename T,
typename U, endian E,
typename View>
675SBEPP_CPP20_CONSTEXPR T
676 get_value(
const View view,
const std::size_t offset)
noexcept
679 view(addressof_tag{}), view(end_ptr_tag{}), offset,
sizeof(U));
680 return T{get_primitive<U, E>(view(addressof_tag{}) + offset)};
683template<endian E,
typename T,
typename View>
684SBEPP_CPP20_CONSTEXPR
void
685 set_value(
const View view,
const std::size_t offset,
const T value)
noexcept
688 view(addressof_tag{}), view(end_ptr_tag{}), offset,
sizeof(T));
689 set_primitive<E>(view(addressof_tag{}) + offset, value);
692template<
typename Res,
typename View>
693SBEPP_CPP20_CONSTEXPR Res
694 get_static_field_view(
const View view,
const std::size_t offset)
noexcept
696 SBEPP_SIZE_CHECK(view(addressof_tag{}), view(end_ptr_tag{}), offset, 0);
697 return {view(addressof_tag{}) + offset, view(end_ptr_tag{})};
700template<
typename Group,
typename View>
701SBEPP_CPP20_CONSTEXPR Group
702 get_first_dynamic_field_view(
const View view)
noexcept
705 view(get_level_tag{}) + view(get_block_length_tag{}),
706 view(end_ptr_tag{})};
709template<
typename Group,
typename View,
typename Prev>
710SBEPP_CPP20_CONSTEXPR Group
711 get_dynamic_field_view(
const View view,
const Prev prev)
noexcept
714 prev(addressof_tag{}) + prev(size_bytes_tag{}), view(end_ptr_tag{})};
719template<
typename Byte>
723 static_assert(
sizeof(Byte) == 1,
"Byte must represent a single byte");
725 template<
typename Byte2>
732 SBEPP_CPP14_CONSTEXPR
byte_range(Byte* begin, Byte* end) noexcept
734#if SBEPP_SIZE_CHECKS_ENABLED
743 constexpr byte_range(Byte* ptr,
const std::size_t size) noexcept
749 template<
typename Byte2,
typename = enable_if_convertible_t<Byte2, Byte>>
753#if SBEPP_SIZE_CHECKS_ENABLED
760 constexpr Byte* operator()(addressof_tag)
const noexcept
765 constexpr Byte* operator()(end_ptr_tag)
const noexcept
767#if SBEPP_SIZE_CHECKS_ENABLED
776#if SBEPP_SIZE_CHECKS_ENABLED
788template<
typename Byte>
803 using result_type = T;
817 typename = detail::enable_if_convertible_t<Byte2, Byte>>
833 typename = detail::enable_if_convertible_t<Byte2, Byte>>
846 SBEPP_CPP14_CONSTEXPR Byte*&
pointer() noexcept
856 SBEPP_CPP14_CONSTEXPR Byte*
pointer() const noexcept
861 template<
typename T,
typename U, endian E,
typename View>
862 SBEPP_CPP20_CONSTEXPR T get_value(
864 const std::size_t offset,
865 const std::size_t absolute_offset)
noexcept
868 ((view(detail::addressof_tag{}) + absolute_offset)
870 &&
"Wrong cursor value");
871 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(U));
872 T res{detail::get_primitive<U, E>(ptr + offset)};
873 ptr += offset +
sizeof(U);
877 template<endian E,
typename T,
typename View>
878 SBEPP_CPP20_CONSTEXPR
void set_value(
880 const std::size_t offset,
881 const std::size_t absolute_offset,
882 const T value)
noexcept
885 ((view(detail::addressof_tag{}) + absolute_offset)
887 &&
"Wrong cursor value");
888 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(T));
889 detail::set_primitive<E>(ptr + offset, value);
890 ptr += offset +
sizeof(T);
893 template<
typename T,
typename U, endian E,
typename View>
894 SBEPP_CPP20_CONSTEXPR T get_last_value(
896 const std::size_t offset,
897 const std::size_t absolute_offset)
noexcept
900 ((view(detail::addressof_tag{}) + absolute_offset)
902 &&
"Wrong cursor value");
903 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(U));
904 auto res = T{detail::get_primitive<U, E>(ptr + offset)};
905 ptr = view(detail::get_level_tag{})
906 + view(detail::get_block_length_tag{});
910 template<endian E,
typename T,
typename View>
911 SBEPP_CPP20_CONSTEXPR
void set_last_value(
913 const std::size_t offset,
914 const std::size_t absolute_offset,
915 const T value)
noexcept
918 ((view(detail::addressof_tag{}) + absolute_offset)
920 &&
"Wrong cursor value");
921 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset,
sizeof(T));
922 detail::set_primitive<E>(ptr + offset, value);
923 ptr = view(detail::get_level_tag{})
924 + view(detail::get_block_length_tag{});
927 template<
typename Res,
typename View>
928 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
930 const std::size_t offset,
931 const std::size_t absolute_offset)
noexcept
934 ((view(detail::addressof_tag{}) + absolute_offset)
936 &&
"Wrong cursor value");
937 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, 0);
938 Res res{ptr + offset, view(detail::end_ptr_tag{})};
939 ptr += offset + res(detail::size_bytes_tag{});
943 template<
typename Res,
typename View>
944 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
946 const std::size_t offset,
947 const std::size_t absolute_offset)
noexcept
950 ((view(detail::addressof_tag{}) + absolute_offset)
952 &&
"Wrong cursor value");
953 SBEPP_SIZE_CHECK(ptr, view(detail::end_ptr_tag{}), offset, 0);
954 Res res{ptr + offset, view(detail::end_ptr_tag{})};
955 ptr = view(detail::get_level_tag{})
956 + view(detail::get_block_length_tag{});
960 template<
typename ResView,
typename View>
961 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
963 ptr = view(detail::get_level_tag{})
964 + view(detail::get_block_length_tag{});
965 ResView g{ptr, view(detail::end_ptr_tag{})};
966 ptr += g(detail::get_header_tag{})(detail::size_bytes_tag{});
971 template<
typename ResView,
typename View>
972 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
974 ptr = view(detail::get_level_tag{})
975 + view(detail::get_block_length_tag{});
976 ResView d{ptr, view(detail::end_ptr_tag{})};
977 ptr += d(detail::size_bytes_tag{});
982 template<
typename ResView,
typename View,
typename Getter>
983 SBEPP_CPP20_CONSTEXPR ResView
984 get_group_view(
const View view, Getter&& getter)
noexcept
987 (getter()(detail::addressof_tag{}) == ptr) &&
"Wrong cursor value");
988 ResView res{ptr, view(detail::end_ptr_tag{})};
989 auto header = res(detail::get_header_tag{});
990 ptr += header(detail::size_bytes_tag{});
994 template<
typename ResView,
typename View,
typename Getter>
995 SBEPP_CPP20_CONSTEXPR ResView
996 get_data_view(
const View view, Getter&& getter)
noexcept
999 (getter()(detail::addressof_tag{}) == ptr) &&
"Wrong cursor value");
1000 ResView res{ptr, view(detail::end_ptr_tag{})};
1001 ptr += res(detail::size_bytes_tag{});
1006 template<
typename T>
1007 friend class cursor;
1014template<
typename Byte>
1015class init_cursor_wrapper
1018 using byte_type = Byte;
1020 template<
typename T>
1021 using result_type = T;
1023 init_cursor_wrapper() =
default;
1030 template<
typename T,
typename U, endian E,
typename View>
1031 SBEPP_CPP20_CONSTEXPR T get_value(
1034 const std::size_t absolute_offset)
noexcept
1037 view(addressof_tag{}),
1038 view(end_ptr_tag{}),
1041 T res{get_primitive<U, E>(view(addressof_tag{}) + absolute_offset)};
1042 cursor->pointer() = view(addressof_tag{}) + absolute_offset +
sizeof(U);
1046 template<endian E,
typename T,
typename View>
1047 SBEPP_CPP20_CONSTEXPR
void set_value(
1050 const std::size_t absolute_offset,
1051 const T value)
noexcept
1054 view(addressof_tag{}),
1055 view(end_ptr_tag{}),
1058 set_primitive<E>(view(addressof_tag{}) + absolute_offset, value);
1059 cursor->pointer() = view(addressof_tag{}) + absolute_offset +
sizeof(T);
1062 template<
typename T,
typename U, endian E,
typename View>
1063 SBEPP_CPP20_CONSTEXPR T get_last_value(
1066 const std::size_t absolute_offset)
noexcept
1069 view(addressof_tag{}),
1070 view(end_ptr_tag{}),
1073 T res{get_primitive<U, E>(view(addressof_tag{}) + absolute_offset)};
1075 view(get_level_tag{}) + view(get_block_length_tag{});
1079 template<endian E,
typename T,
typename View>
1080 SBEPP_CPP20_CONSTEXPR
void set_last_value(
1083 const std::size_t absolute_offset,
1084 const T value)
noexcept
1087 view(addressof_tag{}),
1088 view(end_ptr_tag{}),
1091 set_primitive<E>(view(addressof_tag{}) + absolute_offset, value);
1093 view(get_level_tag{}) + view(get_block_length_tag{});
1096 template<
typename Res,
typename View>
1097 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
1100 const std::size_t absolute_offset)
noexcept
1103 view(addressof_tag{}), view(end_ptr_tag{}), absolute_offset, 0);
1104 Res res{view(addressof_tag{}) + absolute_offset, view(end_ptr_tag{})};
1105 cursor->pointer() = res(addressof_tag{}) + res(size_bytes_tag{});
1109 template<
typename Res,
typename View>
1110 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
1113 const std::size_t absolute_offset)
noexcept
1116 view(addressof_tag{}), view(end_ptr_tag{}), absolute_offset, 0);
1117 Res res{view(addressof_tag{}) + absolute_offset, view(end_ptr_tag{})};
1119 view(get_level_tag{}) + view(get_block_length_tag{});
1123 template<
typename ResView,
typename View>
1124 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
1126 return cursor->template get_first_group_view<ResView>(view);
1129 template<
typename ResView,
typename View>
1130 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
1132 return cursor->template get_first_data_view<ResView>(view);
1135 template<
typename ResView,
typename View,
typename Getter>
1136 SBEPP_CPP20_CONSTEXPR ResView
1137 get_group_view(
const View , Getter&& getter)
noexcept
1139 auto res = getter();
1140 auto header = res(get_header_tag{});
1141 cursor->pointer() = res(addressof_tag{}) + header(size_bytes_tag{});
1145 template<
typename ResView,
typename View,
typename Getter>
1146 SBEPP_CPP20_CONSTEXPR ResView
1147 get_data_view(
const View , Getter&& getter)
noexcept
1149 auto res = getter();
1150 cursor->pointer() = res(addressof_tag{}) + res(size_bytes_tag{});
1158template<
typename Byte>
1159class init_dont_move_cursor_wrapper
1162 using byte_type = Byte;
1164 template<
typename T>
1165 using result_type = T;
1167 init_dont_move_cursor_wrapper() =
default;
1169 explicit constexpr init_dont_move_cursor_wrapper(
1175 template<
typename T,
typename U, endian E,
typename View>
1176 SBEPP_CPP20_CONSTEXPR T get_value(
1178 const std::size_t offset,
1179 const std::size_t absolute_offset)
noexcept
1182 view(addressof_tag{}),
1183 view(end_ptr_tag{}),
1186 cursor->pointer() = view(addressof_tag{}) + absolute_offset - offset;
1187 return T{get_primitive<U, E>(view(addressof_tag{}) + absolute_offset)};
1190 template<endian E,
typename T,
typename View>
1191 SBEPP_CPP20_CONSTEXPR
void set_value(
1193 const std::size_t offset,
1194 const std::size_t absolute_offset,
1195 const T value)
noexcept
1198 view(addressof_tag{}),
1199 view(end_ptr_tag{}),
1202 cursor->pointer() = view(addressof_tag{}) + absolute_offset - offset;
1203 set_primitive<E>(view(addressof_tag{}) + absolute_offset, value);
1206 template<
typename T,
typename U, endian E,
typename View>
1207 SBEPP_CPP20_CONSTEXPR T get_last_value(
1209 const std::size_t offset,
1210 const std::size_t absolute_offset)
noexcept
1212 return get_value<T, U, E>(view, offset, absolute_offset);
1215 template<endian E,
typename T,
typename View>
1216 SBEPP_CPP20_CONSTEXPR
void set_last_value(
1218 const std::size_t offset,
1219 const std::size_t absolute_offset,
1220 const T value)
noexcept
1222 return set_value<E>(view, offset, absolute_offset, value);
1225 template<
typename Res,
typename View>
1226 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
1228 const std::size_t offset,
1229 const std::size_t absolute_offset)
noexcept
1232 view(addressof_tag{}), view(end_ptr_tag{}), absolute_offset, 0);
1233 cursor->pointer() = view(addressof_tag{}) + absolute_offset - offset;
1234 return {view(addressof_tag{}) + absolute_offset, view(end_ptr_tag{})};
1237 template<
typename Res,
typename View>
1238 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
1240 const std::size_t offset,
1241 const std::size_t absolute_offset)
noexcept
1243 return get_static_field_view<Res>(view, offset, absolute_offset);
1246 template<
typename ResView,
typename View>
1247 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
1250 view(get_level_tag{}) + view(get_block_length_tag{});
1251 ResView g{cursor->pointer(), view(end_ptr_tag{})};
1256 template<
typename ResView,
typename View>
1257 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
1260 view(get_level_tag{}) + view(get_block_length_tag{});
1261 ResView d{cursor->pointer(), view(end_ptr_tag{})};
1266 template<
typename ResView,
typename View,
typename Getter>
1267 SBEPP_CPP20_CONSTEXPR ResView
1268 get_group_view(
const View , Getter&& getter)
noexcept
1270 auto res = getter();
1271 cursor->pointer() = res(addressof_tag{});
1275 template<
typename ResView,
typename View,
typename Getter>
1276 SBEPP_CPP20_CONSTEXPR ResView
1277 get_data_view(
const View , Getter&& getter)
noexcept
1279 auto res = getter();
1280 cursor->pointer() = res(addressof_tag{});
1288template<
typename Byte>
1289class dont_move_cursor_wrapper
1292 using byte_type = Byte;
1294 template<
typename T>
1295 using result_type = T;
1297 dont_move_cursor_wrapper() =
default;
1304 template<
typename T,
typename U, endian E,
typename View>
1305 SBEPP_CPP20_CONSTEXPR T get_value(
1307 const std::size_t offset,
1308 const std::size_t absolute_offset)
noexcept
1311 ((view(detail::addressof_tag{}) + absolute_offset)
1312 == (cursor->pointer() + offset))
1313 &&
"Wrong cursor value");
1315 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1316 return T{get_primitive<U, E>(cursor->pointer() + offset)};
1319 template<endian E,
typename T,
typename View>
1320 SBEPP_CPP20_CONSTEXPR
void set_value(
1322 const std::size_t offset,
1323 const std::size_t absolute_offset,
1324 const T value)
noexcept
1327 ((view(detail::addressof_tag{}) + absolute_offset)
1328 == (cursor->pointer() + offset))
1329 &&
"Wrong cursor value");
1331 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(T));
1332 set_primitive<E>(cursor->pointer() + offset, value);
1335 template<
typename T,
typename U, endian E,
typename View>
1336 SBEPP_CPP20_CONSTEXPR T get_last_value(
1338 const std::size_t offset,
1339 const std::size_t absolute_offset)
noexcept
1342 ((view(detail::addressof_tag{}) + absolute_offset)
1343 == (cursor->pointer() + offset))
1344 &&
"Wrong cursor value");
1346 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1347 return T{get_primitive<U, E>(cursor->pointer() + offset)};
1350 template<endian E,
typename T,
typename View>
1351 SBEPP_CPP20_CONSTEXPR
void set_last_value(
1353 const std::size_t offset,
1354 const std::size_t absolute_offset,
1355 const T value)
noexcept
1358 ((view(detail::addressof_tag{}) + absolute_offset)
1359 == (cursor->pointer() + offset))
1360 &&
"Wrong cursor value");
1362 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(T));
1363 set_primitive<E>(cursor->pointer() + offset, value);
1366 template<
typename Res,
typename View>
1367 SBEPP_CPP20_CONSTEXPR Res get_static_field_view(
1369 const std::size_t offset,
1370 const std::size_t absolute_offset)
noexcept
1373 ((view(detail::addressof_tag{}) + absolute_offset)
1374 == (cursor->pointer() + offset))
1375 &&
"Wrong cursor value");
1376 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1377 return {cursor->pointer() + offset, view(end_ptr_tag{})};
1380 template<
typename Res,
typename View>
1381 SBEPP_CPP20_CONSTEXPR Res get_last_static_field_view(
1383 const std::size_t offset,
1384 const std::size_t absolute_offset)
noexcept
1387 ((view(detail::addressof_tag{}) + absolute_offset)
1388 == (cursor->pointer() + offset))
1389 &&
"Wrong cursor value");
1390 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1391 return {cursor->pointer() + offset, view(end_ptr_tag{})};
1394 template<
typename ResView,
typename View>
1395 SBEPP_CPP20_CONSTEXPR ResView get_first_group_view(
const View view)
noexcept
1398 view(get_level_tag{}) + view(get_block_length_tag{});
1399 ResView g{cursor->pointer(), view(end_ptr_tag{})};
1404 template<
typename ResView,
typename View>
1405 SBEPP_CPP20_CONSTEXPR ResView get_first_data_view(
const View view)
noexcept
1408 view(get_level_tag{}) + view(get_block_length_tag{});
1409 ResView d{cursor->pointer(), view(end_ptr_tag{})};
1414 template<
typename ResView,
typename View,
typename Getter>
1415 SBEPP_CPP20_CONSTEXPR ResView
1416 get_group_view(
const View view, Getter&& getter)
noexcept
1419 (getter()(detail::addressof_tag{}) == cursor->pointer())
1420 &&
"Wrong cursor value");
1421 return {cursor->pointer(), view(end_ptr_tag{})};
1424 template<
typename ResView,
typename View,
typename Getter>
1425 SBEPP_CPP20_CONSTEXPR ResView
1426 get_data_view(
const View view, Getter&& getter)
noexcept
1429 (getter()(detail::addressof_tag{}) == cursor->pointer())
1430 &&
"Wrong cursor value");
1431 return {cursor->pointer(), view(end_ptr_tag{})};
1438template<
typename Byte>
1439class skip_cursor_wrapper
1442 using byte_type = Byte;
1444 template<
typename T>
1445 using result_type = void;
1447 skip_cursor_wrapper() =
default;
1454 template<
typename T,
typename U, endian E,
typename View>
1455 SBEPP_CPP20_CONSTEXPR
void get_value(
1457 const std::size_t offset,
1458 const std::size_t absolute_offset)
noexcept
1461 ((view(detail::addressof_tag{}) + absolute_offset)
1462 == (cursor->pointer() + offset))
1463 &&
"Wrong cursor value");
1465 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1466 cursor->pointer() += offset +
sizeof(U);
1469 template<
typename T,
typename U, endian E,
typename View>
1470 SBEPP_CPP20_CONSTEXPR
void get_last_value(
1472 const std::size_t offset,
1473 const std::size_t absolute_offset)
noexcept
1476 ((view(detail::addressof_tag{}) + absolute_offset)
1477 == (cursor->pointer() + offset))
1478 &&
"Wrong cursor value");
1480 cursor->pointer(), view(end_ptr_tag{}), offset,
sizeof(U));
1482 view(get_level_tag{}) + view(get_block_length_tag{});
1485 template<
typename Res,
typename View>
1486 SBEPP_CPP20_CONSTEXPR
void get_static_field_view(
1488 const std::size_t offset,
1489 const std::size_t absolute_offset)
noexcept
1492 ((view(detail::addressof_tag{}) + absolute_offset)
1493 == (cursor->pointer() + offset))
1494 &&
"Wrong cursor value");
1495 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1496 Res res{cursor->pointer(), view(end_ptr_tag{})};
1497 cursor->pointer() += offset + res(size_bytes_tag{});
1500 template<
typename Res,
typename View>
1501 SBEPP_CPP20_CONSTEXPR
void get_last_static_field_view(
1503 const std::size_t offset,
1504 const std::size_t absolute_offset)
noexcept
1507 ((view(detail::addressof_tag{}) + absolute_offset)
1508 == (cursor->pointer() + offset))
1509 &&
"Wrong cursor value");
1510 SBEPP_SIZE_CHECK(cursor->pointer(), view(end_ptr_tag{}), offset, 0);
1512 view(get_level_tag{}) + view(get_block_length_tag{});
1515 template<
typename ResView,
typename View>
1516 SBEPP_CPP20_CONSTEXPR
void get_first_group_view(
const View view)
noexcept
1519 view(get_level_tag{}) + view(get_block_length_tag{});
1520 ResView g{cursor->pointer(), view(end_ptr_tag{})};
1521 cursor->pointer() += g(size_bytes_tag{});
1524 template<
typename ResView,
typename View>
1525 SBEPP_CPP20_CONSTEXPR
void get_first_data_view(
const View view)
noexcept
1528 view(get_level_tag{}) + view(get_block_length_tag{});
1529 ResView d{cursor->pointer(), view(end_ptr_tag{})};
1530 cursor->pointer() += d(size_bytes_tag{});
1533 template<
typename ResView,
typename View,
typename Getter>
1534 SBEPP_CPP20_CONSTEXPR
void
1535 get_group_view(
const View view, Getter&& getter)
noexcept
1538 (getter()(detail::addressof_tag{}) == cursor->pointer())
1539 &&
"Wrong cursor value");
1540 ResView res{cursor->pointer(), view(end_ptr_tag{})};
1541 cursor->pointer() += res(size_bytes_tag{});
1544 template<
typename ResView,
typename View,
typename Getter>
1545 SBEPP_CPP20_CONSTEXPR
void
1546 get_data_view(
const View view, Getter&& getter)
noexcept
1549 (getter()(detail::addressof_tag{}) == cursor->pointer())
1550 &&
"Wrong cursor value");
1551 ResView res{cursor->pointer(), view(end_ptr_tag{})};
1552 cursor->pointer() += res(size_bytes_tag{});
1559template<
typename Cursor,
typename T>
1560using cursor_result_type_t =
1561 typename remove_reference_t<Cursor>::template result_type<T>;
1563template<
typename Cursor>
1564using cursor_byte_type_t =
typename remove_reference_t<Cursor>::byte_type;
1566template<
typename MessageByte,
typename CursorByte>
1567using enable_if_cursor_compatible_t =
1568 enable_if_convertible_t<MessageByte, CursorByte>;
1570template<
typename MessageByte,
typename CursorByte>
1571using enable_if_cursor_writeable_t = enable_if_t<
1572 std::is_convertible<MessageByte*, CursorByte*>::value
1573 && !std::is_const<MessageByte>::value && !std::is_const<CursorByte>::value>;
1589 return v(detail::size_bytes_tag{});
1601template<
typename T,
typename Byte>
1604 return v(detail::size_bytes_tag{}, c);
1614constexpr auto get_header(T v)
noexcept ->
decltype(v(detail::get_header_tag{}))
1616 return v(detail::get_header_tag{});
1626constexpr auto addressof(T v)
noexcept ->
decltype(v(detail::addressof_tag{}))
1628 return v(detail::addressof_tag{});
1636template<
typename View>
1641 std::declval<View>()))>
::type;
1645template<
typename View>
1671template<
typename Byte>
1674 return detail::init_cursor_wrapper<Byte>{c};
1699template<
typename Byte>
1700constexpr detail::dont_move_cursor_wrapper<Byte>
1703 return detail::dont_move_cursor_wrapper<Byte>{c};
1713template<
typename Byte>
1714constexpr detail::init_dont_move_cursor_wrapper<Byte>
1717 return detail::init_dont_move_cursor_wrapper<Byte>{c};
1734template<
typename Byte>
1737 return detail::skip_cursor_wrapper<Byte>{c};
1745template<
typename Byte>
1754template<
typename Byte,
typename Header>
1761 SBEPP_CPP14_CONSTEXPR Header operator()(get_header_tag)
const noexcept
1763 Header header{(*this)(addressof_tag{}), (*
this)(end_ptr_tag{})};
1765 (*
this)(addressof_tag{}),
1766 (*
this)(end_ptr_tag{}),
1772 SBEPP_CPP14_CONSTEXPR Byte* operator()(get_level_tag)
const noexcept
1774 auto header = (*this)(get_header_tag{});
1775 return header(addressof_tag{}) + header(size_bytes_tag{});
1778 constexpr typename std::decay<
1779 decltype(std::declval<Header>().blockLength().value())>::type
1780 operator()(get_block_length_tag)
const noexcept
1782 return operator()(get_header_tag{}).blockLength().value();
1787 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
1788 SBEPP_CPP20_CONSTEXPR std::size_t
1791 return c.
pointer() - (*this)(addressof_tag{});
1796template<
typename Byte,
typename BlockLengthType>
1802 template<
typename Byte2,
typename BlockLengthType2>
1810 Byte* ptr, Byte* end, BlockLengthType block_length) noexcept
1818 const std::size_t size,
1819 const BlockLengthType block_length) noexcept
1825 template<
typename Byte2,
typename = enable_if_convertible_t<Byte2, Byte>>
1827 cursor<Byte2>& c, Byte* end_ptr, BlockLengthType block_length) noexcept
1828 :
entry_base{c.pointer(), end_ptr, block_length}
1837 template<
typename Byte2,
typename = enable_if_convertible_t<Byte2, Byte>>
1844 constexpr BlockLengthType operator()(get_block_length_tag)
const noexcept
1846 return block_length;
1849 constexpr Byte* operator()(get_level_tag)
const noexcept
1851 return (*
this)(addressof_tag{});
1855 BlockLengthType block_length{};
1858template<
typename Entry>
1862 explicit constexpr arrow_proxy(Entry entry) noexcept : entry{entry}
1866 constexpr const Entry* operator->() const noexcept
1879 typename DifferenceType,
1880 typename BlockLengthType>
1881class forward_iterator
1884 using iterator_category = std::forward_iterator_tag;
1885 using value_type = ValueType;
1886 using reference = value_type;
1887 using difference_type = DifferenceType;
1888 using pointer = arrow_proxy<value_type>;
1890 forward_iterator() =
default;
1892 SBEPP_CPP14_CONSTEXPR forward_iterator(
1894 const IndexType index,
1895 const BlockLengthType block_length,
1899 block_length{block_length}
1900#if SBEPP_SIZE_CHECKS_ENABLED
1908 constexpr reference operator*() const noexcept
1910#if SBEPP_SIZE_CHECKS_ENABLED
1911 return {ptr, end, block_length};
1913 return {ptr,
nullptr, block_length};
1917 constexpr pointer operator->() const noexcept
1919 return pointer{operator*()};
1922 SBEPP_CPP14_CONSTEXPR forward_iterator& operator++() noexcept
1930 SBEPP_CPP14_CONSTEXPR forward_iterator operator++(
int)
noexcept
1937 friend constexpr bool operator==(
1938 const forward_iterator& lhs,
const forward_iterator& rhs)
noexcept
1940 return lhs.index == rhs.index;
1943 friend constexpr bool operator!=(
1944 const forward_iterator& lhs,
const forward_iterator& rhs)
noexcept
1946 return lhs.index != rhs.index;
1952 BlockLengthType block_length{};
1953#if SBEPP_SIZE_CHECKS_ENABLED
1961 typename BlockLengthType,
1962 typename DifferenceType,
1964class random_access_iterator
1967 using iterator_category = std::random_access_iterator_tag;
1968 using value_type = ValueType;
1969 using reference = value_type;
1970 using difference_type = DifferenceType;
1971 using pointer = arrow_proxy<value_type>;
1973 random_access_iterator() =
default;
1975 SBEPP_CPP14_CONSTEXPR random_access_iterator(
1977 const BlockLengthType block_length,
1978 const IndexType index,
1981 block_length{block_length},
1983#if SBEPP_SIZE_CHECKS_ENABLED
1991 constexpr reference operator*() const noexcept
1993#if SBEPP_SIZE_CHECKS_ENABLED
1994 return {ptr, end, block_length};
1996 return {ptr,
nullptr, block_length};
2000 constexpr pointer operator->() const noexcept
2002 return pointer{operator*()};
2005 SBEPP_CPP14_CONSTEXPR random_access_iterator& operator++() noexcept
2007 SBEPP_SIZE_CHECK(ptr, end, 0, block_length);
2008 ptr += block_length;
2013 SBEPP_CPP14_CONSTEXPR random_access_iterator operator++(
int)
noexcept
2020 SBEPP_CPP14_CONSTEXPR random_access_iterator& operator--() noexcept
2022 ptr -= block_length;
2027 SBEPP_CPP14_CONSTEXPR random_access_iterator operator--(
int)
noexcept
2034 SBEPP_CPP14_CONSTEXPR random_access_iterator&
2035 operator+=(difference_type n)
noexcept
2037 ptr += n * block_length;
2042 SBEPP_CPP14_CONSTEXPR random_access_iterator
2043 operator+(difference_type n)
const noexcept
2049 friend constexpr random_access_iterator
2050 operator+(difference_type n,
const random_access_iterator& it)
noexcept
2055 SBEPP_CPP14_CONSTEXPR random_access_iterator&
2056 operator-=(difference_type n)
noexcept
2061 SBEPP_CPP14_CONSTEXPR random_access_iterator
2062 operator-(difference_type n)
const noexcept
2068 constexpr difference_type
2069 operator-(
const random_access_iterator& rhs)
const noexcept
2071 return index - rhs.index;
2074 constexpr reference operator[](difference_type n)
const noexcept
2076 return *(*
this + n);
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;
2114 friend constexpr bool operator>=(
2115 const random_access_iterator& lhs,
2116 const random_access_iterator& rhs)
noexcept
2118 return lhs.index >= rhs.index;
2123 BlockLengthType block_length{};
2127#if SBEPP_SIZE_CHECKS_ENABLED
2135 typename CursorType,
2136 typename BlockLengthType,
2141 using iterator_category = std::input_iterator_tag;
2142 using value_type = ValueType;
2143 using reference = value_type;
2144 using difference_type =
typename std::make_signed<IndexType>::type;
2145 using pointer = arrow_proxy<value_type>;
2147 input_iterator() =
default;
2149 SBEPP_CPP14_CONSTEXPR input_iterator(
2150 const IndexType index,
2152 BlockLengthType block_length,
2156 block_length{block_length}
2157#if SBEPP_SIZE_CHECKS_ENABLED
2165 constexpr reference operator*() const noexcept
2167#if SBEPP_SIZE_CHECKS_ENABLED
2168 return {*cursor, end, block_length};
2170 return {*cursor,
nullptr, block_length};
2174 constexpr pointer operator->() const noexcept
2176 return pointer{operator*()};
2179 SBEPP_CPP14_CONSTEXPR input_iterator& operator++() noexcept
2185 SBEPP_CPP14_CONSTEXPR input_iterator operator++(
int)
noexcept
2192 friend constexpr bool operator==(
2193 const input_iterator& lhs,
const input_iterator& rhs)
noexcept
2195 return lhs.index == rhs.index;
2198 friend constexpr bool operator!=(
2199 const input_iterator& lhs,
const input_iterator& rhs)
noexcept
2201 return lhs.index != rhs.index;
2206 CursorType* cursor{};
2207 BlockLengthType block_length{};
2208#if SBEPP_SIZE_CHECKS_ENABLED
2216 typename CursorType,
2217 typename BlockLengthType,
2222 SBEPP_CPP14_CONSTEXPR cursor_range(
2224 BlockLengthType block_length,
2226 IndexType start_pos,
2227 IndexType length) noexcept
2229 block_length{block_length},
2230 start_pos{start_pos},
2231#if SBEPP_SIZE_CHECKS_ENABLED
2240 input_iterator<ValueType, IndexType, CursorType, BlockLengthType, Byte>;
2242 constexpr iterator begin() const noexcept
2244#if SBEPP_SIZE_CHECKS_ENABLED
2245 return {start_pos, cursor, block_length, end_ptr};
2247 return {start_pos, cursor, block_length,
nullptr};
2251 constexpr iterator end() const noexcept
2253#if SBEPP_SIZE_CHECKS_ENABLED
2255 static_cast<IndexType
>(start_pos + size()),
2261 static_cast<IndexType
>(start_pos + size()),
2268 constexpr IndexType size() const noexcept
2274 CursorType* cursor{};
2275 BlockLengthType block_length{};
2276 IndexType start_pos{};
2277#if SBEPP_SIZE_CHECKS_ENABLED
2284template<
typename Byte,
typename Entry,
typename Dimension>
2294 decltype(std::declval<Dimension>().numInGroup())>::type;
2304 typename std::decay<
2305 decltype(std::declval<Dimension>().blockLength().value())>::type,
2312 SBEPP_CPP14_CONSTEXPR Dimension operator()(get_header_tag)
const noexcept
2314 Dimension header{(*this)(addressof_tag{}), (*
this)(end_ptr_tag{})};
2316 (*
this)(addressof_tag{}),
2317 (*
this)(end_ptr_tag{}),
2323 SBEPP_CPP20_CONSTEXPR std::size_t operator()(size_bytes_tag)
const noexcept
2325 auto dimension = (*this)(get_header_tag{});
2327 + dimension.numInGroup().value()
2328 * dimension.blockLength().value();
2334 return (*
this)(get_header_tag{}).numInGroup();
2346 (*this)(get_header_tag{}).numInGroup(count);
2350 SBEPP_CPP17_NODISCARD SBEPP_CPP20_CONSTEXPR
bool empty() const noexcept
2358 return sbe_size_type::max_value();
2364 auto dimension = (*this)(get_header_tag{});
2367 dimension.blockLength().value(),
2369 (*this)(end_ptr_tag{})};
2376 (*this)(addressof_tag{}) + (*
this)(size_bytes_tag{}),
2377 (*
this)(get_header_tag{}).blockLength().value(),
2379 (*this)(end_ptr_tag{})};
2386 SBEPP_ASSERT(pos <
size());
2387 return *(
begin() + pos);
2394 SBEPP_ASSERT(!
empty());
2402 SBEPP_ASSERT(!
empty());
2408 SBEPP_CPP14_CONSTEXPR
void clear() const noexcept
2414 template<
typename Byte2>
2419 typename std::decay<
2420 decltype(std::declval<Dimension>().blockLength().value())>::type,
2426 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2432 (*this)(get_header_tag{}).blockLength().value(),
2433 (*this)(end_ptr_tag{}),
2442 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2443 SBEPP_CPP20_CONSTEXPR cursor_range_t<Byte2>
2446 SBEPP_ASSERT(pos <
size());
2450 (*this)(get_header_tag{}).blockLength().value(),
2451 (*this)(end_ptr_tag{}),
2461 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2467 SBEPP_ASSERT(pos <
size());
2468 SBEPP_ASSERT(count <= (
size() - pos));
2472 (*this)(get_header_tag{}).blockLength().value(),
2473 (*this)(end_ptr_tag{}),
2479 template<
typename Byte2>
2485 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2495 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2496 SBEPP_CPP20_CONSTEXPR cursor_iterator<Byte2>
2502 template<
typename Visitor,
typename Cursor>
2503 SBEPP_CPP14_CONSTEXPR
bool
2504 operator()(visit_children_tag, Visitor& v, Cursor& c)
2506 for(
const auto entry : this->cursor_range(c))
2508 if(v.template on_entry(entry, c))
2518template<
typename Byte,
typename Entry,
typename Dimension>
2528 decltype(std::declval<Dimension>().numInGroup())>::type;
2541 typename std::decay<
2542 decltype(std::declval<Dimension>().blockLength().value())>::type>;
2547 SBEPP_CPP14_CONSTEXPR Dimension operator()(get_header_tag)
const noexcept
2549 Dimension header{(*this)(addressof_tag{}), (*
this)(end_ptr_tag{})};
2551 (*
this)(addressof_tag{}),
2552 (*
this)(end_ptr_tag{}),
2558 SBEPP_CPP20_CONSTEXPR std::size_t operator()(size_bytes_tag)
const noexcept
2561 for(
const auto entry : *this)
2572 return (*
this)(get_header_tag{}).numInGroup();
2584 (*this)(get_header_tag{}).numInGroup(count);
2588 SBEPP_CPP17_NODISCARD SBEPP_CPP20_CONSTEXPR
bool empty() const noexcept
2596 return sbe_size_type::max_value();
2602 auto dimension = (*this)(get_header_tag{});
2606 dimension.blockLength().value(),
2607 (*this)(end_ptr_tag{})};
2615 (*this)(get_header_tag{}).numInGroup().value(),
2616 (*this)(get_header_tag{}).blockLength().value(),
2617 (*this)(end_ptr_tag{})};
2624 SBEPP_ASSERT(!
empty());
2630 SBEPP_CPP14_CONSTEXPR
void clear() const noexcept
2636 template<
typename Byte2>
2641 typename std::decay<
2642 decltype(std::declval<Dimension>().blockLength().value())>::type,
2648 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2654 (*this)(get_header_tag{}).blockLength().value(),
2655 (*this)(end_ptr_tag{}),
2664 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2665 SBEPP_CPP20_CONSTEXPR cursor_range_t<Byte2>
2668 SBEPP_ASSERT(pos <
size());
2672 (*this)(get_header_tag{}).blockLength().value(),
2673 (*this)(end_ptr_tag{}),
2683 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2689 SBEPP_ASSERT(pos <
size());
2690 SBEPP_ASSERT(count <= (
size() - pos));
2694 (*this)(get_header_tag{}).blockLength().value(),
2695 (*this)(end_ptr_tag{}),
2701 template<
typename Byte2>
2707 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2717 typename = enable_if_cursor_compatible_t<Byte, Byte2>>
2718 SBEPP_CPP20_CONSTEXPR cursor_iterator<Byte2>
2724 template<
typename Visitor,
typename Cursor>
2725 SBEPP_CPP14_CONSTEXPR
bool
2726 operator()(visit_children_tag, Visitor& v, Cursor& c)
2728 for(
const auto entry : this->cursor_range(c))
2730 if(v.template on_entry(entry, c))
2768 return bits & (1 << n);
2771 SBEPP_CPP14_CONSTEXPR
void
2772 operator()(set_bit_tag,
const choice_index_t n,
const bool b)
noexcept
2774 bits = ((bits & ~(1 << n)) | (b << n));
2778 constexpr friend bool
2781 return *lhs == *rhs;
2785 constexpr friend bool
2788 return *lhs != *rhs;
2795template<
typename View,
typename =
void_t<>>
2796struct has_get_header : std::false_type
2800template<
typename View>
2801struct has_get_header<
2803 void_t<decltype(
sbepp::
get_header(std::declval<View>()))>> : std::true_type
2809 typename = detail::enable_if_t<detail::has_get_header<View>::value>>
2810constexpr std::size_t get_header_size(View view)
noexcept
2817 typename = detail::enable_if_t<!detail::has_get_header<View>::value>,
2819constexpr std::size_t get_header_size(View)
noexcept
2832template<
typename Enum>
2833constexpr typename std::underlying_type<Enum>::type
2836 return static_cast<typename std::underlying_type<Enum>::type
>(e);
2852template<
typename View>
2874template<
typename View>
2875SBEPP_CPP14_CONSTEXPR cursor<typename std::add_const<byte_type_t<View>>::type>
2916template<
typename From,
typename To>
2917struct copy_cv_qualifiers
2919 using copy_const_t =
typename std::
2920 conditional<std::is_const<From>::value,
const To, To>::type;
2922 using type =
typename std::conditional<
2923 std::is_volatile<From>::value,
2924 volatile copy_const_t,
2925 copy_const_t>::type;
2928template<
typename From,
typename To>
2929using apply_cv_qualifiers_t =
typename copy_cv_qualifiers<From, To>::type;
2933using is_range = std::bool_constant<std::ranges::range<R>>;
2935template<
typename R,
typename =
void_t<>>
2936struct is_range : std::false_type
2944 decltype(std::begin(std::declval<R>())),
2945 decltype(std::end(std::declval<R>()))>> : std::true_type
2950constexpr bool is_constant_evaluated() noexcept
2955#if SBEPP_HAS_IS_CONSTANT_EVALUATED
2956 return std::is_constant_evaluated();
2962inline SBEPP_CPP20_CONSTEXPR std::size_t string_length(
const char* str)
noexcept
2964 if(is_constant_evaluated())
2966 std::size_t length{};
2968 for(; *str !=
'\0'; str++, length++)
2976 return std::strlen(str);
2987template<
typename Byte,
typename Value, std::
size_t N,
typename Tag>
3014 constexpr std::size_t operator()(detail::size_bytes_tag)
const noexcept
3023 SBEPP_ASSERT(pos <
size());
3045 (*
this)(detail::addressof_tag{}),
3046 (*
this)(detail::end_ptr_tag{}),
3049 return (
pointer)(*this)(detail::addressof_tag{});
3053 SBEPP_CPP17_NODISCARD
static constexpr bool empty() noexcept
3109 (*this)(detail::addressof_tag{}), (*
this)(detail::end_ptr_tag{})};
3118 SBEPP_CPP20_CONSTEXPR std::size_t
strlen() const noexcept
3120 if(is_constant_evaluated())
3122 return string_length(
data());
3126 const auto first_null =
static_cast<const value_type*
>(
3127 std::memchr(
data(),
'\0',
size()));
3130 return first_null -
data();
3143 SBEPP_CPP20_CONSTEXPR std::size_t
strlen_r() const noexcept
3145 const auto last_non_null = std::find_if(
3150 return value !=
'\0';
3166 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3170 SBEPP_ASSERT(str !=
nullptr);
3171 const auto length = string_length(str);
3172 SBEPP_ASSERT(length <=
size());
3173 const auto eos_pos = std::copy_n(str, length,
begin());
3174 pad(eos_mode, eos_pos);
3193 enable_if_t<!std::is_const<Byte>::value && is_range<R>::value>>
3198 pad(eos_mode, eos_pos);
3214 enable_if_t<!std::is_const<Byte>::value && is_range<R>::value>>
3218 auto res = std::ranges::copy(std::forward<R>(r),
begin()).out;
3220 auto res = std::copy(std::begin(r), std::end(r),
begin());
3222 SBEPP_ASSERT(res <=
end());
3231 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3245 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3249 SBEPP_ASSERT(count <=
size());
3250 return std::fill_n(
begin(), count, value);
3256 template<
typename InputIt,
typename = enable_if_writable_t<Byte, InputIt>>
3259 const auto last_out = std::copy(first, last,
begin());
3271 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3273 assign(std::initializer_list<value_type> ilist)
const noexcept
3275 SBEPP_ASSERT(ilist.size() <=
size());
3276 return assign(std::begin(ilist), std::end(ilist));
3280 SBEPP_CPP20_CONSTEXPR
void
3285 std::fill(eos_pos,
end(),
'\0');
3289 if(eos_pos !=
end())
3309template<
typename Byte,
typename Value,
typename Length, endian E>
3314 std::is_unsigned<typename Length::value_type>::value,
3315 "Length must be unsigned");
3343 return data_checked();
3368 SBEPP_ASSERT(!
empty());
3376 SBEPP_ASSERT(!
empty());
3389 return data_checked();
3396 SBEPP_ASSERT(pos <
size());
3397 return *(
data() + pos);
3403 return detail::get_value<size_type, size_type, E>(*
this, 0);
3413 SBEPP_CPP17_NODISCARD SBEPP_CPP20_CONSTEXPR
bool empty() const noexcept
3421 return sbe_size_type::max_value();
3425 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3426 SBEPP_CPP20_CONSTEXPR
void clear() const noexcept
3432 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3435 const auto old_size =
size();
3437 if(count > old_size)
3439 for(
auto i = old_size; i != count; i++)
3447 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3448 SBEPP_CPP20_CONSTEXPR
void
3451 const auto old_size =
size();
3453 if(count > old_size)
3455 for(
auto i = old_size; i != count; i++)
3463 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3464 SBEPP_CPP20_CONSTEXPR
void
3470 (*
this)(addressof_tag{}),
3471 (*
this)(end_ptr_tag{}),
3474 set_primitive<E>((*
this)(addressof_tag{}), count);
3478 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3481 const auto current_size =
size();
3483 (*this)[current_size] = value;
3487 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3490 SBEPP_ASSERT(!
empty());
3495 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3498 SBEPP_ASSERT(pos >=
begin() && pos <
end());
3499 std::copy(pos + 1,
end(), pos);
3505 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3509 SBEPP_ASSERT(first >=
begin() && last <
end());
3510 std::copy(last,
end(), first);
3516 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3520 SBEPP_ASSERT(pos >=
begin() && pos <=
end());
3521 const auto old_end =
end();
3523 std::copy_backward(pos, old_end,
end());
3529 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3533 SBEPP_ASSERT(pos >=
begin() && pos <=
end());
3534 const auto old_end =
end();
3536 std::copy_backward(pos, old_end,
end());
3537 std::fill_n(pos, count, value);
3544 typename = detail::enable_if_t<
3545 !std::is_const<Byte>::value
3546 && std::is_convertible<
3547 typename std::iterator_traits<InputIt>::iterator_category,
3548 std::input_iterator_tag>::value>>
3552 SBEPP_ASSERT(pos >=
begin() && pos <=
end());
3554 typename std::iterator_traits<InputIt>::iterator_category;
3555 return insert_impl(pos, first, last, category_t{});
3559 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3561 iterator pos, std::initializer_list<value_type> ilist)
const noexcept
3563 return insert(pos, std::begin(ilist), std::end(ilist));
3568 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3569 SBEPP_CPP20_CONSTEXPR
void
3573 std::fill_n(
begin(), count, value);
3578 template<
typename InputIt,
typename = enable_if_writable_t<Byte, InputIt>>
3579 SBEPP_CPP20_CONSTEXPR
void assign(InputIt first, InputIt last)
const
3581 auto begin = data_unchecked();
3582 const auto new_end = std::copy(first, last,
begin);
3588 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3589 SBEPP_CPP20_CONSTEXPR
void
3590 assign(std::initializer_list<value_type> ilist)
const noexcept
3593 (*
this)(detail::addressof_tag{}),
3594 (*
this)(detail::end_ptr_tag{}),
3597 assign(std::begin(ilist), std::end(ilist));
3610 (*this)(detail::addressof_tag{}), (*
this)(detail::end_ptr_tag{})};
3613 SBEPP_CPP20_CONSTEXPR std::size_t
3614 operator()(detail::size_bytes_tag)
const noexcept
3625 template<
typename T =
void,
typename = enable_if_writable_t<Byte, T>>
3628 SBEPP_ASSERT(str !=
nullptr);
3629 const auto length = string_length(str);
3631 std::copy_n(str, length,
begin());
3644 enable_if_t<!std::is_const<Byte>::value && is_range<R>::value>>
3647 const auto begin = data_unchecked();
3649 const auto new_end = std::ranges::copy(std::forward<R>(r),
begin).out;
3651 const auto new_end = std::copy(std::begin(r), std::end(r),
begin);
3657 SBEPP_CPP14_CONSTEXPR
pointer data_checked() const noexcept
3660 (*
this)(detail::addressof_tag{}),
3661 (*
this)(detail::end_ptr_tag{}),
3664 return data_unchecked();
3667 SBEPP_CPP14_CONSTEXPR
pointer data_unchecked() const noexcept
3670 (*
this)(detail::addressof_tag{}),
3671 (*
this)(detail::end_ptr_tag{}),
3684 template<
typename It>
3685 SBEPP_CPP14_CONSTEXPR
iterator insert_impl(
3686 iterator pos, It first, It last, std::input_iterator_tag)
const
3689 for(; first != last; ++first, ++out)
3697 template<
typename It>
3698 SBEPP_CPP20_CONSTEXPR
iterator insert_impl(
3699 iterator pos, It first, It last, std::forward_iterator_tag)
const
3701 const auto in_size = std::distance(first, last);
3702 auto old_end =
end();
3704 std::copy_backward(pos, old_end,
end());
3705 std::copy(first, last, pos);
3732template<
typename T,
typename Derived>
3770 return (Derived::min_value() <= val) && (val <= Derived::max_value());
3782#if SBEPP_HAS_THREE_WAY_COMPARISON
3787 constexpr friend bool
3790 return *lhs == *rhs;
3794 constexpr friend bool
3797 return *lhs != *rhs;
3801 constexpr friend bool
3808 constexpr friend bool
3811 return *lhs <= *rhs;
3815 constexpr friend bool
3822 constexpr friend bool
3825 return *lhs >= *rhs;
3839template<
typename T,
typename Derived>
3883 return (Derived::min_value() <= val) && (val <= Derived::max_value());
3893 return default_value;
3899 return (val != Derived::null_value());
3903 constexpr explicit operator bool() const noexcept
3916 constexpr friend bool
3919 return *lhs == *rhs;
3928#if SBEPP_HAS_THREE_WAY_COMPARISON
3929 constexpr friend std::strong_ordering
3934 return *lhs <=> *rhs;
3936 return lhs.has_value() <=> rhs.has_value();
3941 constexpr friend bool
3944 return *lhs != *rhs;
3948 constexpr friend bool
3951 return rhs && (!lhs || (*lhs < *rhs));
3955 constexpr friend bool
3958 return !lhs || (rhs && (*lhs <= *rhs));
3962 constexpr friend bool
3965 return lhs && (!rhs || (*lhs > *rhs));
3969 constexpr friend bool
3972 return !rhs || (lhs && (*lhs >= *rhs));
3978 value_type val{Derived::null_value()};
3996template<
typename Message>
3998 ->
decltype(m(detail::fill_message_header_tag{}))
4000 return m(detail::fill_message_header_tag{});
4016template<
typename Group,
typename Size>
4018 ->
decltype(g(detail::fill_group_header_tag{}, num_in_group))
4020 return g(detail::fill_group_header_tag{}, num_in_group);
4055 template<
typename Byte>
4059 static constexpr const char*
name() noexcept;
4062 static constexpr const
char* description() noexcept;
4095 static constexpr const
char* semantic_type() noexcept;
4105 static constexpr const
char* character_encoding() noexcept;
4132 static constexpr const
char* semantic_version() noexcept;
4134 static constexpr
endian byte_order() noexcept;
4136 static constexpr const
char* description() noexcept;
4142 template<typename Byte>
4166 static constexpr const char*
name() noexcept;
4168 static constexpr const
char* description() noexcept;
4203 static constexpr const char*
name() noexcept;
4205 static constexpr const
char* description() noexcept;
4212 static constexpr ScopedEnumType value() noexcept;
4233 static constexpr const char*
name() noexcept;
4235 static constexpr const
char* description() noexcept;
4270 static constexpr const char*
name() noexcept;
4272 static constexpr const
char* description() noexcept;
4300 static constexpr const char*
name() noexcept;
4302 static constexpr const
char* description() noexcept;
4309 static constexpr const
char* semantic_type() noexcept;
4320 template<typename Byte>
4323 static constexpr std::
size_t size_bytes() noexcept;
4344 static constexpr const char*
name() noexcept;
4346 static constexpr const
char* description() noexcept;
4352 static constexpr const
char* semantic_type() noexcept;
4363 template<typename Byte>
4445 static constexpr std::
size_t size_bytes(...) noexcept;
4466 static constexpr const char*
name() noexcept;
4470 static constexpr const
char* description() noexcept;
4491 template<typename Byte>
4515 static constexpr const char*
name() noexcept;
4517 static constexpr const
char* description() noexcept;
4523 static constexpr const
char* semantic_type() noexcept;
4534 template<typename Byte>
4541 template<typename Byte>
4550 template<typename Byte>
4563 static constexpr std::
size_t
4564 size_bytes(const NumInGroupType num_in_group, ...) noexcept;
4585 static constexpr const char*
name() noexcept;
4589 static constexpr const
char* description() noexcept;
4600 template<typename Byte>
4612 static constexpr std::
size_t
4640template<
typename ValueType>
4644template<
typename ValueType>
4653template<
typename ValueType>
4656template<
typename Byte,
typename Value, std::
size_t N,
typename Tag>
4657struct traits_tag<detail::static_array_ref<Byte, Value, N, Tag>>
4663#define SBEPP_BUILT_IN_IMPL(NAME, TYPE, MIN, MAX, NULL) \
4666 class NAME##_t : public detail::required_base<TYPE, NAME##_t> \
4669 using detail::required_base<TYPE, NAME##_t>::required_base; \
4672 static constexpr value_type min_value() noexcept \
4678 static constexpr value_type max_value() noexcept \
4686 class NAME##_opt_t : public detail::optional_base<TYPE, NAME##_opt_t> \
4689 using detail::optional_base<TYPE, NAME##_opt_t>::optional_base; \
4692 static constexpr value_type min_value() noexcept \
4698 static constexpr value_type max_value() noexcept \
4704 static constexpr value_type null_value() noexcept \
4711 class type_traits<NAME##_t> \
4714 static constexpr const char* name() noexcept \
4719 static constexpr const char* description() noexcept \
4724 static constexpr field_presence presence() noexcept \
4726 return field_presence::required; \
4729 static constexpr TYPE min_value() noexcept \
4731 return NAME##_t::min_value(); \
4734 static constexpr TYPE max_value() noexcept \
4736 return NAME##_t::max_value(); \
4739 static constexpr length_t length() noexcept \
4744 static constexpr const char* semantic_type() noexcept \
4749 static constexpr version_t since_version() noexcept \
4754 using value_type = NAME##_t; \
4755 using primitive_type = value_type::value_type; \
4759 struct traits_tag<NAME##_t> \
4761 using type = NAME##_t; \
4765 class type_traits<NAME##_opt_t> \
4768 static constexpr const char* name() noexcept \
4773 static constexpr const char* description() noexcept \
4778 static constexpr field_presence presence() noexcept \
4780 return field_presence::optional; \
4783 static constexpr TYPE min_value() noexcept \
4785 return NAME##_opt_t::min_value(); \
4788 static constexpr TYPE max_value() noexcept \
4790 return NAME##_opt_t::max_value(); \
4793 static constexpr TYPE null_value() noexcept \
4795 return NAME##_opt_t::null_value(); \
4798 static constexpr length_t length() noexcept \
4803 static constexpr const char* semantic_type() noexcept \
4808 static constexpr version_t since_version() noexcept \
4813 using value_type = NAME##_opt_t; \
4814 using primitive_type = value_type::value_type; \
4818 struct traits_tag<NAME##_opt_t> \
4820 using type = NAME##_opt_t; \
4823SBEPP_BUILT_IN_IMPL(
char,
char, 0x20, 0x7E, 0);
4827 std::numeric_limits<std::int8_t>::min() + 1,
4828 std::numeric_limits<std::int8_t>::max(),
4829 std::numeric_limits<std::int8_t>::min());
4833 std::numeric_limits<std::uint8_t>::min(),
4834 std::numeric_limits<std::uint8_t>::max() - 1,
4835 std::numeric_limits<std::uint8_t>::max());
4839 std::numeric_limits<std::int16_t>::min() + 1,
4840 std::numeric_limits<std::int16_t>::max(),
4841 std::numeric_limits<std::int16_t>::min());
4845 std::numeric_limits<std::uint16_t>::min(),
4846 std::numeric_limits<std::uint16_t>::max() - 1,
4847 std::numeric_limits<std::uint16_t>::max());
4851 std::numeric_limits<std::int32_t>::min() + 1,
4852 std::numeric_limits<std::int32_t>::max(),
4853 std::numeric_limits<std::int32_t>::min());
4857 std::numeric_limits<std::uint32_t>::min(),
4858 std::numeric_limits<std::uint32_t>::max() - 1,
4859 std::numeric_limits<std::uint32_t>::max());
4863 std::numeric_limits<std::int64_t>::min() + 1,
4864 std::numeric_limits<std::int64_t>::max(),
4865 std::numeric_limits<std::int64_t>::min());
4869 std::numeric_limits<std::uint64_t>::min(),
4870 std::numeric_limits<std::uint64_t>::max() - 1,
4871 std::numeric_limits<std::uint64_t>::max());
4875 std::numeric_limits<float>::min(),
4876 std::numeric_limits<float>::max(),
4877 std::numeric_limits<float>::quiet_NaN());
4881 std::numeric_limits<double>::min(),
4882 std::numeric_limits<double>::max(),
4883 std::numeric_limits<double>::quiet_NaN());
4885#undef SBEPP_BUILT_IN_IMPL
4904template<
template<
typename>
class View,
typename Byte>
4905constexpr View<Byte>
make_view(Byte* ptr,
const std::size_t size)
noexcept
4928template<
template<
typename>
class View,
typename Byte>
4929constexpr View<typename std::add_const<Byte>::type>
4941struct unknown_enum_value_tag
4948template<
template<
typename...>
class Base,
typename Derived>
4949struct is_base_of_tmp_impl
4951 static constexpr std::false_type test(...);
4953 template<
typename... Ts>
4954 static constexpr std::true_type test(Base<Ts...>*);
4956 using type =
decltype(test(std::declval<Derived*>()));
4959template<
template<
typename...>
class Base,
typename Derived>
4960using is_base_of_tmp =
typename is_base_of_tmp_impl<Base, Derived>::type;
4962#if SBEPP_HAS_CONCEPTS
4963template<
typename Derived,
template<
typename...>
class Base>
4964concept derived_from_tmp = is_base_of_tmp<Base, Derived>::value;
4970template<
typename Derived>
4971struct is_array_type_impl
4973 static constexpr std::false_type test(...);
4975 template<
typename T1,
typename T2, std::
size_t N,
typename T3>
4976 static constexpr std::true_type
4977 test(detail::static_array_ref<T1, T2, N, T3>*);
4979 using type =
decltype(test(std::declval<Derived*>()));
4985using is_array_type =
typename detail::is_array_type_impl<T>::type;
5003using is_type = std::integral_constant<
5009template<
typename T,
typename =
void>
5010struct is_enum : std::false_type
5017 detail::void_t<decltype(tag_invoke(
5018 std::declval<detail::visit_tag>(),
5020 std::declval<int&>()))>> : std::true_type
5026using is_set = detail::is_base_of_tmp<detail::bitset_base, T>;
5030using is_composite = detail::is_base_of_tmp<detail::composite_base, T>;
5034using is_message = detail::is_base_of_tmp<detail::message_base, T>;
5038using is_flat_group = detail::is_base_of_tmp<detail::flat_group_base, T>;
5042using is_nested_group = detail::is_base_of_tmp<detail::nested_group_base, T>;
5046using is_group = std::integral_constant<
5052using is_group_entry = detail::is_base_of_tmp<detail::entry_base, T>;
5056template<
typename Derived>
5059 static constexpr std::false_type test(...);
5061 template<
typename T1,
typename T2,
typename T3, endian E>
5062 static constexpr std::true_type
5065 using type =
decltype(test(std::declval<Derived*>()));
5071using is_data =
typename detail::is_data_impl<T>::type;
5073#if SBEPP_HAS_INLINE_VARS
5127#if SBEPP_HAS_CONCEPTS
5146concept type = is_type_v<T>;
5154concept set = is_set_v<T>;
5162concept message = is_message_v<T>;
5174concept group = is_group_v<T>;
5178concept data = is_data_v<T>;
5184using is_visitable_view = std::integral_constant<
5186 is_message<T>::value || is_group<T>::value || is_group_entry<T>::value
5187 || is_composite<T>::value>;
5205 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5206SBEPP_CPP14_CONSTEXPR Visitor&&
5207 visit(View view, Cursor& c, Visitor&& visitor = {})
5209 view(detail::visit_tag{}, visitor, c);
5210 return std::forward<Visitor>(visitor);
5226 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5227SBEPP_CPP14_CONSTEXPR Visitor&&
visit(View view, Visitor&& visitor = {})
5230 return sbepp::visit(view, c, std::forward<Visitor>(visitor));
5233#ifndef SBEPP_DOXYGEN
5234template<
typename Visitor,
typename Set>
5235SBEPP_CPP14_CONSTEXPR detail::enable_if_t<is_set<Set>::value, Visitor&&>
5236 visit(Set s, Visitor&& visitor = {})
5238 s(detail::visit_tag{}, visitor);
5239 return std::forward<Visitor>(visitor);
5242template<
typename Visitor,
typename Enum>
5243SBEPP_CPP14_CONSTEXPR detail::enable_if_t<is_enum<Enum>::value, Visitor&&>
5244 visit(Enum e, Visitor&& visitor = {})
5246 tag_invoke(detail::visit_tag{}, e, visitor);
5247 return std::forward<Visitor>(visitor);
5268template<
typename Visitor,
typename Set>
5269SBEPP_CPP14_CONSTEXPR Visitor&&
visit(Set s, Visitor&& visitor = {});
5287template<
typename Visitor,
typename Enum>
5288SBEPP_CPP14_CONSTEXPR Visitor&&
visit(Enum e, Visitor&& visitor = {});
5307 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5308SBEPP_CPP14_CONSTEXPR Visitor&&
5311 view(detail::visit_children_tag{}, visitor, c);
5312 return std::forward<Visitor>(visitor);
5328 typename = detail::enable_if_t<detail::is_visitable_view<View>::value>>
5329SBEPP_CPP14_CONSTEXPR Visitor&&
5338class enum_to_string_visitor
5341 template<
typename Enum,
typename Tag>
5342 SBEPP_CPP14_CONSTEXPR
void on_enum_value(Enum , Tag)
noexcept
5347 template<
typename Enum>
5348 SBEPP_CPP14_CONSTEXPR
void
5351 name_value =
nullptr;
5354 constexpr const char* name() const noexcept
5360 const char* name_value;
5374template<typename E, typename = detail::enable_if_t<is_enum<E>::value>>
5375SBEPP_DEPRECATED
constexpr const char*
enum_to_string(
const E e)
noexcept
5377 return visit<detail::enum_to_string_visitor>(e).name();
5391template<
typename Set,
typename Visitor>
5392SBEPP_DEPRECATED
constexpr auto
5393 visit_set(
const Set s, Visitor&& visitor)
noexcept
5394 ->
decltype(s(detail::visit_set_tag{}, std::forward<Visitor>(visitor)))
5396 return s(detail::visit_set_tag{}, std::forward<Visitor>(visitor));
5401class size_bytes_checked_visitor
5404 constexpr explicit size_bytes_checked_visitor(
5405 const std::size_t size) noexcept
5410 template<
typename T,
typename Cursor,
typename Tag>
5411 SBEPP_CPP14_CONSTEXPR
void on_message(T m, Cursor& c, Tag)
noexcept
5415 if(!validate_and_subtract(header_size))
5420 if(!validate_and_subtract(*header.blockLength()))
5428 template<
typename T,
typename Cursor,
typename Tag>
5429 SBEPP_CPP14_CONSTEXPR
bool on_group(T g, Cursor& c, Tag)
noexcept
5433 if(!validate_and_subtract(header_size))
5438 const auto prev_block_length =
5439 set_group_block_length(*header.blockLength());
5441 set_group_block_length(prev_block_length);
5446 template<
typename T,
typename Cursor>
5447 SBEPP_CPP14_CONSTEXPR
bool on_entry(T e, Cursor& c)
noexcept
5449 if(!validate_and_subtract(group_block_length))
5457 template<
typename T,
typename Tag>
5458 SBEPP_CPP14_CONSTEXPR
bool on_data(T d, Tag)
noexcept
5464 template<
typename T,
typename Tag>
5465 constexpr bool on_field(T, Tag)
const noexcept
5470 constexpr bool is_valid() const noexcept
5476 SBEPP_CPP14_CONSTEXPR std::size_t
5477 set_group_block_length(
const std::size_t block_length)
noexcept
5479 auto prev = group_block_length;
5480 group_block_length = block_length;
5484 constexpr std::size_t get_size() const noexcept
5493 std::size_t group_block_length{};
5495 SBEPP_CPP14_CONSTEXPR
bool
5496 validate_and_subtract(
const std::size_t n)
noexcept
5513struct size_bytes_checked_result
5532template<
typename View>
5542 detail::size_bytes_checked_visitor visitor{size};
5545 if(visitor.is_valid())
5547 return {
true, size - visitor.get_size()};
5553#if SBEPP_HAS_RANGES && SBEPP_HAS_CONCEPTS
5555template<
typename Byte,
typename Value, std::
size_t N,
typename Tag>
5556inline constexpr bool std::ranges::enable_borrowed_range<
5559template<
typename Byte,
typename Value,
typename Length, sbepp::endian E>
5560inline constexpr bool std::ranges::enable_borrowed_range<
5563template<sbepp::detail::derived_from_tmp<sbepp::detail::flat_group_base> T>
5564inline constexpr bool std::ranges::enable_borrowed_range<T> =
true;
5566template<sbepp::detail::derived_from_tmp<sbepp::detail::nested_group_base> T>
5567inline constexpr bool std::ranges::enable_borrowed_range<T> =
true;
5570#undef SBEPP_CPP17_INLINE_VAR
5571#undef SBEPP_DEPRECATED
5572#undef SBEPP_CPLUSPLUS
Provides various traits/attributes of a <composite> element.
Definition sbepp.hpp:4297
CompositeType< Byte > value_type
Representation type.
Definition sbepp.hpp:4321
static constexpr const char * name() noexcept
Returns name attribute.
Represents cursor which is used in cursor-based API. Clients should not use undocumented methods.
Definition sbepp.hpp:790
constexpr Byte * pointer() const noexcept
access underlying pointer
Definition sbepp.hpp:856
constexpr cursor(cursor< Byte2 > other) noexcept
Construct from another cursor. Enabled only if Byte2* is convertible to Byte*.
Definition sbepp.hpp:819
Byte byte_type
same as Byte
Definition sbepp.hpp:793
cursor()=default
Construct a new cursor object initialized with nullptr
constexpr Byte *& pointer() noexcept
access underlying pointer. Might be useful in rare cases to initialize cursor with a particular value...
Definition sbepp.hpp:846
constexpr cursor & operator=(cursor< Byte2 > other) noexcept
Assign from another cursor. Enabled only if Byte2* is convertible to Byte
Definition sbepp.hpp:834
Provides various traits/attributes of a <data> element.
Definition sbepp.hpp:4582
static constexpr const char * name() noexcept
Returns name attribute.
DataType value_type
Representation type.
Definition sbepp.hpp:4601
LengthTypeTag length_type_tag
length_type tag
Definition sbepp.hpp:4605
LengthType length_type
Length type.
Definition sbepp.hpp:4603
Base class for bitsets.
Definition sbepp.hpp:2743
constexpr T operator*() const noexcept
Returns underlying value.
Definition sbepp.hpp:2760
constexpr friend bool operator==(const bitset_base &lhs, const bitset_base &rhs) noexcept
Tests if underlying values are equal.
Definition sbepp.hpp:2779
constexpr T & operator*() noexcept
Returns reference to underlying value.
Definition sbepp.hpp:2754
constexpr bitset_base(T value) noexcept
Constructs from given value.
Definition sbepp.hpp:2749
constexpr friend bool operator!=(const bitset_base &lhs, const bitset_base &rhs) noexcept
Tests if underlying values are not equal.
Definition sbepp.hpp:2786
bitset_base()=default
Default constructs underlying value to 0
Base class for all reference semantics types.
Definition sbepp.hpp:721
constexpr byte_range(Byte *ptr, const std::size_t size) noexcept
Constructs from pointer and size.
Definition sbepp.hpp:743
constexpr byte_range(const byte_range< Byte2 > &other) noexcept
Copy constructor. Available if Byte2* is convertible to Byte*
Definition sbepp.hpp:751
byte_range()=default
Initializes to nullptr
constexpr byte_range(Byte *begin, Byte *end) noexcept
Constructs from a pair of pointers.
Definition sbepp.hpp:732
Base class for composites.
Definition sbepp.hpp:1747
Represents reference to dynamic arrays used for <data> elements.
Definition sbepp.hpp:3311
constexpr sbe_size_type sbe_size() const noexcept
Returns SBE size representation.
Definition sbepp.hpp:3401
pointer iterator
iterator type. Satisfies std::random_access_iterator
Definition sbepp.hpp:3333
std::reverse_iterator< iterator > reverse_iterator
reverse iterator type
Definition sbepp.hpp:3335
constexpr iterator insert(iterator pos, std::initializer_list< value_type > ilist) const noexcept
Inserts elements from ilist before pos
Definition sbepp.hpp:3560
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator to the end.
Definition sbepp.hpp:3359
static constexpr size_type max_size() noexcept
Returns max value of SBE length representation.
Definition sbepp.hpp:3419
constexpr iterator erase(iterator first, iterator last) const noexcept
Erases elements in [first; last) range.
Definition sbepp.hpp:3507
constexpr void assign_string(const char *str) const noexcept
Assigns null-terminated string.
Definition sbepp.hpp:3626
constexpr iterator insert(iterator pos, InputIt first, InputIt last) const
Inserts elements from [first; last) range before pos
Definition sbepp.hpp:3550
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:3590
constexpr reference back() const noexcept
Access the last element.
Definition sbepp.hpp:3374
constexpr void resize(size_type count, sbepp::default_init_t) const noexcept
Sets size to count, default initializes new elements.
Definition sbepp.hpp:3465
element_type * pointer
element pointer type
Definition sbepp.hpp:3331
constexpr void push_back(value_type value) const noexcept
Adds new element to the end.
Definition sbepp.hpp:3479
constexpr iterator insert(iterator pos, const value_type value) const noexcept
Inserts value before pos
Definition sbepp.hpp:3518
constexpr reference operator[](size_type pos) const noexcept
Access element at pos
Definition sbepp.hpp:3394
constexpr void resize(size_type count) const noexcept
Sets size to count, value initializes new elements.
Definition sbepp.hpp:3433
constexpr reference front() const noexcept
Access the first element.
Definition sbepp.hpp:3366
std::ptrdiff_t difference_type
std::ptrdiff_t
Definition sbepp.hpp:3327
constexpr void pop_back() const noexcept
Removes the last element.
Definition sbepp.hpp:3488
Value value_type
same as Value
Definition sbepp.hpp:3321
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:3607
detail::apply_cv_qualifiers_t< Byte, Value > element_type
final element type. value_type with the same cv-qualifiers as Byte
Definition sbepp.hpp:3319
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:3341
constexpr void assign_range(R &&r) const
Assigns range.
Definition sbepp.hpp:3645
constexpr iterator insert(iterator pos, size_type count, const value_type value) const noexcept
Inserts count copies of value before pos
Definition sbepp.hpp:3530
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:3570
constexpr pointer data() const noexcept
Direct access to the underlying array.
Definition sbepp.hpp:3387
constexpr iterator erase(iterator pos) const noexcept
Erases element at pos
Definition sbepp.hpp:3496
constexpr void clear() const noexcept
Sets size to 0.
Definition sbepp.hpp:3426
constexpr bool empty() const noexcept
Checks if size() != 0
Definition sbepp.hpp:3413
constexpr reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the beginning.
Definition sbepp.hpp:3353
constexpr void resize(size_type count, value_type value) const noexcept
Sets size to count, initializes new elements with value
Definition sbepp.hpp:3449
constexpr void assign(InputIt first, InputIt last) const
Replaces the contents of the container with the elements from [first; last) range.
Definition sbepp.hpp:3579
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:3347
constexpr size_type size() const noexcept
Returns raw size.
Definition sbepp.hpp:3407
typename sbe_size_type::value_type size_type
raw size type
Definition sbepp.hpp:3325
Length sbe_size_type
length SBE representation of data's encoding
Definition sbepp.hpp:3323
element_type & reference
element reference type
Definition sbepp.hpp:3329
Base class for group entries.
Definition sbepp.hpp:1798
constexpr entry_base(cursor< Byte2 > &c, Byte *end_ptr, BlockLengthType block_length) noexcept
Constructs from cursor.
Definition sbepp.hpp:1826
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:1838
constexpr entry_base(Byte *ptr, const std::size_t size, const BlockLengthType block_length) noexcept
Constructs from pointer and size.
Definition sbepp.hpp:1816
entry_base()=default
Constructs using nullptr
constexpr entry_base(Byte *ptr, Byte *end, BlockLengthType block_length) noexcept
Constructs from two pointers.
Definition sbepp.hpp:1809
Base class for a flat group.
Definition sbepp.hpp:2286
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:2301
constexpr void clear() const noexcept
Resizes to 0
Definition sbepp.hpp:2408
constexpr sbe_size_type sbe_size() const noexcept
Returns header's numInGroup
Definition sbepp.hpp:2332
typename cursor_range_t< Byte2 >::iterator cursor_iterator
cursor_range_t::iterator. Satisfies std::input_iterator
Definition sbepp.hpp:2480
constexpr reference front() const noexcept
Returns the first entry.
Definition sbepp.hpp:2392
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:2444
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:2415
typename std::decay< decltype(std::declval< Dimension >().numInGroup())>::type sbe_size_type
numInGroup value type
Definition sbepp.hpp:2293
Entry value_type
Entry type.
Definition sbepp.hpp:2289
constexpr reference operator[](size_type pos) const noexcept
Access group entry at pos
Definition sbepp.hpp:2384
constexpr size_type size() const noexcept
Returns raw size.
Definition sbepp.hpp:2338
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:2362
constexpr cursor_iterator< Byte2 > cursor_begin(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the beginning.
Definition sbepp.hpp:2487
constexpr cursor_range_t< Byte2 > cursor_range(cursor< Byte2 > &c) const noexcept
Returns cursor range to all group entries.
Definition sbepp.hpp:2428
constexpr bool empty() const noexcept
Checks if size() == 0
Definition sbepp.hpp:2350
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:2373
constexpr void resize(const size_type count) const noexcept
Sets numInGroup to count
Definition sbepp.hpp:2344
constexpr cursor_iterator< Byte2 > cursor_end(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the end.
Definition sbepp.hpp:2497
static constexpr size_type max_size() noexcept
Returns numInGroup's maxValue
Definition sbepp.hpp:2356
constexpr reference back() const noexcept
Returns the last entry.
Definition sbepp.hpp:2400
typename std::make_signed< size_type >::type difference_type
signed size_type
Definition sbepp.hpp:2298
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:2462
typename sbe_size_type::value_type size_type
Raw size type.
Definition sbepp.hpp:2296
value_type reference
value_type
Definition sbepp.hpp:2291
Base class for messages.
Definition sbepp.hpp:1756
Base class for a nested group.
Definition sbepp.hpp:2520
constexpr size_type size() const noexcept
Returns raw size.
Definition sbepp.hpp:2576
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:2611
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:2666
Entry value_type
entry type
Definition sbepp.hpp:2523
static constexpr size_type max_size() noexcept
Returns numInGroup's maxValue
Definition sbepp.hpp:2594
typename cursor_range_t< Byte2 >::iterator cursor_iterator
cursor_range_t::iterator. Satisfies std::input_iterator
Definition sbepp.hpp:2702
value_type reference
value_type
Definition sbepp.hpp:2525
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:2637
typename sbe_size_type::value_type size_type
raw size type
Definition sbepp.hpp:2530
typename std::make_signed< size_type >::type difference_type
signed size_type
Definition sbepp.hpp:2532
constexpr sbe_size_type sbe_size() const noexcept
Returns header's numInGroup
Definition sbepp.hpp:2570
constexpr void resize(const size_type count) const noexcept
Sets numInGroup to count
Definition sbepp.hpp:2582
constexpr reference front() const noexcept
Returns the first element.
Definition sbepp.hpp:2622
constexpr cursor_iterator< Byte2 > cursor_end(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the end.
Definition sbepp.hpp:2719
constexpr void clear() const noexcept
Resizes to 0
Definition sbepp.hpp:2630
constexpr cursor_iterator< Byte2 > cursor_begin(cursor< Byte2 > &c) const noexcept
Returns cursor iterator to the beginning.
Definition sbepp.hpp:2709
constexpr bool empty() const noexcept
Checks if size() == 0
Definition sbepp.hpp:2588
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:2536
constexpr cursor_range_t< Byte2 > cursor_range(cursor< Byte2 > &c) const noexcept
Returns cursor range to all group entries.
Definition sbepp.hpp:2650
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:2684
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:2600
typename std::decay< decltype(std::declval< Dimension >().numInGroup())>::type sbe_size_type
numInGroup value type
Definition sbepp.hpp:2527
Base class for optional types.
Definition sbepp.hpp:3841
constexpr value_type value() const noexcept
Returns underlying value.
Definition sbepp.hpp:3862
constexpr friend bool operator!=(const optional_base &lhs, const optional_base &rhs) noexcept
Tests if lhs is not equal to rhs
Definition sbepp.hpp:3942
constexpr optional_base(nullopt_t) noexcept
Constructs null object.
Definition sbepp.hpp:3851
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:3887
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:3970
T value_type
Underlying type.
Definition sbepp.hpp:3844
constexpr bool in_range() const noexcept
Checks if value is in [Derived::min_value(); Derived::max_value()] range.
Definition sbepp.hpp:3881
constexpr optional_base(value_type val) noexcept
Constructs object from given value.
Definition sbepp.hpp:3857
constexpr bool has_value() const noexcept
Checks if has value.
Definition sbepp.hpp:3897
constexpr friend bool operator>(const optional_base &lhs, const optional_base &rhs) noexcept
Tests if lhs is greater than rhs
Definition sbepp.hpp:3963
constexpr value_type operator*() const noexcept
Returns underlying value.
Definition sbepp.hpp:3874
constexpr value_type & operator*() noexcept
Returns reference to underlying value.
Definition sbepp.hpp:3868
constexpr friend bool operator==(const optional_base &lhs, const optional_base &rhs) noexcept
Tests if lhs is equal to rhs
Definition sbepp.hpp:3917
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:3734
constexpr friend bool operator>(const required_base &lhs, const required_base &rhs) noexcept
Tests if lhs is greater than rhs
Definition sbepp.hpp:3816
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:3823
constexpr value_type value() const noexcept
Returns underlying value.
Definition sbepp.hpp:3749
constexpr friend bool operator!=(const required_base &lhs, const required_base &rhs) noexcept
Tests if lhs is not equal to rhs
Definition sbepp.hpp:3795
constexpr value_type & operator*() noexcept
Returns reference to underlying value.
Definition sbepp.hpp:3755
constexpr friend bool operator==(const required_base &lhs, const required_base &rhs) noexcept
Tests if lhs is equal to rhs
Definition sbepp.hpp:3788
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:3768
T value_type
Underlying type.
Definition sbepp.hpp:3737
constexpr value_type operator*() const noexcept
Returns underlying value.
Definition sbepp.hpp:3761
constexpr required_base(value_type val) noexcept
Constructs from given value.
Definition sbepp.hpp:3744
Represents reference to fixed-size array.
Definition sbepp.hpp:2989
pointer iterator
iterator type. Satisfies std::random_access_iterator
Definition sbepp.hpp:3005
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator to the end.
Definition sbepp.hpp:3089
static constexpr bool empty() noexcept
Checks if size() != 0
Definition sbepp.hpp:3053
detail::apply_cv_qualifiers_t< Byte, Value > element_type
final element type. value_type with the same cv-qualifiers as Byte
Definition sbepp.hpp:2993
constexpr reference operator[](size_type pos) const noexcept
Access element at pos
Definition sbepp.hpp:3021
constexpr std::size_t strlen() const noexcept
Calculates string length from left to right.
Definition sbepp.hpp:3118
constexpr iterator assign_string(const char *str, const eos_null eos_mode=eos_null::all) const noexcept
Assigns null-terminated string.
Definition sbepp.hpp:3167
constexpr reference front() const noexcept
Access the first element.
Definition sbepp.hpp:3028
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition sbepp.hpp:3071
static constexpr size_type size() noexcept
Returns N
Definition sbepp.hpp:3059
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:3106
constexpr iterator assign(std::initializer_list< value_type > ilist) const noexcept
Assigns initializer list to first elements.
Definition sbepp.hpp:3273
element_type & reference
element reference type
Definition sbepp.hpp:3001
std::reverse_iterator< iterator > reverse_iterator
reverse iterator type
Definition sbepp.hpp:3007
constexpr reference back() const noexcept
Access the last element.
Definition sbepp.hpp:3034
Value value_type
same as Value
Definition sbepp.hpp:2995
Tag tag
type tag
Definition sbepp.hpp:3009
element_type * pointer
element pointer type
Definition sbepp.hpp:3003
constexpr std::size_t strlen_r() const noexcept
Calculates string length from right to left.
Definition sbepp.hpp:3143
std::size_t size_type
std::size_t
Definition sbepp.hpp:2997
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition sbepp.hpp:3077
constexpr iterator assign_string(R &&r, const eos_null eos_mode=eos_null::all) const
Assigns string represented by a range.
Definition sbepp.hpp:3195
constexpr void fill(const value_type value) const noexcept
Assigns value to all elements.
Definition sbepp.hpp:3232
constexpr iterator assign_range(R &&r) const
Assigns range.
Definition sbepp.hpp:3215
constexpr reverse_iterator rbegin() const noexcept
Returns a reverse iterator to the beginning.
Definition sbepp.hpp:3083
constexpr iterator assign(InputIt first, InputIt last) const
Assigns elements from [first; last) range to first elements.
Definition sbepp.hpp:3257
static constexpr size_type max_size() noexcept
Returns size()
Definition sbepp.hpp:3065
std::ptrdiff_t difference_type
std::ptrdiff_t
Definition sbepp.hpp:2999
constexpr pointer data() const noexcept
Direct access to the underlying array.
Definition sbepp.hpp:3040
constexpr iterator assign(size_type count, const value_type value) const noexcept
Assigns value to first count elements.
Definition sbepp.hpp:3247
Provides various traits/attributes of an <enum> element.
Definition sbepp.hpp:4163
EncodingType encoding_type
Underlying type.
Definition sbepp.hpp:4170
static constexpr const char * name() noexcept
Returns name attribute.
ScopedEnumType value_type
Representation type.
Definition sbepp.hpp:4182
Provides various traits/attributes of a <validValue> element.
Definition sbepp.hpp:4200
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits/attributes of a <field> element.
Definition sbepp.hpp:4463
static constexpr const char * name() noexcept
Returns name attribute.
ValueType value_type
Representation type.
Definition sbepp.hpp:4485
TypeTag value_type_tag
value_type's tag. Not available for constants of numeric types
Definition sbepp.hpp:4494
Provides various traits/attributes of a <group> element.
Definition sbepp.hpp:4512
HeaderType< Byte > dimension_type
Group dimension composite type.
Definition sbepp.hpp:4542
HeaderTag dimension_type_tag
Dimension composite tag.
Definition sbepp.hpp:4544
GroupType< Byte > value_type
Representation type.
Definition sbepp.hpp:4535
EntryType< Byte > entry_type
Group entry type.
Definition sbepp.hpp:4551
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits/attributes of a <message> element.
Definition sbepp.hpp:4341
static constexpr const char * name() noexcept
Returns name attribute.
SchemaTag schema_tag
Schema tag.
Definition sbepp.hpp:4366
MessageType< Byte > value_type
Representation type.
Definition sbepp.hpp:4364
Provides various traits/attributes of a <messageSchema> element.
Definition sbepp.hpp:4123
HeaderTypeTag header_type_tag
Message header composite tag. Can be used to access its traits.
Definition sbepp.hpp:4145
static constexpr const char * package() noexcept
Returns package attribute.
HeaderComposite< Byte > header_type
Message header composite type.
Definition sbepp.hpp:4143
Provides various traits/attributes of a <choice> element.
Definition sbepp.hpp:4267
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits/attributes of a <set> element.
Definition sbepp.hpp:4230
SetType value_type
Representation type.
Definition sbepp.hpp:4249
EncodingType encoding_type
Underlying type.
Definition sbepp.hpp:4242
static constexpr const char * name() noexcept
Returns name attribute.
Provides various traits and attributes of a <type> element.
Definition sbepp.hpp:4042
ValueType value_type
Representation type.
Definition sbepp.hpp:4048
PrimitiveType primitive_type
Underlying type.
Definition sbepp.hpp:4045
static constexpr const char * name() noexcept
Returns name attribute.
Concept for sbepp::is_array_type<T>::value
Definition sbepp.hpp:5129
Concept for sbepp::is_composite<T>::value
Definition sbepp.hpp:5157
Concept for sbepp::is_data<T>::value
Definition sbepp.hpp:5177
Concept for sbepp::is_enum<T>::value
Definition sbepp.hpp:5149
Concept for sbepp::is_flat_group<T>::value
Definition sbepp.hpp:5165
Concept for sbepp::is_group<T>::value
Definition sbepp.hpp:5173
Concept for sbepp::is_message<T>::value
Definition sbepp.hpp:5161
Concept for sbepp::is_nested_group<T>::value
Definition sbepp.hpp:5169
Concept for sbepp::is_non_array_type<T>::value
Definition sbepp.hpp:5141
Concept for sbepp::is_optional_type<T>::value
Definition sbepp.hpp:5137
Concept for sbepp::is_required_type<T>::value
Definition sbepp.hpp:5133
Concept for sbepp::is_set<T>::value
Definition sbepp.hpp:5153
Concept for sbepp::is_type<T>::value
Definition sbepp.hpp:5145
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:1735
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:1701
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:1672
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:1715
The main sbepp namespace.
Definition sbepp.hpp:232
constexpr auto is_composite_v
Shorthand for sbepp::is_composite<T>::value
Definition sbepp.hpp:5103
constexpr auto is_required_type_v
Shorthand for sbepp::is_required_type<T>::value
Definition sbepp.hpp:5079
constexpr auto is_type_v
Shorthand for sbepp::is_type<T>::value
Definition sbepp.hpp:5091
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:2834
detail::is_base_of_tmp< detail::optional_base, T > is_optional_type
Checks if T is a non-array optional type.
Definition sbepp.hpp:4992
constexpr View< Byte > make_view(Byte *ptr, const std::size_t size) noexcept
Construct view from memory buffer.
Definition sbepp.hpp:4904
typename traits_tag< ValueType >::type traits_tag_t
Shorthand for sbepp::traits_tag<T>::type
Definition sbepp.hpp:4654
constexpr auto is_flat_group_v
Shorthand for sbepp::is_flat_group<T>::value
Definition sbepp.hpp:5111
eos_null
Represents number of null bytes that can be added after the end-of-string by detail::static_array_ref...
Definition sbepp.hpp:2902
@ 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:2853
constexpr auto get_header(T v) noexcept -> decltype(v(detail::get_header_tag{}))
Returns the header of a message/group.
Definition sbepp.hpp:1614
detail::is_base_of_tmp< detail::required_base, T > is_required_type
Checks if T is a non-array required type.
Definition sbepp.hpp:4988
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:5045
detail::is_base_of_tmp< detail::flat_group_base, T > is_flat_group
Checks if T is a flat group.
Definition sbepp.hpp:5037
constexpr auto is_array_type_v
Shorthand for sbepp::is_array_type<T>::value
Definition sbepp.hpp:5075
constexpr nullopt_t nullopt
Helper constant used to initialize optional types with null value.
Definition sbepp.hpp:3724
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:5308
constexpr auto is_enum_v
Shorthand for sbepp::is_enum<T>::value
Definition sbepp.hpp:5095
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:2876
constexpr auto fill_message_header(Message m) noexcept -> decltype(m(detail::fill_message_header_tag{}))
Fill message header.
Definition sbepp.hpp:3997
constexpr auto is_non_array_type_v
Shorthand for sbepp::is_non_array_type<T>::value
Definition sbepp.hpp:5087
constexpr Visitor && visit(View view, Cursor &c, Visitor &&visitor={})
Visit a view using given cursor.
Definition sbepp.hpp:5206
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:5070
typename byte_type< View >::type byte_type_t
Shortcut for byte_type<T>::type
Definition sbepp.hpp:1646
detail::is_base_of_tmp< detail::nested_group_base, T > is_nested_group
Checks if T is a nested group.
Definition sbepp.hpp:5041
constexpr const char * enum_to_string(const E e) noexcept
Converts enum to string.
Definition sbepp.hpp:5374
detail::is_base_of_tmp< detail::message_base, T > is_message
Checks if T is a message.
Definition sbepp.hpp:5033
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:4017
constexpr auto addressof(T v) noexcept -> decltype(v(detail::addressof_tag{}))
Returns pointer to the underlying data referenced by a view.
Definition sbepp.hpp:1626
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:1587
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:5025
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:5002
constexpr auto is_group_v
Shorthand for sbepp::is_group<T>::value
Definition sbepp.hpp:5119
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:5392
constexpr default_init_t default_init
helper to pass default_init_t to dynamic_array_ref::resize().
Definition sbepp.hpp:2897
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:4996
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:5083
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:5533
constexpr auto is_message_v
Shorthand for sbepp::is_message<T>::value
Definition sbepp.hpp:5107
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:5099
detail::is_base_of_tmp< detail::entry_base, T > is_group_entry
Checks if T is a group entry.
Definition sbepp.hpp:5051
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:5115
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:4929
constexpr auto is_data_v
Shorthand for sbepp::is_data<T>::value
Definition sbepp.hpp:5123
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:4984
detail::is_base_of_tmp< detail::composite_base, T > is_composite
Checks if T is a composite.
Definition sbepp.hpp:5029
#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:1638
typename std::remove_pointer< decltype(sbepp::addressof( std::declval< View >()))>::type type
holds View's byte type
Definition sbepp.hpp:1640
tag for dynamic_array_ref::resize(). Used to skip value initialization.
Definition sbepp.hpp:2888
Checks if T is an enumeration.
Definition sbepp.hpp:5010
Tag type used to initialize optional types with null value.
Definition sbepp.hpp:3713
Result type of size_bytes_checked
Definition sbepp.hpp:5513
Maps representation type to its tag.
Definition sbepp.hpp:4646
Tag type
Tag to access ValueType's traits.
Definition sbepp.hpp:4648
Tag for unknown enum values.
Definition sbepp.hpp:4941