Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:31:06

0001 /*
0002 Copyright 2007 Tobias Schwinger
0003 
0004 Copyright 2019 Glen Joseph Fernandes
0005 (glenjofe@gmail.com)
0006 
0007 Distributed under the Boost Software License, Version 1.0.
0008 (http://www.boost.org/LICENSE_1_0.txt)
0009 */
0010 #ifndef BOOST_FUNCTIONAL_FACTORY_HPP
0011 #define BOOST_FUNCTIONAL_FACTORY_HPP
0012 
0013 #include <boost/config.hpp>
0014 #include <boost/core/empty_value.hpp>
0015 #include <boost/core/pointer_traits.hpp>
0016 #include <boost/type_traits/remove_cv.hpp>
0017 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
0018 #include <memory>
0019 #endif
0020 #include <new>
0021 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
0022     !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0023 #include <utility>
0024 #endif
0025 
0026 namespace boost {
0027 
0028 enum factory_alloc_propagation {
0029     factory_alloc_for_pointee_and_deleter,
0030     factory_passes_alloc_to_smart_pointer
0031 };
0032 
0033 namespace detail {
0034 
0035 template<factory_alloc_propagation>
0036 struct fc_tag { };
0037 
0038 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
0039 template<class A, class T>
0040 struct fc_rebind {
0041     typedef typename std::allocator_traits<A>::template rebind_alloc<T> type;
0042 };
0043 
0044 template<class A>
0045 struct fc_pointer {
0046     typedef typename std::allocator_traits<A>::pointer type;
0047 };
0048 #else
0049 template<class A, class T>
0050 struct fc_rebind {
0051     typedef typename A::template rebind<T>::other type;
0052 };
0053 
0054 template<class A>
0055 struct fc_pointer {
0056     typedef typename A::pointer type;
0057 };
0058 #endif
0059 
0060 #if !defined(BOOST_NO_CXX11_ALLOCATOR) && \
0061     !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
0062     !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0063 template<class A, class T>
0064 inline void
0065 fc_destroy(A& a, T* p)
0066 {
0067     std::allocator_traits<A>::destroy(a, p);
0068 }
0069 #else
0070 template<class A, class T>
0071 inline void
0072 fc_destroy(A&, T* p)
0073 {
0074     p->~T();
0075 }
0076 #endif
0077 
0078 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
0079     !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0080 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
0081 template<class A, class T, class... Args>
0082 inline void
0083 fc_construct(A& a, T* p, Args&&... args)
0084 {
0085     std::allocator_traits<A>::construct(a, p, std::forward<Args>(args)...);
0086 }
0087 #else
0088 template<class A, class T, class... Args>
0089 inline void
0090 fc_construct(A&, T* p, Args&&... args)
0091 {
0092     ::new((void*)p) T(std::forward<Args>(args)...);
0093 }
0094 #endif
0095 #endif
0096 
0097 template<class A>
0098 class fc_delete
0099     : boost::empty_value<A> {
0100     typedef boost::empty_value<A> base;
0101 
0102 public:
0103     explicit fc_delete(const A& a) BOOST_NOEXCEPT
0104         : base(boost::empty_init_t(), a) { }
0105 
0106     void operator()(typename fc_pointer<A>::type p) {
0107         boost::detail::fc_destroy(base::get(), boost::to_address(p));
0108         base::get().deallocate(p, 1);
0109     }
0110 };
0111 
0112 template<class R, class A>
0113 class fc_allocate {
0114 public:
0115     explicit fc_allocate(const A& a)
0116         : a_(a)
0117         , p_(a_.allocate(1)) { }
0118 
0119     ~fc_allocate() {
0120         if (p_) {
0121             a_.deallocate(p_, 1);
0122         }
0123     }
0124 
0125     A& state() BOOST_NOEXCEPT {
0126         return a_;
0127     }
0128 
0129     typename A::value_type* get() const BOOST_NOEXCEPT {
0130         return boost::to_address(p_);
0131     }
0132 
0133     R release(fc_tag<factory_alloc_for_pointee_and_deleter>) {
0134         return R(release(), fc_delete<A>(a_), a_);
0135     }
0136 
0137     R release(fc_tag<factory_passes_alloc_to_smart_pointer>) {
0138         return R(release(), fc_delete<A>(a_));
0139     }
0140 
0141 private:
0142     typedef typename fc_pointer<A>::type pointer;
0143 
0144     pointer release() BOOST_NOEXCEPT {
0145         pointer p = p_;
0146         p_ = pointer();
0147         return p;
0148     }
0149 
0150     fc_allocate(const fc_allocate&);
0151     fc_allocate& operator=(const fc_allocate&);
0152 
0153     A a_;
0154     pointer p_;
0155 };
0156 
0157 } /* detail */
0158 
0159 template<class Pointer, class Allocator = void,
0160     factory_alloc_propagation Policy = factory_alloc_for_pointee_and_deleter>
0161 class factory;
0162 
0163 template<class Pointer, factory_alloc_propagation Policy>
0164 class factory<Pointer, void, Policy> {
0165 public:
0166     typedef typename remove_cv<Pointer>::type result_type;
0167 
0168 private:
0169     typedef typename pointer_traits<result_type>::element_type type;
0170 
0171 public:
0172 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
0173     !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0174     template<class... Args>
0175     result_type operator()(Args&&... args) const {
0176         return result_type(new type(std::forward<Args>(args)...));
0177     }
0178 #else
0179     result_type operator()() const {
0180         return result_type(new type());
0181     }
0182 
0183     template<class A0>
0184     result_type operator()(A0& a0) const {
0185         return result_type(new type(a0));
0186     }
0187 
0188     template<class A0, class A1>
0189     result_type operator()(A0& a0, A1& a1) const {
0190         return result_type(new type(a0, a1));
0191     }
0192 
0193     template<class A0, class A1, class A2>
0194     result_type operator()(A0& a0, A1& a1, A2& a2) const {
0195         return result_type(new type(a0, a1, a2));
0196     }
0197 
0198     template<class A0, class A1, class A2, class A3>
0199     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const {
0200         return result_type(new type(a0, a1, a2, a3));
0201     }
0202 
0203     template<class A0, class A1, class A2, class A3, class A4>
0204     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) const {
0205         return result_type(new type(a0, a1, a2, a3, a4));
0206     }
0207 
0208     template<class A0, class A1, class A2, class A3, class A4, class A5>
0209     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4,
0210         A5& a5) const {
0211         return result_type(new type(a0, a1, a2, a3, a4, a5));
0212     }
0213 
0214     template<class A0, class A1, class A2, class A3, class A4, class A5,
0215         class A6>
0216     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
0217         A6& a6) const {
0218         return result_type(new type(a0, a1, a2, a3, a4, a5, a6));
0219     }
0220 
0221     template<class A0, class A1, class A2, class A3, class A4, class A5,
0222         class A6, class A7>
0223     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
0224         A6& a6, A7& a7) const {
0225         return result_type(new type(a0, a1, a2, a3, a4, a5, a6, a7));
0226     }
0227 
0228     template<class A0, class A1, class A2, class A3, class A4, class A5,
0229         class A6, class A7, class A8>
0230     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
0231         A6& a6, A7& a7, A8& a8) const {
0232         return result_type(new type(a0, a1, a2, a3, a4, a5, a6, a7, a8));
0233     }
0234 
0235     template<class A0, class A1, class A2, class A3, class A4, class A5,
0236         class A6, class A7, class A8, class A9>
0237     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
0238         A6& a6, A7& a7, A8& a8, A9& a9) const {
0239         return result_type(new type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9));
0240     }
0241 #endif
0242 };
0243 
0244 template<class Pointer, class Allocator, factory_alloc_propagation Policy>
0245 class factory
0246     : empty_value<typename detail::fc_rebind<Allocator,
0247         typename pointer_traits<typename
0248             remove_cv<Pointer>::type>::element_type>::type> {
0249 public:
0250     typedef typename remove_cv<Pointer>::type result_type;
0251 
0252 private:
0253     typedef typename pointer_traits<result_type>::element_type type;
0254     typedef typename detail::fc_rebind<Allocator, type>::type allocator;
0255     typedef empty_value<allocator> base;
0256 
0257 public:
0258     factory() BOOST_NOEXCEPT
0259         : base(empty_init_t()) { }
0260 
0261     explicit factory(const Allocator& a) BOOST_NOEXCEPT
0262         : base(empty_init_t(), a) { }
0263 
0264 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
0265     !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
0266     template<class... Args>
0267     result_type operator()(Args&&... args) const {
0268         detail::fc_allocate<result_type, allocator> s(base::get());
0269         detail::fc_construct(s.state(), s.get(), std::forward<Args>(args)...);
0270         return s.release(detail::fc_tag<Policy>());
0271     }
0272 #else
0273     result_type operator()() const {
0274         detail::fc_allocate<result_type, allocator> s(base::get());
0275         ::new((void*)s.get()) type();
0276         return s.release(detail::fc_tag<Policy>());
0277     }
0278 
0279     template<class A0>
0280     result_type operator()(A0& a0) const {
0281         detail::fc_allocate<result_type, allocator> s(base::get());
0282         ::new((void*)s.get()) type(a0);
0283         return s.release(detail::fc_tag<Policy>());
0284     }
0285 
0286     template<class A0, class A1>
0287     result_type operator()(A0& a0, A1& a1) const {
0288         detail::fc_allocate<result_type, allocator> s(base::get());
0289         ::new((void*)s.get()) type(a0, a1);
0290         return s.release(detail::fc_tag<Policy>());
0291     }
0292 
0293     template<class A0, class A1, class A2>
0294     result_type operator()(A0& a0, A1& a1, A2& a2) const {
0295         detail::fc_allocate<result_type, allocator> s(base::get());
0296         ::new((void*)s.get()) type(a0, a1, a2);
0297         return s.release(detail::fc_tag<Policy>());
0298     }
0299 
0300     template<class A0, class A1, class A2, class A3>
0301     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3) const {
0302         detail::fc_allocate<result_type, allocator> s(base::get());
0303         ::new((void*)s.get()) type(a0, a1, a2, a3);
0304         return s.release(detail::fc_tag<Policy>());
0305     }
0306 
0307     template<class A0, class A1, class A2, class A3, class A4>
0308     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) const {
0309         detail::fc_allocate<result_type, allocator> s(base::get());
0310         ::new((void*)s.get()) type(a0, a1, a2, a3, a4);
0311         return s.release(detail::fc_tag<Policy>());
0312     }
0313 
0314     template<class A0, class A1, class A2, class A3, class A4, class A5>
0315     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4,
0316         A5& a5) const {
0317         detail::fc_allocate<result_type, allocator> s(base::get());
0318         ::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5);
0319         return s.release(detail::fc_tag<Policy>());
0320     }
0321 
0322     template<class A0, class A1, class A2, class A3, class A4, class A5,
0323         class A6>
0324     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
0325         A6& a6) const {
0326         detail::fc_allocate<result_type, allocator> s(base::get());
0327         ::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6);
0328         return s.release(detail::fc_tag<Policy>());
0329     }
0330 
0331     template<class A0, class A1, class A2, class A3, class A4, class A5,
0332         class A6, class A7>
0333     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
0334         A6& a6, A7& a7) const {
0335         detail::fc_allocate<result_type, allocator> s(base::get());
0336         ::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7);
0337         return s.release(detail::fc_tag<Policy>());
0338     }
0339 
0340     template<class A0, class A1, class A2, class A3, class A4, class A5,
0341         class A6, class A7, class A8>
0342     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
0343         A6& a6, A7& a7, A8& a8) const {
0344         detail::fc_allocate<result_type, allocator> s(base::get());
0345         ::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7, a8);
0346         return s.release(detail::fc_tag<Policy>());
0347     }
0348 
0349     template<class A0, class A1, class A2, class A3, class A4, class A5,
0350         class A6, class A7, class A8, class A9>
0351     result_type operator()(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5,
0352         A6& a6, A7& a7, A8& a8, A9& a9) const {
0353         detail::fc_allocate<result_type, allocator> s(base::get());
0354         ::new((void*)s.get()) type(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
0355         return s.release(detail::fc_tag<Policy>());
0356     }
0357 #endif
0358 };
0359 
0360 template<class Pointer, class Allocator, factory_alloc_propagation Policy>
0361 class factory<Pointer&, Allocator, Policy> { };
0362 
0363 } /* boost */
0364 
0365 #endif