You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
2.6KB

  1. #include <memory>
  2. #include <type_traits>
  3. class C {
  4. protected:
  5. struct Protected {
  6. private:
  7. Protected() {};
  8. public:
  9. static Protected make() { return { }; }
  10. };
  11. int m_x;
  12. private:
  13. struct Private {
  14. private:
  15. Private() {};
  16. public:
  17. static Private make() { return { }; }
  18. };
  19. int m_y;
  20. public:
  21. /* private constructor: */
  22. C(Private, int x, int y) : m_x(x), m_y(y) { }
  23. /* protected constructor: */
  24. C(Protected, int x) : C(Private::make(), x, 2*x) { }
  25. void leak_private_type(Private) { }
  26. static std::unique_ptr<C> Create(int x) {
  27. return std::unique_ptr<C>(new C(Private::make(), x, 2*x));
  28. }
  29. };
  30. class D : public C {
  31. private:
  32. struct Private { };
  33. public:
  34. D(Private&, int x) : C(Protected::make(), x) { }
  35. static std::shared_ptr<D> Create(int x) {
  36. Private p;
  37. return std::make_shared<D>(p, 4*x);
  38. }
  39. };
  40. class A {
  41. struct this_is_private {
  42. };
  43. public:
  44. explicit A(const this_is_private &, int) {}
  45. static ::std::shared_ptr<A> create(int x) {
  46. return ::std::make_shared<A>(this_is_private{}, x);
  47. }
  48. protected:
  49. A(const A &) = delete;
  50. const A &operator =(const A &) = delete;
  51. };
  52. ::std::shared_ptr<A> foo(int x)
  53. {
  54. return A::create(x);
  55. }
  56. /* usage: decltype(return_args(&Class::memberfunction)) */
  57. template<typename Base, typename Result, typename... Args>
  58. std::tuple<Args...> return_args(Result (Base::*func)(Args...));
  59. /* usage: decltype(result_of(&Class::memberfunction)) */
  60. template<typename Base, typename Result, typename... Args>
  61. Result result_of(Result (Base::*func)(Args...));
  62. /* usage: decay_tuple_element<0, decltype(return_args(&Class::memberfunction))> */
  63. template <size_t i, typename Tuple>
  64. using decay_tuple_element = typename std::decay<typename std::tuple_element<i, Tuple>::type>::type;
  65. struct _is_static_castable_impl
  66. {
  67. template<typename _From, typename _To, typename = decltype(static_cast<_To>(std::declval<_From>()))>
  68. static std::true_type __test(int);
  69. template<typename, typename>
  70. static std::false_type __test(...);
  71. };
  72. template<typename _From, typename _To>
  73. struct is_static_castable
  74. : public _is_static_castable_impl
  75. {
  76. typedef decltype(__test<_From, _To>(0)) type;
  77. };
  78. template<typename _From, typename _To>
  79. using is_static_castable_t = typename is_static_castable<_From, _To>::type;
  80. int main() {
  81. auto c = C::Create(0);
  82. auto d = D::Create(0);
  83. typedef decay_tuple_element<0, decltype(return_args(&C::leak_private_type))> Private;
  84. Private::make();
  85. auto a1 = foo(0);
  86. auto a2 = std::shared_ptr<A>(new A({}, 0));
  87. // C c1({}, 0, 0);
  88. }