/*
-Copyright 2017-2018 Glen Joseph Fernandes
+Copyright 2017-2021 Glen Joseph Fernandes
(glenjofe@gmail.com)
Distributed under the Boost Software License, Version 1.0.
#define BOOST_CORE_POINTER_TRAITS_HPP
#include <boost/config.hpp>
-#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
-#include <memory>
-#else
#include <boost/core/addressof.hpp>
#include <cstddef>
-#endif
namespace boost {
-
-#if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
-template<class T>
-struct pointer_traits
- : std::pointer_traits<T> {
- template<class U>
- struct rebind_to {
- typedef typename std::pointer_traits<T>::template rebind<U> type;
- };
-};
-
-template<class T>
-struct pointer_traits<T*>
- : std::pointer_traits<T*> {
- template<class U>
- struct rebind_to {
- typedef U* type;
- };
-};
-#else
namespace detail {
+struct ptr_none { };
+
template<class>
-struct ptr_void {
+struct ptr_valid {
typedef void type;
};
-template<class T>
-struct ptr_first;
+template<class>
+struct ptr_first {
+ typedef ptr_none type;
+};
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<template<class, class...> class T, class U, class... Args>
};
template<class T>
-struct ptr_element<T, typename ptr_void<typename T::element_type>::type> {
+struct ptr_element<T, typename ptr_valid<typename T::element_type>::type> {
typedef typename T::element_type type;
};
template<class T>
struct ptr_difference<T,
- typename ptr_void<typename T::difference_type>::type> {
+ typename ptr_valid<typename T::difference_type>::type> {
typedef typename T::difference_type type;
};
-template<class T, class V>
-struct ptr_transform;
+template<class, class>
+struct ptr_transform { };
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<template<class, class...> class T, class U, class... Args, class V>
#endif
template<class T, class U, class = void>
-struct ptr_rebind {
- typedef typename ptr_transform<T, U>::type type;
-};
+struct ptr_rebind
+ : ptr_transform<T, U> { };
-#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class T, class U>
struct ptr_rebind<T, U,
- typename ptr_void<typename T::template rebind<U> >::type> {
+ typename ptr_valid<typename T::template rebind<U> >::type> {
typedef typename T::template rebind<U> type;
};
+
+#if !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
+template<class T, class E>
+class ptr_to_expr {
+ template<class>
+ struct result {
+ char x, y;
+ };
+
+ static E& source();
+
+ template<class O>
+ static auto check(int) -> result<decltype(O::pointer_to(source()))>;
+
+ template<class>
+ static char check(long);
+
+public:
+ BOOST_STATIC_CONSTEXPR bool value = sizeof(check<T>(0)) > 1;
+};
+
+template<class T, class E>
+struct ptr_to_expr<T*, E> {
+ BOOST_STATIC_CONSTEXPR bool value = true;
+};
+
+template<class T, class E>
+struct ptr_has_to {
+ BOOST_STATIC_CONSTEXPR bool value = ptr_to_expr<T, E>::value;
+};
+#else
+template<class, class>
+struct ptr_has_to {
+ BOOST_STATIC_CONSTEXPR bool value = true;
+};
#endif
template<class T>
-struct ptr_value {
- typedef T type;
+struct ptr_has_to<T, void> {
+ BOOST_STATIC_CONSTEXPR bool value = false;
};
-template<>
-struct ptr_value<void> {
- typedef struct { } type;
+template<class T>
+struct ptr_has_to<T, const void> {
+ BOOST_STATIC_CONSTEXPR bool value = false;
};
-} /* detail */
+template<class T>
+struct ptr_has_to<T, volatile void> {
+ BOOST_STATIC_CONSTEXPR bool value = false;
+};
+
+template<class T>
+struct ptr_has_to<T, const volatile void> {
+ BOOST_STATIC_CONSTEXPR bool value = false;
+};
+
+template<class T, class E, bool = ptr_has_to<T, E>::value>
+struct ptr_to { };
+
+template<class T, class E>
+struct ptr_to<T, E, true> {
+ static T pointer_to(E& v) {
+ return T::pointer_to(v);
+ }
+};
template<class T>
-struct pointer_traits {
+struct ptr_to<T*, T, true> {
+ static T* pointer_to(T& v) BOOST_NOEXCEPT {
+ return boost::addressof(v);
+ }
+};
+
+template<class T, class E>
+struct ptr_traits
+ : ptr_to<T, E> {
typedef T pointer;
- typedef typename detail::ptr_element<T>::type element_type;
- typedef typename detail::ptr_difference<T>::type difference_type;
+ typedef E element_type;
+ typedef typename ptr_difference<T>::type difference_type;
+
template<class U>
- struct rebind_to {
- typedef typename detail::ptr_rebind<T, U>::type type;
- };
+ struct rebind_to
+ : ptr_rebind<T, U> { };
+
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class U>
- using rebind = typename detail::ptr_rebind<T, U>::type;
+ using rebind = typename rebind_to<U>::type;
#endif
- static pointer
- pointer_to(typename detail::ptr_value<element_type>::type& v) {
- return pointer::pointer_to(v);
- }
};
template<class T>
-struct pointer_traits<T*> {
+struct ptr_traits<T, ptr_none> { };
+
+} /* detail */
+
+template<class T>
+struct pointer_traits
+ : detail::ptr_traits<T, typename detail::ptr_element<T>::type> { };
+
+template<class T>
+struct pointer_traits<T*>
+ : detail::ptr_to<T*, T> {
typedef T* pointer;
typedef T element_type;
typedef std::ptrdiff_t difference_type;
+
template<class U>
struct rebind_to {
typedef U* type;
};
+
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class U>
- using rebind = U*;
+ using rebind = typename rebind_to<U>::type*;
#endif
- static T*
- pointer_to(typename detail::ptr_value<T>::type& v) BOOST_NOEXCEPT {
- return boost::addressof(v);
- }
};
-#endif
template<class T>
BOOST_CONSTEXPR inline T*