YSTest: utility.hpp 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

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

- 文件列表
- 文件成员

utility.hpp
浏览该文件的文档.
1 /*
2 © 2010-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_utility_hpp_
29 #define YB_INC_ystdex_utility_hpp_ 1
30
31 #include "type_pun.hpp" // for "type_pun.hpp", is_standard_layout,
32 // pun_storage_t, std::swap, aligned_replace_cast, exclude_self_t,
33 // replace_storage_t;
34 #include <functional> // for std::bind, std::ref
35 #include "memory.hpp" // for yassume, ystdex::construct_in, ystdex::destruct_in;
36 #include "base.h" // for noncopyable, nonmovable;
37
38 namespace ystdex
39 {
40
42
43
48 template<typename _type>
49 inline add_const_t<_type>&
50 as_const(_type& t)
51 {
52 return t;
53 }
54
59 template<typename _type>
60 void
61 swap_underlying(_type& x, _type& y) ynothrow
62 {
63 static_assert(is_standard_layout<_type>(),
64 "Invalid underlying type found.");
65 using utype = pun_storage_t<_type>;
66
67 std::swap(ystdex::aligned_replace_cast<utype&>(x),
68 ystdex::aligned_replace_cast<utype&>(y));
69 }
70
71
72 inline namespace cpp2014
73 {
74
75 #if __cpp_lib_exchange_function >= 201304 || __cplusplus > 201103L
76 using std::exchange;
77 #else
78
84 template<typename _type, typename _type2 = _type>
85 _type
86 exchange(_type& obj, _type2&& new_val)
87 {
88 _type old_val = std::move(obj);
89
90 obj = std::forward<_type2>(new_val);
91 return old_val;
92 }
94 #endif
95
96 } // inline namespace cpp2014;
97
98
106 template<typename _type>
107 yconstfn yimpl(enable_if_convertible_t)<_type, decay_t<_type>, decay_t<_type>>
108 decay_copy(_type&& arg)
109 {
110 return std::forward<_type>(arg);
111 }
112
113
118 template<typename _type, yimpl(typename = enable_if_t<is_enum<_type>::value>)>
119 yconstfn underlying_type_t<_type>
120 underlying(_type val) ynothrow
121 {
122 return underlying_type_t<_type>(val);
123 }
124
125
130 yconstexpr const struct default_init_t{} default_init{};
131
132
138 template<typename _type>
139 struct boxed_value
140 {
142 mutable _type value;
143
145
146 yconstfn
147 boxed_value() ynoexcept(is_nothrow_constructible<_type>())
148 : value()
149 {}
150 yconstfn
151 boxed_value(default_init_t) ynothrow
152 {}
153 template<typename _tParam,
154 yimpl(typename = exclude_self_t<boxed_value, _tParam>)>
155 yconstfn
156 boxed_value(_tParam&& arg)
157 ynoexcept(is_nothrow_constructible<_type, _tParam&&>())
158 : value(yforward(arg))
159 {}
160 template<typename _tParam1, typename _tParam2, typename... _tParams>
161 yconstfn
162 boxed_value(_tParam1&& arg1, _tParam2&& arg2, _tParams&&... args)
163 ynoexcept(is_nothrow_constructible<_type, _tParam1&&, _tParam2&&,
164 _tParams&&...>())
165 : value(yforward(arg1), yforward(arg2), yforward(args)...)
166 {}
168
170 boxed_value(const boxed_value&) = default;
171 boxed_value(boxed_value&&) = default;
172
173 boxed_value&
174 operator=(const boxed_value&) = default;
175 boxed_value&
176 operator=(boxed_value&&) = default;
178
179 operator _type&() ynothrow
180 {
181 return value;
182 }
183
184 operator const _type&() const ynothrow
185 {
186 return value;
187 }
188 };
189
190
196 template<typename _type>
197 using classify_value_t = cond_t<std::is_class<_type>, _type,
198 boxed_value<_type>>;
199
200
207 template<typename _type, typename, typename...>
208 inline _type&
209 parameterize_static_object()
210 {
211 static _type obj;
212
213 return obj;
214 }
221 template<typename _type, size_t...>
222 inline _type&
223 parameterize_static_object()
224 {
225 static _type obj;
226
227 return obj;
228 }
229
230
240 template<typename _tKey, typename... _tKeys, typename _fInit,
241 typename... _tParams>
242 inline auto
243 get_init(_fInit&& f, _tParams&&... args) -> decltype(f(yforward(args)...))&
244 {
245 using obj_type = decltype(f(yforward(args)...));
246
247 auto& p(ystdex::parameterize_static_object<obj_type*, _tKey, _tKeys...>());
248
249 if(!p)
250 p = new obj_type(f(yforward(args)...));
251 return *p;
252 }
261 template<size_t... _vKeys, typename _fInit, typename... _tParams>
262 inline auto
263 get_init(_fInit&& f, _tParams&&... args) -> decltype(f(yforward(args)...))&
264 {
265 using obj_type = decltype(f(yforward(args)...));
266
267 auto& p(ystdex::parameterize_static_object<obj_type*, _vKeys...>());
268
269 if(!p)
270 p = new obj_type(f(yforward(args)...));
271 return *p;
272 }
273
274
296 template<class _type>
297 class nifty_counter
298 {
299 public:
300 using object_type = _type;
301
302 template<typename... _tParams>
303 nifty_counter(_tParams&&... args)
304 {
305 if(get_count()++ == 0)
306 get_object_ptr() = new _type(yforward(args)...);
307 }
309
310 ~nifty_counter()
312 {
313 if(--get_count() == 0)
314 delete get_object_ptr();
315 }
316
317 static object_type&
318 get() ynothrow
319 {
320 yassume(get_object_ptr());
321 return *get_object_ptr();
322 }
323
324 private:
325 static size_t&
326 get_count() ynothrow
327 {
328 ythread size_t count;
329
330 return count;
331 }
332 static object_type*&
333 get_object_ptr() ynothrow
334 {
335 ythread object_type* ptr;
336
337 return ptr;
338 }
339
340 public:
341 static size_t
342 use_count() ynothrow
343 {
344 return get_count();
345 }
347 };
348
349
369 template<typename _type, typename _tOnceFlag>
370 class call_once_init : private noncopyable, private nonmovable
371 {
372 public:
373 using object_type = _type;
374 using flag_type = _tOnceFlag;
375
376 private:
378 flag_type init_flag, uninit_flag;
380 replace_storage_t<_type> storage;
381
382 public:
383 template<typename... _tParams>
384 call_once_init(_tParams&&... args)
385 : init_flag(), uninit_flag()
386 {
387 call_once(init_flag, std::bind(ystdex::construct_in<_type,
388 _tParams&&...>, std::ref(get()), std::ref(args)...));
389 }
390 ~call_once_init()
391 {
392 call_once(init_flag, std::bind(ystdex::destruct_in<_type>,
393 std::ref(get())));
394 }
395
397 object_type&
398 get() ynothrow
399 {
400 return storage.template access<object_type>();
401 }
403 const object_type&
404 get() const ynothrow
405 {
406 return storage.template access<const object_type>();
407 }
408 };
409
410 } // namespace ystdex;
411
412 #if !YB_HAS_BUILTIN_NULLPTR
413 using ystdex::nullptr;
414 #endif
415
416 #endif
417
yassume
#define yassume(_expr)
假定：环境语义。
Definition: cassert.h:99
platform::p
while p p
Definition: YCLib/FileSystem.h:225
ystdex::cpp2014::exchange
_type exchange(_type &obj, _type2 &&new_val)
交换值并返回旧值。
Definition: utility.hpp:86
YSLib::Drawing::x
The boundary is out of the const Rect SDst SPos x
Definition: YDraw.h:127
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:653
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:740
ystdex::boxed_value::operator=
boxed_value & operator=(const boxed_value &)=default
ystdex::enable_if_convertible_t
enable_if_t< is_convertible< _tFrom, _tTo >::value, _type > enable_if_convertible_t
Definition: type_traits.hpp:993
ystdex::get_init
auto get_init(_fInit &&f, _tParams &&...args) -> decltype(f(std::forward< decltype(args)>(args)...))&
取类型标识和初始化调用指定的对象。
Definition: utility.hpp:243
ystdex::classify_value_t
cond_t< std::is_class< _type >, _type, boxed_value< _type >> classify_value_t
包装非类类型为类类型。
Definition: utility.hpp:198
ystdex::default_init
const struct ystdex::default_init_t default_init
ystdex::nifty_counter::~nifty_counter
~nifty_counter()
Definition: utility.hpp:311
ystdex::swap
void swap(container_adaptor< _tSeqCon > &x, container_adaptor< _tSeqCon > &y)
Definition: container.hpp:179
ystdex::swap_underlying
void swap_underlying(_type &x, _type &y)
交换相同标准布局类型可修改左值的存储。
Definition: utility.hpp:61
ystdex::decay_copy
enable_if_convertible_t< _type, decay_t< _type >, decay_t< _type > > decay_copy(_type &&arg)
退化复制。
Definition: utility.hpp:108
ystdex::call_once_init::~call_once_init
~call_once_init()
Definition: utility.hpp:390
ystdex::nullptr
const class ystdex::nullptr_t nullptr
ystdex::underlying
underlying_type_t< _type > underlying(_type val)
取枚举值的底层整数。
Definition: utility.hpp:120
ystdex::boxed_value
包装类类型的值的对象。
Definition: utility.hpp:139
YSLib::GUIApplication::InitBlock
Definition: GUIApplication.h:206
type_pun.hpp
共享存储和直接转换。
ystdex::call_once_init::uninit_flag
flag_type uninit_flag
Definition: utility.hpp:378
ystdex::call_once_init::storage
replace_storage_t< _type > storage
Definition: utility.hpp:380
ystdex::pun_storage_t
aligned_storage_t< sizeof(_type), _vAlign > pun_storage_t
显式转换的替代对齐存储对齐存储类型。
Definition: type_pun.hpp:114
ystdex::single_thread::call_once
void call_once(once_flag &flag, _fCallable &&f, _tParams &&...args)
按标识调用函数，保证调用一次。
Definition: pseudo_mutex.h:537
ystdex::exclude_self_t
enable_if_t<!is_same< _tClass &, decay_t< _tParam > & >::value, _type > exclude_self_t
移除选择类类型的特定重载避免构造模板和复制/转移特殊成员函数冲突。
Definition: type_traits.hpp:708
ystdex::nifty_counter::object_type
_type object_type
Definition: utility.hpp:300
ystdex::nifty_counter::nifty_counter
nifty_counter(_tParams &&...args)
Definition: utility.hpp:303
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:256
ystdex::construct_in
void construct_in(_type &obj, _tParams &&...args)
原地构造。
Definition: memory.hpp:164
base.h
基类实用设施。
ystdex::call_once_init::call_once_init
call_once_init(_tParams &&...args)
Definition: utility.hpp:384
ythread
#define ythread
线程局部存储：若实现支持，指定为 thread_local 。
Definition: ydef.h:780
ystdex::nifty_counter::use_count
static size_t use_count()
Definition: utility.hpp:342
ystdex::call_once_init::init_flag
flag_type init_flag
Definition: utility.hpp:378
ystdex::call_once_init::object_type
_type object_type
Definition: utility.hpp:373
ystdex::default_init_t
默认初始化标记。
Definition: utility.hpp:130
ystdex::call_once_init
使用 call_once 的静态初始化管理器。
Definition: utility.hpp:370
ystdex
特性测试宏。
Definition: ydef.h:796
ystdex::boxed_value::boxed_value
boxed_value(default_init_t)
Definition: utility.hpp:151
memory.hpp
存储和智能指针特性。
ystdex::nonmovable
Definition: base.h:81
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
ystdex::nifty_counter::get_count
static size_t & get_count()
Definition: utility.hpp:326
ystdex::call_once_init< YSLib::GUIApplication::InitBlock, once_flag >::flag_type
once_flag flag_type
Definition: utility.hpp:374
ynoexcept
#define ynoexcept(...)
YSLib 无异常抛出保证：指定特定的异常规范。
Definition: ydef.h:720
ystdex::nifty_counter
使用引用计数的静态初始化管理器。
Definition: utility.hpp:297
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:654
ystdex::noncopyable
不可复制对象：禁止派生类调用默认原型的复制构造函数和复制赋值操作符。
Definition: base.h:41
ystdex::boxed_value::boxed_value
boxed_value(_tParam1 &&arg1, _tParam2 &&arg2, _tParams &&...args)
Definition: utility.hpp:162
ystdex::standard_layout_storage
任意标准布局类型存储。
Definition: type_pun.hpp:227
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:969
ystdex::boxed_value::value
_type value
Definition: utility.hpp:142
ystdex::nifty_counter::get_object_ptr
static object_type *& get_object_ptr()
Definition: utility.hpp:333
YSLib::IO::f
const string &path const String &path _func f
Definition: YSLib/Service/FileSystem.h:430
ystdex::parameterize_static_object
_type & parameterize_static_object()
类型参数化静态对象。
Definition: utility.hpp:209
CHRLib::args
_tParams && args
Definition: CharacterProcessing.h:538
ystdex::boxed_value::boxed_value
boxed_value()
Definition: utility.hpp:147
ystdex::boxed_value::boxed_value
boxed_value(_tParam &&arg)
Definition: utility.hpp:156
ystdex::as_const
add_const_t< _type > & as_const(_type &t)
转换 const 引用。
Definition: utility.hpp:50
ystdex::ref
lref< _type > ref(_type &t)
构造引用包装。
Definition: ref.hpp:120