23 using underlying_type=uint64_t;
25 template<underlying_type bit_pos,
class Iter,
class End,
bool AtEnd=
std::is_same<Iter, End>::value>
35 using selected_obj_type=
typename boost::mpl::deref<Iter>::type::second;
38 const std::size_t current_size=((mask & 0x1u) ?
static_cast<
std::size_t>(
give_void_a_size_of<selected_obj_type>::value) : 0u);
39 return current_size+index<bit_pos-1u,
typename boost::mpl::next<Iter>::type, End>::result(mask>>1u);
48 template<underlying_type bit_pos,
class Iter,
class End>
49 struct index<bit_pos, Iter, End,
true> {
59 template<
class Iter,
class End,
bool AtEnd>
60 struct index<1u, Iter, End, AtEnd> {
70 template<
class Iter,
class End>
71 struct index<1u, Iter, End,
true> {
81 template<
class Iter,
class End>
82 struct index<0u, Iter, End,
false> {
90 template<
class Iter,
class End,
bool AtEnd=
std::is_same<Iter, End>::value>
98 result(underlying_type mask)
noexcept(
true) {
99 using selected_obj_type=
typename boost::mpl::deref<Iter>::type::second;
101 if (mask!=underlying_type()) {
102 const std::size_t curr_size=((mask & 0x1u) ?
static_cast<
std::size_t>(
give_void_a_size_of<selected_obj_type>::value) : 0u);
103 return curr_size+current_size<
typename boost::mpl::next<Iter>::type, End>::result(mask>>1u);
105 return std::size_t();
112 template<
class Iter,
class End>
116 return std::size_t();
122 typename Cls::bitfields_tags_type SelectedField,
127 at(
typename Cls::key_type
const &bfs,
typename Cls::raw_mapped_data_t
const &raw_mapped_data)
noexcept(
false) {
128 BOOST_MPL_ASSERT_NOT((
std::is_same<
typename boost::mpl::at<
typename Cls::mapped_types, AsType>::type,
boost::mpl::void_>));
130 if (bfs &
static_cast<
typename Cls::key_type>(SelectedField)) {
132 mpl::bit_position<
static_cast<
typename Cls::underlying_key_type>(SelectedField)>::value,
133 typename boost::mpl::begin<
typename Cls::mapped_types>::type,
134 typename boost::mpl::end<
typename Cls::mapped_types>::type
136 const std::size_t offset_in_range_types=indexer::result(bfs);
137 assert(offset_in_range_types<Cls::range_mapped_types_size);
138 const typename Cls::raw_mapped_data_t::value_type &data=raw_mapped_data[offset_in_range_types];
139 return *
reinterpret_cast<Ret
const *>(&data);
141 std::ostringstream os;
142 os<<
"Selected field: 0x"<<
std::hex<<
static_cast<
typename Cls::underlying_key_type>(SelectedField)<<
", not found in mask=0x"<<
std::hex<<bfs;
143 throw std::range_error(os.str());
149 typename Cls::bitfields_tags_type SelectedField,
154 at(
typename Cls::key_type
const &bfs,
typename Cls::raw_mapped_data_t &raw_mapped_data)
noexcept(
false) {
155 BOOST_MPL_ASSERT_NOT((
std::is_same<
typename boost::mpl::at<
typename Cls::mapped_types, AsType>::type,
boost::mpl::void_>));
157 if (bfs &
static_cast<
typename Cls::underlying_key_type>(SelectedField)) {
159 mpl::bit_position<
static_cast<
typename Cls::underlying_key_type>(SelectedField)>::value,
160 typename boost::mpl::begin<
typename Cls::mapped_types>::type,
161 typename boost::mpl::end<
typename Cls::mapped_types>::type
163 const std::size_t offset_in_range_types=indexer::result(bfs);
164 assert(offset_in_range_types<Cls::range_mapped_types_size);
165 typename Cls::raw_mapped_data_t::value_type &data=raw_mapped_data[offset_in_range_types];
166 return *
reinterpret_cast<Ret *>(&data);
168 std::ostringstream os;
169 os<<
"Selected field: 0x"<<
std::hex<<
static_cast<
typename Cls::underlying_key_type>(SelectedField)<<
", not found in mask=0x"<<
std::hex<<bfs;
170 throw std::range_error(os.str());
176 typename Cls::bitfields_tags_type SelectedField,
181 erase(
typename Cls::key_type &bfs,
typename Cls::raw_mapped_data_t &raw_mapped_data)
noexcept(
true) {
182 BOOST_MPL_ASSERT_NOT((
std::is_same<
typename boost::mpl::at<
typename Cls::mapped_types, AsType>::type,
boost::mpl::void_>));
183 if (bfs & SelectedField) {
186 mpl::bit_position<
static_cast<
typename Cls::underlying_key_type>(SelectedField)>::value,
187 typename boost::mpl::begin<
typename Cls::mapped_types>::type,
188 typename boost::mpl::end<
typename Cls::mapped_types>::type
190 const std::size_t offset_in_range_types=indexer::result(bfs);
191 assert(offset_in_range_types<Cls::range_mapped_types_size);
192 Ret *data=
reinterpret_cast<Ret *>(
std::next(raw_mapped_data.begin(), offset_in_range_types));
195 bfs&=(~SelectedField);
201 typename Cls::bitfields_tags_type SelectedField,
206 insert(
typename Cls::key_type &bfs,
typename Cls::raw_mapped_data_t &raw_mapped_data, Arg
const &arg)
noexcept(
false) {
207 BOOST_MPL_ASSERT_NOT((
std::is_same<
typename boost::mpl::at<
typename Cls::mapped_types, AsType>::type,
boost::mpl::void_>));
211 mpl::bit_position<
static_cast<
typename Cls::underlying_key_type>(SelectedField)>::value,
212 typename boost::mpl::begin<
typename Cls::mapped_types>::type,
213 typename boost::mpl::end<
typename Cls::mapped_types>::type
217 assert(((bfs|mpl::lsb_bitmask<
static_cast<
unsigned long long>(SelectedField)>::value)^mpl::lsb_bitmask<
static_cast<
unsigned long long>(SelectedField)>::value)==0u);
218 const std::size_t offset_in_range_types=indexer::result(bfs);
219 assert(offset_in_range_types<Cls::range_mapped_types_size);
220 typename Cls::raw_mapped_data_t::value_type &data=raw_mapped_data[offset_in_range_types];
221 if (!(bfs &
static_cast<
typename Cls::underlying_key_type>(SelectedField))) {
225 *
reinterpret_cast<Arg *>(&data)=arg;
227 bfs|=
static_cast<
typename Cls::underlying_key_type>(SelectedField);
232 template<
class ObjToDel>
234 template<
class Cls,
typename Cls::key_type SelectedField>
236 result(
typename Cls::key_type &mask,
typename Cls::raw_mapped_data_t &raw_mapped_data)
noexcept(
true) {
237 mask&=(~SelectedField);
238 const std::size_t offset_in_range_types=index<
239 mpl::bit_position<
static_cast<
typename Cls::underlying_key_type>(SelectedField)>::value,
240 typename boost::mpl::begin<
typename Cls::mapped_types>::type,
241 typename boost::mpl::end<
typename Cls::mapped_types>::type
243 assert(offset_in_range_types<Cls::range_mapped_types_size);
244 ObjToDel *data=
reinterpret_cast<ObjToDel *>(
std::next(raw_mapped_data.begin(), offset_in_range_types));
250 template<
class Cls,
typename Cls::key_type SelectedField>
252 result(
typename Cls::key_type &,
typename Cls::raw_mapped_data_t &)
noexcept(
true) {
256 template<
class Cls,
unsigned long long SelectedField>
258 BOOST_MPL_ASSERT_RELATION(
sizeof(
typename Cls::key_type), <=,
sizeof(
unsigned long long));
261 result(
typename Cls::key_type mask,
typename Cls::raw_mapped_data_t &raw_mapped_data)
noexcept(
true) {
262 if (mask & SelectedField) {
263 using AsType=
typename std::integral_constant<
typename Cls::bitfields_tags_type,
static_cast<
typename Cls::bitfields_tags_type>(SelectedField)>::type;
264 using Ret=
typename boost::mpl::at<
typename Cls::mapped_types, AsType>::type;
265 delete_non_void<Ret>::
template result<Cls,
static_cast<
typename Cls::key_type>(SelectedField)>(mask, raw_mapped_data);
267 return deletor<Cls, (SelectedField>>1u)>::result(mask, raw_mapped_data);
273 result(
typename Cls::key_type mask,
typename Cls::raw_mapped_data_t
const &)
noexcept(
true) {
280 clear(
typename Cls::key_type &bfs,
typename Cls::raw_mapped_data_t &raw_mapped_data)
noexcept(
true) {
281 enum :
typename Cls::key_type {
282 msb_set=~(
std::numeric_limits<
typename Cls::key_type>::max()>>1)
285 bfs=
deletor<Cls, msb_set>::result(bfs, raw_mapped_data);
287 bfs=
typename Cls::key_type();
293 template<
class BFSM,
std::size_t BFSz>
297 BOOST_MPL_ASSERT_RELATION(range_mapped_types_size, <,
sizeof(bitfield_map));
298 raw_mapped_data.fill(
typename raw_mapped_data_t::value_type());
301 template<
class BFSM,
std::size_t BFSz>
302 inline constexpr typename bitfield_map<BFSM, BFSz>::key_type
303 bitfield_map<BFSM, BFSz>::convert_to_biggest_integral_type()
const noexcept(
true) {
304 BOOST_MPL_ASSERT_RELATION(
sizeof(key_type), <=,
sizeof(private_::underlying_type));
309 return conv.conv_bfs;
312 template<
class BFSM,
std::size_t BFSz>
313 inline constexpr void
315 const raw_key_type_t tmp=bfs;
318 raw_mapped_data.swap(bm.raw_mapped_data);
321 template<
class BFSM,
std::size_t BFSz>
325 raw_mapped_data.fill(
typename raw_mapped_data_t::value_type());
326 memcpy_opt(bm.raw_mapped_data, raw_mapped_data);
329 template<
class BFSM,
std::size_t BFSz>
333 raw_mapped_data.fill(
typename raw_mapped_data_t::value_type());
337 template<
class BFSM,
std::size_t BFSz>
338 inline constexpr void
348 template<
class BFSM,
std::size_t BFSz>
354 template<
class BFSM,
std::size_t BFSz>
361 template<
class BFSM,
std::size_t BFSz>
362 inline constexpr bool
364 return !
static_cast<
bool>(convert_to_biggest_integral_type());
367 template<
class BFSM,
std::size_t BFSz>
368 inline constexpr typename bitfield_map<BFSM, BFSz>::size_type
370 const std::size_t sz=private_::current_size<
371 typename boost::mpl::begin<mapped_types>::type,
372 typename boost::mpl::end<mapped_types>::type
373 >::result(convert_to_biggest_integral_type());
374 assert(sz<=range_mapped_types_size);
375 return sz+bitfields_size;
378 template<
class BFSM,
std::size_t BFSz>
379 inline constexpr typename bitfield_map<BFSM, BFSz>::size_type
381 return static_cast<size_type>(bitfields_size+range_mapped_types_size);
385 template<
typename bitfield_map<BFSM, BFSz>::bitfields_tags_type SelectedField,
class AsType,
class Ret>
386 inline constexpr const Ret &
388 return private_::at<
bitfield_map, SelectedField, AsType, Ret>(convert_to_biggest_integral_type(), raw_mapped_data);
392 template<
typename bitfield_map<BFSM, BFSz>::bitfields_tags_type SelectedField,
class AsType,
class Ret>
393 inline constexpr Ret &
395 return private_::at<
bitfield_map, SelectedField, AsType, Ret>(convert_to_biggest_integral_type(), raw_mapped_data);
399 template<
typename bitfield_map<BFSM, BFSz>::bitfields_tags_type SelectedField,
class AsType,
class Ret>
411 template<
typename bitfield_map<BFSM, BFSz>::bitfields_tags_type SelectedField>
418 return convert_to_biggest_integral_type() &
static_cast<underlying_key_type>(SelectedField);
422 template<
typename bitfield_map<BFSM, BFSz>::bitfields_tags_type SelectedField,
class AsType,
class Arg>
429 private_::insert<
bitfield_map, SelectedField, AsType, Arg>(conv.conv_bfs, raw_mapped_data, arg);