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 */
43 {
44 protected:
49  yconstfn
50  noncopyable() = default;
54  ~noncopyable() = default;
55 
56 public:
60  yconstfn
61  noncopyable(const noncopyable&) = delete;
62 
67  operator=(const noncopyable&) = delete;
68 };
69 
70 
71 /*
72 \brief 不可转移对象:禁止继承此类的对象调用默认原型的转移构造函数和转移赋值操作符。
73 \warning 非虚析构。
74 \since build 373
75 */
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&
184 {
185  static _type obj;
186 
187  return obj;
188 }
195 template<typename _type, size_t...>
196 inline _type&
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>
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  }
281  {
282  if(--get_count() == 0)
283  delete get_object_ptr();
284  }
285 
286  static object_type&
287  get()
288  {
290 
291  return *get_object_ptr();
292  }
293 
294 private:
295  static count_type&
297  {
298  static count_type count;
299 
300  return count;
301  }
302  static object_type*&
304  {
305  static object_type* ptr;
306 
307  return ptr;
308  }
309 
310 public:
311  static count_type
313  {
314  return get_count();
315  }
316 };
317 
318 
338 template<typename _type, typename _tOnceFlag>
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  }
351  {
353  }
354 
355  static object_type&
356  get()
357  {
359 
360  return *get_object_ptr();
361  }
362 
363 private:
364  static flag_type&
366  {
367  static flag_type flag;
368 
369  return flag;
370  }
371 
372  static object_type*&
374  {
375  static object_type* ptr;
376 
377  return ptr;
378  }
379 
380  static flag_type&
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
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