YSTest: bitseg.hpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

bitseg.hpp
浏览该文件的文档.
1 /*
2 © 2013-2016, 2018-2019 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #ifndef YB_INC_ystdex_bitseg_hpp_
29 #define YB_INC_ystdex_bitseg_hpp_ 1
30
31 #include "iterator_op.hpp" // for size_t, index_sequence, fseq::fold,
32 // fseq::plus, std::integral_constant, CHAR_BIT, byte, vseq::at_t,
33 // vseq::split_n_t, fseq::vfold, std::random_access_iterator_tag, ptrdiff_t,
34 // yconstraint, yassume;
35 #include "functor.hpp" // for bit_or;
36 #include "cstdint.hpp" // for ystdex::make_width_int;
37
38 namespace ystdex
39 {
40
45 namespace nodep
46 {
47
59 template<size_t... _vSize>
60 struct bitseg_traits
61 {
63
64 using sequence = index_sequence<_vSize...>;
65
66 static yconstexpr const size_t bits_n = fseq::fold(fseq::plus(),
67 size_t_<0>(), sequence());
68 static yconstexpr const size_t bytes_n = (bits_n + CHAR_BIT - 1) / CHAR_BIT;
69
70 using array = byte[bytes_n];
71 using integer
72 = typename ystdex::make_width_int<bits_n>::unsigned_least_type;
73
74 template<size_t _vIdx>
75 using component_width = vseq::at_t<sequence, _vIdx>;
76
77 template<size_t _vIdx>
78 using component_t = typename ystdex::make_width_int<
79 component_width<_vIdx>::value>::unsigned_least_type;
80
81 template<size_t _vIdx>
82 using shift = decltype(fseq::fold(fseq::plus(), size_t_<0>(),
83 vseq::split_n_t<_vIdx, sequence>()));
84
85 template<size_t _vIdx>
86 using mask = std::integral_constant<integer,
87 ((1ULL << component_width<_vIdx>::value) - 1) << shift<_vIdx>::value>;
88
89 template<size_t _vIdx>
90 static yconstfn component_t<_vIdx>
91 extract(integer i) ynothrow
92 {
93 return
94 component_t<_vIdx>((i & mask<_vIdx>::value) >> shift<_vIdx>::value);
95 }
96
97 template<size_t _vIdx>
98 static yconstfn integer
99 lift(component_t<_vIdx> val) ynothrow
100 {
101 return integer(integer(val) << shift<_vIdx>::value);
102 }
103
104 template<typename... _types>
105 static yconstfn integer
106 pack(_types... xs) ynothrow
107 {
108 return project(make_index_sequence<sizeof...(xs)>(), xs...);
109 }
110
111 template<size_t... _vIdxSeq>
112 static yconstfn integer
113 project(index_sequence<_vIdxSeq...>, component_t<_vIdxSeq>... xs) ynothrow
114 {
115 return fseq::vfold(bit_or<>(), integer(), lift<_vIdxSeq>(xs)...);
116 }
118 };
119
120
132 template<class _tTraits, size_t... _vSeq>
133 struct ordered_bitseg_traits : _tTraits
134 {
136 static_assert(_tTraits::sequence::size() == sizeof...(_vSeq),
137 "Invalid coponent index sequence found.");
138
140
141 using base = _tTraits;
142 using typename base::integer;
144 using mapping = index_sequence<_vSeq...>;
146 template<size_t _vIdx>
147 using map = vseq::at_t<mapping, _vIdx>;
148 template<size_t _vIdx>
149 using component_t = typename base::template component_t<map<_vIdx>::value>;
150 template<size_t _vIdx>
151 using component_width
152 = typename base::template component_width<map<_vIdx>::value>;
153 template<size_t _vIdx>
154 using shift = typename base::template shift<map<_vIdx>::value>;
155 template<size_t _vIdx>
156 using mask = typename base::template mask<map<_vIdx>::value>;
158
159 template<size_t _vIdx>
161 using inversed_map = vseq::find_t<mapping, size_t_<_vIdx>>;
162 template<size_t _vIdx>
163 using inversed_mapped_component_t = component_t<inversed_map<_vIdx>::value>;
165
166 template<size_t _vIdx>
167 static yconstfn component_t<_vIdx>
168 extract(integer i) ynothrow
169 {
170 return base::template extract<map<_vIdx>::value>(i);
171 }
172
173 template<size_t _vIdx>
174 static yconstfn component_t<_vIdx>
175 lift(component_t<map<_vIdx>::value> val) ynothrow
176 {
177 return base::template lift<map<_vIdx>::value>(val);
178 }
179
180 template<typename... _types>
181 static yconstfn integer
182 pack(_types... xs) ynothrow
183 {
184 return project(make_index_sequence<sizeof...(xs)>(), xs...);
185 }
186
187 template<size_t... _vIdxSeq>
188 static yconstfn integer
189 project(index_sequence<_vIdxSeq...>,
190 component_t<map<_vIdxSeq>::value>... xs) ynothrow
191 {
192 return base::template project(index_sequence<map<_vIdxSeq>::value...>(),
193 xs...);
194 }
196 };
198
199 } // namespace nodep;
200
202 template<size_t... _vSize>
203 using bitseg_traits = nodep::bitseg_traits<_vSize...>;
204
206 template<class _tTraits, size_t... _vSeq>
207 using ordered_bitseg_traits = nodep::ordered_bitseg_traits<_tTraits, _vSeq...>;
208
209
222 template<size_t _vN, bool _bEndian = false>
223 class bitseg_iterator : public
224 random_access_iteratable<bitseg_iterator<_vN, _bEndian>, ptrdiff_t, byte&>
225 {
226 static_assert(_vN != 0, "A bit segment should contain at least one bit.");
227 static_assert(_vN != CHAR_BIT, "A bit segment should not be a byte.");
228 static_assert(CHAR_BIT % _vN == 0,
229 "A byte should be divided by number of segments without padding.");
230
231 public:
233 using iterator_category = std::random_access_iterator_tag;
235 using value_type = byte;
236 using difference_type = ptrdiff_t;
237 using pointer = byte*;
238 using reference = byte&;
239
241 static yconstexpr const bool lsb = _bEndian;
242 static yconstexpr const unsigned char seg_n = CHAR_BIT / _vN;
243 static yconstexpr const unsigned char seg_size = 1 << _vN;
244 static yconstexpr const unsigned char seg_width = _vN;
245
246 protected:
247 byte* base;
249 unsigned char shift;
250 mutable byte value;
251
252 public:
254
255
261 bitseg_iterator(byte* p = {}, size_t n = 0) ynothrow
262 : base(p),
263 shift((yconstraint(n < seg_n), static_cast<unsigned char>(n)))
264 {}
265
266 bitseg_iterator&
267 operator+=(difference_type n) ynothrowv
268 {
269 yconstraint(base);
270 yassume(shift < seg_n);
271
272 const size_t new_shift(shift + size_t(n));
273
274 yunseq(base += new_shift / seg_n, shift = new_shift % seg_n);
275 return *this;
276 }
277
278 bitseg_iterator&
279 operator-=(difference_type n) ynothrowv
280 {
281 base += -n;
282 return *this;
283 }
284
285 reference
286 operator*() const ynothrowv
287 {
288 yconstraint(base);
289 return value = byte(std::uintptr_t(*base) >> seg_width
290 * (lsb ? seg_n - 1 - shift : shift) & ((1 << seg_width) - 1));
291 }
292
293 inline bitseg_iterator&
294 operator++() ynothrowv
295 {
296 yconstraint(base);
297 yassume(shift < seg_n);
298 if(++shift == seg_n)
299 yunseq(shift = 0, ++base);
300 return *this;
301 }
302
303 inline bitseg_iterator&
304 operator--() ynothrowv
305 {
306 yconstraint(base);
307 yassume(shift < seg_n);
308 if(shift == 0)
309 yunseq(--base, shift = seg_n - 1);
310 else
311 --shift;
312 return *this;
313 }
314
316
317 friend bool
318 operator==(const bitseg_iterator& x, const bitseg_iterator& y) ynothrow
319 {
320 return x.base == y.base && x.shift == y.shift;
321 }
322
323 friend bool
324 operator<(const bitseg_iterator& x, const bitseg_iterator& y) ynothrow
325 {
326 return x.base < y.base || (x.base == y.base && x.shift < y.shift);
327 }
329
330 explicit yconstfn
331 operator pointer() const ynothrow
332 {
333 return base;
334 }
335
336 yconstfn size_t
337 get_shift() const ynothrow
338 {
339 return shift;
340 }
342 };
343
344 } // namespace ystdex;
345
346 #endif
347
ystdex::nodep::ordered_bitseg_traits::inversed_mapped_component_t
component_t< inversed_map< _vIdx >::value > inversed_mapped_component_t
Definition: bitseg.hpp:163
x
const EncapsulationBase & x
Definition: NPLA1Forms.cpp:1536
size
size_t size
Definition: memory_resource.cpp:295
ystdex::nodep::ordered_bitseg_traits::shift
typename base::template shift< map< _vIdx >::value > shift
Definition: bitseg.hpp:154
ystdex::make_width_int::unsigned_least_type
typename make_width_int<(_vWidth<=8U ? 8U :(_vWidth<=16U ? 16U :(_vWidth<=32U ? 32U :64U)))> ::unsigned_least_type unsigned_least_type
Definition: cstdint.hpp:144
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:1072
ystdex::bitseg_iterator::operator--
bitseg_iterator & operator--()
Definition: bitseg.hpp:304
ystdex::bitseg_iterator::reference
byte & reference
Definition: bitseg.hpp:238
ystdex::fseq::vfold
_tState vfold(_func, _tState s)
Definition: variadic.hpp:103
ystdex::nodep::ordered_bitseg_traits::map
vseq::at_t< mapping, _vIdx > map
取指定的索引实现映射。
Definition: bitseg.hpp:147
ystdex::nodep::ordered_bitseg_traits::mask
typename base::template mask< map< _vIdx >::value > mask
Definition: bitseg.hpp:156
YSLib::IO::_tTraits
const string &path const String &path class class _tTraits
Definition: YSLib/Service/FileSystem.h:582
ystdex::nodep::bitseg_traits::pack
static integer pack(_types... xs)
Definition: bitseg.hpp:106
ystdex::bitseg_iterator::bitseg_iterator
bitseg_iterator(byte *p={}, size_t n=0)
构造：使用基指针和偏移位。
Definition: bitseg.hpp:261
ystdex::bitseg_iterator::operator<
friend bool operator<(const bitseg_iterator &x, const bitseg_iterator &y)
Definition: bitseg.hpp:324
ystdex::nodep::ordered_bitseg_traits::base
_tTraits base
Definition: bitseg.hpp:141
ystdex::fseq::fold
_tState fold(_func, _tState s, integer_sequence< _tInt >)
Definition: integer_sequence.hpp:98
ystdex::make_width_int
取按指定宽度的整数类型。
Definition: cstdint.hpp:132
ystdex::bitseg_iterator::base
byte * base
Definition: bitseg.hpp:247
ystdex::nodep::bitseg_traits::integer
typename ystdex::make_width_int< bits_n >::unsigned_least_type integer
Definition: bitseg.hpp:72
ystdex::nodep::bitseg_traits::array
byte[bytes_n] array
Definition: bitseg.hpp:70
ystdex::nodep::ordered_bitseg_traits::lift
static component_t< _vIdx > lift(component_t< map< _vIdx >::value > val)
Definition: bitseg.hpp:175
ystdex::bitseg_iterator::operator++
bitseg_iterator & operator++()
Definition: bitseg.hpp:294
ystdex::bitseg_iterator::operator-=
bitseg_iterator & operator-=(difference_type n)
Definition: bitseg.hpp:279
ystdex::nodep::ordered_bitseg_traits
按索引有序映射的特征适配模板。
Definition: bitseg.hpp:134
ystdex::bitseg_iterator::operator+=
bitseg_iterator & operator+=(difference_type n)
Definition: bitseg.hpp:267
yassume
#define yassume(_expr)
假定：环境语义。
Definition: cassert.h:96
ystdex::nodep::ordered_bitseg_traits::component_width
typename base::template component_width< map< _vIdx >::value > component_width
Definition: bitseg.hpp:152
ystdex::nodep::bitseg_traits::sequence
index_sequence< _vSize... > sequence
Definition: bitseg.hpp:64
ystdex::bitseg_iterator::get_shift
size_t get_shift() const
Definition: bitseg.hpp:337
ystdex::details::ebases
Definition: operators.hpp:108
ystdex::bitseg_iterator::value_type
byte value_type
Definition: bitseg.hpp:235
ystdex::bitseg_iterator::seg_size
static const unsigned char seg_size
Definition: bitseg.hpp:243
ystdex::size_t_
integral_constant< size_t, _vInt > size_t_
Definition: integral_constant.hpp:103
ystdex::bitseg_iterator::difference_type
ptrdiff_t difference_type
Definition: bitseg.hpp:236
ystdex::nodep::ordered_bitseg_traits::inversed_map
vseq::find_t< mapping, size_t_< _vIdx > > inversed_map
在索引序列查找指定的索引以实现逆映射。
Definition: bitseg.hpp:161
ystdex::nodep::ordered_bitseg_traits::project
static integer project(index_sequence< _vIdxSeq... >, component_t< map< _vIdxSeq >::value >... xs)
Definition: bitseg.hpp:189
YSLib::i
return i
Definition: YCoreUtilities.h:177
ystdex::nodep::bitseg_traits::bytes_n
static const size_t bytes_n
Definition: bitseg.hpp:68
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:1535
ystdex::bitseg_iterator::pointer
byte * pointer
Definition: bitseg.hpp:237
ystdex::nodep::bitseg_traits::project
static integer project(index_sequence< _vIdxSeq... >, component_t< _vIdxSeq >... xs)
Definition: bitseg.hpp:113
ystdex::bitseg_iterator::value
byte value
Definition: bitseg.hpp:250
ystdex::bitseg_iterator::operator*
reference operator*() const
Definition: bitseg.hpp:286
yconstraint
#define yconstraint(_expr)
约束：接口语义。
Definition: cassert.h:125
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
ystdex::cpp2014::bit_or
位或仿函数。
Definition: functor.hpp:421
ystdex::nodep::bitseg_traits::component_t
typename ystdex::make_width_int< component_width< _vIdx >::value >::unsigned_least_type component_t
Definition: bitseg.hpp:79
ystdex::nodep::bitseg_traits::component_width
vseq::at_t< sequence, _vIdx > component_width
Definition: bitseg.hpp:75
ystdex::fseq::plus
Definition: integer_sequence.hpp:113
ystdex::nodep::bitseg_traits::lift
static integer lift(component_t< _vIdx > val)
Definition: bitseg.hpp:99
iterator_op.hpp
迭代器操作。
ystdex::bitseg_iterator::seg_width
static const unsigned char seg_width
Definition: bitseg.hpp:244
ystdex::vseq::at_t
_t< at< _tSeq, _vIdx, _tEnabler > > at_t
Definition: variadic.hpp:548
ystdex::nodep::ordered_bitseg_traits::pack
static integer pack(_types... xs)
Definition: bitseg.hpp:182
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:1219
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
ystdex::nodep::bitseg_traits::mask
std::integral_constant< integer,((1ULL<< component_width< _vIdx >::value) - 1)<< shift< _vIdx >::value > mask
Definition: bitseg.hpp:87
ystdex::nodep::bitseg_traits
位段特征。
Definition: bitseg.hpp:61
ystdex::bitseg_iterator::shift
unsigned char shift
Definition: bitseg.hpp:249
ystdex::bitseg_iterator::seg_n
static const unsigned char seg_n
Definition: bitseg.hpp:242
ystdex::nodep::ordered_bitseg_traits::component_t
typename base::template component_t< map< _vIdx >::value > component_t
Definition: bitseg.hpp:149
ystdex::cpp2014::make_index_sequence
make_integer_sequence< size_t, _vN > make_index_sequence
Definition: integer_sequence.hpp:304
ystdex::cpp2014::integer_sequence
Definition: integer_sequence.hpp:53
ystdex::byte
unsigned char byte
字节类型。
Definition: ydef.h:1283
platform::p
return p p
Definition: YCLib/FileSystem.h:209
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
ystdex::bitseg_iterator::lsb
static const bool lsb
Definition: bitseg.hpp:241
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:1199
ystdex::bitseg_iterator
位段迭代器。
Definition: bitseg.hpp:225
ystdex::nodep::bitseg_traits::bits_n
static const size_t bits_n
Definition: bitseg.hpp:66
functor.hpp
通用仿函数。
ystdex::vseq::split_n_t
_t< split_n< _vN, _tSeq, _tEnabler > > split_n_t
Definition: variadic.hpp:582
ystdex::nodep::bitseg_traits::shift
decltype(fseq::fold(fseq::plus(), size_t_< 0 >(), vseq::split_n_t< _vIdx, sequence >())) shift
Definition: bitseg.hpp:83
ystdex::vseq::find_t
_t< find< _tSeq, _type, _tEnabler > > find_t
Definition: variadic.hpp:657
ystdex::bitseg_iterator::operator==
friend bool operator==(const bitseg_iterator &x, const bitseg_iterator &y)
Definition: bitseg.hpp:318
ystdex::bitseg_iterator::iterator_category
std::random_access_iterator_tag iterator_category
Definition: bitseg.hpp:233
ystdex::nodep::bitseg_traits::extract
static component_t< _vIdx > extract(integer i)
Definition: bitseg.hpp:91
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:1073
ystdex::nodep::ordered_bitseg_traits::extract
static component_t< _vIdx > extract(integer i)
Definition: bitseg.hpp:168
cstdint.hpp
ISO C 标准整数类型和相关扩展操作。