1
2[section In-Place Factories]
3
4One of the typical problems with wrappers and containers is that their
5interfaces usually provide an operation to initialize or assign the
6contained object as a copy of some other object. This not only requires the
7underlying type to be __COPY_CONSTRUCTIBLE__, but also requires the existence of
8a fully constructed object, often temporary, just to follow the copy from:
9
10    struct X
11    {
12        X ( int, std::string ) ;
13    } ;
14
15    class W
16    {
17        X wrapped_ ;
18
19        public:
20
21        W ( X const& x ) : wrapped_(x) {}
22    } ;
23
24    void foo()
25    {
26        // Temporary object created.
27        W ( X(123,"hello") ) ;
28    }
29
30A solution to this problem is to support direct construction of the
31contained object right in the container's storage.
32In this scheme, the user only needs to supply the arguments to the
33constructor to use in the wrapped object construction.
34
35    class W
36    {
37        X wrapped_ ;
38
39        public:
40
41        W ( X const& x ) : wrapped_(x) {}
42        W ( int a0, std::string a1) : wrapped_(a0,a1) {}
43    } ;
44
45    void foo()
46    {
47        // Wrapped object constructed in-place
48        // No temporary created.
49        W (123,"hello") ;
50    }
51
52A limitation of this method is that it doesn't scale well to wrapped
53objects with multiple constructors nor to generic code were the constructor
54overloads are unknown.
55
56The solution presented in this library is the family of [*InPlaceFactories]
57and [*TypedInPlaceFactories].
58These factories are a family of classes which encapsulate an increasing
59number of arbitrary constructor parameters and supply a method to construct
60an object of a given type using those parameters at an address specified by
61the user via placement new.
62
63For example, one member of this family looks like:
64
65    template<class T,class A0, class A1>
66    class TypedInPlaceFactory2
67    {
68        A0 m_a0 ; A1 m_a1 ;
69
70        public:
71
72        TypedInPlaceFactory2( A0 const& a0, A1 const& a1 ) : m_a0(a0), m_a1(a1) {}
73
74        void construct ( void* p ) { new (p) T(m_a0,m_a1) ; }
75     } ;
76
77A wrapper class aware of this can use it as:
78
79    class W
80    {
81        X wrapped_ ;
82
83        public:
84
85        W ( X const& x ) : wrapped_(x) {}
86        W ( TypedInPlaceFactory2 const& fac ) { fac.construct(&wrapped_) ; }
87    } ;
88
89    void foo()
90    {
91        // Wrapped object constructed in-place via a TypedInPlaceFactory.
92        // No temporary created.
93        W ( TypedInPlaceFactory2<X,int,std::string>(123,"hello")) ;
94    }
95
96The factories are divided in two groups:
97
98* [_TypedInPlaceFactories]: those which take the target type as a primary
99template parameter.
100* [_InPlaceFactories]: those with a template `construct(void*)` member
101function taking the target type.
102
103Within each group, all the family members differ only in the number of
104parameters allowed.
105
106This library provides an overloaded set of helper template functions to
107construct these factories without requiring unnecessary template parameters:
108
109    template<class A0,...,class AN>
110    InPlaceFactoryN <A0,...,AN> in_place ( A0 const& a0, ..., AN const& aN) ;
111
112    template<class T,class A0,...,class AN>
113    TypedInPlaceFactoryN <T,A0,...,AN> in_place ( T const& a0, A0 const& a0, ..., AN const& aN) ;
114
115In-place factories can be used generically by the wrapper and user as follows:
116
117    class W
118    {
119        X wrapped_ ;
120
121        public:
122
123        W ( X const& x ) : wrapped_(x) {}
124
125        template< class InPlaceFactory >
126        W ( InPlaceFactory const& fac ) { fac.template <X>construct(&wrapped_) ; }
127
128    } ;
129
130    void foo()
131    {
132        // Wrapped object constructed in-place via a InPlaceFactory.
133        // No temporary created.
134        W ( in_place(123,"hello") ) ;
135    }
136
137The factories are implemented in the headers: __IN_PLACE_FACTORY_HPP__ and __TYPED_IN_PLACE_FACTORY_HPP__
138
139[endsect]
140