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

#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);
}