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.
118 lines
2.6 KiB
118 lines
2.6 KiB
|
|
#include <memory> |
|
#include <type_traits> |
|
|
|
class C { |
|
protected: |
|
struct Protected { |
|
private: |
|
Protected() {}; |
|
public: |
|
static Protected make() { return { }; } |
|
}; |
|
int m_x; |
|
|
|
private: |
|
struct Private { |
|
private: |
|
Private() {}; |
|
public: |
|
static Private make() { return { }; } |
|
}; |
|
int m_y; |
|
|
|
public: |
|
/* private constructor: */ |
|
C(Private, int x, int y) : m_x(x), m_y(y) { } |
|
/* protected constructor: */ |
|
C(Protected, int x) : C(Private::make(), x, 2*x) { } |
|
|
|
void leak_private_type(Private) { } |
|
|
|
static std::unique_ptr<C> Create(int x) { |
|
return std::unique_ptr<C>(new C(Private::make(), x, 2*x)); |
|
} |
|
}; |
|
|
|
class D : public C { |
|
private: |
|
struct Private { }; |
|
public: |
|
D(Private&, int x) : C(Protected::make(), x) { } |
|
|
|
static std::shared_ptr<D> Create(int x) { |
|
Private p; |
|
return std::make_shared<D>(p, 4*x); |
|
} |
|
}; |
|
|
|
|
|
class A { |
|
struct this_is_private { |
|
}; |
|
|
|
public: |
|
explicit A(const this_is_private &, int) {} |
|
|
|
static ::std::shared_ptr<A> create(int x) { |
|
return ::std::make_shared<A>(this_is_private{}, x); |
|
} |
|
|
|
protected: |
|
A(const A &) = delete; |
|
const A &operator =(const A &) = delete; |
|
}; |
|
|
|
::std::shared_ptr<A> foo(int x) |
|
{ |
|
return A::create(x); |
|
} |
|
|
|
|
|
/* usage: decltype(return_args(&Class::memberfunction)) */ |
|
template<typename Base, typename Result, typename... Args> |
|
std::tuple<Args...> return_args(Result (Base::*func)(Args...)); |
|
|
|
/* usage: decltype(result_of(&Class::memberfunction)) */ |
|
template<typename Base, typename Result, typename... Args> |
|
Result result_of(Result (Base::*func)(Args...)); |
|
|
|
/* usage: decay_tuple_element<0, decltype(return_args(&Class::memberfunction))> */ |
|
template <size_t i, typename Tuple> |
|
using decay_tuple_element = typename std::decay<typename std::tuple_element<i, Tuple>::type>::type; |
|
|
|
|
|
struct _is_static_castable_impl |
|
{ |
|
template<typename _From, typename _To, typename = decltype(static_cast<_To>(std::declval<_From>()))> |
|
static std::true_type __test(int); |
|
|
|
template<typename, typename> |
|
static std::false_type __test(...); |
|
}; |
|
|
|
template<typename _From, typename _To> |
|
struct is_static_castable |
|
: public _is_static_castable_impl |
|
{ |
|
typedef decltype(__test<_From, _To>(0)) type; |
|
}; |
|
|
|
template<typename _From, typename _To> |
|
using is_static_castable_t = typename is_static_castable<_From, _To>::type; |
|
|
|
|
|
|
|
int main() { |
|
auto c = C::Create(0); |
|
auto d = D::Create(0); |
|
|
|
typedef decay_tuple_element<0, decltype(return_args(&C::leak_private_type))> Private; |
|
Private::make(); |
|
|
|
|
|
auto a1 = foo(0); |
|
auto a2 = std::shared_ptr<A>(new A({}, 0)); |
|
|
|
// C c1({}, 0, 0); |
|
}
|
|
|