9 #include "../element_fwd.hpp"
14 template <
typename Container>
void value_set(basic_element<Container>&, ...) {
15 static_assert(std::is_void<Container>::value,
16 "A valid overload of value_set must be supplied for user-defined types.");
24 template <
typename Container,
typename IteratorT,
typename T>
25 void serialise(Container& c, IteratorT& it, T val, std::enable_if_t<std::is_arithmetic<T>::value>* =
nullptr) {
26 auto data = detail::native_to_little_endian(val);
27 it = c.insert(it, std::begin(data), std::end(data));
29 std::advance(it, boost::distance(data));
33 template <
typename Container,
typename IteratorT>
void serialise(Container& c, IteratorT& it, boost::string_ref val) {
34 serialise(c, it, static_cast<int32_t>(val.size() + 1));
35 it = c.insert(it, std::begin(val), std::end(val));
37 std::advance(it, boost::distance(val));
38 it = std::next(c.insert(it,
'\0'));
42 template <
typename Container,
typename IteratorT,
typename DocContainer,
typename DocEContainer>
43 void serialise(Container& c, IteratorT& it,
const basic_document<DocContainer, DocEContainer>& val) {
45 c = Container{val.data().begin(), val.data().end()};
49 it = c.insert(it, std::begin(val.data()), std::end(val.data()));
51 std::advance(it, boost::distance(val.data()));
55 template <
typename Container,
typename IteratorT,
typename DocContainer,
typename DocEContainer>
56 void serialise(Container& c, IteratorT& it,
const basic_array<DocContainer, DocEContainer>& val) {
58 c = Container{val.data().begin(), val.data().end()};
62 it = c.insert(it, std::begin(val.data()), std::end(val.data()));
64 std::advance(it, boost::distance(val.data()));
68 template <
typename Container,
typename IteratorT>
69 void serialise(Container& c, IteratorT& it,
const std::array<char, 12>& val) {
70 it = c.insert(it, std::begin(val), std::end(val));
76 template <
typename Container,
typename IteratorT,
typename StringT>
77 void serialise(Container& c, IteratorT& it,
const std::tuple<StringT, StringT>& val,
78 std::enable_if_t<std::is_convertible<StringT, boost::string_ref>::value>* =
nullptr) {
79 boost::string_ref str1 = std::get<0>(val);
80 it = c.insert(it, std::begin(str1), std::end(str1));
82 std::advance(it, boost::distance(str1));
83 it = std::next(c.insert(it,
'\0'));
85 boost::string_ref str2 = std::get<1>(val);
86 it = c.insert(it, std::begin(str2), std::end(str2));
88 std::advance(it, boost::distance(str2));
89 it = std::next(c.insert(it,
'\0'));
93 template <
typename Container,
typename IteratorT,
typename StringT>
94 void serialise(Container& c, IteratorT& it,
const std::tuple<StringT, std::array<char, 12>>& val) {
95 serialise(c, it, std::get<0>(val));
96 serialise(c, it, std::get<1>(val));
100 template <
typename Container,
typename IteratorT,
typename StringT,
typename DocContainer,
typename DocEContainer>
101 void serialise(Container&, IteratorT&,
const std::tuple<StringT, basic_document<DocContainer, DocEContainer>>&,
102 std::enable_if_t<std::is_convertible<StringT, boost::string_ref>::value>* =
nullptr) {
104 BOOST_THROW_EXCEPTION(incompatible_type_conversion{});
108 template <element_type EType,
typename C,
typename It,
typename A,
typename Enable =
void>
struct set_visitor;
110 #ifndef DOXYGEN_SHOULD_SKIP_THIS
113 template <element_type EType,
typename C,
typename It,
typename A>
114 struct set_visitor<EType, C, It, A, std::enable_if_t<std::is_void<ElementTypeMapSet<EType, std::decay_t<C>>>::value>> {
115 template <
typename... Args>
void operator()(Args&&...)
const {
121 template <element_type EType,
typename Container,
typename IteratorT,
typename A>
122 struct set_visitor<EType, Container, IteratorT, A,
123 std::enable_if_t<!std::is_void<ElementTypeMapSet<EType, std::decay_t<Container>>>::value>> {
124 static_assert(detail::container_has_push_back<Container>::value,
125 "Cannot set value of an element without a modifiable container");
127 using container_type = std::decay_t<Container>;
128 using set_type = ElementTypeMapSet<EType, container_type>;
130 template <
typename T>
void operator()(container_type& data, T&& val)
const {
131 (*this)(data, std::end(data), std::forward<T>(val));
134 void operator()(container_type& data,
typename container_type::const_iterator it, set_type val)
const {
135 serialise(data, it, std::move(val));
138 template <
typename T>
140 operator()(container_type& data,
typename container_type::const_iterator it, T&& val,
141 std::enable_if_t<std::is_constructible<set_type, T>::value || std::is_convertible<T, set_type>::value>* =
143 serialise(data, it, set_type(std::forward<T>(val)));
146 template <
typename T>
147 void operator()(container_type&,
typename container_type::const_iterator
const&, T&&,
148 std::enable_if_t<!std::is_constructible<set_type, T>::value>* =
nullptr,
149 std::enable_if_t<!std::is_convertible<std::decay_t<T>, set_type>::value>* =
nullptr)
const {
150 BOOST_THROW_EXCEPTION(incompatible_type_conversion{} << expected_type(
typeid(set_type))
151 << actual_type(
typeid(T)));
155 #endif // DOXYGEN_SHOULD_SKIP_THIS
160 #endif // JBSON_SET_HPP
Exception thrown when an element has a value not convertible to that requested.