YSTest  PreAlpha_b400_20130424
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
type_op.hpp
浏览该文件的文档.
1 /*
2  Copyright by FrankHB 2011 - 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_type_op_hpp_
29 #define YB_INC_ystdex_type_op_hpp_ 1
30 
31 #include "../ydef.h" // for <type_traits> and std::declval;
32 
33 namespace ystdex
34 {
35 
36 #if 0
37 using std::tr1::add_reference;
38 
39 using std::tr1::has_nothrow_assign;
40 using std::tr1::has_nothrow_constructor;
41 using std::tr1::has_nothrow_copy;
42 using std::tr1::has_trivial_assign;
43 using std::tr1::has_trivial_constructor;
44 using std::tr1::has_trivial_copy;
45 using std::tr1::has_trivial_destructor;
46 #endif
47 
48 using std::integral_constant;
49 using std::true_type;
50 using std::false_type;
51 
52 using std::is_void;
53 using std::is_integral;
54 using std::is_floating_point;
55 using std::is_array;
56 using std::is_pointer;
57 using std::is_lvalue_reference;
58 using std::is_rvalue_reference;
59 using std::is_member_object_pointer;
60 using std::is_member_function_pointer;
61 using std::is_enum;
62 using std::is_class;
63 using std::is_union;
64 using std::is_function;
65 
66 using std::is_reference;
67 using std::is_arithmetic;
68 using std::is_fundamental;
69 using std::is_object;
70 using std::is_scalar;
71 using std::is_compound;
72 using std::is_member_pointer;
73 
74 using std::is_const;
75 using std::is_volatile;
76 using std::is_trivial;
77 // using std::is_trivially_copyable;
78 using std::is_standard_layout;
79 using std::is_pod;
80 using std::is_literal_type;
81 using std::is_empty;
82 using std::is_polymorphic;
83 using std::is_abstract;
84 
85 using std::is_signed;
86 using std::is_unsigned;
87 
88 using std::is_constructible;
89 #if 0
90 using std::is_default_constructible;
91 using std::is_copy_constructible;
92 using std::is_move_constructible;
93 
94 using std::is_assignable;
95 using std::is_copy_assignable;
96 using std::is_move_assignable;
97 
98 using std::is_destructible;
99 
100 using std::is_trivially_constructible;
101 using std::is_trivially_default_constructible;
102 using std::is_trivially_copy_constructible;
103 using std::is_trivially_move_constructible;
104 
105 using std::is_trivially_assignable;
106 using std::is_trivially_copy_assignable;
107 using std::is_trivially_move_assignable;
108 using std::is_trivially_destructible;
109 
110 using std::is_nothrow_constructible;
111 using std::is_nothrow_default_constructible;
112 using std::is_nothrow_copy_constructible;
113 using std::is_nothrow_move_constructible;
114 
115 using std::is_nothrow_assignable;
116 using std::is_nothrow_copy_assignable;
117 using std::is_nothrow_move_assignable;
118 
119 using std::is_nothrow_destructible;
120 #endif
121 using std::has_virtual_destructor;
122 
123 using std::alignment_of;
124 using std::rank;
125 using std::extent;
126 
127 using std::is_same;
128 using std::is_base_of;
129 using std::is_convertible;
130 
131 using std::remove_const;
132 using std::remove_volatile;
133 using std::remove_cv;
134 using std::add_const;
135 using std::add_volatile;
136 using std::add_cv;
137 
138 using std::remove_reference;
139 using std::add_lvalue_reference;
140 using std::add_rvalue_reference;
141 
142 using std::make_signed;
143 using std::make_unsigned;
144 
145 using std::remove_extent;
146 using std::remove_all_extents;
147 
148 using std::remove_pointer;
149 using std::add_pointer;
150 
151 using std::aligned_storage;
152 using std::decay;
153 using std::enable_if;
154 using std::conditional;
155 using std::common_type;
156 // using std::underlying_type;
157 using std::result_of;
158 
159 
212 template<typename _type>
213 struct is_returnable : integral_constant<bool, !is_array<_type>::value
214  && !is_abstract<_type>::value && !is_function<_type>::value>
215 {};
216 
217 
223 template<typename _type>
224 struct is_decayable : integral_constant<bool,
225  !is_same<typename decay<_type>::type, _type>::value>
226 {};
227 
228 
234 template<typename _type>
235 struct is_class_pointer : integral_constant<bool, is_pointer<_type>::value
236  && is_class<typename remove_pointer<_type>::type>::value>
237 {};
238 
239 
245 template<typename _type>
246 struct is_lvalue_class_reference : integral_constant<bool, !is_lvalue_reference<
247  _type>::value && is_class<typename remove_reference<_type>::type>::value>
248 {};
249 
250 
257 template<typename _type>
258 struct is_rvalue_class_reference : integral_constant<bool, !is_lvalue_reference<
259  _type>::value && is_class<typename remove_reference<_type>::type>::value>
260 {};
261 
262 
269 template<typename _type>
270 struct is_pod_struct : integral_constant<bool,
271  is_pod<_type>::value && is_class<_type>::value>
272 {};
273 
274 
281 template<typename _type>
282 struct is_pod_union : integral_constant<bool,
283  is_pod<_type>::value && is_union<_type>::value>
284 {};
285 
286 
287 namespace details
288 {
289 
290 #ifdef YB_IMPL_GNUCPP
291 # if YB_IMPL_GNUCPP >= 40600
292 # pragma GCC diagnostic push
293 # pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
294 # else
295 # pragma GCC system_header
296 //临时处理:关闭所有警告。
297 /*
298 关闭编译警告:(C++ only) Ambiguous virtual bases. ,
299 参见 http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html 。
300 */
301 # endif
302 #endif
303 
304 
310 #define YB_TYPE_OP_TEST_2(_n, _expr) \
311  template<typename _type1, typename _type2> \
312  struct _n \
313  { \
314  private: \
315  template<typename _type> \
316  static yconstfn bool \
317  test(int, typename enable_if<(_expr), int>::type = 0) \
318  { \
319  return true; \
320  } \
321  template<typename> \
322  static yconstfn bool \
323  test(...) \
324  { \
325  return false; \
326  } \
327  \
328  public: \
329  static yconstexpr bool value = test(); \
330  };
331 
332 
338 YB_TYPE_OP_TEST_2(have_equality_operator, (is_convertible<decltype(std::declval<
339  _type>() == std::declval<_type2>()), bool>::value))
340 
341 
342 
343 YB_TYPE_OP_TEST_2(has_subscription, !is_void<decltype(std::declval<_type>()[
344  std::declval<_type2>()])>::value)
345 
346 
347 #if YB_IMPL_GNUCPP && YB_IMPL_GNUCPP >= 40600
348 //# pragma GCC diagnostic warning "-Wctor-dtor-privacy"
349 # pragma GCC diagnostic pop
350 #endif
351 
352 
356 template<class _type>
358 {
359  static_assert(std::is_class<_type>::value,
360  "Non-class type found @ ystdex::has_nonempty_virtual_base;");
361 
362 private:
363  struct A : _type
364  {
366  {}
367  };
368  struct B : _type
369  {
370  ~B() ynothrow
371  {}
372  };
373  struct C : A, B
374  {
375  ~C() ynothrow
376  {}
377  };
378 
379 public:
380  static yconstexpr bool value = sizeof(C) < sizeof(A) + sizeof(B);
381 };
382 
383 
387 template<class _type1, class _type2>
388 struct have_common_nonempty_virtual_base
389 {
390  static_assert(std::is_class<_type1>::value
391  && std::is_class<_type2>::value,
392  "Non-class type found @ ystdex::has_common_nonempty_virtual_base;");
393 
394 private:
395  struct A : virtual _type1
396  {
397  ~A() ynothrow
398  {}
399  };
400 
401 #ifdef YB_IMPL_GNUCPP
402 # if YB_IMPL_GNUCPP >= 40600
403 # pragma GCC diagnostic push
404 # pragma GCC diagnostic ignored "-Wextra"
405 # else
406 # pragma GCC system_header
407 # endif
408 #endif
409 
410  struct B : virtual _type2
411  {
413  {}
414  };
415  struct C : A, B
416  {
417  ~C() ynothrow
418  {}
419  };
420 
421 #if YB_IMPL_GNUCPP && YB_IMPL_GNUCPP >= 40600
422 //# pragma GCC diagnostic warning "-Wextra"
423 # pragma GCC diagnostic pop
424 #endif
425 
426 public:
427  static yconstexpr bool value = sizeof(C) < sizeof(A) + sizeof(B);
428 };
429 
430 } // namespace details;
431 
432 
438 template<typename _type1, typename _type2>
439 struct has_subscription : details::has_subscription<_type1, _type2>
440 {};
441 
442 
448 template<typename _type1, typename _type2>
449 struct has_equality_operator : integral_constant<bool,
450  details::have_equality_operator<_type1, _type2>::value>
451 {};
452 
453 
459 template<class _type>
460 struct has_nonempty_virtual_base : integral_constant<bool,
461  details::have_nonempty_virtual_base<_type>::value>
462 {};
463 
464 
470 template<class _type1, class _type2>
471 struct has_common_nonempty_virtual_base : integral_constant<bool,
472  details::have_common_nonempty_virtual_base<_type1, _type2>::value>
473 {};
474 
475 
483 template<typename _type>
484 struct identity
485 {
486  typedef _type type;
487 };
488 
489 
496 template<typename _type>
497 struct remove_rcv
498 {
499  typedef typename remove_cv<typename remove_reference<_type>::type>::type
500  type;
501 };
502 
503 
510 template<typename _type>
511 struct remove_rp
512 {
513  typedef typename remove_pointer<typename remove_reference<_type>
515 };
516 
517 
523 template<typename _type>
524 struct remove_rpcv
525 {
526  typedef typename remove_cv<typename remove_rp<_type>::type>::type type;
527 };
528 
529 
530 
538 template<typename _type>
539 struct array_decay
540 {
541  typedef typename conditional<is_array<_type>::value,
542  typename decay<_type>::type, _type>::type type;
543 };
544 
545 
554 template<typename _type>
555 struct qualified_decay
556 {
557 private:
558  typedef typename remove_reference<_type>::type value_type;
559 
560 public:
561  typedef typename conditional<is_function<value_type>::value
562  || is_array<value_type>::value, typename decay<_type>::type,
563  _type>::type type;
564 };
565 
566 
576 template<typename _type>
578 {
579  typedef typename array_decay<_type>::type type;
580 };
581 
582 template<typename _type>
583 struct array_ref_decay<_type&>
584 {
585  typedef typename array_decay<_type>::type type;
586  typedef type& reference;
587 };
588 
589 template<typename _type>
590 struct array_ref_decay<_type&&>
591 {
592  typedef typename array_decay<_type>::type type;
593  typedef type&& reference;
594 };
596 
597 
603 template<typename _tInt>
604 struct integer_width
605  : public integral_constant<size_t, sizeof(_tInt) * CHAR_BIT>
606 {};
607 
608 
615 template<typename _type, bool>
617 {
618  typedef typename std::make_signed<_type>::type type;
619 };
620 
621 template<typename _type>
622 struct make_signed_c<_type, false>
623 {
624  typedef typename std::make_unsigned<_type>::type type;
625 };
627 
628 
635 template<size_t>
636 struct make_fixed_width_int
637 {
638  typedef int type;
639  typedef unsigned unsigned_type;
640 };
641 
642 template<>
643 struct make_fixed_width_int<8U>
644 {
645  typedef std::int8_t type;
646  typedef std::uint8_t unsigned_type;
647 };
648 
649 template<>
650 struct make_fixed_width_int<16U>
651 {
652  typedef std::int16_t type;
653  typedef std::uint16_t unsigned_type;
654 };
655 
656 template<>
657 struct make_fixed_width_int<32U>
658 {
659  typedef std::int32_t type;
660  typedef std::uint32_t unsigned_type;
661 };
662 
663 template<>
664 struct make_fixed_width_int<64U>
665 {
666  typedef std::int64_t type;
667  typedef std::uint64_t unsigned_type;
668 };
670 
671 
682 template<size_t _vN>
683 struct n_tag
684 {
685  typedef n_tag<_vN - 1> type;
686 };
687 
688 template<>
689 struct n_tag<0>
690 {
691  typedef void type;
692 };
694 
700 
705 typedef n_tag<1> second_tag;
706 
712 template<size_t... _vSeq>
713 struct variadic_sequence
714 {};
716 
717 
724 template<class>
725 struct make_successor;
726 
727 template<size_t... _vSeq>
728 struct make_successor<variadic_sequence<_vSeq...>>
729 {
730  typedef variadic_sequence<_vSeq..., sizeof...(_vSeq)> type;
731 };
733 
734 
741 template<size_t _vN>
743 {
744  typedef typename make_successor<typename
746 };
747 
748 template<>
749 struct make_natural_sequence<0>
750 {
751  typedef variadic_sequence<> type;
752 };
754 
755 } // namespace ystdex;
756 
757 #endif
758