On 03/15/2016 09:07 PM, Glen Fernandes wrote:
On Tue, Mar 15, 2016 at 8:58 PM, Phil Bouchard
wrote: Yes you're right. I need to make my references const.
[snip]
Thanks for the clarifications.
No problem. Remember the goal isn't to provide convoluted interfaces that are strange to people who are used to a simpler convention established in the C++ standard library (or Boost, or any other library that supports C++ allocator concepts).
The Allocator class template in the example you have is a valid C++ stateful allocator. Observe how it is used with existing C++ standard library facilities that are allocator aware:
int c1 = 0, c2 = 0;
vector
v(Allocator<char>(c1, c2)); list
l(Allocator<int>(c1, c2)); function
f(allocator_arg, Allocator<void>(c1, c2), [](int){ }); auto p = allocate_shared<double>(Allocator<double>(c1, c2), 1.5);
With your root_ptr, the interface for creation should be equally simple. No temporaries required. No extremely long type definitions required. And certainly no expressions that look like: new (temporary) Type(temporary, ...) (i.e. an expression that looks like 'temporary' is both the subject of the placement-new and an argument to the constructor of Type).
I'm still working on it but right now I have already simplified the syntax, by adding a wrapper function, to: int main() { int n1 = 0, m1 = 0; int n2 = 0, m2 = 0; { typedef boost::node node; boost::root_ptr<U> p1, p2, p3; node::allocator_type a1(n1, m1); node::allocator_type a2(n2, m2); node::allocator_type a3(n2, m2); p1 = node::allocate(a1, 1, 'a'); p2 = node::allocate(a2, 2, 'b'); p3 = node::allocate(a3, 3, 'c'); if (n1 != 1 || m1 != 1 || n2 != 2 || m2 != 2) { throw 3; } } if (n1 != 0 || m1 != 0 || n2 != 0 || m2 != 0) { throw 4; } } -Phil