[Boost.Assign] list_of::range without an initial (single) element?

What is the recommended way of initializing an array from a
concatenation of other arrays?
list_of::range looks right and I would like to use something like:
array

Michael McNeil Forbes wrote:
What is the recommended way of initializing an array from a concatenation of other arrays?
list_of::range looks right and I would like to use something like:
array
a = { 1, 2 }; array b = { 3, 4 }; array c = list_of<int>().range(a).range(b); However, list_of<int>() inserts a default value (so that list_of<int>().range(a).range(b) == {0,1,2,3,4}). There are several workarounds, e.g.
array
c = list_of<int>(a[0]) .range(a.begin()+1, a.end()) .range(b); array c = boost::assign_detail::generic_list<int>() .range(a) .range(b); The first is ugly; the second seems an abuse of assign_detail (and fails for static_generic_list).
I am sure I am missing a simple solution, but can't seem to find it.
Thanks, Michael.
The proposed extension of Boost.Assign offers an alternative approach to
this problem:
boost::array

er skrev:
Michael McNeil Forbes wrote:
What is the recommended way of initializing an array from a concatenation of other arrays?
list_of::range looks right and I would like to use something like:
array
a = { 1, 2 }; array b = { 3, 4 }; array c = list_of<int>().range(a).range(b); However, list_of<int>() inserts a default value (so that list_of<int>().range(a).range(b) == {0,1,2,3,4}).
Maybe we should add empty_list_of<int>() ? It's quite trivial to add. -Thorsten

Thorsten Ottosen wrote:
However, list_of<int>() inserts a default value (so that list_of<int>().range(a).range(b) == {0,1,2,3,4}).
Maybe we should add
empty_list_of<int>()
? It's quite trivial to add.
Does list_of<T>() have a default value for its T parameter? Maybe introduce no-params list_of<T>() to produce an empty list, while list_of<T>(const T&) keeps its current implementation? That would seem to behave intuitively in both cases...

Nat Goodspeed skrev:
Thorsten Ottosen wrote:
However, list_of<int>() inserts a default value (so that list_of<int>().range(a).range(b) == {0,1,2,3,4}).
Maybe we should add
empty_list_of<int>()
? It's quite trivial to add.
Does list_of<T>() have a default value for its T parameter?
No, how could it?
Maybe introduce no-params list_of<T>() to produce an empty list, while list_of<T>(const T&) keeps its current implementation? That would seem to behave intuitively in both cases...
Just to be clear, you want list_of() to be empty_list_of<*any type*>(), and for the type of the list to be deduced by the first argument: list_of()(42); would be a list of ints with one value (42). ? If so, I think this syntax is possible, but I am worried that the difference between list_of() and list_of<T>() is too subtle. -Thorsten

Thorsten Ottosen wrote:
Nat Goodspeed skrev:
Thorsten Ottosen wrote:
However, list_of<int>() inserts a default value (so that list_of<int>().range(a).range(b) == {0,1,2,3,4}).
Maybe we should add
empty_list_of<int>()
? It's quite trivial to add.
Does list_of<T>() have a default value for its T parameter?
No, how could it?
In that case, I'm confused about why list_of<int>() inserts a default value.

Nat Goodspeed skrev:
Thorsten Ottosen wrote:
Nat Goodspeed skrev:
Thorsten Ottosen wrote:
However, list_of<int>() inserts a default value (so that list_of<int>().range(a).range(b) == {0,1,2,3,4}).
Maybe we should add
empty_list_of<int>()
? It's quite trivial to add.
Does list_of<T>() have a default value for its T parameter?
No, how could it?
... as it cannot assume what T will be.
In that case, I'm confused about why list_of<int>() inserts a default value.
It was a consistency issue. Consider list_of<int>()(42); // 0, 42 list_of<int>(42)(); // 42, 0 list_of(42)(); // 42, 0 would you expect that to be any different? -Thorsten

