YSTest: utility.hpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

utility.hpp
浏览该文件的文档.
1 /*
2 © 2010-2020 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 "swap.hpp" // for "swap.hpp", is_lvalue_reference, conditional_t,
32 // remove_reference_t, std::forward, add_const_t, std::move,
33 // is_nothrow_constructible, enable_if_convertible_t, exclude_self_t;
34 #include "type_op.hpp" // for exclude_self_params_t;
35 #include "placement.hpp" // for yassume, ystdex::construct_in,
36 // ystdex::destruct_in;
37 #include "base.h" // for noncopyable, nonmovable;
38 #include <functional> // for std::bind, std::ref
39 #include <tuple> // for tuple workaround;
40
41 namespace ystdex
42 {
43
49 template<typename _type, typename _type2>
51 using forward_like_t = conditional_t<is_lvalue_reference<_type>::value,
52 remove_reference_t<_type2>&, remove_reference_t<_type2>&&>;
53
55 template<typename _type, typename _type2>
56 YB_ATTR_nodiscard YB_STATELESS forward_like_t<_type, _type2>
57 forward_like(_type2&& x)
58 {
59 return std::forward<forward_like_t<_type, _type2>>(yforward(x));
60 }
62
63 inline namespace cpp2017
64 {
65
71 #if __cpp_lib_as_const >= 201510L
72 using std::as_const;
73 #else
74 template<typename _type>
76 YB_ATTR_nodiscard YB_STATELESS inline add_const_t<_type>&
77 as_const(_type& t)
78 {
79 return t;
80 }
82 template<class _type>
83 void
84 as_const(const _type&&) = delete;
85 #endif
86
87
88 } // inline namespace cpp2017;
89
94 template<typename _type, typename _type2 = _type>
95 YB_ATTR_nodiscard inline _type
96 copy_or_move(bool copy, _type& obj)
97 {
98 if(copy)
99 return ystdex::as_const(obj);
100 return std::move(obj);
101 }
102
103
111 template<typename _type>
112 YB_ATTR_nodiscard yconstfn
113 yimpl(enable_if_convertible_t)<_type, decay_t<_type>, decay_t<_type>>
114 decay_copy(_type&& arg)
115 {
116 return yforward(arg);
117 }
118
119
124 template<typename _type, yimpl(typename = enable_if_t<is_enum<_type>::value>)>
125 YB_ATTR_nodiscard YB_STATELESS yconstfn underlying_type_t<_type>
126 underlying(_type val) ynothrow
127 {
128 return underlying_type_t<_type>(val);
129 }
130
131 namespace details
132 {
133
134 template<typename _type>
135 struct is_nt_dc : is_nothrow_constructible<_type>
136 {};
137
138 #if defined(__GLIBCXX__) \
139 && (YB_IMPL_GNUCPP && YB_IMPL_GNUCPP < 80200 && YB_IMPL_GNUCPP > 70100)
140 // XXX: Workaround of libstdc++ non-SFINAE friendly std::tuple implementation.
141 // It is unknown which versions are exactly affected. See $2019-01
142 // @ %Documentation::Workflow.
143 template<size_t _vIdx, typename _type, typename... _types>
144 struct is_nt_dc<std::_Tuple_impl<_vIdx, _type, _types...>>
145 : and_<is_nothrow_constructible<_type>,
146 is_nt_dc<std::_Tuple_impl<_vIdx + 1, _types...>>>
147 {};
148 #endif
149
150 } // namespace details;
151
157 template<typename _type>
158 struct boxed_value
159 {
161 using nothrow_default_constructible = details::is_nt_dc<_type>;
162
164 mutable _type value;
165
167
168 template<yimpl(typename _tParam = _type,
169 typename = enable_if_t<is_constructible<_tParam>::value>)>
170 yconstfn
171 boxed_value() ynoexcept(nothrow_default_constructible())
172 : value()
173 {}
174 template<yimpl(typename _tParam = _type,
175 typename = enable_if_t<is_constructible<_tParam>::value>)>
176 explicit
177 boxed_value(default_init_t) ynoexcept(nothrow_default_constructible())
178 {}
180 template<typename... _tParams,
182 yimpl(typename = exclude_self_params_t<boxed_value, _tParams...>,
183 typename = enable_if_t<is_constructible<_type, _tParams...>::value>)>
184 yconstfn
185 boxed_value(_tParams&&... args)
186 ynoexcept(is_nothrow_constructible<_type, _tParams...>())
187 : value(yforward(args)...)
188 {}
190
191 boxed_value(const boxed_value&) = default;
192 boxed_value(boxed_value&&) = default;
193
194 boxed_value&
195 operator=(const boxed_value&) = default;
196 boxed_value&
197 operator=(boxed_value&&) = default;
199
200 YB_ATTR_nodiscard
201 operator _type&() ynothrow
202 {
203 return value;
204 }
205
206 YB_ATTR_nodiscard
207 operator const _type&() const ynothrow
208 {
209 return value;
210 }
211 };
212
213
219 template<typename _type>
220 using classify_value_t = cond_t<std::is_class<_type>, _type,
221 boxed_value<_type>>;
222
223
230 template<typename _type, typename, typename...>
231 YB_ATTR_nodiscard inline _type&
232 parameterize_static_object()
233 {
234 static _type obj;
235
236 return obj;
237 }
245 template<typename _type, size_t...>
246 YB_ATTR_nodiscard _type&
247 parameterize_static_object()
248 {
249 static _type obj;
250
251 return obj;
252 }
253
254
264 template<typename _tKey, typename... _tKeys, typename _fInit,
265 typename... _tParams>
266 inline auto
267 get_init(_fInit&& f, _tParams&&... args) -> decltype(f(yforward(args)...))&
268 {
269 using obj_type = decltype(f(yforward(args)...));
270
271 auto& p(ystdex::parameterize_static_object<obj_type*, _tKey, _tKeys...>());
272
273 if(!p)
274 p = new obj_type(f(yforward(args)...));
275 return *p;
276 }
285 template<size_t... _vKeys, typename _fInit, typename... _tParams>
286 inline auto
287 get_init(_fInit&& f, _tParams&&... args) -> decltype(f(yforward(args)...))&
288 {
289 using obj_type = decltype(f(yforward(args)...));
290
291 auto& p(ystdex::parameterize_static_object<obj_type*, _vKeys...>());
292
293 if(!p)
294 p = new obj_type(f(yforward(args)...));
295 return *p;
296 }
297
298
320 template<class _type>
321 class nifty_counter
322 {
323 public:
324 using object_type = _type;
325
326 template<typename... _tParams>
327 nifty_counter(_tParams&&... args)
328 {
329 if(get_count()++ == 0)
330 get_object_ptr() = new _type(yforward(args)...);
331 }
333
334 ~nifty_counter()
336 {
337 if(--get_count() == 0)
338 delete get_object_ptr();
339 }
340
341 YB_ATTR_nodiscard static object_type&
342 get() ynothrow
343 {
344 yassume(get_object_ptr());
345 return *get_object_ptr();
346 }
347
348 private:
349 YB_ATTR_nodiscard static size_t&
350 get_count() ynothrow
351 {
352 ythread size_t count;
353
354 return count;
355 }
356 YB_ATTR_nodiscard static object_type*&
357 get_object_ptr() ynothrow
358 {
359 ythread object_type* ptr;
360
361 return ptr;
362 }
363
364 public:
365 YB_ATTR_nodiscard static size_t
366 use_count() ynothrow
367 {
368 return get_count();
369 }
371 };
372
373
393 template<typename _type, typename _tOnceFlag>
394 class call_once_init : private noncopyable, private nonmovable
395 {
396 public:
397 using object_type = _type;
398 using flag_type = _tOnceFlag;
399
400 private:
402 flag_type init_flag;
404 flag_type deinit_flag;
406 replace_storage_t<_type> storage;
407
408 public:
409 template<typename... _tParams>
410 call_once_init(_tParams&&... args)
411 : init_flag(), deinit_flag()
412 {
413 call_once(init_flag, std::bind(ystdex::construct_in<_type,
414 _tParams&&...>, std::ref(get()), std::ref(args)...));
415 }
416 ~call_once_init()
417 {
418 call_once(deinit_flag, std::bind(ystdex::destruct_in<_type>,
419 std::ref(get())));
420 }
421
423 YB_ATTR_nodiscard object_type&
424 get() ynothrow
425 {
426 return storage.template access<object_type>();
427 }
429 YB_ATTR_nodiscard const object_type&
430 get() const ynothrow
431 {
432 return storage.template access<const object_type>();
433 }
434 };
435
436 } // namespace ystdex;
437
438 #if !YB_HAS_BUILTIN_NULLPTR
439 using ystdex::nullptr;
440 #endif
441
442 #endif
443
ystdex::nifty_counter::nifty_counter
nifty_counter(_tParams &&... args)
Definition: utility.hpp:327
ystdex::forward_like
forward_like_t< _type, _type2 > forward_like(_type2 &&x)
按第一模板参数指定类型蕴含的值类别传递参数。
Definition: utility.hpp:57
YB_ATTR_nodiscard
#define YB_ATTR_nodiscard
标记返回值不被忽略的属性。
Definition: ydef.h:715
x
const EncapsulationBase & x
Definition: NPLA1Forms.cpp:1536
ystdex::nifty_counter
使用引用计数的静态初始化管理器。
Definition: utility.hpp:322
ystdex::cpp2014::conditional_t
typename conditional< _bCond, _type, _type2 >::type conditional_t
Definition: meta.hpp:202
ystdex::boxed_value::boxed_value
boxed_value()
Definition: utility.hpp:171
base.h
基类实用设施。
placement.hpp
放置对象管理操作。
ystdex::cpp2017::as_const
void as_const(const _type &&)=delete
ystdex::nifty_counter::get
static object_type & get()
Definition: utility.hpp:342
ystdex::nifty_counter::~nifty_counter
~nifty_counter()
Definition: utility.hpp:335
ystdex::cpp2014::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: meta.hpp:199
ystdex::exclude_self_params_t
enable_if_t< not_< cond_or_t< bool_< sizeof...(_tParams)==1 >, false_, is_same_param, _tSelected, _tParams... > >::value, void > exclude_self_params_t
排除选择类型的特定参数类型的重载。
Definition: type_op.hpp:295
ystdex::nifty_counter::get_object_ptr
static object_type *& get_object_ptr()
Definition: utility.hpp:357
ystdex::nifty_counter::use_count
static size_t use_count()
Definition: utility.hpp:366
swap.hpp
交换操作。
ystdex::call_once_init::get
object_type & get()
Definition: utility.hpp:424
ystdex::boxed_value::operator=
boxed_value & operator=(boxed_value &&)=default
ystdex::call_once_init::init_flag
flag_type init_flag
Definition: utility.hpp:402
ystdex::parameterize_static_object
_type & parameterize_static_object()
类型参数化静态对象。
Definition: utility.hpp:232
CHRLib::f
f(d, s)
ystdex::default_init_t
默认初始化标记。
Definition: placement.hpp:150
ystdex::boxed_value::operator=
boxed_value & operator=(const boxed_value &)=default
CHRLib::args
YB_ATTR_nodiscard _tParams && args
Definition: CharacterProcessing.h:649
ystdex::details::_type2
_type2
Definition: operators.hpp:241
yassume
#define yassume(_expr)
假定：环境语义。
Definition: cassert.h:96
ystdex::standard_layout_storage
任意标准布局类型对象提供空间的存储。
Definition: type_pun.hpp:308
ystdex::call_once_init< YSLib::GUIApplication::InitBlock, once_flag >::flag_type
once_flag flag_type
Definition: utility.hpp:398
ystdex::bases::nonmovable
不可转移对象：禁止继承此类的对象调用默认原型的转移构造函数和转移赋值操作符。
Definition: base.h:90
ystdex::nifty_counter::get_count
static size_t & get_count()
Definition: utility.hpp:350
ystdex::call_once_init::object_type
_type object_type
Definition: utility.hpp:397
ystdex::boxed_value::boxed_value
boxed_value(boxed_value &&)=default
ystdex::call_once_init::deinit_flag
flag_type deinit_flag
Definition: utility.hpp:404
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 转发对应参数。
Definition: ydef.h:1508
ystdex::boxed_value
包装类类型的值的对象。
Definition: utility.hpp:159
ystdex::decay_copy
enable_if_convertible_t< _type, decay_t< _type >, decay_t< _type > > decay_copy(_type &&arg)
退化复制。
Definition: utility.hpp:114
ystdex::boxed_value::value
_type value
Definition: utility.hpp:164
ystdex::call_once_init::~call_once_init
~call_once_init()
Definition: utility.hpp:416
ystdex::nifty_counter::object_type
_type object_type
Definition: utility.hpp:324
YB_STATELESS
#define YB_STATELESS
指示函数或函数模板实例为无状态函数。
Definition: ydef.h:941
std
Definition: optional.h:982
type_op.hpp
C++ 类型操作。
ystdex::get_init
auto get_init(_fInit &&f, _tParams &&... args) -> decltype(f(std::forward< decltype(args)>(args)...))&
取类型标识和初始化调用指定的对象。
Definition: utility.hpp:267
ystdex::single_thread::call_once
void call_once(once_flag &flag, _fCallable &&f, _tParams &&... args)
按标识调用函数，保证调用一次。
Definition: pseudo_mutex.h:1021
ystdex::call_once_init::call_once_init
call_once_init(_tParams &&... args)
Definition: utility.hpp:410
ystdex::classify_value_t
cond_t< std::is_class< _type >, _type, boxed_value< _type > > classify_value_t
包装非类类型为类类型。
Definition: utility.hpp:221
ystdex::call_once_init::get
const object_type & get() const
Definition: utility.hpp:430
YSLib::GUIApplication::InitBlock
Definition: GUIApplication.h:204
ystdex::cond_t
_t< cond< _tCond, _tThen, _tElse > > cond_t
Definition: meta.hpp:794
ystdex::boxed_value::boxed_value
boxed_value(const boxed_value &)=default
ystdex::cpp2014::underlying_type_t
typename underlying_type< _type >::type underlying_type_t
Definition: meta.hpp:208
ystdex::enable_if_convertible_t
enable_if_t< is_convertible< _tFrom, _tTo >::value, _type > enable_if_convertible_t
Definition: meta.hpp:837
ystdex::boxed_value::nothrow_default_constructible
details::is_nt_dc< _type > nothrow_default_constructible
Definition: utility.hpp:161
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
YSLib::_tParams
YB_ATTR_nodiscard YB_PURE typename _tParams
Definition: ValueNode.h:1294
ystdex::call_once_init::storage
replace_storage_t< _type > storage
Definition: utility.hpp:406
ystdex::underlying
enable_if_t< is_enum_union< _type >::value, wrapped_enum_traits_t< _type > > underlying(_type val)
Definition: enum.hpp:112
ystdex::construct_in
void construct_in(_type &obj, _tParams &&... args)
以值初始化原地构造。
Definition: placement.hpp:352
ystdex::cpp2014::remove_reference_t
typename remove_reference< _type >::type remove_reference_t
Definition: meta.hpp:155
ystdex::nullptr
const class ystdex::nullptr_t nullptr
ystdex::call_once_init
使用 call_once 的静态初始化管理器。
Definition: utility.hpp:395
ystdex::boxed_value::boxed_value
boxed_value(_tParams &&... args)
Definition: utility.hpp:185
platform::p
return p p
Definition: YCLib/FileSystem.h:209
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:413
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:1199
ystdex::bases::noncopyable
不可复制对象：禁止派生类调用默认原型的复制构造函数和复制赋值操作符。
Definition: base.h:50
ystdex::copy_or_move
_type copy_or_move(bool copy, _type &obj)
按参数复制或转移。
Definition: utility.hpp:96
ynoexcept
#define ynoexcept(...)
YSLib 无异常抛出保证：指定特定的异常规范。
Definition: ydef.h:1151
ythread
#define ythread
线程局部存储：若实现支持，指定为 thread_local 。
Definition: ydef.h:1243
ystdex::ref
void ref(const _type &&)=delete
ystdex::details::is_nt_dc
Definition: utility.hpp:136
ystdex::forward_like_t
conditional_t< is_lvalue_reference< _type >::value, remove_reference_t< _type2 > &, remove_reference_t< _type2 > && > forward_like_t
按指定类型蕴含的值类别传递参数的结果类型。
Definition: utility.hpp:52
ystdex::cpp2017::as_const
add_const_t< _type > & as_const(_type &t)
转换 const 引用。
Definition: utility.hpp:77
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:1073
NPL::_tParam
_tParam
Definition: NPLA.h:2367
ystdex::boxed_value::boxed_value
boxed_value(default_init_t)
Definition: utility.hpp:177
ystdex::and_
逻辑操作元函数。
Definition: integral_constant.hpp:151