summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/assign/test/multi_index_container.cpp
blob: 711ba5d4daef20b381cd58f45ad5c677b75bdcec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Boost.Assign library
//
//  Copyright Thorsten Ottosen 2003-2004. Use, modification and
//  distribution is subject to the Boost Software License, Version
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/assign/
//


#include <boost/detail/workaround.hpp>

#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
#  pragma warn -8091 // suppress warning in Boost.Test
#  pragma warn -8057 // unused argument argc/argv in Boost.Test
#endif

#include <boost/assign/list_of.hpp>
#include <boost/assign/list_inserter.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <cstddef>
#include <ostream>
#include <string>

using namespace boost;
using namespace boost::multi_index;
namespace ba =  boost::assign;

//
// Define a classical multi_index_container for employees
//
struct employee
{
  int         id;
  std::string name;
  int         age;

  employee(int id_,std::string name_,int age_):id(id_),name(name_),age(age_){}

  bool operator==(const employee& x)const
  {
    return id==x.id&&name==x.name&&age==x.age;
  }

  bool operator<(const employee& x)const
  {
    return id<x.id;
  }

  bool operator!=(const employee& x)const{return !(*this==x);}
  bool operator> (const employee& x)const{return x<*this;}
  bool operator>=(const employee& x)const{return !(*this<x);}
  bool operator<=(const employee& x)const{return !(x<*this);}

  struct comp_id
  {
    bool operator()(int x,const employee& e2)const{return x<e2.id;}
    bool operator()(const employee& e1,int x)const{return e1.id<x;}
  };

  friend std::ostream& operator<<(std::ostream& os,const employee& e)
  {
    os<<e.id<<" "<<e.name<<" "<<e.age<<std::endl;
    return os;
  }
};

struct name{};
struct by_name{};
struct age{};
struct as_inserted{};

typedef
  multi_index_container<
    employee,
    indexed_by<
      ordered_unique<
        identity<employee> >,
      ordered_non_unique<
        tag<name,by_name>,
        BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>,
      ordered_non_unique<
        tag<age>,
        BOOST_MULTI_INDEX_MEMBER(employee,int,age)>,
      sequenced<
        tag<as_inserted> > > >
  employee_set;

#if defined(BOOST_NO_MEMBER_TEMPLATES)
typedef nth_index<
  employee_set,1>::type                       employee_set_by_name;
#else
typedef employee_set::nth_index<1>::type employee_set_by_name;
#endif

typedef boost::multi_index::index<
         employee_set,age>::type         employee_set_by_age;
typedef boost::multi_index::index<
         employee_set,as_inserted>::type employee_set_as_inserted;

//
// Define a multi_index_container with a list-like index and an ordered index
//
typedef multi_index_container<
  std::string,
  indexed_by<
    sequenced<>,                               // list-like index
    ordered_non_unique<identity<std::string> > // words by alphabetical order
  >
> text_container;



void test_multi_index_container()
{
    employee_set eset = ba::list_of< employee >(1,"Franz",30)(2,"Hanz",40)(3,"Ilse",50);
    BOOST_CHECK( eset.size() == 3u );
    
    //
    // This container is associative, hence we can use 'insert()' 
    // 
    
    ba::insert( eset )(4,"Kurt",55)(5,"Bjarne",77)(7,"Thorsten",24);
    BOOST_CHECK( eset.size() == 6u );
    
    employee_set_by_name& name_index = boost::multi_index::get<name>(eset);
    employee_set_by_name::iterator i = name_index.find("Ilse");
    BOOST_CHECK( i->id == 3 );
    BOOST_CHECK( i->age == 50 );
    
    text_container text = ba::list_of< std::string >("Have")("you")("ever")("wondered")("how")("much")("Boost")("rocks?!");
    BOOST_CHECK_EQUAL( text.size(), 8u );
    BOOST_CHECK_EQUAL( *text.begin(), "Have" );
    
    //
    // This container is a sequence, hence we can use 'push_back()' and 'push_font()'
    //
    
    ba::push_back( text )("Well")(",")("A")("LOT")(",")("obviously!");
    BOOST_CHECK_EQUAL( text.size(), 14u );
    BOOST_CHECK_EQUAL( *--text.end(), "obviously!" );
    
    ba::push_front( text ) = "question:", "simple", "A";
    BOOST_CHECK_EQUAL( text.size(), 17u );
    BOOST_CHECK_EQUAL( text.front(), "A" );
}



using boost::unit_test::test_suite;

test_suite* init_unit_test_suite( int argc, char* argv[] )
{
    test_suite* test = BOOST_TEST_SUITE( "List Test Suite" );

    test->add( BOOST_TEST_CASE( &test_multi_index_container ) );

    return test;
}