source: XIOS/dev/dev_olga/src/extern/boost/include/boost/functional/factory.hpp @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 5.3 KB
Line 
1/*=============================================================================
2    Copyright (c) 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#ifndef BOOST_FUNCTIONAL_FACTORY_HPP_INCLUDED
10#   ifndef BOOST_PP_IS_ITERATING
11
12#     include <boost/preprocessor/iteration/iterate.hpp>
13#     include <boost/preprocessor/repetition/enum_params.hpp>
14#     include <boost/preprocessor/repetition/enum_binary_params.hpp>
15
16#     include <new>
17#     include <boost/pointee.hpp>
18#     include <boost/none_t.hpp>
19#     include <boost/get_pointer.hpp>
20#     include <boost/non_type.hpp>
21#     include <boost/type_traits/remove_cv.hpp>
22
23#     ifndef BOOST_FUNCTIONAL_FACTORY_MAX_ARITY
24#       define BOOST_FUNCTIONAL_FACTORY_MAX_ARITY 10
25#     elif BOOST_FUNCTIONAL_FACTORY_MAX_ARITY < 3
26#       undef  BOOST_FUNCTIONAL_FACTORY_MAX_ARITY
27#       define BOOST_FUNCTIONAL_FACTORY_MAX_ARITY 3
28#     endif
29
30namespace boost
31{
32    enum factory_alloc_propagation
33    {
34        factory_alloc_for_pointee_and_deleter,
35        factory_passes_alloc_to_smart_pointer
36    };
37
38    template< typename Pointer, class Allocator = boost::none_t,
39        factory_alloc_propagation AP = factory_alloc_for_pointee_and_deleter >
40    class factory;
41
42    //----- ---- --- -- - -  -   -
43
44    template< typename Pointer, factory_alloc_propagation AP >
45    class factory<Pointer, boost::none_t, AP> 
46    {
47      public:
48        typedef typename boost::remove_cv<Pointer>::type result_type;
49        typedef typename boost::pointee<result_type>::type value_type;
50
51        factory()
52        { }
53
54#     define BOOST_PP_FILENAME_1 <boost/functional/factory.hpp>
55#     define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_FACTORY_MAX_ARITY)
56#     include BOOST_PP_ITERATE()
57    };
58
59    template< class Pointer, class Allocator, factory_alloc_propagation AP >
60    class factory
61        : private Allocator::template rebind< typename boost::pointee<
62            typename boost::remove_cv<Pointer>::type >::type >::other
63    {
64      public:
65        typedef typename boost::remove_cv<Pointer>::type result_type;
66        typedef typename boost::pointee<result_type>::type value_type;
67
68        typedef typename Allocator::template rebind<value_type>::other
69            allocator_type;
70
71        explicit factory(allocator_type const & a = allocator_type())
72          : allocator_type(a)
73        { }
74
75      private:
76
77        struct deleter
78            : allocator_type
79        {
80            inline deleter(allocator_type const& that) 
81              : allocator_type(that)
82            { }
83
84            allocator_type& get_allocator() const
85            {
86                return *const_cast<allocator_type*>(
87                    static_cast<allocator_type const*>(this));
88            }
89
90            void operator()(value_type* ptr) const
91            {
92                if (!! ptr) ptr->~value_type();
93                const_cast<allocator_type*>(static_cast<allocator_type const*>(
94                    this))->deallocate(ptr,1);
95            }
96        };
97
98        inline allocator_type& get_allocator() const
99        {
100            return *const_cast<allocator_type*>(
101                static_cast<allocator_type const*>(this));
102        }
103
104        inline result_type make_pointer(value_type* ptr, boost::non_type<
105            factory_alloc_propagation,factory_passes_alloc_to_smart_pointer>)
106        const
107        {
108            return result_type(ptr,deleter(this->get_allocator()));
109        }
110        inline result_type make_pointer(value_type* ptr, boost::non_type<
111            factory_alloc_propagation,factory_alloc_for_pointee_and_deleter>)
112        const
113        {
114            return result_type(ptr,deleter(this->get_allocator()),
115                this->get_allocator());
116        }
117
118      public:
119
120#     define BOOST_TMP_MACRO
121#     define BOOST_PP_FILENAME_1 <boost/functional/factory.hpp>
122#     define BOOST_PP_ITERATION_LIMITS (0,BOOST_FUNCTIONAL_FACTORY_MAX_ARITY)
123#     include BOOST_PP_ITERATE()
124#     undef BOOST_TMP_MACRO
125    };
126
127    template< typename Pointer, class Allocator, factory_alloc_propagation AP > 
128    class factory<Pointer&, Allocator, AP>;
129    // forbidden, would create a dangling reference
130}
131
132#     define BOOST_FUNCTIONAL_FACTORY_HPP_INCLUDED
133#   else // defined(BOOST_PP_IS_ITERATING)
134#     define N BOOST_PP_ITERATION()
135#     if !defined(BOOST_TMP_MACRO)
136#       if N > 0
137    template< BOOST_PP_ENUM_PARAMS(N, typename T) >
138#       endif
139    inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const
140    {
141        return result_type( new value_type(BOOST_PP_ENUM_PARAMS(N,a)) );
142    }
143#     else // defined(BOOST_TMP_MACRO)
144#       if N > 0
145    template< BOOST_PP_ENUM_PARAMS(N, typename T) >
146#       endif
147    inline result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& a)) const
148    {
149        value_type* memory = this->get_allocator().allocate(1);
150        try
151        { 
152            return make_pointer(
153                new(memory) value_type(BOOST_PP_ENUM_PARAMS(N,a)),
154                boost::non_type<factory_alloc_propagation,AP>() );
155        }
156        catch (...) { this->get_allocator().deallocate(memory,1); throw; }
157    }
158#     endif
159#     undef N
160#   endif // defined(BOOST_PP_IS_ITERATING)
161
162#endif // include guard
163
Note: See TracBrowser for help on using the repository browser.