Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:03:18

0001 //
0002 // associated_allocator.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
0012 #define BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 #include <memory>
0020 #include <boost/asio/associator.hpp>
0021 #include <boost/asio/detail/functional.hpp>
0022 #include <boost/asio/detail/type_traits.hpp>
0023 
0024 #include <boost/asio/detail/push_options.hpp>
0025 
0026 namespace boost {
0027 namespace asio {
0028 
0029 template <typename T, typename Allocator>
0030 struct associated_allocator;
0031 
0032 namespace detail {
0033 
0034 template <typename T, typename = void>
0035 struct has_allocator_type : false_type
0036 {
0037 };
0038 
0039 template <typename T>
0040 struct has_allocator_type<T, void_t<typename T::allocator_type>> : true_type
0041 {
0042 };
0043 
0044 template <typename T, typename A, typename = void, typename = void>
0045 struct associated_allocator_impl
0046 {
0047   typedef void asio_associated_allocator_is_unspecialised;
0048 
0049   typedef A type;
0050 
0051   static type get(const T&) noexcept
0052   {
0053     return type();
0054   }
0055 
0056   static const type& get(const T&, const A& a) noexcept
0057   {
0058     return a;
0059   }
0060 };
0061 
0062 template <typename T, typename A>
0063 struct associated_allocator_impl<T, A, void_t<typename T::allocator_type>>
0064 {
0065   typedef typename T::allocator_type type;
0066 
0067   static auto get(const T& t) noexcept
0068     -> decltype(t.get_allocator())
0069   {
0070     return t.get_allocator();
0071   }
0072 
0073   static auto get(const T& t, const A&) noexcept
0074     -> decltype(t.get_allocator())
0075   {
0076     return t.get_allocator();
0077   }
0078 };
0079 
0080 template <typename T, typename A>
0081 struct associated_allocator_impl<T, A,
0082   enable_if_t<
0083     !has_allocator_type<T>::value
0084   >,
0085   void_t<
0086     typename associator<associated_allocator, T, A>::type
0087   >> : associator<associated_allocator, T, A>
0088 {
0089 };
0090 
0091 } // namespace detail
0092 
0093 /// Traits type used to obtain the allocator associated with an object.
0094 /**
0095  * A program may specialise this traits type if the @c T template parameter in
0096  * the specialisation is a user-defined type. The template parameter @c
0097  * Allocator shall be a type meeting the Allocator requirements.
0098  *
0099  * Specialisations shall meet the following requirements, where @c t is a const
0100  * reference to an object of type @c T, and @c a is an object of type @c
0101  * Allocator.
0102  *
0103  * @li Provide a nested typedef @c type that identifies a type meeting the
0104  * Allocator requirements.
0105  *
0106  * @li Provide a noexcept static member function named @c get, callable as @c
0107  * get(t) and with return type @c type or a (possibly const) reference to @c
0108  * type.
0109  *
0110  * @li Provide a noexcept static member function named @c get, callable as @c
0111  * get(t,a) and with return type @c type or a (possibly const) reference to @c
0112  * type.
0113  */
0114 template <typename T, typename Allocator = std::allocator<void>>
0115 struct associated_allocator
0116 #if !defined(GENERATING_DOCUMENTATION)
0117   : detail::associated_allocator_impl<T, Allocator>
0118 #endif // !defined(GENERATING_DOCUMENTATION)
0119 {
0120 #if defined(GENERATING_DOCUMENTATION)
0121   /// If @c T has a nested type @c allocator_type, <tt>T::allocator_type</tt>.
0122   /// Otherwise @c Allocator.
0123   typedef see_below type;
0124 
0125   /// If @c T has a nested type @c allocator_type, returns
0126   /// <tt>t.get_allocator()</tt>. Otherwise returns @c type().
0127   static decltype(auto) get(const T& t) noexcept;
0128 
0129   /// If @c T has a nested type @c allocator_type, returns
0130   /// <tt>t.get_allocator()</tt>. Otherwise returns @c a.
0131   static decltype(auto) get(const T& t, const Allocator& a) noexcept;
0132 #endif // defined(GENERATING_DOCUMENTATION)
0133 };
0134 
0135 /// Helper function to obtain an object's associated allocator.
0136 /**
0137  * @returns <tt>associated_allocator<T>::get(t)</tt>
0138  */
0139 template <typename T>
0140 BOOST_ASIO_NODISCARD inline typename associated_allocator<T>::type
0141 get_associated_allocator(const T& t) noexcept
0142 {
0143   return associated_allocator<T>::get(t);
0144 }
0145 
0146 /// Helper function to obtain an object's associated allocator.
0147 /**
0148  * @returns <tt>associated_allocator<T, Allocator>::get(t, a)</tt>
0149  */
0150 template <typename T, typename Allocator>
0151 BOOST_ASIO_NODISCARD inline auto get_associated_allocator(
0152     const T& t, const Allocator& a) noexcept
0153   -> decltype(associated_allocator<T, Allocator>::get(t, a))
0154 {
0155   return associated_allocator<T, Allocator>::get(t, a);
0156 }
0157 
0158 template <typename T, typename Allocator = std::allocator<void>>
0159 using associated_allocator_t
0160   = typename associated_allocator<T, Allocator>::type;
0161 
0162 namespace detail {
0163 
0164 template <typename T, typename A, typename = void>
0165 struct associated_allocator_forwarding_base
0166 {
0167 };
0168 
0169 template <typename T, typename A>
0170 struct associated_allocator_forwarding_base<T, A,
0171     enable_if_t<
0172       is_same<
0173         typename associated_allocator<T,
0174           A>::asio_associated_allocator_is_unspecialised,
0175         void
0176       >::value
0177     >>
0178 {
0179   typedef void asio_associated_allocator_is_unspecialised;
0180 };
0181 
0182 } // namespace detail
0183 
0184 /// Specialisation of associated_allocator for @c std::reference_wrapper.
0185 template <typename T, typename Allocator>
0186 struct associated_allocator<reference_wrapper<T>, Allocator>
0187 #if !defined(GENERATING_DOCUMENTATION)
0188   : detail::associated_allocator_forwarding_base<T, Allocator>
0189 #endif // !defined(GENERATING_DOCUMENTATION)
0190 {
0191   /// Forwards @c type to the associator specialisation for the unwrapped type
0192   /// @c T.
0193   typedef typename associated_allocator<T, Allocator>::type type;
0194 
0195   /// Forwards the request to get the allocator to the associator specialisation
0196   /// for the unwrapped type @c T.
0197   static type get(reference_wrapper<T> t) noexcept
0198   {
0199     return associated_allocator<T, Allocator>::get(t.get());
0200   }
0201 
0202   /// Forwards the request to get the allocator to the associator specialisation
0203   /// for the unwrapped type @c T.
0204   static auto get(reference_wrapper<T> t, const Allocator& a) noexcept
0205     -> decltype(associated_allocator<T, Allocator>::get(t.get(), a))
0206   {
0207     return associated_allocator<T, Allocator>::get(t.get(), a);
0208   }
0209 };
0210 
0211 } // namespace asio
0212 } // namespace boost
0213 
0214 #include <boost/asio/detail/pop_options.hpp>
0215 
0216 #endif // BOOST_ASIO_ASSOCIATED_ALLOCATOR_HPP