13 #include "./config.hpp"
15 JBSON_PUSH_DISABLE_DOCUMENTATION_WARNING
16 #include <boost/utility/string_ref.hpp>
17 JBSON_CLANG_POP_WARNINGS
22 #include "detect_size.hpp"
26 template <
typename Container>
27 void value_get(
const basic_element<Container>&, ...) {
28 static_assert(std::is_void<Container>::value,
29 "A valid overload of value_get must be supplied for user-defined types.");
35 static_assert(!std::is_same<std::decay_t<StringT>,
const char*>::value,
"");
36 static_assert(!std::is_same<std::decay_t<StringT>,
char*>::value,
"");
37 template <
typename Iterator>
static StringT call(
const Iterator& first,
const Iterator& last) {
38 return StringT{first, last};
43 template <
typename Iterator>
static boost::string_ref call(
const Iterator& first,
const Iterator& last) {
45 return boost::string_ref{&*first,
static_cast<size_t>(std::distance(first, last))};
50 template <
typename RangeT,
typename ArithT>
51 void deserialise(
const RangeT& data, ArithT& num, std::enable_if_t<std::is_arithmetic<ArithT>::value>* =
nullptr) {
52 if(boost::distance(data) !=
sizeof(ArithT))
54 << detail::expected_size(
sizeof(ArithT)));
55 num = detail::little_endian_to_native<ArithT>(data.begin(), data.end());
59 template <
typename RangeT,
typename StringT>
60 void deserialise(
const RangeT& data, StringT& str,
61 std::enable_if_t<std::is_convertible<std::decay_t<StringT>, boost::string_ref>::value>* =
nullptr) {
62 auto first = data.begin(), last = data.end();
63 if(std::distance(first, last) <= static_cast<ptrdiff_t>(
sizeof(int32_t)))
65 << detail::expected_size(
sizeof(int32_t)));
66 std::advance(first,
sizeof(int32_t));
67 const auto length = detail::little_endian_to_native<int32_t>(data.begin(), first) - 1;
70 last = std::find(first, last,
'\0');
71 if(std::distance(first, last) != length)
73 << detail::expected_size(length));
79 template <
typename RangeT,
typename Container,
typename EContainer>
84 template <
typename RangeT,
typename Container,
typename EContainer>
90 template <
typename RangeT>
void deserialise(
const RangeT& data, std::vector<char>& vec) {
91 boost::range::push_back(vec, data);
95 template <
typename RangeT>
void deserialise(
const RangeT& data, RangeT& vec) { vec = data; }
98 template <
typename RangeT>
void deserialise(
const RangeT& data, std::array<char, 12>& oid) {
99 if(boost::distance(data) != 12)
101 << detail::expected_size(12));
102 std::copy(data.begin(), data.end(), oid.data());
106 template <
typename RangeT,
typename StringT>
107 void deserialise(
const RangeT& data, std::tuple<StringT, StringT>& tuple,
108 std::enable_if_t<std::is_constructible<std::string, std::decay_t<StringT>>::value>* =
nullptr) {
111 auto first = std::find(data.begin(), data.end(),
'\0');
112 if(first == data.end())
114 std::get<0>(tuple) = string_maker::call(data.begin(), first);
116 auto last = std::find(++first, data.end(),
'\0');
117 if(last == data.end())
119 std::get<1>(tuple) = string_maker::call(first, last);
123 template <
typename RangeT,
typename StringT>
124 void deserialise(
const RangeT& data, std::tuple<StringT, std::array<char, 12>>& tuple,
125 std::enable_if_t<std::is_constructible<std::string, std::decay_t<StringT>>::value>* =
nullptr) {
126 deserialise(data, std::get<0>(tuple));
128 data.begin(), data.end())),
134 template <
typename RangeT,
typename StringT,
typename DocContainerT,
typename DocEContainerT>
136 std::enable_if_t<std::is_constructible<std::string, std::decay_t<StringT>>::value>* =
nullptr) {
138 auto it = data.begin();
139 deserialise(boost::make_iterator_range(it, std::next(it, 4)), length);
140 if(length != boost::distance(data))
142 << detail::expected_size(length));
144 deserialise(boost::make_iterator_range(it, data.end()), std::get<0>(tuple));
145 deserialise(boost::make_iterator_range(
152 template <
typename Container>
159 #endif // JBSON_GET_HPP
std::string or boost::string_ref (string_type)
Exception thrown when an element's data size differs from that reported.
typename mpl::at< typename TypeMap< Container >::map_type, element_type_c< EType >>::type ElementTypeMap
Type alias to perform boost::mpl::at on TypeMap::map_type.
Trait to determine if an iterator is a pointer, or pointer in disguise.