DAW JSON Link
daw_json_serialize_policy_details.h
Go to the documentation of this file.
1 // Copyright (c) Darrell Wright
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6 // Official repository: https://github.com/beached/daw_json_link
7 //
8 
9 #pragma once
10 
11 #include "version.h"
12 
13 #include "daw_json_option_bits.h"
16 
17 #include <cstddef>
18 #include <iterator>
19 
20 namespace daw::json {
21  inline namespace DAW_JSON_VER {
22  namespace json_details {
23  template<typename OutputIterator>
24  struct iterator_wrapper : OutputIterator {
25  inline constexpr OutputIterator get( ) const {
26  return *this;
27  }
28 
29  static constexpr bool is_pointer = false;
30 
31  inline constexpr void set( OutputIterator it ) {
32  *static_cast<OutputIterator *>( this ) = it;
33  }
34 
35  protected:
36  inline constexpr OutputIterator &raw_it( ) {
37  return *this;
38  }
39  };
40 
41  template<typename CharT>
42  struct iterator_wrapper<CharT *> {
43  using difference_type = std::ptrdiff_t;
44  using size_type = std::size_t;
45  using value_type = CharT;
46  using pointer = CharT *;
47  using reference = CharT &;
48  using iterator_category = std::random_access_iterator_tag;
49 
50  CharT *ptr;
51 
52  static constexpr bool is_pointer = true;
53 
54  protected:
55  inline constexpr CharT *raw_it( ) {
56  return ptr;
57  }
58 
59  public:
60  inline constexpr CharT *get( ) const {
61  return ptr;
62  }
63 
64  inline constexpr void set( CharT *p ) {
65  ptr = p;
66  }
67 
68  inline constexpr reference operator*( ) {
69  return *ptr;
70  }
71 
72  inline constexpr pointer operator->( ) {
73  return ptr;
74  }
75 
76  inline constexpr iterator_wrapper &operator++( ) {
77  ++ptr;
78  return *this;
79  }
80 
81  inline constexpr iterator_wrapper operator++( int ) & {
82  auto result = *this;
83  ++ptr;
84  return result;
85  }
86 
87  inline constexpr iterator_wrapper &operator--( ) {
88  --ptr;
89  return *this;
90  }
91 
92  inline constexpr iterator_wrapper operator--( int ) & {
93  auto result = *this;
94  --ptr;
95  return result;
96  }
97 
98  inline constexpr iterator_wrapper &operator+=( difference_type n ) {
99  ptr += n;
100  return *this;
101  }
102 
103  inline constexpr iterator_wrapper &operator-=( difference_type n ) {
104  ptr -= n;
105  return *this;
106  }
107 
108  inline constexpr iterator_wrapper
109  operator+( difference_type n ) const noexcept {
110  iterator_wrapper result = *this;
111  ptr += n;
112  return result;
113  }
114 
115  inline constexpr iterator_wrapper
116  operator-( difference_type n ) const noexcept {
117  iterator_wrapper result = *this;
118  ptr -= n;
119  return result;
120  }
121 
122  inline constexpr reference operator[]( size_type n ) noexcept {
123  return *( ptr + static_cast<difference_type>( n ) );
124  }
125 
126  explicit inline constexpr operator bool( ) const {
127  return static_cast<bool>( ptr );
128  }
129 
130  friend inline constexpr bool operator==( iterator_wrapper const &lhs,
131  iterator_wrapper const &rhs ) {
132  return lhs.ptr == rhs.ptr;
133  }
134 
135  friend inline constexpr bool operator!=( iterator_wrapper const &lhs,
136  iterator_wrapper const &rhs ) {
137  return lhs.ptr != rhs.ptr;
138  }
139 
140  friend inline constexpr bool operator<( iterator_wrapper const &lhs,
141  iterator_wrapper const &rhs ) {
142  return lhs.ptr < rhs.ptr;
143  }
144 
145  friend inline constexpr bool operator<=( iterator_wrapper const &lhs,
146  iterator_wrapper const &rhs ) {
147  return lhs.ptr <= rhs.ptr;
148  }
149 
150  friend inline constexpr bool operator>( iterator_wrapper const &lhs,
151  iterator_wrapper const &rhs ) {
152  return lhs.ptr > rhs.ptr;
153  }
154 
155  friend inline constexpr bool operator>=( iterator_wrapper const &lhs,
156  iterator_wrapper const &rhs ) {
157  return lhs.ptr >= rhs.ptr;
158  }
159  };
160 
161  } // namespace json_details
162 
163  namespace json_details::serialization {
164  using policy_list = typename option_list_impl<
168 
169  template<typename Policy, typename Policies>
170  inline constexpr unsigned basic_policy_bits_start =
171  option_bits_start_impl<Policy, Policies>::template calc<>(
172  std::make_index_sequence<pack_size_v<Policies>>{ } );
173 
174  template<typename Policy>
175  inline constexpr unsigned policy_bits_start =
176  basic_policy_bits_start<Policy, policy_list>;
177 
178  template<typename Policy>
179  static constexpr void set_bits_in( json_options_t &value, Policy e ) {
180  static_assert( is_option_flag<Policy>,
181  "Only registered policy types are allowed" );
182  auto new_bits = static_cast<unsigned>( e );
183  constexpr unsigned mask = (1U << json_option_bits_width<Policy>)-1U;
184  new_bits &= mask;
185  new_bits <<= policy_bits_start<Policy>;
186  value &= ~mask;
187  value |= new_bits;
188  }
189 
190  template<typename Policy, typename... Policies>
191  static constexpr json_options_t set_bits( json_options_t value,
192  Policy pol, Policies... pols ) {
193  static_assert( are_option_flags<Policies...>,
194  "Only registered policy types are allowed" );
195 
196  auto new_bits = static_cast<unsigned>( pol );
197  constexpr unsigned mask = ( (1U << json_option_bits_width<Policy>)-1U );
198  new_bits &= mask;
199  new_bits <<= policy_bits_start<Policy>;
200  value &= ~( mask << policy_bits_start<Policy> );
201  value |= new_bits;
202  if constexpr( sizeof...( Policies ) > 0 ) {
203  if constexpr( sizeof...( pols ) > 0 ) {
204  return set_bits( value, pols... );
205  } else {
206  return value;
207  }
208  } else {
209  return value;
210  }
211  }
212 
213  template<typename Policy>
214  static constexpr json_options_t set_bits_for( Policy e ) {
215  static_assert( is_option_flag<Policy>,
216  "Only registered policy types are allowed" );
217  auto new_bits = static_cast<json_options_t>( e );
218  new_bits <<= policy_bits_start<Policy>;
219  return new_bits;
220  }
221 
222  template<typename>
223  struct default_policy_flag_t;
224 
225  template<typename... Policies>
226  struct default_policy_flag_t<pack_list<Policies...>> {
227  static constexpr json_options_t value =
228  ( set_bits_for<Policies>( default_json_option_value<Policies> ) |
229  ... );
230  };
231 
232  /***
233  * The defaults for all known policies encoded as a json_options_t
234  */
235  inline static constexpr json_options_t default_policy_flag =
236  default_policy_flag_t<policy_list>::value;
237 
238  template<typename Policy, typename Result = Policy>
239  static constexpr Result get_bits_for( json_options_t value ) {
240  static_assert( is_option_flag<Policy>,
241  "Only registered policy types are allowed" );
242  constexpr unsigned mask = ( 1U << (policy_bits_start<Policy> +
243  json_option_bits_width<Policy>)) -
244  1U;
245  value &= mask;
246  value >>= policy_bits_start<Policy>;
247  return static_cast<Result>( Policy{ value } );
248  }
249 
250  template<options::SerializationFormat, options::IndentationType>
251  inline constexpr std::string_view generate_indent{ };
252 
253  template<>
254  inline constexpr std::string_view generate_indent<
255  options::SerializationFormat::Pretty, options::IndentationType::Tab> =
256  "\t";
257 
258  template<>
259  inline constexpr std::string_view
260  generate_indent<options::SerializationFormat::Pretty,
261  options::IndentationType::Space1> = " ";
262 
263  template<>
264  inline constexpr std::string_view
265  generate_indent<options::SerializationFormat::Pretty,
266  options::IndentationType::Space2> = " ";
267 
268  template<>
269  inline constexpr std::string_view
270  generate_indent<options::SerializationFormat::Pretty,
271  options::IndentationType::Space3> = " ";
272 
273  template<>
274  inline constexpr std::string_view
275  generate_indent<options::SerializationFormat::Pretty,
276  options::IndentationType::Space4> = " ";
277 
278  template<>
279  inline constexpr std::string_view
280  generate_indent<options::SerializationFormat::Pretty,
281  options::IndentationType::Space5> = " ";
282 
283  template<>
284  inline constexpr std::string_view
285  generate_indent<options::SerializationFormat::Pretty,
286  options::IndentationType::Space8> = " ";
287 
288  template<>
289  inline constexpr std::string_view
290  generate_indent<options::SerializationFormat::Pretty,
291  options::IndentationType::Space10> = " ";
292  } // namespace json_details::serialization
293  } // namespace DAW_JSON_VER
294 } // namespace daw::json
constexpr decltype(auto) get(basic_json_pair< PolicyFlags, Allocator > const &parse_state)
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:25