diff --git a/include/boost/core/pointer_traits.hpp b/include/boost/core/pointer_traits.hpp new file mode 100644 index 0000000..d4d264b --- /dev/null +++ b/include/boost/core/pointer_traits.hpp @@ -0,0 +1,256 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_POINTER_TRAITS_HPP +#define BOOST_CORE_POINTER_TRAITS_HPP + +#include +#include +#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \ + !BOOST_WORKAROUND(BOOST_MSVC, < 1910) +#include +#else +#include +#endif + +namespace boost { + +template +struct pointer_traits; + +namespace detail { + +template +static typename pointer_traits::element_type* +ptr_traits_address(U v) BOOST_NOEXCEPT +{ + return pointer_traits::to_address(v); +} + +} /* detail */ + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \ + !BOOST_WORKAROUND(BOOST_MSVC, < 1910) +template +struct pointer_traits + : std::pointer_traits { + template + struct rebind_to { + typedef typename std::pointer_traits::template rebind type; + }; + static typename std::pointer_traits::element_type* + to_address(T v) BOOST_NOEXCEPT { + return detail::ptr_traits_address(v.operator->()); + } +}; + +template +struct pointer_traits + : std::pointer_traits { + template + struct rebind_to { + typedef U* type; + }; + static T* to_address(T* v) BOOST_NOEXCEPT { + return v; + } +}; +#else +namespace detail { + +struct ptr_traits_none { char first; char second; }; + +template +struct ptr_traits_has_element { +private: + template + static ptr_traits_none call(...); + template + static char call(typename U::element_type* = 0); +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(call(0)) == 1; +}; + +template +struct ptr_traits_first; + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template class T, class U, class... Args> +struct ptr_traits_first > { + typedef U type; +}; +#else +template class T, class U> +struct ptr_traits_first > { + typedef U type; +}; + +template class T, class U1, class U2> +struct ptr_traits_first > { + typedef U1 type; +}; + +template class T, class U1, class U2, class U3> +struct ptr_traits_first > { + typedef U1 type; +}; +#endif + +template::value> +struct ptr_traits_element; + +template +struct ptr_traits_element { + typedef typename T::element_type type; +}; + +template +struct ptr_traits_element { + typedef typename ptr_traits_first::type type; +}; + +template +struct ptr_traits_has_difference { +private: + template + static ptr_traits_none call(...); + template + static char call(typename U::difference_type* = 0); +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(call(0)) == 1; +}; + +template::value> +struct ptr_traits_difference; + +template +struct ptr_traits_difference { + typedef typename T::difference_type type; +}; + +template +struct ptr_traits_difference { + typedef std::ptrdiff_t type; +}; + +template +struct ptr_traits_has_rebind { +private: + template + static ptr_traits_none call(...); + template + static char call(typename U::template rebind* = 0); +public: + BOOST_STATIC_CONSTEXPR bool value = sizeof(call(0)) == 1; +}; + +template +struct ptr_traits_rebind_to; + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template class T, class U, class... Args, class V> +struct ptr_traits_rebind_to, V> { + typedef T type; +}; +#else +template class T, class U, class V> +struct ptr_traits_rebind_to, V> { + typedef T type; +}; + +template class T, class U1, class U2, class V> +struct ptr_traits_rebind_to, V> { + typedef T type; +}; + +template class T, + class U1, class U2, class U3, class V> +struct ptr_traits_rebind_to, V> { + typedef T type; +}; +#endif + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +template::value> +struct ptr_traits_rebind; + +template +struct ptr_traits_rebind { + typedef typename T::template rebind type; +}; + +template +struct ptr_traits_rebind { + typedef typename ptr_traits_rebind_to::type type; +}; +#else +template +struct ptr_traits_rebind { + typedef typename ptr_traits_rebind_to::type type; +}; +#endif + +template +struct ptr_traits_value { + typedef T type; +}; + +template<> +struct ptr_traits_value { + typedef struct { } type; +}; + +} /* detail */ + +template +struct pointer_traits { + typedef T pointer; + typedef typename detail::ptr_traits_element::type element_type; + typedef typename detail::ptr_traits_difference::type difference_type; + template + struct rebind_to { + typedef typename detail::ptr_traits_rebind::type type; + }; +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + template + using rebind = typename detail::ptr_traits_rebind::type; +#endif + static pointer + pointer_to(typename detail::ptr_traits_value::type& v) { + return pointer::pointer_to(v); + } + static element_type* to_address(pointer v) BOOST_NOEXCEPT { + return detail::ptr_traits_address(v.operator->()); + } +}; + +template +struct pointer_traits { + typedef T* pointer; + typedef T element_type; + typedef std::ptrdiff_t difference_type; + template + struct rebind_to { + typedef U* type; + }; +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + template + using rebind = U*; +#endif + static T* + pointer_to(typename detail::ptr_traits_value::type& v) BOOST_NOEXCEPT { + return addressof(v); + } + static T* to_address(T* v) BOOST_NOEXCEPT { + return v; + } +}; +#endif + +} /* boost */ + +#endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index fded1cd..5e0e5d3 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -105,5 +105,12 @@ compile-fail scoped_enum_compile_fail_conv_to_int.cpp ; run underlying_type.cpp ; +run pointer_traits_to_address_test.cpp ; +run pointer_traits_pointer_test.cpp ; +run pointer_traits_element_type_test.cpp ; +run pointer_traits_difference_type_test.cpp ; +run pointer_traits_rebind_test.cpp ; +run pointer_traits_pointer_to_test.cpp ; + use-project /boost/core/swap : ./swap ; build-project ./swap ; diff --git a/test/pointer_traits_difference_type_test.cpp b/test/pointer_traits_difference_type_test.cpp new file mode 100644 index 0000000..e9d0b09 --- /dev/null +++ b/test/pointer_traits_difference_type_test.cpp @@ -0,0 +1,41 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +template +struct P { }; + +template +struct E { + typedef long difference_type; +}; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::difference_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::difference_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::difference_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::difference_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::difference_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::difference_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::difference_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::difference_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::difference_type>)); + return boost::report_errors(); +} diff --git a/test/pointer_traits_element_type_test.cpp b/test/pointer_traits_element_type_test.cpp new file mode 100644 index 0000000..a20733e --- /dev/null +++ b/test/pointer_traits_element_type_test.cpp @@ -0,0 +1,83 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +template +struct P1 { }; + +template +struct P2 { }; + +template +struct P3 { }; + +template +struct E1 { + typedef bool element_type; +}; + +template +struct E2 { + typedef bool element_type; +}; + +template +struct E3 { + typedef bool element_type; +}; + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +struct P { }; + +template +struct E { + typedef bool element_type; +}; +#endif + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::element_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); +#endif + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); +#endif + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::element_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::element_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same >::element_type>)); + return boost::report_errors(); +} diff --git a/test/pointer_traits_pointer_test.cpp b/test/pointer_traits_pointer_test.cpp new file mode 100644 index 0000000..a98eb4d --- /dev/null +++ b/test/pointer_traits_pointer_test.cpp @@ -0,0 +1,30 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +template +struct P { }; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::pointer>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::pointer>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::pointer>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::pointer>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::pointer>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::pointer>)); + return boost::report_errors(); +} diff --git a/test/pointer_traits_pointer_to_test.cpp b/test/pointer_traits_pointer_to_test.cpp new file mode 100644 index 0000000..33e21ad --- /dev/null +++ b/test/pointer_traits_pointer_to_test.cpp @@ -0,0 +1,63 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include + +template +class pointer { +public: + typedef typename boost::pointer_traits::element_type element_type; + pointer(T value) + : value_(value) { } + T get() const BOOST_NOEXCEPT { + return value_; + } + static pointer pointer_to(element_type& value) { + return pointer(&value); + } +private: + T value_; +}; + +template +inline bool +operator==(const pointer& lhs, const pointer& rhs) BOOST_NOEXCEPT +{ + return lhs.get() == rhs.get(); +} + +int main() +{ + int i = 0; + { + typedef int* type; + type p = &i; + BOOST_TEST(boost::pointer_traits::pointer_to(i) == p); + } + { + typedef pointer type; + type p(&i); + BOOST_TEST(boost::pointer_traits::pointer_to(i) == p); + } + { + typedef pointer > type; + type p(&i); + BOOST_TEST(boost::pointer_traits::pointer_to(i) == p); + } + { + typedef const int* type; + type p = &i; + BOOST_TEST(boost::pointer_traits::pointer_to(i) == p); + } + { + typedef pointer type; + type p(&i); + BOOST_TEST(boost::pointer_traits::pointer_to(i) == p); + } + return boost::report_errors(); +} diff --git a/test/pointer_traits_rebind_test.cpp b/test/pointer_traits_rebind_test.cpp new file mode 100644 index 0000000..999d195 --- /dev/null +++ b/test/pointer_traits_rebind_test.cpp @@ -0,0 +1,107 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include +#include + +template +struct P1 { }; + +template +struct P2 { }; + +template +struct P3 { }; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +template +struct E1 { + template + using rebind = E1; +}; + +template +struct E2 { + template + using rebind = E2; +}; + +template +struct E3 { + template + using rebind = E3; +}; +#endif + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +struct P { }; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) +template +struct E { + template + using rebind = E; +}; +#endif +#endif + +struct R { }; + +int main() +{ + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); +#endif + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); +#endif + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); + BOOST_TEST_TRAIT_TRUE((boost::core::is_same, + boost::pointer_traits >::rebind_to::type>)); +#endif + return boost::report_errors(); +} diff --git a/test/pointer_traits_to_address_test.cpp b/test/pointer_traits_to_address_test.cpp new file mode 100644 index 0000000..3a86b42 --- /dev/null +++ b/test/pointer_traits_to_address_test.cpp @@ -0,0 +1,63 @@ +/* +Copyright 2017 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#include +#include + +template +class pointer { +public: + typedef typename boost::pointer_traits::element_type element_type; + pointer(T value) + : value_(value) { } + T operator->() const BOOST_NOEXCEPT { + return value_; + } +private: + T value_; +}; + +int main() +{ + int i = 0; + { + typedef int* type; + type p = &i; + BOOST_TEST(boost::pointer_traits::to_address(p) == &i); + } + { + typedef pointer type; + type p(&i); + BOOST_TEST(boost::pointer_traits::to_address(p) == &i); + } + { + typedef pointer > type; + type p(&i); + BOOST_TEST(boost::pointer_traits::to_address(p) == &i); + } + { + typedef void* type; + type p = &i; + BOOST_TEST(boost::pointer_traits::to_address(p) == &i); + } + { + typedef pointer type; + type p(&i); + BOOST_TEST(boost::pointer_traits::to_address(p) == &i); + } + { + typedef const int* type; + type p = &i; + BOOST_TEST(boost::pointer_traits::to_address(p) == &i); + } + { + typedef pointer type; + type p(&i); + BOOST_TEST(boost::pointer_traits::to_address(p) == &i); + } + return boost::report_errors(); +}