16_in_place_factories.qbk 3.8 KB

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