YSTest  PreAlpha_b400_20130424
The YSLib Test Project
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
any.h
浏览该文件的文档.
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_any_h_
29 #define YB_INC_ystdex_any_h_ 1
30 
31 #include "type_op.hpp"
32 #include <memory> // for std::addressof, std::unique_ptr;
33 #include <typeinfo> // for typeid, std::bad_cast;
34 
35 namespace ystdex
36 {
37 
38 /*
39 \brief 用于表示任意不需要复制存储的非聚集 POD 类型。
40 \note POD 和聚集类型的含义参考 ISO C++11 。
41 \since build 352
42 \todo 确定整数和枚举类型的必要性。
43 */
45 {
46  void* object_ptr;
47  const void* const_object_ptr;
48  volatile void* volatile_object_ptr;
49  const volatile void* const_volatile_object_ptr;
50  void(*function_ptr)();
53 };
54 
55 
56 /*
57 \brief 任意 POD 类型存储。
58 \note POD 的含义参考 ISO C++11 。
59 \since build 351
60 */
61 template<typename _tPOD = typename aligned_storage<sizeof(void*)>::type>
63 {
64  static_assert(is_pod<_tPOD>::value, "Non-POD underlying type found.");
65 
66  typedef _tPOD underlying;
67 
69  byte data[sizeof(underlying)];
70 
72 
73  pod_storage() = default;
74  template<typename _type>
75  pod_storage(_type&& x)
76  {
77  new(access()) typename remove_reference<_type>::type(yforward(x));
78  }
79 
81  template<typename _type>
83  operator=(_type&& x)
84  {
85  access<typename remove_reference<_type>::type>() = yforward(x);
86  return *this;
87  }
89 
90  YB_PURE void*
92  {
93  return &data[0];
94  }
95  yconstfn YB_PURE const void*
96  access() const
97  {
98  return &data[0];
99  }
100  template<typename _type>
101  YB_PURE _type&
103  {
104  return *static_cast<_type*>(access());
105  }
106  template<typename _type>
107  yconstfn YB_PURE const _type&
108  access() const
109  {
110  return *static_cast<const _type*>(access());
111  }
112 };
113 
114 
121 class void_ref
122 {
123 private:
124  const volatile void* ptr;
125 
126 public:
127  template<typename _type>
128  yconstfn
129  void_ref(_type& obj)
130  : ptr(&obj)
131  {}
132 
133  template<typename _type>
134  yconstfn YB_PURE operator _type&()
135  {
136  return *static_cast<_type*>(&*this);
137  }
138 
139  YB_PURE void*
140  operator&() const volatile
141  {
142  return const_cast<void*>(ptr);
143  }
144 };
145 
146 
148 namespace any_ops
149 {
150 
155 class holder
156 {
157 public:
159 
160  holder() = default;
161  holder(const holder&) = default;
162  holder(holder&&) = default;
164  virtual
166  {}
167 
169  virtual void*
170  get() const = 0;
171 
172  virtual holder*
173  clone() const = 0;
174 
176  virtual const std::type_info&
177  type() const ynothrow = 0;
178 };
179 
180 
186 template<typename _type>
187 class value_holder : public holder
188 {
189  static_assert(is_object<_type>::value, "Non-object type found.");
190  static_assert(!(is_const<_type>::value || is_volatile<_type>::value),
191  "Cv-qualified type found.");
192 
193 public:
195  typedef _type value_type;
196 
197 protected:
199  mutable _type held;
200 
201 public:
202  value_holder(const _type& value)
203  : held(value)
204  {}
210  value_holder(_type&& value) ynoexcept(ynoexcept(_type(std::move(value))))
211  : held(std::move(value))
212  {}
213 
214  value_holder*
215  clone() const override
216  {
217  return new value_holder(held);
218  }
219 
221  void*
222  get() const override
223  {
224  return std::addressof(held);
225  }
226 
228  const std::type_info&
229  type() const ynothrow override
230  {
231  return typeid(_type);
232  }
233 };
234 
235 
242 template<typename _type>
243 class pointer_holder : public holder
244 {
245  static_assert(std::is_object<_type>::value, "Invalid type found.");
246 
247 public:
249  typedef _type value_type;
250 
251 protected:
253  _type* p_held;
254 
255 public:
256  pointer_holder(_type* value)
257  : p_held(value)
258  {}
260 
262  : pointer_holder(h.p_held ? new _type(*h.p_held) : nullptr)
263  {}
265  : p_held(h.p_held)
266  {
267  h.p_held = nullptr;
268  }
270  virtual
272  {
273  delete p_held;
274  }
275 
277  clone() const override
278  {
279  return new pointer_holder(*this);
280  }
281 
283  void*
284  get() const override
285  {
286  return p_held;
287  }
288 
290  const std::type_info&
291  type() const ynothrow override
292  {
293  return p_held ? typeid(_type) : typeid(void);
294  }
295 };
296 
297 
299 typedef std::uint32_t op_code;
300 
302 enum base_op : op_code
303 {
314 };
315 
316 
320 typedef void(*any_manager)(any_storage&, const any_storage&, op_code);
321 
322 
324 struct holder_tag
325 {};
327 
328 
333 template<typename _type, bool bStoredLocally = sizeof(_type)
334  <= sizeof(any_storage) && yalignof(_type) <= yalignof(any_storage)
335  && yalignof(any_storage) % yalignof(_type) == 0>
336 class value_handler
337 {
338 public:
340 
341  typedef _type value_type;
342  typedef integral_constant<bool, bStoredLocally> local_storage;
343 
344  static value_type*
345  get_pointer(const any_storage& s)
346  {
347  return const_cast<value_type*>(bStoredLocally ? std::addressof(
348  s.access<value_type>()) : s.access<const value_type*>());
349  }
351 
353  static value_type&
354  get_reference(const any_storage& s)
355  {
356  yassume(get_pointer(s));
357 
358  return *get_pointer(s);
359  }
360 
362  static void
363  copy(any_storage& d, const any_storage& s, true_type)
364  {
365  new(d.access()) value_type(s.access<value_type>());
366  }
368  static void
369  copy(any_storage& d, const any_storage& s, false_type)
370  {
371  d = new value_type(*s.access<value_type*>());
372  }
373 
375 
376  static void
377  uninit(any_storage& d, true_type)
378  {
379  d.access<value_type>().~value_type();
380  }
381  static void
382  uninit(any_storage& d, false_type)
383  {
384  delete d.access<value_type*>();
385  }
386 
387  template<typename _tValue>
388  static void
389  init(any_storage& d, _tValue&& x)
390  {
391  init_impl(d, yforward(x), local_storage());
392  }
394 
395 private:
397 
398  template<typename _tValue>
399  static void
400  init_impl(any_storage& d, _tValue&& x, true_type)
401  {
402  new(d.access()) value_type(yforward(x));
403  }
404  template<typename _tValue>
405  static void
406  init_impl(any_storage& d, _tValue&& x, false_type)
407  {
408  d = new value_type(yforward(x));
409  }
411 
412 public:
414  static void
415  manage(any_storage& d, const any_storage& s, op_code op)
416  {
417  switch(op)
418  {
419  case get_type:
420  d = &typeid(value_type);
421  break;
422  case get_ptr:
423  d = get_pointer(s);
424  break;
425  case clone:
426  copy(d, s, local_storage());
427  break;
428  case destroy:
429  uninit(d, local_storage());
430  break;
431  case get_holder_type:
432  d = &typeid(void);
433  break;
434  case get_holder_ptr:
435  d = static_cast<holder*>(nullptr);
436  }
437  }
438 };
439 
440 
445 template<typename _type>
446 class ref_handler : public value_handler<_type*>
447 {
448 public:
449  typedef _type value_type;
450  typedef value_handler<value_type*> base;
451 
453  static value_type*
454  get_pointer(const any_storage& s)
455  {
456  return base::get_reference(s);
457  }
458 
460  static value_type&
461  get_reference(const any_storage& s)
462  {
463  yassume(get_pointer(s));
464 
465  return *get_pointer(s);
466  }
467 
468  static void
469  init(any_storage& d, std::reference_wrapper<value_type> x)
470  {
471  base::init(d, std::addressof(x.get()));
472  }
473 
474  static void
475  manage(any_storage& d, const any_storage& s, op_code op)
476  {
477  switch(op)
478  {
479  case get_type:
480  d = &typeid(value_type);
481  break;
482  case get_ptr:
483  d = get_pointer(s);
484  break;
485  default:
486  base::manage(d, s, op);
487  }
488  }
489 };
490 
491 
496 template<typename _tHolder>
497 class holder_handler : public value_handler<_tHolder>
498 {
499  static_assert(is_convertible<_tHolder&, holder&>::value,
500  "Invalid holder type found.");
501 
502 public:
503  typedef typename _tHolder::value_type value_type;
504  typedef value_handler<_tHolder> base;
505  typedef typename base::local_storage local_storage;
506 
507  static value_type*
508  get_pointer(const any_storage& s)
509  {
510  return static_cast<value_type*>(base::get_pointer(s)->_tHolder::get());
511  }
512 
513 private:
515  static void
516  init(any_storage& d, std::unique_ptr<_tHolder> p, true_type)
517  {
518  new(d.access()) _tHolder(std::move(*p));
519  }
521  static void
522  init(any_storage& d, std::unique_ptr<_tHolder> p, false_type)
523  {
524  d = p.release();
525  }
526 
527 public:
529  static void
530  init(any_storage& d, std::unique_ptr<_tHolder> p)
531  {
532  init(d, std::move(p), local_storage());
533  }
534  static void
535  init(any_storage& d, _tHolder&& x)
536  {
537  base::init(d, std::move(x));
538  }
539  template<typename... _tParams>
540  static void
541  init(any_storage& d, _tParams&&... args)
542  {
543  init(d, _tHolder(yforward(args)...));
544  }
545 
546  static void
547  manage(any_storage& d, const any_storage& s, op_code op)
548  {
549  switch(op)
550  {
551  case get_type:
552  d = &typeid(value_type);
553  break;
554  case get_ptr:
555  d = get_pointer(s);
556  break;
557  case clone:
558  base::copy(d, s, local_storage());
559  break;
560  case destroy:
561  base::uninit(d, local_storage());
562  break;
563  case get_holder_type:
564  d = &typeid(_tHolder);
565  break;
566  case get_holder_ptr:
567  d = static_cast<holder*>(base::get_pointer(s));
568  }
569  }
570 };
571 
572 } // namespace any_ops;
573 
574 
584 class YB_API any
585 {
586 protected:
590  any_ops::any_manager manager;
592 
593 public:
596  any() ynothrow
597  : storage(), manager()
598  {}
600 
601  template<typename _type, typename = typename
602  std::enable_if<!is_same<_type&, any&>::value, int>::type>
603  any(_type&& x)
604  : manager(any_ops::value_handler<typename
605  remove_reference<_type>::type>::manage)
606  {
607  any_ops::value_handler<typename remove_rcv<_type>::type>::init(storage,
608  yforward(x));
609  }
610  template<typename _type>
611  any(std::reference_wrapper<_type> x)
612  : manager(any_ops::ref_handler<_type>::manage)
613  {
614  any_ops::ref_handler<_type>::init(storage, x);
615  }
620  template<typename _tHolder>
621  any(any_ops::holder_tag, std::unique_ptr<_tHolder> p)
622  : manager(any_ops::holder_handler<_tHolder>::manage)
623  {
624  any_ops::holder_handler<_tHolder>::init(storage, std::move(p));
625  }
626  template<typename _type>
627  any(_type&& x, any_ops::holder_tag)
628  : manager(any_ops::holder_handler<any_ops::value_holder<typename
629  remove_rcv<_type>::type>>::manage)
630  {
631  any_ops::holder_handler<any_ops::value_holder<typename
632  remove_cv<_type>::type>>::init(storage, yforward(x));
633  }
635  any(const any&);
636  any(any&& a) ynothrow
637  : any()
638  {
639  a.swap(*this);
640  }
642  ~any();
644  template<typename _type>
645  any&
646  operator=(const _type& x)
647  {
648  any(x).swap(*this);
649  return *this;
650  }
655  any&
656  operator=(const any& a)
657  {
658  any(a).swap(*this);
659  return *this;
660  }
665  any&
666  operator=(any&& a) ynothrow
667  {
668  any(std::move(a)).swap(*this);
669  return *this;
670  }
671 
672  bool
673  operator!() const ynothrow
674  {
675  return empty();
676  }
677 
678  explicit
679  operator bool() const ynothrow
680  {
681  return !empty();
682  }
683 
684  bool
685  empty() const ynothrow
686  {
687  return !manager;
688  }
689 
691  void*
692  get() const ynothrow;
693 
694  any_ops::holder*
695  get_holder() const;
696 
697  void
698  clear() ynothrow;
699 
700  void
701  swap(any& a) ynothrow;
702 
704 
705  template<typename _type>
706  _type*
707  target() ynothrow
708  {
709  return type() == typeid(_type) ? static_cast<_type*>(get()) : nullptr;
710  }
711  template<typename _type>
712  const _type*
713  target() const ynothrow
714  {
715  return type() == typeid(_type)
716  ? static_cast<const _type*>(get()) : nullptr;
717  }
719 
721  const std::type_info&
722  type() const ynothrow;
723 };
724 
725 
732 class bad_any_cast : public std::bad_cast
733 {
734 private:
736  const char* from_name;
738  const char* to_name;
739 
740 public:
742 
743  bad_any_cast()
744  : std::bad_cast(),
745  from_name("unknown"), to_name("unknown")
746  {};
747  bad_any_cast(const std::type_info& from_type, const std::type_info& to_type)
748  : std::bad_cast(),
749  from_name(from_type.name()), to_name(to_type.name())
750  {}
751 
752  const char*
753  from() const ynothrow
754  {
755  return from_name;
756  }
757 
758  const char*
759  to() const ynothrow
760  {
761  return to_name;
762  }
764 
765  virtual const char*
766  what() const ynothrow override
767  {
768  return "Failed conversion: any_cast.";
769  }
770 };
771 
772 
785 template<typename _tPointer>
786 inline _tPointer
787 any_cast(any* p) ynothrow
788 {
789  return p ? p->target<typename remove_pointer<_tPointer>::type>() : nullptr;
790 }
791 template<typename _tPointer>
792 inline _tPointer
793 any_cast(const any* p) ynothrow
794 {
795  return p ? p->target<typename remove_pointer<_tPointer>::type>() : nullptr;
796 }
798 
803 template<typename _tValue>
804 inline _tValue
805 any_cast(any& x)
806 {
807  const auto tmp(any_cast<typename remove_reference<_tValue>::type*>(&x));
808 
809  if(!tmp)
810  throw bad_any_cast(x.type(), typeid(_tValue));
811  return static_cast<_tValue>(*tmp);
812 }
813 template<typename _tValue>
814 _tValue
815 any_cast(const any& x)
816 {
817  const auto tmp(any_cast<typename remove_reference<_tValue>::type*>(&x));
818 
819  if(!tmp)
820  throw bad_any_cast(x.type(), typeid(_tValue));
821  return static_cast<_tValue>(*tmp);
822 }
824 
825 
833 template<typename _type>
834 inline _type*
835 unsafe_any_cast(any* p)
836 {
837  yconstraint(p);
838 
839  return static_cast<_type*>(p->get());
840 }
841 
842 template<typename _type>
843 inline const _type*
844 unsafe_any_cast(const any* p)
845 {
846  yconstraint(p);
847 
848  return static_cast<const _type*>(p->get());
849 }
851 
852 
858 struct pseudo_output
859 {
860  template<typename... _tParams>
861  inline pseudo_output&
862  operator=(_tParams&&...)
863  {
864  return *this;
865  }
866 };
867 
868 } // namespace ystdex;
869 
870 
871 namespace std
872 {
873 
878 inline void
879 swap(ystdex::any& x, ystdex::any& y) ynothrow
880 {
881  x.swap(y);
882 }
883 
884 } // namespace std;
885 
886 #endif
887