[mpl][docs]why use list?

Comparing the vector doc: http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/vector.html which contains: supports constant-time insertion and removal of elements at both ends, and linear-time insertion and removal of elements in the middle. with the list doc: http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/list.html which contains: supports constant-time insertion and removal of elements at the beginning, and linear-time insertion and removal of elements at the end and in the middle. shows these documents indicate no reason to prefer list over vector but does indicate a reason to prefer vector over list. Is there any reason to prefer list over of vector? -regards, Larry

AMDG Larry Evans wrote:
Comparing the vector doc:
http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/vector.html
which contains:
supports constant-time insertion and removal of elements at both ends, and linear-time insertion and removal of elements in the middle.
with the list doc:
http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/list.html
which contains:
supports constant-time insertion and removal of elements at the beginning, and linear-time insertion and removal of elements at the end and in the middle.
shows these documents indicate no reason to prefer list over vector but does indicate a reason to prefer vector over list. Is there any reason to prefer list over of vector?
Usually vector is better. The maximum size of a vector is 50 on compilers that don't support typeof. Also, it is possible for memoization to reduce the number of template instantiations when iterating over lists with identical tails, iterators into distinct vectors always have different types. In Christ, Steven Watanabe

On 03/21/09 11:31, Steven Watanabe wrote: Thank you Steven for your response.
AMDG
Larry Evans wrote:
[snip]
Is there any reason to prefer list over of vector?
Usually vector is better. The maximum size of a vector is 50 on compilers that don't support typeof.
Unfortunately, following the directions on: http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/limit-vector-siz... I created vector_max.cpp which had an 80 element vector preceded by this at the top of the file: -{--cut here-- #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #define BOOST_MPL_LIMIT_VECTOR_SIZE 80 #include <boost/mpl/vector.hpp> -}--cut here-- However, compilation resulted in: -{--compilation-- /home/evansl/download/gcc/4.4-20090109/install/bin/g++ -c -Wall -ftemplate-depth-100 -O0 -fno-inline -I/home/evansl/prog_dev/boost-svn/ro/boost-trunk vector_max.cpp -o /home/evansl/prog_dev/boost-svn/ro/boost-trunk/sandbox/build/gcc4_4/variadic-templates/libs/mpl/sandbox/vector_max.o -MMD In file included from vector_max.cpp:10: /home/evansl/prog_dev/boost-svn/ro/boost-trunk/boost/mpl/vector.hpp:36:73: error: boost/mpl/vector/vector80.hpp: No such file or directory In file included from /home/evansl/prog_dev/boost-svn/ro/boost-trunk/boost/preprocessor/iteration/detail/iter/forward1.hpp:47, from /home/evansl/prog_dev/boost-svn/ro/boost-trunk/boost/mpl/aux_/sequence_wrapper.hpp:164, from /home/evansl/prog_dev/boost-svn/ro/boost-trunk/boost/mpl/vector.hpp:54, -}--compilation-- Does anyone know what I might be doing wrong?
Also, it is possible for memoization to reduce the number of template instantiations when iterating over lists with identical tails, iterators into distinct vectors always have different types.
Thank you. This is what I needed to know. In summary. vector is better for modification at end. list may be better for traversal over many lists with similar tails. This list advantage is true for compilar using memoization. This information would have been useful to me while developing the variadic template version of mpl because, IIRC, I started trying to emulate the mpl list, but couldn't see any reason to continue. As a result, the mpl-vt.zip in vault only has the package template which is used to implement both the vector and list templates. So, I'd recommend adding this justification for list to the docs. [snip]

Larry Evans wrote:
Unfortunately, following the directions on:
http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/limit-vector-siz...
I created vector_max.cpp which had an 80 element vector preceded by this at the top of the file: -{--cut here-- #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS #define BOOST_MPL_LIMIT_VECTOR_SIZE 80 #include <boost/mpl/vector.hpp> -}--cut here--
However, compilation resulted in:
-{--compilation--
/home/evansl/download/gcc/4.4-20090109/install/bin/g++ -c -Wall -ftemplate-depth-100 -O0 -fno-inline -I/home/evansl/prog_dev/boost-svn/ro/boost-trunk vector_max.cpp -o /home/evansl/prog_dev/boost-svn/ro/boost-trunk/sandbox/build/gcc4_4/variadic-templates/libs/mpl/sandbox/vector_max.o -MMD In file included from vector_max.cpp:10: /home/evansl/prog_dev/boost-svn/ro/boost-trunk/boost/mpl/vector.hpp:36:73: error: boost/mpl/vector/vector80.hpp: No such file or directory In file included from /home/evansl/prog_dev/boost-svn/ro/boost-trunk/boost/preprocessor/iteration/detail/iter/forward1.hpp:47,
from /home/evansl/prog_dev/boost-svn/ro/boost-trunk/boost/mpl/aux_/sequence_wrapper.hpp:164,
from
/home/evansl/prog_dev/boost-svn/ro/boost-trunk/boost/mpl/vector.hpp:54,
-}--compilation--
Does anyone know what I might be doing wrong?
You can find the answer here http://lists.boost.org/boost-users/2004/08/7647.php. BR, Dmitry

On 03/23/09 06:11, Dmitry Goncharov wrote:
Larry Evans wrote:
Unfortunately, following the directions on:
http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/limit-vector-siz...
[snip]
Does anyone know what I might be doing wrong?
You can find the answer here http://lists.boost.org/boost-users/2004/08/7647.php.
Thank you, Dmitry. AFAICT, this is a documentation bug. Although limit-vector-size.html contains: [Note: Overriding will take effect only if the library is configured not to use preprocessed headers. See BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS for more information. — end note] looking at: http://www.boost.org/doc/libs/1_38_0/libs/mpl/doc/refmanual/cfg-no-preproces... which contains: When defined, it instructs the MPL to discard the pre-generated headers found in boost/mpl/aux_/preprocessed directory and use preprocessor metaprogramming techniques to generate the necessary versions of the library components on the fly. suggests that mpl will do the metaprogramming when, in fact, the user must either do the metaprogramming: http://lists.boost.org/boost-users/2004/08/7647.php or the user must first invoke a python program to generate some headers before doing the compile: http://lists.boost.org/boost-users/2004/08/7621.php If nobody disagrees (within the next day or so), I'll create a trac-ticket for this doc bug. -regards, Larry

On 03/23/09 05:40, Larry Evans wrote:
On 03/21/09 11:31, Steven Watanabe wrote: [snip]
Also, it is possible for memoization to reduce the number of template instantiations when iterating over lists with identical tails, iterators into distinct vectors always have different types.
Thank you. This is what I needed to know. In summary.
[snip] Hi Steven, After viewing the code some more, I'm wondering if the memoization is not also possible with vectors with identical tails. That's because, from: https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/preproc... containing: template< 39 typename T0, typename T1, typename T2 40 > 41 struct vector3 42 : v_item< 43 T2 44 , vector2< T0,T1 > 45 > 46 { 47 typedef vector3 type; 48 }; it appears that vector would have a memoization advantage for idential heads. For instance: vector<T0,T1,T2_1> vs vector<T0,T1,T2_2> from the above vector3 code: v_item<T2_1,vector2<T0,T1> > vs v_item<T2_2,vector2<T0,T1> > So, maybe list has an advantage for identical tails but vector has an advantage for identical heads? -regards, Larry

AMDG Larry Evans wrote:
After viewing the code some more, I'm wondering if the memoization is not also possible with vectors with identical tails. That's because, from:
https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/preproc...
containing:
template< 39 typename T0, typename T1, typename T2 40 > 41 struct vector3 42 : v_item< 43 T2 44 , vector2< T0,T1 > 45 > 46 { 47 typedef vector3 type; 48 };
it appears that vector would have a memoization advantage for idential heads. For instance:
vector<T0,T1,T2_1> vs vector<T0,T1,T2_2>
from the above vector3 code:
v_item<T2_1,vector2<T0,T1> > vs v_item<T2_2,vector2<T0,T1> >
So, maybe list has an advantage for identical tails but vector has an advantage for identical heads?
No. Take a look at how the iterators for vector work. template< typename Vector , BOOST_MPL_AUX_NTTP_DECL(long, n_) > struct v_iter; Iterators into different vectors are always distinct. In Christ, Steven Watanabe

On 03/27/09 10:43, Steven Watanabe wrote:
AMDG
Larry Evans wrote:
After viewing the code some more, I'm wondering if the memoization is not also possible with vectors with identical tails. [snip] So, maybe list has an advantage for identical tails but vector has an advantage for identical heads?
No. Take a look at how the iterators for vector work.
template< typename Vector , BOOST_MPL_AUX_NTTP_DECL(long, n_)
struct v_iter;
Iterators into different vectors are always distinct.
Ah! Thanks. Now, on a related matter, what's the rationale for vector0::lower_bound_::value == 32768 as shown here: https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/vector0... and what's the rationale for at_front=0 here: https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/item.hp... The only reason, AFAICT, for the at_front value is that the vectorI specializations here: https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/preproc... for some reason add items starting from the tail, as shown at: https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/preproc... However, if the items were added from the head, then at_front=1 could be used. The reason that would be desirable is that it enables the variadic template compiler to used to simplify the mpl::vector implementation, as shown here: TinyURL.com/cof5br The reason I'd like to know the vector0::lower_bound_::value rationale is I'd like to add that to the in source documentation. However, as you can see from looking at the current mpl/vector/aux_/vector0.hpp source file, I can't figure out a good reason for 32768. Thanks very much for your help, Steven. -regards, Larry

AMDG Larry Evans wrote:
Now, on a related matter,
what's the rationale for vector0::lower_bound_::value == 32768
push_front decreases lower_bound_, and the lower_bound_ needs to stay positive. the lower_bound_ in vector zero needs to be fairly high to avoid problems. There is no reason why it has to be exactly 32768.
as shown here:
https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/vector0...
and what's the rationale for at_front=0 here:
https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/item.hp...
The only reason, AFAICT, for the at_front value is that the vectorI specializations here:
https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/preproc...
for some reason add items starting from the tail, as shown at:
https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/preproc...
However, if the items were added from the head, then at_front=1 could be used. The reason that would be desirable is that it enables the variadic template compiler to used to simplify the mpl::vector implementation, as shown here:
TinyURL.com/cof5br at_front indicates whether to use push_front or push_back. It's really a bool not an int.
In Christ, Steven Watanabe

On 03/29/09 14:35, Steven Watanabe wrote: [snip]
what's the rationale for vector0::lower_bound_::value == 32768
push_front decreases lower_bound_, and the lower_bound_ needs to stay positive. the lower_bound_ in vector zero needs to be fairly high to avoid problems. There is no reason why it has to be exactly 32768.
OK. That's what I initially thought, i.e. it has to be positive; however, I'm wondering if that's true. What would happen if it it were zero? I know the v_item<_,_1> uses prior; however, I don't see how that would cause a problem. After all, the static item_ function only requires some type which just happens to be, in the current implementation, an instance of long_, but why couldn't there be an item_<long_<-1> >? Is there some other piece of code that requires a positive index_? [snip]
However, if the items were added from the head, then at_front=1 could be used. The reason that would be desirable is that it enables the variadic template compiler to used to simplify the mpl::vector implementation, as shown here:
TinyURL.com/cof5br at_front indicates whether to use push_front or push_back. It's really a bool not an int.
I understand; however, I really just wanted to know why the items could be added from the front instead of the back. This would allow the least change to the code in order to use a variadic template compiler, AFAICT. Thanks again Steven, -Larry

On Sun, 29 Mar 2009 16:33:14 -0500, Larry Evans <cppljevans@suddenlink.net> wrote:
On 03/29/09 14:35, Steven Watanabe wrote: [snip]
what's the rationale for vector0::lower_bound_::value == 32768 push_front decreases lower_bound_, and the lower_bound_ needs to stay positive. the lower_bound_ in vector zero needs to be fairly high to avoid problems. There is no reason why it has to be exactly 32768.
OK. That's what I initially thought, i.e. it has to be positive; however, I'm wondering if that's true. What would happen if it it were zero? I know the v_item<_,_1> uses prior; however, I don't see how that would cause a problem. After all, the static item_ function only requires some type which just happens to be, in the current implementation, an instance of long_, but why couldn't there be an item_<long_<-1> >? Is there some other piece of code that requires a positive index_?
This might be a historic artifact at this point. It's easy enough to verify: just change it to go negative and run the tests :).
at_front indicates whether to use push_front or push_back. It's really a bool not an int.
I understand; however, I really just wanted to know why the items could be added from the front instead of the back.
It makes vector a more versatile sequence at almost no cost, thus helping to avoid proliferation of different types of sequences user has to chose from. HTH, -- Aleksey Gurtovoy MetaCommunications Engineering

On 04/06/09 00:23, Aleksey Gurtovoy wrote:
On Sun, 29 Mar 2009 16:33:14 -0500, Larry Evans [snip]
This might be a historic artifact at this point. It's easy enough to verify: just change it to go negative and run the tests :).
Did that and it runs OK: However, I just ran the test on the variadic version of gcc4.4.
at_front indicates whether to use push_front or push_back. It's really a bool not an int.
I understand; however, I really just wanted to know why the items could be added from the front instead of the back.
It makes vector a more versatile sequence at almost no cost, thus helping to avoid proliferation of different types of sequences user has to chose from.
HTH,
Thank you Aleksey; however, I'm not sure I made myself clear. I'm not wondering why vector has a push_back, I'm wondering why the implementation here: https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/preproc... adds from the back instead of the front. IOW, instead of: 26 template< 27 typename T0, typename T1 28 > 29 struct vector2 30 : v_item< 31 T1 32 , vector1<T0> 33 > 34 { 35 typedef vector2 type; 36 }; why not: 26 template< 27 typename T0, typename T1 28 > 29 struct vector2 30 : v_item< 31 T0 32 , vector1<T1> 33 > 34 { 35 typedef vector2 type; 36 }; The reason for doing it this way is that the variadic template compiler can be used as follows: template < typename Head , typename... Tail
struct vector < Head , Tail...
: v_item < Head , vector<Tail...> > { ... }; This compiler can't do it the other way because the argument packs (e.g. Tail...) must occur at the end and not at the beginning. I've actually run the tests on this and they pass the tests. -regards, Larry

On Mon, 06 Apr 2009 08:11:06 -0500, Larry Evans <cppljevans@suddenlink.net> wrote:
Thank you Aleksey; however, I'm not sure I made myself clear. I'm not wondering why vector has a push_back, I'm wondering why the implementation here:
https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/preproc...
adds from the back instead of the front. IOW, instead of:
26 template< 27 typename T0, typename T1 28 > 29 struct vector2 30 : v_item< 31 T1 32 , vector1<T0> 33 > 34 { 35 typedef vector2 type; 36 };
why not:
26 template< 27 typename T0, typename T1 28 > 29 struct vector2 30 : v_item< 31 T0 32 , vector1<T1> 33 > 34 { 35 typedef vector2 type; 36 };
The former has potential for better compilation times due to memoization gains on reusing a likely existing vector(n-1) instantiation in vector(n), e.g. vector2<T0,T1> -> vector2<T0,T1>, vector1<T0> vector3<T0,T1,T2> -> vector3<T0,T1,T2>, vector2<T0,T1>*, vector1<T0>* vs. vector2<T0,T1> -> vector2<T0,T1>, vector1<T1> vector3<T0,T1,T2> -> vector3<T0,T1,T2>, vector2<T1,T2>, vector1<T2> (*) reused instantiation Personally, I also find the first formulation more intuitive. HTH, -- Aleksey Gurtovoy MetaCommunications Engineering

On 04/12/09 01:55, Aleksey Gurtovoy wrote:
On Mon, 06 Apr 2009 08:11:06 -0500, Larry Evans <cppljevans@suddenlink.net> wrote:
[snip]
I'm wondering why the implementation here:
https://svn.boost.org/trac/boost/browser/trunk/boost/mpl/vector/aux_/preproc...
adds from the back instead of the front. IOW, instead of:
26 template< 27 typename T0, typename T1 28 > 29 struct vector2 30 : v_item< 31 T1 32 , vector1<T0> 33 > 34 { 35 typedef vector2 type; 36 };
why not:
26 template< 27 typename T0, typename T1 28 > 29 struct vector2 30 : v_item< 31 T0 32 , vector1<T1> 33 > 34 { 35 typedef vector2 type; 36 };
The former has potential for better compilation times due to memoization gains on reusing a likely existing vector(n-1) instantiation in vector(n), e.g.
vector2<T0,T1> -> vector2<T0,T1>, vector1<T0> vector3<T0,T1,T2> -> vector3<T0,T1,T2>, vector2<T0,T1>*, vector1<T0>*
vs.
vector2<T0,T1> -> vector2<T0,T1>, vector1<T1> vector3<T0,T1,T2> -> vector3<T0,T1,T2>, vector2<T1,T2>, vector1<T2>
(*) reused instantiation
Ah! I see. Hmm... what about: vector2<T1,T2> -> vector2<T1,T2>, vector1<T2> vector3<T0,T1,T2> -> vector3<T0,T1,T2>, vector2<T1,T2>*, vector1<T2>* (*) reused instantiation IOW, if the vector3 differs from the vector2 by push_front, then the latter method (using v_item starting from the head,i.e. the proposed method) would have the memoization advantage, but if the vector3 differs from the vector2 by a push_back then the former method (using v_item starting from the tail,i.e., the existing method) would have the memoization advantage. If that's right, then maybe there should be a vec_back and vec_front where vec_back is the existing vector and vec_front is the proposed vector. Then the docs for vec_back and vec_front would highlight why one might be preferred over the other. But OOPS, vec_back couldn't take advantage of a variadic compiler since (as mentioned previously) the existing variadic compiler only allows parameter packs at the end. Instead, it would have to resort to the existing preprocessor :(. [snip]
HTH,
Yes, thanks very much. -regards, Larry
participants (4)
-
Aleksey Gurtovoy
-
Dmitry Goncharov
-
Larry Evans
-
Steven Watanabe