Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / intrusive / test / slist_test.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Olaf Krzikalla 2004-2006.
4 // (C) Copyright Ion Gaztanaga  2006-2013.
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 //    (See accompanying file LICENSE_1_0.txt or copy at
8 //          http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // See http://www.boost.org/libs/intrusive for documentation.
11 //
12 /////////////////////////////////////////////////////////////////////////////
13
14 #include <boost/intrusive/slist.hpp>
15 #include <boost/intrusive/pointer_traits.hpp>
16 #include "itestvalue.hpp"
17 #include "bptr_value.hpp"
18 #include "smart_ptr.hpp"
19 #include "common_functors.hpp"
20 #include <vector>
21 #include <boost/detail/lightweight_test.hpp>
22 #include "test_macros.hpp"
23 #include "test_container.hpp"
24 #include <typeinfo>
25
26 using namespace boost::intrusive;
27
28 struct my_tag;
29
30 template<class VoidPointer>
31 struct hooks
32 {
33    typedef slist_base_hook<void_pointer<VoidPointer> >                  base_hook_type;
34    typedef slist_base_hook< link_mode<auto_unlink>
35                          , void_pointer<VoidPointer>, tag<my_tag> >     auto_base_hook_type;
36    typedef slist_member_hook<void_pointer<VoidPointer>, tag<my_tag> >   member_hook_type;
37    typedef slist_member_hook< link_mode<auto_unlink>
38                            , void_pointer<VoidPointer> >                auto_member_hook_type;
39    typedef nonhook_node_member< slist_node_traits< VoidPointer >,
40                                 circular_slist_algorithms
41                               > nonhook_node_member_type;
42 };
43
44 template < typename List_Type, typename Value_Container >
45 struct test_slist
46 {
47    typedef List_Type list_type;
48    typedef typename list_type::value_traits value_traits;
49    typedef typename value_traits::value_type value_type;
50    typedef typename list_type::node_algorithms node_algorithms;
51
52    static void test_all(Value_Container&);
53    static void test_front(Value_Container&);
54    static void test_back(Value_Container&, detail::true_type);
55    static void test_back(Value_Container&, detail::false_type) {}
56    static void test_sort(Value_Container&);
57    static void test_merge(Value_Container&);
58    static void test_remove_unique(Value_Container&);
59    static void test_insert(Value_Container&);
60    static void test_shift(Value_Container&);
61    static void test_swap(Value_Container&);
62    static void test_slow_insert(Value_Container&);
63    static void test_clone(Value_Container&);
64    static void test_container_from_end(Value_Container&, detail::true_type);
65    static void test_container_from_end(Value_Container&, detail::false_type) {}
66 };
67
68 template < typename List_Type, typename Value_Container >
69 void test_slist< List_Type, Value_Container >
70    ::test_all (Value_Container& values)
71 {
72    {
73       list_type list(values.begin(), values.end());
74       test::test_container(list);
75       list.clear();
76       list.insert(list.end(), values.begin(), values.end());
77       test::test_sequence_container(list, values);
78    }
79    test_front(values);
80    test_back(values, detail::bool_< list_type::cache_last >());
81    test_sort(values);
82    test_merge (values);
83    test_remove_unique(values);
84    test_insert(values);
85    test_shift(values);
86    test_slow_insert (values);
87    test_swap(values);
88    test_clone(values);
89    test_container_from_end(values, detail::bool_< !list_type::linear && list_type::has_container_from_iterator >());
90 }
91
92 //test: push_front, pop_front, front, size, empty:
93 template < typename List_Type, typename Value_Container >
94 void test_slist< List_Type, Value_Container >
95    ::test_front(Value_Container& values)
96 {
97    list_type testlist;
98    BOOST_TEST (testlist.empty());
99
100    testlist.push_front (values[0]);
101    BOOST_TEST (testlist.size() == 1);
102    BOOST_TEST (&testlist.front() == &values[0]);
103
104    testlist.push_front (values[1]);
105    BOOST_TEST (testlist.size() == 2);
106    BOOST_TEST (&testlist.front() == &values[1]);
107
108    testlist.pop_front();
109    BOOST_TEST (testlist.size() == 1);
110    BOOST_TEST (&testlist.front() == &values[0]);
111
112    testlist.pop_front();
113    BOOST_TEST (testlist.empty());
114 }
115
116 //test: push_front, pop_front, front, size, empty:
117 template < typename List_Type, typename Value_Container >
118 void test_slist< List_Type, Value_Container >
119    ::test_back(Value_Container& values, detail::true_type)
120 {
121    list_type testlist;
122    BOOST_TEST (testlist.empty());
123
124    testlist.push_back (values[0]);
125    BOOST_TEST (testlist.size() == 1);
126    BOOST_TEST (&testlist.front() == &values[0]);
127    BOOST_TEST (&testlist.back() == &values[0]);
128    testlist.push_back(values[1]);
129    BOOST_TEST(*testlist.previous(testlist.end()) == values[1]);
130    BOOST_TEST (&testlist.front() == &values[0]);
131    BOOST_TEST (&testlist.back() == &values[1]);
132 }
133
134 //test: merge due to error in merge implementation:
135 template < typename List_Type, typename Value_Container >
136 void test_slist< List_Type, Value_Container >
137    ::test_merge (Value_Container& values)
138 {
139    list_type testlist1, testlist2;
140    testlist1.push_front (values[0]);
141    testlist2.push_front (values[4]);
142    testlist2.push_front (values[3]);
143    testlist2.push_front (values[2]);
144    testlist1.merge (testlist2);
145
146    int init_values [] = { 1, 3, 4, 5 };
147    TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );
148 }
149
150 //test: merge due to error in merge implementation:
151 template < typename List_Type, typename Value_Container >
152 void test_slist< List_Type, Value_Container >
153    ::test_remove_unique (Value_Container& values)
154 {
155    {
156       list_type list(values.begin(), values.end());
157       list.remove_if(is_even());
158       int init_values [] = { 1, 3, 5 };
159       TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
160    }
161    {
162       list_type list(values.begin(), values.end());
163       list.remove_if(is_odd());
164       int init_values [] = { 2, 4 };
165       TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
166    }
167    {
168       list_type list(values.begin(), values.end());
169       list.remove_and_dispose_if(is_even(), test::empty_disposer());
170       int init_values [] = { 1, 3, 5 };
171       TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
172    }
173    {
174       list_type list(values.begin(), values.end());
175       list.remove_and_dispose_if(is_odd(), test::empty_disposer());
176       int init_values [] = { 2, 4 };
177       TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
178    }
179    {
180       Value_Container values2(values);
181       list_type list(values.begin(), values.end());
182       list.insert_after(list.before_begin(), values2.begin(), values2.end());
183       list.sort();
184       int init_values [] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 };
185       TEST_INTRUSIVE_SEQUENCE( init_values, list.begin() );
186       list.unique();
187       int init_values2 [] = { 1, 2, 3, 4, 5 };
188       TEST_INTRUSIVE_SEQUENCE( init_values2, list.begin() );
189    }
190 }
191
192 //test: constructor, iterator, sort, reverse:
193 template < typename List_Type, typename Value_Container >
194 void test_slist< List_Type, Value_Container >
195    ::test_sort(Value_Container& values)
196 {
197    list_type testlist (values.begin(), values.end());
198
199    {  int init_values [] = { 1, 2, 3, 4, 5 };
200       TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() );  }
201
202    testlist.sort (even_odd());
203    {  int init_values [] = { 2, 4, 1, 3, 5 };
204       TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() );  }
205
206    testlist.reverse();
207    {  int init_values [] = { 5, 3, 1, 4, 2 };
208       TEST_INTRUSIVE_SEQUENCE( init_values, testlist.begin() );  }
209 }
210
211 //test: assign, insert_after, const_iterator, erase_after, s_iterator_to, previous:
212 template < typename List_Type, typename Value_Container >
213 void test_slist< List_Type, Value_Container >
214    ::test_insert(Value_Container& values)
215 {
216    list_type testlist;
217    testlist.assign (values.begin() + 2, values.begin() + 5);
218
219    const list_type& const_testlist = testlist;
220    {  int init_values [] = { 3, 4, 5 };
221       TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
222
223    typename list_type::iterator i = ++testlist.begin();
224    BOOST_TEST (i->value_ == 4);
225
226    testlist.insert_after (i, values[0]);
227    {  int init_values [] = { 3, 4, 1, 5 };
228       TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
229
230    i = testlist.iterator_to (values[4]);
231    BOOST_TEST (&*i == &values[4]);
232    i = list_type::s_iterator_to (values[4]);
233    BOOST_TEST (&*i == &values[4]);
234
235    typename list_type::const_iterator ic;
236    ic = testlist.iterator_to (static_cast< typename list_type::const_reference >(values[4]));
237    BOOST_TEST (&*ic == &values[4]);
238    ic = list_type::s_iterator_to (static_cast< typename list_type::const_reference >(values[4]));
239    BOOST_TEST (&*ic == &values[4]);
240
241    i = testlist.previous (i);
242    BOOST_TEST (&*i == &values[0]);
243
244    testlist.erase_after (i);
245    BOOST_TEST (&*i == &values[0]);
246    {  int init_values [] = { 3, 4, 1 };
247       TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
248 }
249
250 //test: insert, const_iterator, erase, siterator_to:
251 template < typename List_Type, typename Value_Container >
252 void test_slist< List_Type, Value_Container >
253    ::test_slow_insert (Value_Container& values)
254 {
255    list_type testlist;
256    testlist.push_front (values[4]);
257    testlist.insert (testlist.begin(), values.begin() + 2, values.begin() + 4);
258
259    const list_type& const_testlist = testlist;
260    {  int init_values [] = { 3, 4, 5 };
261       TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
262
263    typename list_type::iterator i = ++testlist.begin();
264    BOOST_TEST (i->value_ == 4);
265
266    testlist.insert (i, values[0]);
267    {  int init_values [] = { 3, 1, 4, 5 };
268       TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
269
270    i = testlist.iterator_to (values[4]);
271    BOOST_TEST (&*i == &values[4]);
272
273    i = list_type::s_iterator_to (values[4]);
274    BOOST_TEST (&*i == &values[4]);
275
276    i = testlist.erase (i);
277    BOOST_TEST (i == testlist.end());
278
279    {  int init_values [] = { 3, 1, 4 };
280       TEST_INTRUSIVE_SEQUENCE( init_values, const_testlist.begin() );  }
281
282    testlist.erase (++testlist.begin(), testlist.end());
283    BOOST_TEST (testlist.size() == 1);
284    BOOST_TEST (testlist.begin()->value_ == 3);
285 }
286
287 template < typename List_Type, typename Value_Container >
288 void test_slist< List_Type, Value_Container >
289    ::test_shift(Value_Container& values)
290 {
291    list_type testlist;
292    const int num_values = (int)values.size();
293    std::vector<int> expected_values(num_values);
294
295    //Shift forward all possible positions 3 times
296    for(int s = 1; s <= num_values; ++s){
297       expected_values.resize(s);
298       for(int i = 0; i < s*3; ++i){
299          testlist.insert_after(testlist.before_begin(), values.begin(), values.begin() + s);
300          testlist.shift_forward(i);
301          for(int j = 0; j < s; ++j){
302             expected_values[(j + s - i%s) % s] = (j + 1);
303          }
304
305          TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin())
306          testlist.clear();
307       }
308
309       //Shift backwards all possible positions
310       for(int i = 0; i < s*3; ++i){
311          testlist.insert_after(testlist.before_begin(), values.begin(), values.begin() + s);
312          testlist.shift_backwards(i);
313          for(int j = 0; j < s; ++j){
314             expected_values[(j + i) % s] = (j + 1);
315          }
316
317          TEST_INTRUSIVE_SEQUENCE_EXPECTED(expected_values, testlist.begin())
318          testlist.clear();
319       }
320    }
321 }
322
323 //test: insert_after (seq-version), swap, splice_after:
324 template < typename List_Type, typename Value_Container >
325 void test_slist< List_Type, Value_Container >
326    ::test_swap(Value_Container& values)
327 {
328    {
329       list_type testlist1 (values.begin(), values.begin() + 2);
330       list_type testlist2;
331       testlist2.insert_after (testlist2.before_begin(), values.begin() + 2, values.begin() + 5);
332       testlist1.swap(testlist2);
333       {  int init_values [] = { 3, 4, 5 };
334          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
335       {  int init_values [] = { 1, 2 };
336          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
337          testlist2.splice_after (testlist2.begin(), testlist1);
338       {  int init_values [] = { 1, 3, 4, 5, 2 };
339          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
340       BOOST_TEST (testlist1.empty());
341
342       testlist1.splice_after (testlist1.before_begin(), testlist2, ++testlist2.begin());
343       {  int init_values [] = { 4 };
344          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
345       {  int init_values [] = { 1, 3, 5, 2 };
346          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
347
348       testlist1.splice_after (testlist1.begin(), testlist2,
349                               testlist2.before_begin(), ++++testlist2.begin());
350       {  int init_values [] = { 4, 1, 3, 5 };
351          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
352       {  int init_values [] = { 2 };
353          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
354    }
355    {  //Now test swap when testlist2 is empty
356       list_type testlist1 (values.begin(), values.begin() + 2);
357       list_type testlist2;
358       testlist1.swap(testlist2);
359       BOOST_TEST (testlist1.empty());
360       {  int init_values [] = { 1, 2 };
361          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
362    }
363    {  //Now test swap when testlist1 is empty
364       list_type testlist2 (values.begin(), values.begin() + 2);
365       list_type testlist1;
366       testlist1.swap(testlist2);
367       BOOST_TEST (testlist2.empty());
368       {  int init_values [] = { 1, 2 };
369          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
370    }
371    {  //Now test when both are empty
372       list_type testlist1, testlist2;
373       testlist2.swap(testlist1);
374       BOOST_TEST (testlist1.empty() && testlist2.empty());
375    }
376
377    if(!list_type::linear)
378    {
379       list_type testlist1 (values.begin(), values.begin() + 2);
380       list_type testlist2 (values.begin() + 3, values.begin() + 5);
381
382       swap_nodes< node_algorithms >(values[0], values[2]);
383       {  int init_values [] = { 3, 2 };
384          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
385
386       swap_nodes< node_algorithms >(values[2], values[4]);
387       {  int init_values [] = { 5, 2 };
388          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
389       {  int init_values [] = { 4, 3 };
390          TEST_INTRUSIVE_SEQUENCE( init_values, testlist2.begin() );  }
391    }
392    if(!list_type::linear)
393    {
394       list_type testlist1 (values.begin(), values.begin()+1);
395       if(testlist1.size() != 1){
396          abort();
397       }
398       {  int init_values [] = { 1 };
399          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
400
401       swap_nodes< node_algorithms >(values[1], values[2]);
402
403       BOOST_TEST(testlist1.size() == 1);
404       BOOST_TEST(!(&values[1])->is_linked());
405       BOOST_TEST(!(&values[2])->is_linked());
406       {  int init_values [] = { 1 };
407          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
408
409       swap_nodes< node_algorithms >(values[0], values[2]);
410       BOOST_TEST(testlist1.size() == 1);
411       BOOST_TEST((&values[2])->is_linked());
412       BOOST_TEST(!(&values[0])->is_linked());
413       {  int init_values [] = { 3 };
414          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
415
416       swap_nodes< node_algorithms >(values[0], values[2]);
417       BOOST_TEST(testlist1.size() == 1);
418       BOOST_TEST(!(&values[2])->is_linked());
419       BOOST_TEST((&values[0])->is_linked());
420       {  int init_values [] = { 1 };
421          TEST_INTRUSIVE_SEQUENCE( init_values, testlist1.begin() );  }
422    }
423 }
424
425 template < typename List_Type, typename Value_Container >
426 void test_slist< List_Type, Value_Container >
427    ::test_clone(Value_Container& values)
428 {
429       list_type testlist1 (values.begin(), values.begin() + values.size());
430       list_type testlist2;
431
432       testlist2.clone_from(testlist1, test::new_cloner<value_type>(), test::delete_disposer<value_type>());
433       BOOST_TEST (testlist2 == testlist1);
434       testlist2.clear_and_dispose(test::delete_disposer<value_type>());
435       BOOST_TEST (testlist2.empty());
436 }
437
438 template < typename List_Type, typename Value_Container >
439 void test_slist< List_Type, Value_Container >
440    ::test_container_from_end(Value_Container& values, detail::true_type)
441 {
442    list_type testlist1 (values.begin(), values.begin() + values.size());
443    BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.end()));
444    BOOST_TEST (testlist1 == list_type::container_from_end_iterator(testlist1.cend()));
445 }
446
447 template < typename Value_Traits, bool ConstantTimeSize, bool Linear, bool CacheLast, bool Default_Holder, typename Value_Container >
448 struct make_and_test_slist
449    : test_slist< slist< typename Value_Traits::value_type,
450                         value_traits< Value_Traits >,
451                         size_type< std::size_t >,
452                         constant_time_size< ConstantTimeSize >,
453                         linear<Linear>,
454                         cache_last<CacheLast>
455                       >,
456                   Value_Container
457                 >
458 {};
459
460 template < typename Value_Traits, bool ConstantTimeSize, bool Linear, bool CacheLast, typename Value_Container >
461 struct make_and_test_slist< Value_Traits, ConstantTimeSize, Linear, CacheLast, false, Value_Container >
462    : test_slist< slist< typename Value_Traits::value_type,
463                         value_traits< Value_Traits >,
464                         size_type< std::size_t >,
465                         constant_time_size< ConstantTimeSize >,
466                         linear<Linear>,
467                         cache_last<CacheLast>,
468                         header_holder_type< pointer_holder< typename Value_Traits::node_traits::node > >
469                       >,
470                   Value_Container
471                 >
472 {};
473
474 template<class VoidPointer, bool constant_time_size, bool Default_Holder>
475 class test_main_template
476 {
477    public:
478    int operator()()
479    {
480       typedef testvalue<hooks<VoidPointer> , constant_time_size> value_type;
481       std::vector< value_type > data (5);
482       for (int i = 0; i < 5; ++i)
483          data[i].value_ = i + 1;
484
485       make_and_test_slist < typename detail::get_base_value_traits
486                   < value_type
487                   , typename hooks<VoidPointer>::base_hook_type
488                   >::type
489                  , constant_time_size
490                  , false
491                  , false
492                  , Default_Holder
493                  , std::vector< value_type >
494                 >::test_all(data);
495       make_and_test_slist < typename detail::get_member_value_traits
496                   < member_hook< value_type
497                                , typename hooks<VoidPointer>::member_hook_type
498                                , &value_type::node_
499                                >
500                   >::type
501                  , constant_time_size
502                  , false
503                  , false
504                  , Default_Holder
505                  , std::vector< value_type >
506                 >::test_all(data);
507       make_and_test_slist < nonhook_node_member_value_traits< value_type,
508                                                      typename hooks<VoidPointer>::nonhook_node_member_type,
509                                                      &value_type::nhn_member_,
510                                                      safe_link
511                                                    >
512                  , constant_time_size
513                  , false
514                  , false
515                  , Default_Holder
516                  , std::vector< value_type >
517                 >::test_all(data);
518
519       //Now linear slists
520       make_and_test_slist < typename detail::get_base_value_traits
521                   < value_type
522                   , typename hooks<VoidPointer>::base_hook_type
523                   >::type
524                  , constant_time_size
525                  , true
526                  , false
527                  , Default_Holder
528                  , std::vector< value_type >
529                 >::test_all(data);
530
531       make_and_test_slist < typename detail::get_member_value_traits
532                   < member_hook< value_type
533                                , typename hooks<VoidPointer>::member_hook_type
534                                , &value_type::node_
535                                >
536                   >::type
537                  , constant_time_size
538                  , true
539                  , false
540                  , Default_Holder
541                  , std::vector< value_type >
542                 >::test_all(data);
543
544       //Now the same but caching the last node
545       make_and_test_slist < typename detail::get_base_value_traits
546                   < value_type
547                   , typename hooks<VoidPointer>::base_hook_type
548                   >::type
549                  , constant_time_size
550                  , false
551                  , true
552                  , Default_Holder
553                  , std::vector< value_type >
554                 >::test_all(data);
555       make_and_test_slist < typename detail::get_member_value_traits
556                   < member_hook< value_type
557                                , typename hooks<VoidPointer>::member_hook_type
558                                , &value_type::node_
559                                >
560                   >::type
561                  , constant_time_size
562                  , false
563                  , true
564                  , Default_Holder
565                  , std::vector< value_type >
566                 >::test_all(data);
567
568       //Now linear slists
569       make_and_test_slist < typename detail::get_base_value_traits
570                   < value_type
571                   , typename hooks<VoidPointer>::base_hook_type
572                   >::type
573                  , constant_time_size
574                  , true
575                  , true
576                  , Default_Holder
577                  , std::vector< value_type >
578                 >::test_all(data);
579
580       make_and_test_slist < typename detail::get_member_value_traits
581                   < member_hook< value_type
582                                , typename hooks<VoidPointer>::member_hook_type
583                                , &value_type::node_
584                                >
585                   >::type
586                  , constant_time_size
587                  , true
588                  , true
589                  , Default_Holder
590                  , std::vector< value_type >
591                 >::test_all(data);
592       return 0;
593    }
594 };
595
596 template<class VoidPointer, bool Default_Holder>
597 class test_main_template<VoidPointer, false, Default_Holder>
598 {
599    public:
600    int operator()()
601    {
602       typedef testvalue<hooks<VoidPointer> , false> value_type;
603       std::vector< value_type > data (5);
604       for (int i = 0; i < 5; ++i)
605          data[i].value_ = i + 1;
606
607       make_and_test_slist < typename detail::get_base_value_traits
608                   < value_type
609                   , typename hooks<VoidPointer>::base_hook_type
610                   >::type
611                  , false
612                  , false
613                  , false
614                  , Default_Holder
615                  , std::vector< value_type >
616                 >::test_all(data);
617
618       make_and_test_slist < typename detail::get_member_value_traits
619                   < member_hook< value_type
620                                , typename hooks<VoidPointer>::member_hook_type
621                                , &value_type::node_
622                                >
623                   >::type
624                  , false
625                  , false
626                  , false
627                  , Default_Holder
628                  , std::vector< value_type >
629                 >::test_all(data);
630
631       make_and_test_slist < typename detail::get_base_value_traits
632                   < value_type
633                   , typename hooks<VoidPointer>::auto_base_hook_type
634                   >::type
635                  , false
636                  , false
637                  , false
638                  , Default_Holder
639                  , std::vector< value_type >
640                 >::test_all(data);
641
642       make_and_test_slist < typename detail::get_member_value_traits
643                   < member_hook< value_type
644                                , typename hooks<VoidPointer>::auto_member_hook_type
645                                , &value_type::auto_node_
646                                >
647                   >::type
648                  , false
649                  , false
650                  , false
651                  , Default_Holder
652                  , std::vector< value_type >
653                 >::test_all(data);
654
655       make_and_test_slist < typename detail::get_base_value_traits
656                   < value_type
657                   , typename hooks<VoidPointer>::base_hook_type
658                   >::type
659                  , false
660                  , true
661                  , false
662                  , Default_Holder
663                  , std::vector< value_type >
664                 >::test_all(data);
665
666       make_and_test_slist < typename detail::get_member_value_traits
667                   < member_hook< value_type
668                                , typename hooks<VoidPointer>::member_hook_type
669                                , &value_type::node_
670                                >
671                   >::type
672                  , false
673                  , true
674                  , false
675                  , Default_Holder
676                  , std::vector< value_type >
677                 >::test_all(data);
678
679       //Now cache last
680       make_and_test_slist < typename detail::get_base_value_traits
681                   < value_type
682                   , typename hooks<VoidPointer>::base_hook_type
683                   >::type
684                  , false
685                  , false
686                  , true
687                  , Default_Holder
688                  , std::vector< value_type >
689                 >::test_all(data);
690
691       make_and_test_slist < typename detail::get_member_value_traits
692                   < member_hook< value_type
693                                , typename hooks<VoidPointer>::member_hook_type
694                                , &value_type::node_
695                                >
696                   >::type
697                  , false
698                  , false
699                  , true
700                  , Default_Holder
701                  , std::vector< value_type >
702                 >::test_all(data);
703
704       make_and_test_slist < typename detail::get_base_value_traits
705                   < value_type
706                   , typename hooks<VoidPointer>::base_hook_type
707                   >::type
708                  , false
709                  , true
710                  , true
711                  , Default_Holder
712                  , std::vector< value_type >
713                 >::test_all(data);
714
715       make_and_test_slist < typename detail::get_member_value_traits
716                   < member_hook< value_type
717                                , typename hooks<VoidPointer>::member_hook_type
718                                , &value_type::node_
719                                >
720                   >::type
721                  , false
722                  , true
723                  , true
724                  , Default_Holder
725                  , std::vector< value_type >
726                 >::test_all(data);
727       return 0;
728    }
729 };
730
731 template < bool ConstantTimeSize >
732 struct test_main_template_bptr
733 {
734    int operator()()
735    {
736       typedef BPtr_Value value_type;
737       typedef BPtr_Value_Traits< List_BPtr_Node_Traits > list_value_traits;
738       typedef typename list_value_traits::node_ptr node_ptr;
739       typedef bounded_allocator< value_type > allocator_type;
740
741       allocator_type::init();
742       allocator_type allocator;
743
744       {
745           bounded_reference_cont< value_type > ref_cont;
746           for (int i = 0; i < 5; ++i)
747           {
748               node_ptr tmp = allocator.allocate(1);
749               new (tmp.raw()) value_type(i + 1);
750               ref_cont.push_back(*tmp);
751           }
752
753           test_slist < slist < value_type,
754                                value_traits< list_value_traits >,
755                                size_type< std::size_t >,
756                                constant_time_size< ConstantTimeSize >,
757                                header_holder_type< bounded_pointer_holder< value_type > >
758                              >,
759                        bounded_reference_cont< value_type >
760           >::test_all(ref_cont);
761       }
762
763       assert(allocator_type::is_clear());
764       allocator_type::destroy();
765       return 0;
766    }
767 };
768
769 int main(int, char* [])
770 {
771    // test (plain/smart pointers) x (nonconst/const size) x (void node allocator)
772    test_main_template<void*, false, true>()();
773    test_main_template<boost::intrusive::smart_ptr<void>, false, true>()();
774    test_main_template<void*, true, true>()();
775    test_main_template<boost::intrusive::smart_ptr<void>, true, true>()();
776    // test (bounded pointers) x ((nonconst/const size) x (special node allocator)
777    test_main_template_bptr< true >()();
778    test_main_template_bptr< false >()();
779
780
781    return boost::report_errors();
782 }