1 /*=============================================================================
2     Copyright (c) 2006-2007 Tobias Schwinger
3 
4     Use modification and distribution are subject to the Boost Software
5     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6     http://www.boost.org/LICENSE_1_0.txt).
7 ==============================================================================*/
8 
9 #if !defined(BOOST_FUSION_FUNCTIONAL_INVOCATION_DETAIL_THAT_PTR_HPP_INCLUDED)
10 #define BOOST_FUSION_FUNCTIONAL_INVOCATION_DETAIL_THAT_PTR_HPP_INCLUDED
11 
12 #include <boost/fusion/support/config.hpp>
13 #include <boost/get_pointer.hpp>
14 #include <boost/utility/addressof.hpp>
15 #include <boost/type_traits/remove_reference.hpp>
16 
17 namespace boost { namespace fusion { namespace detail
18 {
19     template <typename Wanted>
20     struct that_ptr
21     {
22       private:
23 
24         typedef typename remove_reference<Wanted>::type pointee;
25 
26         template <typename T>
27         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
do_get_pointerboost::fusion::detail::that_ptr28         static inline pointee * do_get_pointer(T &, pointee * x)
29         {
30             return x;
31         }
32         template <typename T>
33         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
do_get_pointerboost::fusion::detail::that_ptr34         static inline pointee * do_get_pointer(T & x, void const *)
35         {
36             return get_pointer(x);
37         }
38 
39       public:
40 
41         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
getboost::fusion::detail::that_ptr42         static inline pointee * get(pointee * x)
43         {
44             return x;
45         }
46 
47         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
getboost::fusion::detail::that_ptr48         static inline pointee * get(pointee & x)
49         {
50             return boost::addressof(x);
51         }
52 
53         template <typename T>
54         BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
getboost::fusion::detail::that_ptr55         static inline pointee * get(T & x)
56         {
57             return do_get_pointer(x, boost::addressof(x));
58         }
59     };
60 
61     template <typename PtrOrSmartPtr> struct non_const_pointee;
62 
63 #if defined(BOOST_MSVC) || (defined(BOOST_BORLANDC) && !defined(BOOST_DISABLE_WIN32))
64 #   define BOOST_FUSION_TRAIT_DECL __cdecl
65 #else
66 #   define BOOST_FUSION_TRAIT_DECL /**/
67 #endif
68 
69 namespace adl_barrier
70     {
71         using boost::get_pointer;
72         void const * BOOST_FUSION_TRAIT_DECL get_pointer(...); // fallback
73 
74         template< typename T> char const_tester(T *);
75         template< typename T> long const_tester(T const *);
76 
77         template <typename Ptr>
78         struct non_const_pointee_impl
79         {
80             static Ptr & what;
81 
82             static bool const value =
83                 sizeof(const_tester(get_pointer(what))) == 1;
84         };
85     }
86 
87     template <typename PtrOrSmartPtr> struct non_const_pointee
88         : adl_barrier::non_const_pointee_impl<
89               typename remove_cv<
90                   typename remove_reference<PtrOrSmartPtr>::type >::type >
91     {
92         typedef non_const_pointee type;
93         typedef bool value_type;
94     };
95 
96 }}}
97 
98 #endif
99 
100