Thorsten Ottosen wrote:
In that case, I'm confused about why list_of<int>() inserts a default value.
It was a consistency issue. Consider
list_of<int>()(42); // 0, 42 list_of<int>(42)(); // 42, 0 list_of(42)(); // 42, 0
would you expect that to be any different?
I suppose the only consistent interpretation would be for either () to be a no-op (no default's) Proposal 1: list_of<int>()(42); // 42 list_of<int>(42)(); // 42 list_of(42)(); // 42 or the slightly more complex rule that the default constructor always returns an empty list and () only inserts after the list has been created: Proposal 2: list_of<int>(42); // 42 list_of<int>()(42); // 42 list_of<int>(42)(); // 42, 0 list_of(42); // 42 list_of()(42); // 42 list_of(42)(); // 42, 0 list_of<int>()(); // 0 list_of()(); // 0 Michael.

Thorsten Ottosen wrote:
Nat Goodspeed skrev:
However, list_of<int>() inserts a default value (so that list_of<int>().range(a).range(b) == {0,1,2,3,4}).
Maybe we should add
empty_list_of<int>()
? It's quite trivial to add.
...
Maybe introduce no-params list_of<T>() to produce an empty list, while list_of<T>(const T&) keeps its current implementation? That would seem to behave intuitively in both cases...
Just to be clear, you want list_of() to be empty_list_of<*any type*>(), and for the type of the list to be deduced by the first argument:
list_of()(42);
would be a list of ints with one value (42).
This is what I was expecting when I first started. Semantically this behaviour seems to make sense, but I have not thought too deeply about it.
If so, I think this syntax is possible, but I am worried that the difference between list_of() and list_of<T>() is too subtle.
What exactly would be the subtle difference between these two? Would
they not both be forms of empty lists, except the second form would
only accept arguments of type T?
The other thing I was expecting was perhaps an exposed range()
function so that one can just go:
... = range(a).range(b)
(I also thought that the exposed repeat() functions would also allow
for this:
boost::array

I have to look more deeply into the new proposal for operator&&(), but it seems a little specific. Is there no way that the ideas discussed
operator && is fairly general as it works for any pair of ranges and is composable: v1 && v2 && v3 It also preserves lvalue-ness e.g. boost::copy( v4, boost::begin( v1 && v2 ) ); Either of v1 and v2, here, can be a range of reference wrappers, so, for example, this call to copy could be preceded by BOOST_AUTO(v1,ref_csv(a,b,c)); // v1 is an array of ref-wrappers std::vector<int> v2(2); Internally it uses chain.hpp from RangeEx. By the way, I didn't see it in the latest release, so I've made the file temporarily avail here: http://svn.boost.org/svn/boost/sandbox/statistics/support/boost/range/
here could be made as efficient, requiring a separate operator&&() for chaining? As a user, I would not mind being steered towards the efficient usage if documented properly.
If you have specifics in mind, please let us know. http://svn.boost.org/svn/boost/sandbox/statistics/support/libs/assign/doc/in... Thanks.

Michael McNeil Forbes skrev:
Thorsten Ottosen wrote:
Just to be clear, you want list_of() to be empty_list_of<*any type*>(), and for the type of the list to be deduced by the first argument:
list_of()(42);
would be a list of ints with one value (42).
This is what I was expecting when I first started. Semantically this behaviour seems to make sense, but I have not thought too deeply about it.
If so, I think this syntax is possible, but I am worried that the difference between list_of() and list_of<T>() is too subtle.
What exactly would be the subtle difference between these two? Would they not both be forms of empty lists, except the second form would only accept arguments of type T?
Currently list_of<int>() is not an empty list.
The other thing I was expecting was perhaps an exposed range() function so that one can just go:
... = range(a).range(b)
(I also thought that the exposed repeat() functions would also allow for this:
boost::array
c = boost::assign::repeat(4, 5); use but I apparently do not understand yet how the exposed repeat is intended to be used.)
array has a fill member for that purpose, albeit it lacks a constructor. No, repeat() and range() are used inside lists: push_back( vec ) += 1,2,3,repeat(4,5),range(other_rng),5,6,7;
I have to look more deeply into the new proposal for operator&&(), but it seems a little specific. Is there no way that the ideas discussed here could be made as efficient, requiring a separate operator&&() for chaining? As a user, I would not mind being steered towards the efficient usage if documented properly.
The new methods are quite efficient. In the old library, list_of<T>() is not efficient (ease of use is the key goal here), whereas ref_list_of<T>()/cref_list_of() are. -Thorsten -Thorsten
participants (4)
-
er
-
Michael McNeil Forbes
-
Nat Goodspeed
-
Thorsten Ottosen