DAW JSON Link
daw_json_option_bits.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 <daw/cpp_17.h>
12#include <daw/daw_attributes.h>
13#include <daw/daw_traits.h>
14
15#include <climits>
16#include <cstddef>
17#include <cstdint>
18#include <utility>
19
20namespace daw::json {
21 inline namespace DAW_JSON_VER {
22 namespace json_details {
23 using json_options_t = std::uint32_t;
24
25 template<typename>
26 inline constexpr unsigned json_option_bits_width = 0;
27
28 template<typename>
29 inline constexpr auto default_json_option_value = [] {
30 struct unknown_policy {};
31 return unknown_policy{ };
32 }( );
33
34 template<typename Policy, typename Options>
36
37 template<typename Policy, typename... Options>
38 struct option_bits_start_impl<Policy, pack_list<Options...>> {
39 static constexpr auto idx = traits::pack_index_of_v<Policy, Options...>;
40 static_assert( idx >= 0, "Policy is not registered" );
41 using tp_policies = pack_list<Options...>;
42
43 template<std::size_t Pos, int End>
44 static constexpr unsigned do_step( ) {
45 if constexpr( Pos >= static_cast<std::size_t>( End ) ) {
46 return 0U;
47 }
48 return json_option_bits_width<pack_element_t<Pos, tp_policies>>;
49 }
50
51 template<std::size_t... Is>
52 static constexpr unsigned calc( std::index_sequence<Is...> ) {
53 return ( do_step<Is, idx>( ) + ... );
54 }
55 };
56
57 template<typename... Options>
59 using type = pack_list<Options...>;
60
61 static_assert(
62 ( json_option_bits_width<Options> + ... ) <=
63 ( sizeof( json_options_t ) * CHAR_BIT ),
64 "The size of json_options_t is not large enough "
65 "to safely hold all the bits of state. Use a larger size." );
66 };
67
68 template<typename Option>
69 inline constexpr bool is_option_flag = json_option_bits_width<Option> > 0;
70
71 template<typename Option, typename Options>
72 inline constexpr unsigned basic_option_bits_start =
74 std::make_index_sequence<pack_size_v<Options>>{ } );
75
76 template<typename... JsonOptions>
77 struct JsonOptionList;
78
79 template<typename... OptionList, typename Option>
80 static constexpr json_options_t
81 set_bits_for( JsonOptionList<OptionList...>, Option e );
82
83 template<typename... JsonOptions>
85 using OptionList = typename option_list_impl<JsonOptions...>::type;
86
87 template<typename Option>
88 static inline constexpr unsigned option_bits_start =
89 basic_option_bits_start<Option, OptionList>;
90
91 template<typename... OptionList, typename Option>
92 static constexpr json_options_t set_bits_for( Option e ) {
93 static_assert( is_option_flag<Option>,
94 "Only registered policy types are allowed" );
95 auto new_bits = static_cast<json_options_t>( e );
96 new_bits <<= option_bits_start<Option>;
97 return new_bits;
98 }
99
101 ( set_bits_for<JsonOptions>(
102 default_json_option_value<JsonOptions> ) |
103 ... );
104 /***
105 * Create the parser options flag for BasicParseOption
106 * @tparam Options Option types that satisfy the `is_option_flag`
107 * trait.
108 * @param policies A list of parser options to change from the defaults.
109 * @return A json_options_t that encodes the options for the parser
110 */
111 template<typename... Options>
112 static constexpr json_options_t options( Options... options ) {
113 static_assert( ( json_details::is_option_flag<Options> and ... ),
114 "Only registered option types are allowed" );
115 auto result = default_option_flag;
116 if constexpr( sizeof...( Options ) > 0 ) {
117 result |= ( set_bits_for( options ) | ... );
118 }
119 return result;
120 }
121 };
122
123 template<typename... OptionList, typename Option>
125 json_options_t &value, Option e ) {
126 static_assert( is_option_flag<Option>,
127 "Only registered policy types are allowed" );
128 auto new_bits = static_cast<unsigned>( e );
129 constexpr unsigned mask = (1U << json_option_bits_width<Option>)-1U;
130 new_bits &= mask;
131 new_bits <<=
132 JsonOptionList<OptionList...>::template option_bits_start<Option>;
133 value &= ~mask;
134 value |= new_bits;
135 }
136
137 template<typename... OptionList, typename Option, typename... Options>
139 json_options_t value, Option pol,
140 Options... pols ) {
141 static_assert( ( is_option_flag<Options> and ... ),
142 "Only registered policy types are allowed" );
143
144 auto new_bits = static_cast<unsigned>( pol );
145 constexpr unsigned mask = ( (1U << json_option_bits_width<Option>)-1U );
146 new_bits &= mask;
147 new_bits <<=
148 JsonOptionList<OptionList...>::template option_bits_start<Option>;
149 value &= ~( mask << JsonOptionList<
150 OptionList...>::template option_bits_start<Option> );
151 value |= new_bits;
152 if constexpr( sizeof...( Options ) > 0 ) {
153 return set_bits( JsonOptionList<OptionList...>{ }, value, pols... );
154 } else {
155 return value;
156 }
157 }
158
159 template<typename... OptionList, typename Option>
160 static constexpr json_options_t
162 return JsonOptionList<OptionList...>::template set_bits_for( e );
163 }
164
165 template<typename Option, typename Result = Option,
166 typename... OptionList>
168 json_options_t value ) {
169 static_assert( std::is_enum_v<Option>,
170 "Only enum options are allowed" );
171 static_assert( std::is_same_v<unsigned, std::underlying_type_t<Option>>,
172 "Looks like option was no specified correctly. "
173 "Underlying type should be unsigned" );
174 static_assert( is_option_flag<Option>,
175 "Only registered option types are allowed" );
176 constexpr unsigned mask =
177 ( 1U << (JsonOptionList<OptionList...>::template option_bits_start<
178 Option> +
179 json_option_bits_width<Option>)) -
180 1U;
181 value &= mask;
182 value >>=
183 JsonOptionList<OptionList...>::template option_bits_start<Option>;
184 return static_cast<Result>( Option{ value } );
185 }
186
187 template<typename... OptionList, typename... Options>
189 Options... options ) {
190 return JsonOptionList<OptionList...>::template options( options... );
191 }
192
193 template<typename>
195
196 template<template<class...> class OptionList, typename... Options>
197 struct default_option_flag_t<OptionList<Options...>> {
198 static constexpr json_options_t value =
199 ( OptionList<Options...>::template set_bits_for<Options>(
200 default_json_option_value<Options> ) |
201 ... );
202 };
203
204 /***
205 * The defaults for all known policies encoded as a json_options_t
206 */
207 template<typename OptionList>
208 static inline constexpr json_options_t default_option_flag =
210
211 } // namespace json_details
212 } // namespace DAW_JSON_VER
213} // namespace daw::json
static constexpr json_options_t set_bits_for(JsonOptionList< OptionList... >, Option e)
Definition: daw_json_option_bits.h:161
constexpr json_options_t set_bits(JsonOptionList< OptionList... >, json_options_t value, Option pol, Options... pols)
Definition: daw_json_option_bits.h:138
constexpr unsigned json_option_bits_width
Definition: daw_json_option_bits.h:26
std::uint32_t json_options_t
Definition: daw_json_option_bits.h:23
static constexpr json_options_t default_option_flag
Definition: daw_json_option_bits.h:208
constexpr void set_bits_in(JsonOptionList< OptionList... >, json_options_t &value, Option e)
Definition: daw_json_option_bits.h:124
constexpr Result get_bits_for(JsonOptionList< OptionList... >, json_options_t value)
Definition: daw_json_option_bits.h:167
constexpr bool is_option_flag
Definition: daw_json_option_bits.h:69
constexpr auto default_json_option_value
Definition: daw_json_option_bits.h:29
constexpr json_options_t json_option(JsonOptionList< OptionList... >, Options... options)
Definition: daw_json_option_bits.h:188
constexpr unsigned basic_option_bits_start
Definition: daw_json_option_bits.h:72
Definition: daw_from_json.h:22
Definition: daw_json_option_bits.h:84
static constexpr unsigned option_bits_start
Definition: daw_json_option_bits.h:88
static constexpr json_options_t default_option_flag
Definition: daw_json_option_bits.h:100
static constexpr json_options_t options(Options... options)
Definition: daw_json_option_bits.h:112
static constexpr json_options_t set_bits_for(Option e)
Definition: daw_json_option_bits.h:92
typename option_list_impl< JsonOptions... >::type OptionList
Definition: daw_json_option_bits.h:85
static constexpr unsigned do_step()
Definition: daw_json_option_bits.h:44
static constexpr unsigned calc(std::index_sequence< Is... >)
Definition: daw_json_option_bits.h:52
Definition: daw_json_option_bits.h:58
pack_list< Options... > type
Definition: daw_json_option_bits.h:59
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:16