119 lines
2.6 KiB
C++
119 lines
2.6 KiB
C++
|
|
#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);
|
|
}
|