#include #include #include #include #include template< class ... > using void_t = void; template< class T , class = void > struct is_dereferenceable : std::false_type { }; template< class T > struct is_dereferenceable::operator* )>> : std::true_type { typedef std::result_of_t::operator*)(T)> result; }; template< class T > struct is_dereferenceable>::value && std::is_pointer>::value > > : std::true_type { typedef std::add_lvalue_reference_t>> result; }; template< class T > constexpr bool is_dereferenceable_v = is_dereferenceable::value; template< class T , class = void > struct has_arrow_operator : std::false_type { }; template< class T > struct has_arrow_operator::operator-> )>> : std::true_type { typedef typename std::result_of_t::operator->)(T)> result; }; template< class T > struct has_arrow_operator>::value>> : std::true_type { typedef std::remove_reference_t result; }; template< class T > constexpr bool has_arrow_operator_v = has_arrow_operator::value; template< class T , class = void > struct is_model_of_pointer : std::false_type { }; template< class T > struct is_model_of_pointer() && has_arrow_operator() && std::is_same< std::remove_pointer_t::result>, std::remove_reference_t::result> >::value > > : std::true_type { }; template< class T > constexpr bool is_model_of_pointer_v = is_model_of_pointer::value; template auto value_of(V &&v) -> std::enable_if_t, decltype(*v)> { return *v; } template auto value_of(V &&v) -> std::enable_if_t::value, V> { return std::forward(v); } int main() { static_assert(is_dereferenceable::iterator>(), "iter"); static_assert(is_dereferenceable::const_iterator>(), "const_iter"); static_assert(is_dereferenceable(), "ptr"); static_assert(!is_dereferenceable(), "value"); static_assert(is_dereferenceable>(), "shared_ptr"); static_assert(is_dereferenceable>(), "unique_ptr"); static_assert(!is_dereferenceable(), "void *"); static_assert(!is_dereferenceable(), "const void *"); const std::array a{1,2,3}; const std::vector v1{4,5,6}; const std::vector> v2{std::make_shared(7),std::make_shared(8),std::make_shared(9)}; const std::vector v3{new int(10), new int(11), new int(12)}; const std::vector> v4 = [](){ std::vector> v; v.emplace_back(std::make_unique(13)); v.emplace_back(std::make_unique(14)); v.emplace_back(std::make_unique(15)); return v; }(); const std::vector::const_iterator> v5{v1.begin()+2, v1.begin()+1, v1.begin()}; const auto printer = [](const auto &v){ std::cout << value_of(v) << '\n'; }; const auto print_all = [printer](const auto &c) { std::for_each(std::begin(c), std::end(c), printer); }; print_all(a); print_all(v1); print_all(v2); print_all(v3); print_all(v4); print_all(v5); }