YSTest: bitseg.hpp 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

bitseg.hpp
浏览该文件的文档.
1 /*
2 © 2013-2016 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
52 template<size_t... _vSize>
53 struct bitseg_traits
54 {
56
57 using sequence = index_sequence<_vSize...>;
58
59 static yconstexpr size_t bits_n = fseq::fold(fseq::plus(), size_t_<0>(),
60 sequence());
61 static yconstexpr size_t bytes_n = (bits_n + CHAR_BIT - 1) / CHAR_BIT;
62
63 using array = byte[bytes_n];
64 using integer
65 = typename ystdex::make_width_int<bits_n>::unsigned_least_type;
66
67 template<size_t _vIdx>
68 using component_width = vseq::at_t<sequence, _vIdx>;
69
70 template<size_t _vIdx>
71 using component_t = typename ystdex::make_width_int<
72 component_width<_vIdx>::value>::unsigned_least_type;
73
74 template<size_t _vIdx>
75 using shift = decltype(fseq::fold(fseq::plus(), size_t_<0>(),
76 vseq::split_n_t<_vIdx, sequence>()));
77
78 template<size_t _vIdx>
79 using mask = std::integral_constant<integer,
80 ((1ULL << component_width<_vIdx>::value) - 1) << shift<_vIdx>::value>;
81
82 template<size_t _vIdx>
83 static yconstfn component_t<_vIdx>
84 extract(integer i) ynothrow
85 {
86 return
87 component_t<_vIdx>((i & mask<_vIdx>::value) >> shift<_vIdx>::value);
88 }
89
90 template<size_t _vIdx>
91 static yconstfn integer
92 lift(component_t<_vIdx> val) ynothrow
93 {
94 return integer(integer(val) << shift<_vIdx>::value);
95 }
96
97 template<typename... _types>
98 static yconstfn integer
99 pack(_types... xs) ynothrow
100 {
101 return project(make_index_sequence<sizeof...(xs)>(), xs...);
102 }
103
104 template<size_t... _vIdxSeq>
105 static yconstfn integer
106 project(index_sequence<_vIdxSeq...>, component_t<_vIdxSeq>... xs) ynothrow
107 {
108 return fseq::vfold(bit_or<>(), integer(), lift<_vIdxSeq>(xs)...);
109 }
111 };
112
113
125 template<class _tTraits, size_t... _vSeq>
126 struct ordered_bitseg_traits : _tTraits
127 {
129 static_assert(_tTraits::sequence::size() == sizeof...(_vSeq),
130 "Invalid coponent index sequence found.");
131
133
134 using base = _tTraits;
135 using typename base::integer;
137 using mapping = index_sequence<_vSeq...>;
139 template<size_t _vIdx>
140 using map = vseq::at_t<mapping, _vIdx>;
141 template<size_t _vIdx>
142 using component_t = typename base::template component_t<map<_vIdx>::value>;
143 template<size_t _vIdx>
144 using component_width
145 = typename base::template component_width<map<_vIdx>::value>;
146 template<size_t _vIdx>
147 using shift = typename base::template shift<map<_vIdx>::value>;
148 template<size_t _vIdx>
149 using mask = typename base::template mask<map<_vIdx>::value>;
151
152 template<size_t _vIdx>
154 using inversed_map = vseq::find_t<mapping, size_t_<_vIdx>>;
155 template<size_t _vIdx>
156 using inversed_mapped_component_t = component_t<inversed_map<_vIdx>::value>;
158
159 template<size_t _vIdx>
160 static yconstfn component_t<_vIdx>
161 extract(integer i) ynothrow
162 {
163 return base::template extract<map<_vIdx>::value>(i);
164 }
165
166 template<size_t _vIdx>
167 static yconstfn component_t<_vIdx>
168 lift(component_t<map<_vIdx>::value> val) ynothrow
169 {
170 return base::template lift<map<_vIdx>::value>(val);
171 }
172
173 template<typename... _types>
174 static yconstfn integer
175 pack(_types... xs) ynothrow
176 {
177 return project(make_index_sequence<sizeof...(xs)>(), xs...);
178 }
179
180 template<size_t... _vIdxSeq>
181 static yconstfn integer
182 project(index_sequence<_vIdxSeq...>,
183 component_t<map<_vIdxSeq>::value>... xs) ynothrow
184 {
185 return base::template project(index_sequence<map<_vIdxSeq>::value...>(),
186 xs...);
187 }
189 };
191
192
205 template<size_t _vN, bool _bEndian = false>
206 class bitseg_iterator : public
207 random_access_iteratable<bitseg_iterator<_vN, _bEndian>, ptrdiff_t, byte&>
208 {
209 static_assert(_vN != 0, "A bit segment should contain at least one bit.");
210 static_assert(_vN != CHAR_BIT, "A bit segment should not be a byte.");
211 static_assert(CHAR_BIT % _vN == 0,
212 "A byte should be divided by number of segments without padding.");
213
214 public:
216 using iterator_category = std::random_access_iterator_tag;
218 using value_type = byte;
219 using difference_type = ptrdiff_t;
220 using pointer = byte*;
221 using reference = byte&;
222
224 static yconstexpr const bool lsb = _bEndian;
225 static yconstexpr const unsigned char seg_n = CHAR_BIT / _vN;
226 static yconstexpr const unsigned char seg_size = 1 << _vN;
227 static yconstexpr const unsigned char seg_width = _vN;
228
229 protected:
230 byte* base;
232 unsigned char shift;
233 mutable byte value;
234
235 public:
237
238
244 bitseg_iterator(byte* p = {}, size_t n = 0) ynothrow
245 : base(p),
246 shift((yconstraint(n < seg_n), static_cast<unsigned char>(n)))
247 {}
248
249 bitseg_iterator&
250 operator+=(difference_type n) ynothrowv
251 {
252 yconstraint(base);
253 yassume(shift < seg_n);
254
255 const size_t new_shift(shift + size_t(n));
256
257 yunseq(base += new_shift / seg_n, shift = new_shift % seg_n);
258 return *this;
259 }
260
261 bitseg_iterator&
262 operator-=(difference_type n) ynothrowv
263 {
264 base += -n;
265 return *this;
266 }
267
268 reference
269 operator*() const ynothrowv
270 {
271 yconstraint(base);
272 return value = *base >> seg_width * (lsb ? seg_n - 1 - shift : shift)
273 & ((1 << seg_width) - 1);
274 }
275
276 inline bitseg_iterator&
277 operator++() ynothrowv
278 {
279 yconstraint(base);
280 yassume(shift < seg_n);
281 if(++shift == seg_n)
282 yunseq(shift = 0, ++base);
283 return *this;
284 }
285
286 inline bitseg_iterator&
287 operator--() ynothrowv
288 {
289 yconstraint(base);
290 yassume(shift < seg_n);
291 if(shift == 0)
292 yunseq(--base, shift = seg_n - 1);
293 else
294 --shift;
295 return *this;
296 }
297
299
300 friend bool
301 operator==(const bitseg_iterator& x, const bitseg_iterator& y) ynothrow
302 {
303 return x.base == y.base && x.shift == y.shift;
304 }
305
306 friend bool
307 operator<(const bitseg_iterator& x, const bitseg_iterator& y) ynothrow
308 {
309 return x.base < y.base || (x.base == y.base && x.shift < y.shift);
310 }
312
313 explicit yconstfn
314 operator pointer() const ynothrow
315 {
316 return base;
317 }
318
319 yconstfn size_t
320 get_shift() const ynothrow
321 {
322 return shift;
323 }
325 };
326
327 } // namespace ystdex;
328
329 #endif
330
ystdex::ordered_bitseg_traits< _tBitSegTraits, _vIdxA, _vIdxX, _vIdxY, _vIdxZ >::component_width
typename base::template component_width< map< _vIdx >::value > component_width
Definition: bitseg.hpp:145
ystdex::bitseg_traits
位段特征。
Definition: bitseg.hpp:53
ystdex::bitseg_iterator::operator+=
bitseg_iterator & operator+=(difference_type n)
Definition: bitseg.hpp:250
ystdex::bitseg_iterator::operator-=
bitseg_iterator & operator-=(difference_type n)
Definition: bitseg.hpp:262
ystdex::bitseg_traits::mask
std::integral_constant< integer,((1ULL<< component_width< _vIdx >::value)-1)<< shift< _vIdx >::value > mask
Definition: bitseg.hpp:80
ystdex::bitseg_iterator::seg_size
static const unsigned char seg_size
Definition: bitseg.hpp:226
ystdex::bitseg_iterator::pointer
byte * pointer
Definition: bitseg.hpp:220
ystdex::ordered_bitseg_traits::pack
static integer pack(_types...xs)
Definition: bitseg.hpp:175
ystdex::bitseg_iterator::seg_n
static const unsigned char seg_n
Definition: bitseg.hpp:225
ystdex::bitseg_traits::shift
decltype(fseq::fold(fseq::plus(), size_t_< 0 >(), vseq::split_n_t< _vIdx, sequence >())) shift
Definition: bitseg.hpp:76
ystdex::bitseg_iterator::operator--
bitseg_iterator & operator--()
Definition: bitseg.hpp:287
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:680
ystdex::bitseg_iterator::iterator_category
std::random_access_iterator_tag iterator_category
Definition: bitseg.hpp:216
ystdex::bitseg_traits::pack
static integer pack(_types...xs)
Definition: bitseg.hpp:99
ystdex::ordered_bitseg_traits< _tBitSegTraits, _vIdxA, _vIdxX, _vIdxY, _vIdxZ >::component_t
typename base::template component_t< map< _vIdx >::value > component_t
Definition: bitseg.hpp:142
ystdex::cpp2014::index_sequence
integer_sequence< size_t, _vSeq... > index_sequence
Definition: integer_sequence.hpp:63
ystdex::details::ebases
Definition: operators.hpp:100
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
NPL::x
const TermNode &term ynothrow const TermNode &term ynothrow const TermNode &term ynothrow TermNode &term const TermNode &term ValueNode &node const ValueNode &node const _type & x
Definition: SContext.h:94
ystdex::bitseg_traits::array
byte[bytes_n] array
Definition: bitseg.hpp:63
ystdex::vseq::split_n_t
_t< split_n< _vN, _tSeq, _tEnabler >> split_n_t
Definition: variadic.hpp:565
ystdex::bitseg_iterator
位段迭代器。
Definition: bitseg.hpp:206
ystdex::ordered_bitseg_traits< _tBitSegTraits, _vIdxA, _vIdxX, _vIdxY, _vIdxZ >::map
vseq::at_t< mapping, _vIdx > map
取指定的索引实现映射。
Definition: bitseg.hpp:140
ystdex::ordered_bitseg_traits< _tBitSegTraits, _vIdxA, _vIdxX, _vIdxY, _vIdxZ >::base
_tBitSegTraits base
Definition: bitseg.hpp:134
ystdex::fseq::fold
_tState fold(_func, _tState s, integer_sequence< _tInt >)
Definition: integer_sequence.hpp:96
ystdex::bitseg_iterator::base
byte * base
Definition: bitseg.hpp:230
ystdex::bitseg_iterator::lsb
static const bool lsb
Definition: bitseg.hpp:224
ystdex::vseq::at_t
_t< at< _tSeq, _vIdx, _tEnabler >> at_t
Definition: variadic.hpp:531
ystdex::bitseg_traits::project
static integer project(index_sequence< _vIdxSeq... >, component_t< _vIdxSeq >...xs)
Definition: bitseg.hpp:106
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:679
ystdex::fseq::vfold
_tState vfold(_func, _tState s)
Definition: variadic.hpp:103
ystdex::fseq::plus
Definition: integer_sequence.hpp:110
ystdex::bitseg_iterator::reference
byte & reference
Definition: bitseg.hpp:221
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:1022
ystdex::bitseg_iterator::difference_type
ptrdiff_t difference_type
Definition: bitseg.hpp:219
ystdex::bitseg_iterator::seg_width
static const unsigned char seg_width
Definition: bitseg.hpp:227
ystdex::make_width_int
取按指定宽度的整数类型。
Definition: cstdint.hpp:129
ystdex::bitseg_iterator::operator<
friend bool operator<(const bitseg_iterator &x, const bitseg_iterator &y)
Definition: bitseg.hpp:307
ystdex::bitseg_iterator::operator*
reference operator*() const
Definition: bitseg.hpp:269
ystdex::bitseg_traits::extract
static component_t< _vIdx > extract(integer i)
Definition: bitseg.hpp:84
ystdex::bitseg_iterator::value_type
byte value_type
Definition: bitseg.hpp:218
ystdex::bitseg_iterator::operator++
bitseg_iterator & operator++()
Definition: bitseg.hpp:277
ystdex::ordered_bitseg_traits< _tBitSegTraits, _vIdxA, _vIdxX, _vIdxY, _vIdxZ >::inversed_map
vseq::find_t< mapping, size_t_< _vIdx >> inversed_map
在索引序列查找指定的索引以实现逆映射。
Definition: bitseg.hpp:154
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:766
ystdex::bitseg_iterator::bitseg_iterator
bitseg_iterator(byte *p={}, size_t n=0)
构造：使用基指针和偏移位。
Definition: bitseg.hpp:244
ystdex::bitseg_iterator::get_shift
size_t get_shift() const
Definition: bitseg.hpp:320
ystdex
特性测试宏。
Definition: ydef.h:822
ystdex::ordered_bitseg_traits< _tBitSegTraits, _vIdxA, _vIdxX, _vIdxY, _vIdxZ >::inversed_mapped_component_t
component_t< inversed_map< _vIdx >::value > inversed_mapped_component_t
Definition: bitseg.hpp:156
YSLib::i
return i
Definition: YCoreUtilities.h:176
ystdex::size_t_
std::integral_constant< size_t, _vInt > size_t_
Definition: type_traits.hpp:385
ystdex::bitseg_iterator::shift
unsigned char shift
Definition: bitseg.hpp:232
ystdex::bitseg_traits::lift
static integer lift(component_t< _vIdx > val)
Definition: bitseg.hpp:92
ystdex::ordered_bitseg_traits::lift
static component_t< _vIdx > lift(component_t< map< _vIdx >::value > val)
Definition: bitseg.hpp:168
ystdex::bitseg_iterator::operator==
friend bool operator==(const bitseg_iterator &x, const bitseg_iterator &y)
Definition: bitseg.hpp:301
ystdex::bitseg_traits::component_width
vseq::at_t< sequence, _vIdx > component_width
Definition: bitseg.hpp:68
ystdex::ordered_bitseg_traits::extract
static component_t< _vIdx > extract(integer i)
Definition: bitseg.hpp:161
ystdex::vseq::find_t
_t< find< _tSeq, _type, _tEnabler >> find_t
Definition: variadic.hpp:640
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:786
cstdint.hpp
ISO C 标准整数类型和相关扩展操作。
iterator_op.hpp
迭代器操作。
ystdex::byte
unsigned char byte
字节类型。
Definition: ydef.h:834
ystdex::bitseg_iterator::value
byte value
Definition: bitseg.hpp:233
ystdex::ordered_bitseg_traits::project
static integer project(index_sequence< _vIdxSeq... >, component_t< map< _vIdxSeq >::value >...xs)
Definition: bitseg.hpp:182
functor.hpp
通用仿函数。
ystdex::ordered_bitseg_traits< _tBitSegTraits, _vIdxA, _vIdxX, _vIdxY, _vIdxZ >::shift
typename base::template shift< map< _vIdx >::value > shift
Definition: bitseg.hpp:147
ystdex::ordered_bitseg_traits
按索引有序映射的特征适配模板。
Definition: bitseg.hpp:126
ystdex::bitseg_traits::bits_n
static size_t bits_n
Definition: bitseg.hpp:59
yassume
#define yassume(_expr)
假定：环境语义。
Definition: cassert.h:105
ystdex::bitseg_traits::component_t
typename ystdex::make_width_int< component_width< _vIdx >::value >::unsigned_least_type component_t
Definition: bitseg.hpp:72
ystdex::bitseg_traits::bytes_n
static size_t bytes_n
Definition: bitseg.hpp:61
ystdex::bitseg_traits::sequence
index_sequence< _vSize... > sequence
Definition: bitseg.hpp:57
ystdex::size
auto size(const _tRange &c) -> decltype(c.size())
类容器访问。
Definition: range.hpp:233
ystdex::cpp2014::make_index_sequence
make_integer_sequence< size_t, _vN > make_index_sequence
Definition: integer_sequence.hpp:302
yconstraint
#define yconstraint(_expr)
约束：接口语义。
Definition: cassert.h:88
ystdex::ordered_bitseg_traits< _tBitSegTraits, _vIdxA, _vIdxX, _vIdxY, _vIdxZ >::mapping
index_sequence< _vSeq... > mapping
指定映射关系的索引序列。
Definition: bitseg.hpp:137
ystdex::ordered_bitseg_traits< _tBitSegTraits, _vIdxA, _vIdxX, _vIdxY, _vIdxZ >::mask
typename base::template mask< map< _vIdx >::value > mask
Definition: bitseg.hpp:149
ystdex::bitseg_traits::integer
typename ystdex::make_width_int< bits_n >::unsigned_least_type integer
Definition: bitseg.hpp:65
CHRLib::p
const auto p(d)
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:142