| 1 | /* Boost.MultiIndex test for standard set operations. |
| 2 | * |
| 3 | * Copyright 2003-2022 Joaquin M Lopez Munoz. |
| 4 | * Distributed under the Boost Software License, Version 1.0. |
| 5 | * (See accompanying file LICENSE_1_0.txt or copy at |
| 6 | * http://www.boost.org/LICENSE_1_0.txt) |
| 7 | * |
| 8 | * See http://www.boost.org/libs/multi_index for library home page. |
| 9 | */ |
| 10 | |
| 11 | #include "test_set_ops.hpp" |
| 12 | |
| 13 | #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ |
| 14 | #include <algorithm> |
| 15 | #include <vector> |
| 16 | #include "pre_multi_index.hpp" |
| 17 | #include "employee.hpp" |
| 18 | #include <boost/detail/lightweight_test.hpp> |
| 19 | |
| 20 | using namespace boost::multi_index; |
| 21 | |
| 22 | struct type1{}; |
| 23 | |
| 24 | struct type2 |
| 25 | { |
| 26 | private: |
| 27 | operator type1()const{return type1();} |
| 28 | }; |
| 29 | |
| 30 | struct type3 |
| 31 | { |
| 32 | operator type1()const{return type1();} |
| 33 | }; |
| 34 | |
| 35 | struct less_type12 |
| 36 | { |
| 37 | bool operator()(type1,type1)const{return false;} |
| 38 | bool operator()(type1,type2)const{return false;} |
| 39 | bool operator()(type2,type1)const{return false;} |
| 40 | }; |
| 41 | |
| 42 | bool less_type1_f(type1,type1){return false;} |
| 43 | |
| 44 | struct hash_type12 |
| 45 | { |
| 46 | std::size_t operator()(type1)const{return 0;} |
| 47 | std::size_t operator()(type2)const{return 0;} |
| 48 | }; |
| 49 | |
| 50 | struct eq_type12 |
| 51 | { |
| 52 | bool operator()(type1,type1)const{return true;} |
| 53 | bool operator()(type1,type2)const{return true;} |
| 54 | bool operator()(type2,type1)const{return true;} |
| 55 | }; |
| 56 | |
| 57 | void test_set_ops() |
| 58 | { |
| 59 | employee_set es; |
| 60 | employee_set_by_name& i1=get<by_name>(m&: es); |
| 61 | const employee_set_by_age& i2=get<age>(m&: es); |
| 62 | employee_set_by_ssn& i4=get<ssn>(m&: es); |
| 63 | |
| 64 | es.insert(x: employee(0,"Joe" ,31,1123)); |
| 65 | es.insert(x: employee(1,"Robert" ,27,5601)); |
| 66 | es.insert(x: employee(2,"John" ,40,7889)); |
| 67 | es.insert(x: employee(3,"Albert" ,20,9012)); |
| 68 | es.insert(x: employee(4,"John" ,57,1002)); |
| 69 | |
| 70 | BOOST_TEST(i1.find("John" )->name=="John" ); |
| 71 | BOOST_TEST(i2.find(41)==i2.end()); |
| 72 | BOOST_TEST(i4.find(5601)->name=="Robert" ); |
| 73 | |
| 74 | BOOST_TEST(i1.count("John" )==2); |
| 75 | BOOST_TEST(i2.count(20)==1); |
| 76 | BOOST_TEST(es.count(employee(10,"" ,-1,0))==0); |
| 77 | BOOST_TEST(i4.count(7881)==0); |
| 78 | |
| 79 | BOOST_TEST(i1.contains("John" )); |
| 80 | BOOST_TEST(!es.contains(employee(10,"" ,-1,0))); |
| 81 | BOOST_TEST(!i4.contains(7881)); |
| 82 | |
| 83 | BOOST_TEST( |
| 84 | std::distance( |
| 85 | i2.lower_bound(31), |
| 86 | i2.upper_bound(60))==3); |
| 87 | |
| 88 | std::pair<employee_set_by_name::iterator,employee_set_by_name::iterator> p= |
| 89 | i1.equal_range(k: "John" ); |
| 90 | BOOST_TEST(std::distance(p.first,p.second)==2); |
| 91 | |
| 92 | p=i1.equal_range(k: "Serena" ); |
| 93 | BOOST_TEST(p.first==i1.end()&&p.second==i1.end()); |
| 94 | |
| 95 | std::pair<employee_set_by_age::iterator,employee_set_by_age::iterator> p2= |
| 96 | i2.equal_range(x: 30); |
| 97 | BOOST_TEST(p2.first==p2.second&&p2.first->age==31); |
| 98 | |
| 99 | /* check promotion detection plays nice with private conversion */ |
| 100 | |
| 101 | multi_index_container< |
| 102 | type1, |
| 103 | indexed_by< |
| 104 | ordered_unique<identity<type1>,less_type12>, |
| 105 | hashed_unique<identity<type1>,hash_type12,eq_type12> |
| 106 | > |
| 107 | > c; |
| 108 | c.insert(x: type1()); |
| 109 | |
| 110 | BOOST_TEST(c.find(type2())==c.begin()); |
| 111 | BOOST_TEST(c.count(type2())==1); |
| 112 | BOOST_TEST(c.contains(type2())); |
| 113 | BOOST_TEST(c.lower_bound(type2())==c.begin()); |
| 114 | BOOST_TEST(c.upper_bound(type2())==c.end()); |
| 115 | BOOST_TEST(c.equal_range(type2())==std::make_pair(c.begin(),c.end())); |
| 116 | |
| 117 | BOOST_TEST(c.get<1>().find(type2())==c.get<1>().begin()); |
| 118 | BOOST_TEST(c.get<1>().count(type2())==1); |
| 119 | BOOST_TEST(c.get<1>().contains(type2())); |
| 120 | BOOST_TEST(c.get<1>().equal_range(type2())== |
| 121 | std::make_pair(c.get<1>().begin(),c.get<1>().end())); |
| 122 | |
| 123 | /* check promotion detection does not break with functions */ |
| 124 | |
| 125 | multi_index_container< |
| 126 | type1, |
| 127 | indexed_by< |
| 128 | ordered_unique<identity<type1>,bool(*)(type1,type1)> |
| 129 | > |
| 130 | > c2(boost::make_tuple(t0: boost::make_tuple(t0: identity<type1>(),t1: &less_type1_f))); |
| 131 | c2.insert(x: type1()); |
| 132 | |
| 133 | BOOST_TEST(c2.find(type3())==c2.begin()); |
| 134 | } |
| 135 | |