YSTest: utility.hpp 源文件

YSTest PreAlpha_b400_20130424 The YSLib Test Project

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

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
utility.hpp
浏览该文件的文档.
1 ﻿/*
2 Copyright by FrankHB 2010 - 2013.
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_op.hpp" // for ../ydef.h, ystdex::qualified_decay;
32 #include <utility>
33
34 namespace ystdex
35 {
36
37 /*
38 \brief 不可复制对象：禁止继承此类的对象调用默认原型的复制构造函数和复制赋值操作符。
39 \warning 非虚析构。
40 \since build 373
41 */
42 class noncopyable
43 {
44 protected:
49 yconstfn
50 noncopyable() = default;
54 ~noncopyable() = default;
55
56 public:
60 yconstfn
61 noncopyable(const noncopyable&) = delete;
62
66 noncopyable&
67 operator=(const noncopyable&) = delete;
68 };
69
70
71 /*
72 \brief 不可转移对象：禁止继承此类的对象调用默认原型的转移构造函数和转移赋值操作符。
73 \warning 非虚析构。
74 \since build 373
75 */
76 class nonmovable
77 {
78 protected:
83 yconstfn
84 nonmovable() = default;
88 ~nonmovable() = default;
89
90 public:
94 yconstfn
95 nonmovable(const nonmovable&) = delete;
96
100 nonmovable&
101 operator=(const nonmovable&) = delete;
102 };
103
104
112 template<typename _type>
113 typename decay<_type>::type
114 decay_copy(_type&& arg)
115 {
116 return std::forward<_type>(arg);
117 }
118
119
126 template<typename _type>
127 typename qualified_decay<_type>::type
128 decay_forward(_type&& arg)
129 {
130 return std::forward<_type>(arg);
131 }
132
133
140 template<typename _type, size_t _vN>
141 yconstfn size_t
142 arrlen(_type(&)[_vN])
143 {
144 return _vN;
145 }
146 template<typename _type, size_t _vN>
147 yconstfn size_t
148 arrlen(_type(&&)[_vN])
149 {
150 return _vN;
151 }
153
154
163 template<typename _fCallable, typename... _tParams>
164 inline void
165 call_once(bool& b, _fCallable&& f, _tParams&&... args)
166 {
167 if(!b)
168 {
169 f(yforward(args)...);
170 b = true;
171 }
172 }
173
174
181 template<typename _type, typename, typename...>
182 inline _type&
183 parameterize_static_object()
184 {
185 static _type obj;
186
187 return obj;
188 }
195 template<typename _type, size_t...>
196 inline _type&
197 parameterize_static_object()
198 {
199 static _type obj;
200
201 return obj;
202 }
203
204
214 template<typename _tKey, typename... _tKeys, typename _fInit,
215 typename... _tParams>
216 inline auto
217 get_init(_fInit&& f, _tParams&&... args) -> decltype(f(yforward(args)...))&
218 {
219 typedef decltype(f(yforward(args)...)) obj_type;
220
221 auto& p(ystdex::parameterize_static_object<obj_type*, _tKey, _tKeys...>());
222
223 if(!p)
224 p = new obj_type(f(yforward(args)...));
225 return *p;
226 }
235 template<size_t... _vKeys, typename _fInit, typename... _tParams>
236 inline auto
237 get_init(_fInit&& f, _tParams&&... args) -> decltype(f(yforward(args)...))&
238 {
239 typedef decltype(f(yforward(args)...)) obj_type;
240
241 auto& p(ystdex::parameterize_static_object<obj_type*, _vKeys...>());
242
243 if(!p)
244 p = new obj_type(f(yforward(args)...));
245 return *p;
246 }
247
248
267 template<class _type, typename _tCount = size_t>
268 class nifty_counter
269 {
270 public:
271 typedef _type object_type;
272 typedef _tCount count_type;
273
274 template<typename... _tParams>
275 nifty_counter(_tParams&&... args)
276 {
277 if(get_count()++ == 0)
278 get_object_ptr() = new _type(yforward(args)...);
279 }
280 ~nifty_counter()
281 {
282 if(--get_count() == 0)
283 delete get_object_ptr();
284 }
285
286 static object_type&
287 get()
288 {
289 yassume(get_object_ptr());
290
291 return *get_object_ptr();
292 }
293
294 private:
295 static count_type&
296 get_count()
297 {
298 static count_type count;
299
300 return count;
301 }
302 static object_type*&
303 get_object_ptr()
304 {
305 static object_type* ptr;
306
307 return ptr;
308 }
309
310 public:
311 static count_type
312 use_count()
313 {
314 return get_count();
315 }
316 };
317
318
338 template<typename _type, typename _tOnceFlag>
339 class call_once_init
340 {
341 public:
342 typedef _type object_type;
343 typedef _tOnceFlag flag_type;
344
345 template<typename... _tParams>
346 call_once_init(_tParams&&... args)
347 {
348 call_once(get_init_flag(), init<_tParams...>, yforward(args)...);
349 }
350 ~call_once_init()
351 {
352 call_once(get_uninit_flag(), uninit);
353 }
354
355 static object_type&
356 get()
357 {
358 yassume(get_object_ptr());
359
360 return *get_object_ptr();
361 }
362
363 private:
364 static flag_type&
365 get_init_flag()
366 {
367 static flag_type flag;
368
369 return flag;
370 }
371
372 static object_type*&
373 get_object_ptr()
374 {
375 static object_type* ptr;
376
377 return ptr;
378 }
379
380 static flag_type&
381 get_uninit_flag()
382 {
383 static flag_type flag;
384
385 return flag;
386 }
387
388 template<typename... _tParams>
389 static void
390 init(_tParams&&... args)
391 {
392 get_object_ptr() = new object_type(yforward(args)...);
393 }
394
395 static void
396 uninit()
397 {
398 delete get_object_ptr();
399 }
400 };
401
402 } // namespace ystdex;
403
404 #if !YB_HAS_BUILTIN_NULLPTR
405 using ystdex::nullptr;
406 #endif
407
408 #endif
409