summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/multi_index
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/multi_index')
-rw-r--r--src/boost/libs/multi_index/README.md10
-rw-r--r--src/boost/libs/multi_index/example/Jamfile.v269
-rw-r--r--src/boost/libs/multi_index/example/basic.cpp119
-rw-r--r--src/boost/libs/multi_index/example/bimap.cpp149
-rw-r--r--src/boost/libs/multi_index/example/complex_structs.cpp315
-rw-r--r--src/boost/libs/multi_index/example/composite_keys.cpp285
-rw-r--r--src/boost/libs/multi_index/example/fun_key.cpp100
-rw-r--r--src/boost/libs/multi_index/example/hashed.cpp124
-rw-r--r--src/boost/libs/multi_index/example/ip_allocator.cpp293
-rw-r--r--src/boost/libs/multi_index/example/non_default_ctor.cpp96
-rw-r--r--src/boost/libs/multi_index/example/random_access.cpp102
-rw-r--r--src/boost/libs/multi_index/example/rearrange.cpp265
-rw-r--r--src/boost/libs/multi_index/example/sequenced.cpp100
-rw-r--r--src/boost/libs/multi_index/example/serialization.cpp144
-rw-r--r--src/boost/libs/multi_index/index.html20
-rw-r--r--src/boost/libs/multi_index/meta/libraries.json15
-rw-r--r--src/boost/libs/multi_index/perf/Jamfile.v214
-rw-r--r--src/boost/libs/multi_index/perf/test_perf.cpp545
-rw-r--r--src/boost/libs/multi_index/test/Jamfile.v275
-rw-r--r--src/boost/libs/multi_index/test/check_bmi_key_supported.cpp13
-rw-r--r--src/boost/libs/multi_index/test/employee.hpp152
-rw-r--r--src/boost/libs/multi_index/test/non_std_allocator.hpp141
-rw-r--r--src/boost/libs/multi_index/test/pair_of_ints.hpp78
-rw-r--r--src/boost/libs/multi_index/test/pre_multi_index.hpp49
-rw-r--r--src/boost/libs/multi_index/test/rooted_allocator.hpp64
-rw-r--r--src/boost/libs/multi_index/test/small_allocator.hpp58
-rw-r--r--src/boost/libs/multi_index/test/test_all_main.cpp65
-rw-r--r--src/boost/libs/multi_index/test/test_alloc_awareness.cpp159
-rw-r--r--src/boost/libs/multi_index/test/test_alloc_awareness.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_alloc_awareness_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_basic.cpp158
-rw-r--r--src/boost/libs/multi_index/test/test_basic.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_basic_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_capacity.cpp97
-rw-r--r--src/boost/libs/multi_index/test/test_capacity.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_capacity_main.cpp19
-rw-r--r--src/boost/libs/multi_index/test/test_comparison.cpp151
-rw-r--r--src/boost/libs/multi_index/test/test_comparison.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_comparison_main.cpp19
-rw-r--r--src/boost/libs/multi_index/test/test_composite_key.cpp670
-rw-r--r--src/boost/libs/multi_index/test/test_composite_key.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_composite_key_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_conv_iterators.cpp75
-rw-r--r--src/boost/libs/multi_index/test/test_conv_iterators.hpp12
-rw-r--r--src/boost/libs/multi_index/test/test_conv_iterators_main.cpp21
-rw-r--r--src/boost/libs/multi_index/test/test_copy_assignment.cpp365
-rw-r--r--src/boost/libs/multi_index/test/test_copy_assignment.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_copy_assignment_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_hash_ops.cpp118
-rw-r--r--src/boost/libs/multi_index/test/test_hash_ops.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_hash_ops_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_iterators.cpp250
-rw-r--r--src/boost/libs/multi_index/test/test_iterators.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_iterators_main.cpp19
-rw-r--r--src/boost/libs/multi_index/test/test_key.cpp170
-rw-r--r--src/boost/libs/multi_index/test/test_key.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_key_extractors.cpp604
-rw-r--r--src/boost/libs/multi_index/test/test_key_extractors.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_key_extractors_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_key_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_list_ops.cpp275
-rw-r--r--src/boost/libs/multi_index/test/test_list_ops.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_list_ops_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_modifiers.cpp581
-rw-r--r--src/boost/libs/multi_index/test/test_modifiers.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_modifiers_main.cpp20
-rw-r--r--src/boost/libs/multi_index/test/test_mpl_ops.cpp75
-rw-r--r--src/boost/libs/multi_index/test/test_mpl_ops.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_mpl_ops_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_observers.cpp56
-rw-r--r--src/boost/libs/multi_index/test/test_observers.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_observers_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_projection.cpp135
-rw-r--r--src/boost/libs/multi_index/test/test_projection.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_projection_main.cpp20
-rw-r--r--src/boost/libs/multi_index/test/test_range.cpp125
-rw-r--r--src/boost/libs/multi_index/test/test_range.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_range_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_rank_ops.cpp154
-rw-r--r--src/boost/libs/multi_index/test/test_rank_ops.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_rank_ops_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_rearrange.cpp132
-rw-r--r--src/boost/libs/multi_index/test/test_rearrange.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_rearrange_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_safe_mode.cpp472
-rw-r--r--src/boost/libs/multi_index/test/test_safe_mode.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_safe_mode_main.cpp19
-rw-r--r--src/boost/libs/multi_index/test/test_serialization.cpp21
-rw-r--r--src/boost/libs/multi_index/test/test_serialization.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_serialization1.cpp66
-rw-r--r--src/boost/libs/multi_index/test/test_serialization1.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_serialization2.cpp81
-rw-r--r--src/boost/libs/multi_index/test/test_serialization2.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_serialization3.cpp216
-rw-r--r--src/boost/libs/multi_index/test/test_serialization3.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_serialization_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_serialization_template.hpp105
-rw-r--r--src/boost/libs/multi_index/test/test_set_ops.cpp127
-rw-r--r--src/boost/libs/multi_index/test/test_set_ops.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_set_ops_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_special_set_ops.cpp95
-rw-r--r--src/boost/libs/multi_index/test/test_special_set_ops.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_special_set_ops_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test/test_update.cpp281
-rw-r--r--src/boost/libs/multi_index/test/test_update.hpp11
-rw-r--r--src/boost/libs/multi_index/test/test_update_main.cpp18
-rw-r--r--src/boost/libs/multi_index/test_results.svg26
107 files changed, 10041 insertions, 0 deletions
diff --git a/src/boost/libs/multi_index/README.md b/src/boost/libs/multi_index/README.md
new file mode 100644
index 000000000..93a9f2faa
--- /dev/null
+++ b/src/boost/libs/multi_index/README.md
@@ -0,0 +1,10 @@
+# Boost Multi-index Containers Library
+
+Branch | Travis | AppVeyor | Regression tests
+---------|--------|----------|-----------------
+develop | [![Build Status](https://travis-ci.com/boostorg/multi_index.svg?branch=develop)](https://travis-ci.com/boostorg/multi_index) | [![Build Status](https://ci.appveyor.com/api/projects/status/github/boostorg/multi_index?branch=develop&svg=true)](https://ci.appveyor.com/project/joaquintides/multi-index) | [![Test Results](./test_results.svg)](https://www.boost.org/development/tests/develop/developer/multi_index.html)
+master | [![Build Status](https://travis-ci.com/boostorg/multi_index.svg?branch=master)](https://travis-ci.com/boostorg/multi_index) | [![Build Status](https://ci.appveyor.com/api/projects/status/github/boostorg/multi_index?branch=master&svg=true)](https://ci.appveyor.com/project/joaquintides/multi-index) | [![Test Results](./test_results.svg)](https://www.boost.org/development/tests/master/developer/multi_index.html)
+
+[Boost.MultiIndex](http://boost.org/libs/multi_index) provides a class template
+named `multi_index_container` which enables the construction of containers
+maintaining one or more indices with different sorting and access semantics.
diff --git a/src/boost/libs/multi_index/example/Jamfile.v2 b/src/boost/libs/multi_index/example/Jamfile.v2
new file mode 100644
index 000000000..a4dc9c318
--- /dev/null
+++ b/src/boost/libs/multi_index/example/Jamfile.v2
@@ -0,0 +1,69 @@
+# Boost.MultiIndex examples Jamfile
+#
+# Copyright 2003-2007 Joaquín M López Muñoz.
+# Distributed under 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)
+#
+# See http://www.boost.org/libs/multi_index for library home page.
+
+exe basic
+ : basic.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe bimap
+ : bimap.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe complex_structs
+ : complex_structs.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe composite_keys
+ : composite_keys.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe fun_key
+ : fun_key.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe hashed
+ : hashed.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe ip_allocator
+ : ip_allocator.cpp
+ : <include>$(BOOST_ROOT) <threading>multi
+ ;
+
+exe non_default_ctor
+ : non_default_ctor.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe random_access
+ : random_access.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe rearrange
+ : rearrange.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe sequenced
+ : sequenced.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe serialization
+ : serialization.cpp
+ /boost/serialization//boost_serialization
+ : <include>$(BOOST_ROOT)
+ ;
diff --git a/src/boost/libs/multi_index/example/basic.cpp b/src/boost/libs/multi_index/example/basic.cpp
new file mode 100644
index 000000000..f7c46ced0
--- /dev/null
+++ b/src/boost/libs/multi_index/example/basic.cpp
@@ -0,0 +1,119 @@
+/* Boost.MultiIndex basic example.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <string>
+
+using boost::multi_index_container;
+using namespace boost::multi_index;
+
+/* an employee record holds its ID, name and age */
+
+struct employee
+{
+ int id;
+ std::string name;
+ int age;
+
+ employee(int id_,std::string name_,int age_):id(id_),name(name_),age(age_){}
+
+ friend std::ostream& operator<<(std::ostream& os,const employee& e)
+ {
+ os<<e.id<<" "<<e.name<<" "<<e.age<<std::endl;
+ return os;
+ }
+};
+
+/* tags for accessing the corresponding indices of employee_set */
+
+struct id{};
+struct name{};
+struct age{};
+
+/* see Compiler specifics: Use of member_offset for info on
+ * BOOST_MULTI_INDEX_MEMBER
+ */
+
+/* Define a multi_index_container of employees with following indices:
+ * - a unique index sorted by employee::int,
+ * - a non-unique index sorted by employee::name,
+ * - a non-unique index sorted by employee::age.
+ */
+
+typedef multi_index_container<
+ employee,
+ indexed_by<
+ ordered_unique<
+ tag<id>, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>,
+ ordered_non_unique<
+ tag<name>,BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>,
+ ordered_non_unique<
+ tag<age>, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> >
+> employee_set;
+
+template<typename Tag,typename MultiIndexContainer>
+void print_out_by(const MultiIndexContainer& s)
+{
+ /* obtain a reference to the index tagged by Tag */
+
+ const typename boost::multi_index::index<MultiIndexContainer,Tag>::type& i=
+ get<Tag>(s);
+
+ typedef typename MultiIndexContainer::value_type value_type;
+
+ /* dump the elements of the index to cout */
+
+ std::copy(i.begin(),i.end(),std::ostream_iterator<value_type>(std::cout));
+}
+
+
+int main()
+{
+ employee_set es;
+
+ es.insert(employee(0,"Joe",31));
+ es.insert(employee(1,"Robert",27));
+ es.insert(employee(2,"John",40));
+
+ /* next insertion will fail, as there is an employee with
+ * the same ID
+ */
+
+ es.insert(employee(2,"Aristotle",2387));
+
+ es.insert(employee(3,"Albert",20));
+ es.insert(employee(4,"John",57));
+
+ /* list the employees sorted by ID, name and age */
+
+ std::cout<<"by ID"<<std::endl;
+ print_out_by<id>(es);
+ std::cout<<std::endl;
+
+ std::cout<<"by name"<<std::endl;
+ print_out_by<name>(es);
+ std::cout<<std::endl;
+
+ std::cout<<"by age"<<std::endl;
+ print_out_by<age>(es);
+ std::cout<<std::endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/bimap.cpp b/src/boost/libs/multi_index/example/bimap.cpp
new file mode 100644
index 000000000..aac99d06c
--- /dev/null
+++ b/src/boost/libs/multi_index/example/bimap.cpp
@@ -0,0 +1,149 @@
+/* Boost.MultiIndex example of a bidirectional map.
+ *
+ * Copyright 2003-2009 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <iostream>
+#include <string>
+
+using boost::multi_index_container;
+using namespace boost::multi_index;
+
+/* tags for accessing both sides of a bidirectional map */
+
+struct from{};
+struct to{};
+
+/* The class template bidirectional_map wraps the specification
+ * of a bidirectional map based on multi_index_container.
+ */
+
+template<typename FromType,typename ToType>
+struct bidirectional_map
+{
+ struct value_type
+ {
+ value_type(const FromType& first_,const ToType& second_):
+ first(first_),second(second_)
+ {}
+
+ FromType first;
+ ToType second;
+ };
+
+#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) ||\
+ defined(BOOST_MSVC)&&(BOOST_MSVC<1300) ||\
+ defined(BOOST_INTEL_CXX_VERSION)&&defined(_MSC_VER)&&\
+ (BOOST_INTEL_CXX_VERSION<=700)
+
+/* see Compiler specifics: Use of member_offset for info on member<> and
+ * member_offset<>
+ */
+
+ BOOST_STATIC_CONSTANT(unsigned,from_offset=offsetof(value_type,first));
+ BOOST_STATIC_CONSTANT(unsigned,to_offset =offsetof(value_type,second));
+
+ typedef multi_index_container<
+ value_type,
+ indexed_by<
+ ordered_unique<
+ tag<from>,member_offset<value_type,FromType,from_offset> >,
+ ordered_unique<
+ tag<to>, member_offset<value_type,ToType,to_offset> >
+ >
+ > type;
+
+#else
+
+ /* A bidirectional map can be simulated as a multi_index_container
+ * of pairs of (FromType,ToType) with two unique indices, one
+ * for each member of the pair.
+ */
+
+ typedef multi_index_container<
+ value_type,
+ indexed_by<
+ ordered_unique<
+ tag<from>,member<value_type,FromType,&value_type::first> >,
+ ordered_unique<
+ tag<to>, member<value_type,ToType,&value_type::second> >
+ >
+ > type;
+
+#endif
+};
+
+/* a dictionary is a bidirectional map from strings to strings */
+
+typedef bidirectional_map<std::string,std::string>::type dictionary;
+
+int main()
+{
+ dictionary d;
+
+ /* Fill up our microdictionary. first members Spanish, second members
+ * English.
+ */
+
+ d.insert(dictionary::value_type("hola","hello"));
+ d.insert(dictionary::value_type("adios","goodbye"));
+ d.insert(dictionary::value_type("rosa","rose"));
+ d.insert(dictionary::value_type("mesa","table"));
+
+
+ std::cout<<"enter a word"<<std::endl;
+ std::string word;
+ std::getline(std::cin,word);
+
+#if defined(BOOST_NO_MEMBER_TEMPLATES) /* use global get<> and family instead */
+
+ dictionary::iterator it=get<from>(d).find(word);
+ if(it!=d.end()){
+ std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl;
+ }
+ else{
+ nth_index<dictionary,1>::type::iterator it2=get<1>(d).find(word);
+ if(it2!=get<1>(d).end()){
+ std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
+ }
+ else std::cout<<"No such word in the dictionary"<<std::endl;
+ }
+
+#else
+
+ /* search the queried word on the from index (Spanish) */
+
+ dictionary::iterator it=d.get<from>().find(word);
+ if(it!=d.end()){ /* found */
+
+ /* the second part of the element is the equivalent in English */
+
+ std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl;
+ }
+ else{
+ /* word not found in Spanish, try our luck in English */
+
+ dictionary::index<to>::type::iterator it2=d.get<to>().find(word);
+ if(it2!=d.get<to>().end()){
+ std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
+ }
+ else std::cout<<"No such word in the dictionary"<<std::endl;
+ }
+
+#endif
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/complex_structs.cpp b/src/boost/libs/multi_index/example/complex_structs.cpp
new file mode 100644
index 000000000..70eb78bcd
--- /dev/null
+++ b/src/boost/libs/multi_index/example/complex_structs.cpp
@@ -0,0 +1,315 @@
+/* Boost.MultiIndex example: complex searches and foreign keys.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <iostream>
+#include <string>
+
+using boost::multi_index_container;
+using namespace boost::multi_index;
+
+/* This small utility that cascades two key extractors will be
+ * used througout the example.
+ */
+
+template<class KeyExtractor1,class KeyExtractor2>
+struct key_from_key
+{
+public:
+ typedef typename KeyExtractor1::result_type result_type;
+
+ key_from_key(
+ const KeyExtractor1& key1_=KeyExtractor1(),
+ const KeyExtractor2& key2_=KeyExtractor2()):
+ key1(key1_),key2(key2_)
+ {}
+
+ template<typename Arg>
+ result_type operator()(Arg& arg)const
+ {
+ return key1(key2(arg));
+ }
+
+private:
+ KeyExtractor1 key1;
+ KeyExtractor2 key2;
+};
+
+/* tags for accessing several indices defined below */
+
+struct model{};
+struct manufacturer{};
+struct price{};
+
+/* a manufacturer struct just holds the name of the manufacturer */
+
+struct car_manufacturer
+{
+ std::string name;
+
+ car_manufacturer(const std::string& name_):name(name_){}
+};
+
+/* car_model holds the model of car, its price and a pointer to the
+ * manufacturer. The pointer thing eliminates duplication of the same
+ * data among cars of the same manufacturer.
+ */
+
+struct car_model
+{
+ std::string model;
+ const car_manufacturer* manufacturer;
+ int price;
+
+ car_model(
+ const std::string& model_,const car_manufacturer* manufacturer_,int price_):
+ model(model_),manufacturer(manufacturer_),price(price_)
+ {}
+
+ friend std::ostream& operator<<(std::ostream& os,const car_model& c)
+ {
+ os<<c.manufacturer->name<<" "<<c.model<<" $"<<c.price<<std::endl;
+ return os;
+ }
+};
+
+/* see Compiler specifics: Use of member_offset for info on
+ * BOOST_MULTI_INDEX_MEMBER
+ */
+
+/* Car manufacturers are stored in a multi_index_container with one single
+ * index on the name member. This is functionally equivalent to an std::set,
+ * though in this latter case we woud have to define a non-default comparison
+ * predicate (with multi_index_container, member<> does the work for us.)
+ */
+
+typedef multi_index_container<
+ car_manufacturer,
+ indexed_by<
+ ordered_unique<
+ BOOST_MULTI_INDEX_MEMBER(car_manufacturer,std::string,name)
+ >
+ >
+> car_manufacturer_table;
+
+/* Define a multi_index_container of car_models with following indices:
+ * - a unique index sorted by car_model::model,
+ * - a non-unique index sorted by car_model::manufacturer; note the
+ * non-standard manufacturer_extractor used.
+ * - a non-unique index sorted by car_model::price.
+ */
+
+typedef multi_index_container<
+ car_model,
+ indexed_by<
+ ordered_unique<
+ tag<model>,BOOST_MULTI_INDEX_MEMBER(car_model,std::string,model)
+ >,
+ ordered_non_unique<
+ tag<manufacturer>,
+ key_from_key<
+ BOOST_MULTI_INDEX_MEMBER(car_manufacturer,const std::string,name),
+ BOOST_MULTI_INDEX_MEMBER(
+ car_model,const car_manufacturer *,manufacturer)
+ >
+ >,
+ ordered_non_unique<
+ tag<price>,BOOST_MULTI_INDEX_MEMBER(car_model,int,price)
+ >
+ >
+> car_table;
+
+/* We call a *view* to a multi_index_container storing pointers instead of
+ * actual objects. These views are used in the complex search performed
+ * in the program. Resorting to multi_index of pointers eliminates
+ * unnecessary copying of objects, and provides us with an opportunity
+ * to show how BOOST_MULTI_INDEX_MEMBER can be used with pointer
+ * type elements.
+ * car_table_price_view indexes (pointers to) car_models by price.
+ */
+
+typedef multi_index_container<
+ const car_model*,
+ indexed_by<
+ ordered_non_unique<BOOST_MULTI_INDEX_MEMBER(car_model,const int,price)>
+ >
+> car_table_price_view;
+
+/* car_table_manufacturer_view indexes (pointers to) car_models by
+ * manufacturer
+ */
+
+typedef multi_index_container<
+ const car_model*,
+ indexed_by<
+ ordered_non_unique<
+ key_from_key<
+ BOOST_MULTI_INDEX_MEMBER(car_manufacturer,const std::string,name),
+ BOOST_MULTI_INDEX_MEMBER(
+ car_model,const car_manufacturer * const,manufacturer)
+ >
+ >
+ >
+> car_table_manufacturer_view;
+
+int main()
+{
+ car_manufacturer_table cmt;
+
+ /* Fill the car_manufacturer table and keep pointers to the
+ * elements inserted.
+ */
+
+ const car_manufacturer * cadillac=
+ &*(cmt.insert(car_manufacturer("Cadillac")).first);
+ const car_manufacturer * ford =
+ &*(cmt.insert(car_manufacturer("Ford")).first);
+ const car_manufacturer * bmw =
+ &*(cmt.insert(car_manufacturer("BMW")).first);
+ const car_manufacturer * audi =
+ &*(cmt.insert(car_manufacturer("Audi")).first);
+
+ car_table ct;
+
+ /* Fill the car_model_table. We use the previously initialized
+ * pointers to the elements of cmt.
+ */
+
+ ct.insert(car_model("XLR",cadillac,76200));
+ ct.insert(car_model("SRX",cadillac,38690));
+ ct.insert(car_model("CTS",cadillac,30695));
+ ct.insert(car_model("Escalade",cadillac,54770));
+ ct.insert(car_model("ESV",cadillac,57195));
+ ct.insert(car_model("EXT",cadillac,52045));
+ ct.insert(car_model("Deville",cadillac,45195));
+ ct.insert(car_model("Seville",cadillac,46330));
+
+ ct.insert(car_model("ZX2",ford,15355));
+ ct.insert(car_model("Thunderbird",ford,43995));
+ ct.insert(car_model("Windstar",ford,35510));
+ ct.insert(car_model("Focus",ford,19630));
+ ct.insert(car_model("Taurus",ford,24290));
+ ct.insert(car_model("Mustang",ford,39900));
+ ct.insert(car_model("Crown Victoria",ford,30370));
+
+ ct.insert(car_model("325i",bmw,27800));
+ ct.insert(car_model("545i",bmw,54300));
+ ct.insert(car_model("745i",bmw,68500));
+ ct.insert(car_model("M3 coupe",bmw,46500));
+ ct.insert(car_model("Z4 roadster 3.0i",bmw,40250));
+ ct.insert(car_model("X5 4.4i",bmw,49950));
+
+ ct.insert(car_model("A4 1.8T",audi,25940));
+ ct.insert(car_model("TT Coupe",audi,33940));
+ ct.insert(car_model("A6 3.0",audi,36640));
+ ct.insert(car_model("Allroad quattro 2.7T",audi,40640));
+ ct.insert(car_model("A8 L",audi,69190));
+
+ std::cout<<"enter a car manufacturer"<<std::endl;
+ std::string cm;
+ std::getline(std::cin,cm);
+
+ /* check for manufacturer */
+
+ car_manufacturer_table::iterator icm=cmt.find(cm);
+
+ if(icm==cmt.end()){
+ std::cout<<"no such manufacturer in the table"<<std::endl;
+ return 0;
+ }
+
+ std::cout<<"enter a minimum price"<<std::endl;
+ int min_price;
+ std::cin>>min_price;
+ std::cout<<"enter a maximum price"<<std::endl;
+ int max_price;
+ std::cin>>max_price;
+
+ {
+ /* method 1 */
+
+ /* find all the cars for the manufacturer given */
+
+ boost::multi_index::index<car_table,manufacturer>::type::iterator ic0,ic1;
+ boost::tuples::tie(ic0,ic1)=get<manufacturer>(ct).equal_range(cm);
+
+ /* construct a view (indexed by price) with these */
+
+ car_table_price_view ctpv;
+ while(ic0!=ic1){
+ ctpv.insert(&*ic0);
+ ++ic0;
+ }
+
+ /* select the cars in the range given */
+
+ car_table_price_view::iterator ictpv0=ctpv.lower_bound(min_price);
+ car_table_price_view::iterator ictpv1=ctpv.upper_bound(max_price);
+ if(ictpv0==ictpv1){
+ std::cout<<"no cars in the range given"<<std::endl;
+ return 0;
+ }
+
+ /* list them */
+
+ std::cout<<"listing by method 1"<<std::endl;
+ while(ictpv0!=ictpv1){
+ std::cout<<**ictpv0;
+ ++ictpv0;
+ }
+ std::cout<<std::endl;
+ }
+
+ {
+ /* method 2 will give the same results */
+
+ /* find the cars in the range given */
+
+ boost::multi_index::index<car_table,price>::type::iterator ic0,ic1;
+ ic0=get<price>(ct).lower_bound(min_price);
+ ic1=get<price>(ct).upper_bound(max_price);
+
+ /* construct a view with these */
+
+ car_table_manufacturer_view ctmv;
+ while(ic0!=ic1){
+ ctmv.insert(&*ic0);
+ ++ic0;
+ }
+
+ /* select the cars with given manufacturer */
+
+ car_table_manufacturer_view::iterator ictmv0,ictmv1;
+ boost::tuples::tie(ictmv0,ictmv1)=ctmv.equal_range(cm);
+ if(ictmv0==ictmv1){
+ std::cout<<"no cars in the range given"<<std::endl;
+ return 0;
+ }
+
+ /* list them */
+
+ std::cout<<"listing by method 2"<<std::endl;
+ while(ictmv0!=ictmv1){
+ std::cout<<**ictmv0;
+ ++ictmv0;
+ }
+ std::cout<<std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/composite_keys.cpp b/src/boost/libs/multi_index/example/composite_keys.cpp
new file mode 100644
index 000000000..e9da2affa
--- /dev/null
+++ b/src/boost/libs/multi_index/example/composite_keys.cpp
@@ -0,0 +1,285 @@
+/* Boost.MultiIndex example of composite keys.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/call_traits.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/composite_key.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/tokenizer.hpp>
+#include <functional>
+#include <iostream>
+#include <iterator>
+#include <map>
+#include <string>
+
+using namespace boost::multi_index;
+
+/* A file record maintains some info on name and size as well
+ * as a pointer to the directory it belongs (null meaning the root
+ * directory.)
+ */
+
+struct file_entry
+{
+ file_entry(
+ std::string name_,unsigned size_,bool is_dir_,const file_entry* dir_):
+ name(name_),size(size_),is_dir(is_dir_),dir(dir_)
+ {}
+
+ std::string name;
+ unsigned size;
+ bool is_dir;
+ const file_entry* dir;
+
+ friend std::ostream& operator<<(std::ostream& os,const file_entry& f)
+ {
+ os<<f.name<<"\t"<<f.size;
+ if(f.is_dir)os<<"\t <dir>";
+ return os;
+ }
+};
+
+/* A file system is just a multi_index_container of entries with indices on
+ * file and size. These indices are firstly ordered by directory, as commands
+ * work on a current directory basis. Composite keys are just fine to model
+ * this.
+ * NB: The use of derivation here instead of simple typedef is explained in
+ * Compiler specifics: type hiding.
+ */
+
+struct name_key:composite_key<
+ file_entry,
+ BOOST_MULTI_INDEX_MEMBER(file_entry,const file_entry*,dir),
+ BOOST_MULTI_INDEX_MEMBER(file_entry,std::string,name)
+>{};
+
+struct size_key:composite_key<
+ file_entry,
+ BOOST_MULTI_INDEX_MEMBER(file_entry,const file_entry* const,dir),
+ BOOST_MULTI_INDEX_MEMBER(file_entry,unsigned,size)
+>{};
+
+/* see Compiler specifics: composite_key in compilers without partial
+ * template specialization, for info on composite_key_result_less
+ */
+
+typedef multi_index_container<
+ file_entry,
+ indexed_by<
+ /* primary index sorted by name (inside the same directory) */
+ ordered_unique<name_key>,
+ /* secondary index sorted by size (inside the same directory) */
+ ordered_non_unique<size_key>
+ >
+> file_system;
+
+/* typedef's of the two indices of file_system */
+
+typedef nth_index<file_system,0>::type file_system_by_name;
+typedef nth_index<file_system,1>::type file_system_by_size;
+
+/* We build a rudimentary file system simulation out of some global
+ * info and a map of commands provided to the user.
+ */
+
+static file_system fs; /* the one and only file system */
+static file_system_by_name& fs_by_name=fs; /* name index to fs */
+static file_system_by_size& fs_by_size=get<1>(fs); /* size index to fs */
+static const file_entry* current_dir=0; /* root directory */
+
+/* command framework */
+
+/* A command provides an execute memfun fed with the corresponding params
+ * (first param is stripped off as it serves to identify the command
+ * currently being used.)
+ */
+
+typedef boost::tokenizer<boost::char_separator<char> > command_tokenizer;
+
+class command
+{
+public:
+ virtual ~command(){}
+ virtual void execute(
+ command_tokenizer::iterator tok1,command_tokenizer::iterator tok2)=0;
+};
+
+/* available commands */
+
+/* cd: syntax cd [.|..|<directory>] */
+
+class command_cd:public command
+{
+public:
+ virtual void execute(
+ command_tokenizer::iterator tok1,command_tokenizer::iterator tok2)
+ {
+ if(tok1==tok2)return;
+ std::string dir=*tok1++;
+
+ if(dir==".")return;
+ if(dir==".."){
+ if(current_dir)current_dir=current_dir->dir;
+ return;
+ }
+
+ file_system_by_name::iterator it=fs.find(
+ boost::make_tuple(current_dir,dir));
+ if(it==fs.end()){
+ std::cout<<"non-existent directory"<<std::endl;
+ return;
+ }
+ if(!it->is_dir){
+ std::cout<<dir<<" is not a directory"<<std::endl;
+ return;
+ }
+ current_dir=&*it;
+ }
+};
+static command_cd cd;
+
+/* ls: syntax ls [-s] */
+
+class command_ls:public command
+{
+public:
+ virtual void execute(
+ command_tokenizer::iterator tok1,command_tokenizer::iterator tok2)
+ {
+ std::string option;
+ if(tok1!=tok2)option=*tok1++;
+
+ if(!option.empty()){
+ if(option!="-s"){
+ std::cout<<"incorrect parameter"<<std::endl;
+ return;
+ }
+
+ /* list by size */
+
+ file_system_by_size::iterator it0,it1;
+ boost::tie(it0,it1)=fs_by_size.equal_range(
+ boost::make_tuple(current_dir));
+ std::copy(it0,it1,std::ostream_iterator<file_entry>(std::cout,"\n"));
+
+ return;
+ }
+
+ /* list by name */
+
+ file_system_by_name::iterator it0,it1;
+ boost::tie(it0,it1)=fs.equal_range(boost::make_tuple(current_dir));
+ std::copy(it0,it1,std::ostream_iterator<file_entry>(std::cout,"\n"));
+ }
+};
+static command_ls ls;
+
+/* mkdir: syntax mkdir <directory> */
+
+class command_mkdir:public command
+{
+public:
+ virtual void execute(
+ command_tokenizer::iterator tok1,command_tokenizer::iterator tok2)
+ {
+ std::string dir;
+ if(tok1!=tok2)dir=*tok1++;
+
+ if(dir.empty()){
+ std::cout<<"missing parameter"<<std::endl;
+ return;
+ }
+
+ if(dir=="."||dir==".."){
+ std::cout<<"incorrect parameter"<<std::endl;
+ return;
+ }
+
+ if(!fs.insert(file_entry(dir,0,true,current_dir)).second){
+ std::cout<<"directory already exists"<<std::endl;
+ return;
+ }
+ }
+};
+static command_mkdir mkdir;
+
+/* table of commands, a map from command names to class command pointers */
+
+typedef std::map<std::string,command*> command_table;
+static command_table cmt;
+
+int main()
+{
+ /* fill the file system with some data */
+
+ file_system::iterator it0,it1;
+
+ fs.insert(file_entry("usr.cfg",240,false,0));
+ fs.insert(file_entry("memo.txt",2430,false,0));
+ it0=fs.insert(file_entry("dev",0,true,0)).first;
+ fs.insert(file_entry("tty0",128,false,&*it0));
+ fs.insert(file_entry("tty1",128,false,&*it0));
+ it0=fs.insert(file_entry("usr",0,true,0)).first;
+ it1=fs.insert(file_entry("bin",0,true,&*it0)).first;
+ fs.insert(file_entry("bjam",172032,false,&*it1));
+ it0=fs.insert(file_entry("home",0,true,0)).first;
+ it1=fs.insert(file_entry("andy",0,true,&*it0)).first;
+ fs.insert(file_entry("logo.jpg",5345,false,&*it1)).first;
+ fs.insert(file_entry("foo.cpp",890,false,&*it1)).first;
+ fs.insert(file_entry("foo.hpp",93,false,&*it1)).first;
+ fs.insert(file_entry("foo.html",750,false,&*it1)).first;
+ fs.insert(file_entry("a.obj",12302,false,&*it1)).first;
+ fs.insert(file_entry(".bash_history",8780,false,&*it1)).first;
+ it1=fs.insert(file_entry("rachel",0,true,&*it0)).first;
+ fs.insert(file_entry("test.py",650,false,&*it1)).first;
+ fs.insert(file_entry("todo.txt",241,false,&*it1)).first;
+ fs.insert(file_entry(".bash_history",9510,false,&*it1)).first;
+
+ /* fill the command table */
+
+ cmt["cd"] =&cd;
+ cmt["ls"] =&ls;
+ cmt["mkdir"]=&mkdir;
+
+ /* main looop */
+
+ for(;;){
+ /* print out the current directory and the prompt symbol */
+
+ if(current_dir)std::cout<<current_dir->name;
+ std::cout<<">";
+
+ /* get an input line from the user: if empty, exit the program */
+
+ std::string com;
+ std::getline(std::cin,com);
+ command_tokenizer tok(com,boost::char_separator<char>(" \t\n"));
+ if(tok.begin()==tok.end())break; /* null command, exit */
+
+ /* select the corresponding command and execute it */
+
+ command_table::iterator it=cmt.find(*tok.begin());
+ if(it==cmt.end()){
+ std::cout<<"invalid command"<<std::endl;
+ continue;
+ }
+
+ it->second->execute(boost::next(tok.begin()),tok.end());
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/fun_key.cpp b/src/boost/libs/multi_index/example/fun_key.cpp
new file mode 100644
index 000000000..769d7bf6c
--- /dev/null
+++ b/src/boost/libs/multi_index/example/fun_key.cpp
@@ -0,0 +1,100 @@
+/* Boost.MultiIndex example of functions used as key extractors.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/global_fun.hpp>
+#include <boost/multi_index/mem_fun.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <iostream>
+#include <string>
+
+using namespace boost::multi_index;
+
+/* A name record consists of the given name (e.g. "Charlie")
+ * and the family name (e.g. "Brown"). The full name, calculated
+ * by name_record::name() is laid out in the "phonebook order"
+ * family name + given_name.
+ */
+
+struct name_record
+{
+ name_record(std::string given_name_,std::string family_name_):
+ given_name(given_name_),family_name(family_name_)
+ {}
+
+ std::string name()const
+ {
+ std::string str=family_name;
+ str+=" ";
+ str+=given_name;
+ return str;
+ }
+
+private:
+ std::string given_name;
+ std::string family_name;
+};
+
+std::string::size_type name_record_length(const name_record& r)
+{
+ return r.name().size();
+}
+
+/* multi_index_container with indices based on name_record::name()
+ * and name_record_length().
+ * See Compiler specifics: Use of const_mem_fun_explicit and
+ * mem_fun_explicit for info on BOOST_MULTI_INDEX_CONST_MEM_FUN.
+ */
+
+typedef multi_index_container<
+ name_record,
+ indexed_by<
+ ordered_unique<
+ BOOST_MULTI_INDEX_CONST_MEM_FUN(name_record,std::string,name)
+ >,
+ ordered_non_unique<
+ global_fun<const name_record&,std::string::size_type,name_record_length>
+ >
+ >
+> name_record_set;
+
+int main()
+{
+ name_record_set ns;
+
+ ns.insert(name_record("Joe","Smith"));
+ ns.insert(name_record("Robert","Nightingale"));
+ ns.insert(name_record("Robert","Brown"));
+ ns.insert(name_record("Marc","Tuxedo"));
+
+ /* list the names in ns in phonebook order */
+
+ std::cout<<"Phonenook order\n"
+ <<"---------------"<<std::endl;
+ for(name_record_set::iterator it=ns.begin();it!=ns.end();++it){
+ std::cout<<it->name()<<std::endl;
+ }
+
+ /* list the names in ns according to their length*/
+
+ std::cout<<"\nLength order\n"
+ << "------------"<<std::endl;
+ for(nth_index<name_record_set,1>::type::iterator it1=get<1>(ns).begin();
+ it1!=get<1>(ns).end();++it1){
+ std::cout<<it1->name()<<std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/hashed.cpp b/src/boost/libs/multi_index/example/hashed.cpp
new file mode 100644
index 000000000..98228ea25
--- /dev/null
+++ b/src/boost/libs/multi_index/example/hashed.cpp
@@ -0,0 +1,124 @@
+/* Boost.MultiIndex example of use of hashed indices.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/tokenizer.hpp>
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+using boost::multi_index_container;
+using namespace boost::multi_index;
+
+/* word_counter keeps the ocurrences of words inserted. A hashed
+ * index allows for fast checking of preexisting entries.
+ */
+
+struct word_counter_entry
+{
+ std::string word;
+ unsigned int occurrences;
+
+ word_counter_entry(std::string word_):word(word_),occurrences(0){}
+};
+
+/* see Compiler specifics: Use of member_offset for info on
+ * BOOST_MULTI_INDEX_MEMBER
+ */
+
+typedef multi_index_container<
+ word_counter_entry,
+ indexed_by<
+ ordered_non_unique<
+ BOOST_MULTI_INDEX_MEMBER(word_counter_entry,unsigned int,occurrences),
+ std::greater<unsigned int> /* sorted beginning with most frequent */
+ >,
+ hashed_unique<
+ BOOST_MULTI_INDEX_MEMBER(word_counter_entry,std::string,word)
+ >
+ >
+> word_counter;
+
+/* utilities */
+
+template<typename T>
+struct increment
+{
+ void operator()(T& x)const{++x;}
+};
+
+typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
+
+int main()
+{
+ /* boostinspect:noascii */
+
+ std::string text=
+ "En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha "
+ "mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga "
+ "antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que "
+ "carnero, salpicón las más noches, duelos y quebrantos los sábados, "
+ "lantejas los viernes, algún palomino de añadidura los domingos, "
+ "consumían las tres partes de su hacienda. El resto della concluían sayo "
+ "de velarte, calzas de velludo para las fiestas, con sus pantuflos de lo "
+ "mesmo, y los días de entresemana se honraba con su vellorí de lo más "
+ "fino. Tenía en su casa una ama que pasaba de los cuarenta, y una "
+ "sobrina que no llegaba a los veinte, y un mozo de campo y plaza, que "
+ "así ensillaba el rocín como tomaba la podadera. Frisaba la edad de "
+ "nuestro hidalgo con los cincuenta años; era de complexión recia, seco "
+ "de carnes, enjuto de rostro, gran madrugador y amigo de la caza. "
+ "Quieren decir que tenía el sobrenombre de Quijada, o Quesada, que en "
+ "esto hay alguna diferencia en los autores que deste caso escriben; "
+ "aunque, por conjeturas verosímiles, se deja entender que se llamaba "
+ "Quejana. Pero esto importa poco a nuestro cuento; basta que en la "
+ "narración dél no se salga un punto de la verdad.";
+
+ /* feed the text into the container */
+
+ word_counter wc;
+ text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
+ unsigned int total_occurrences=0;
+ for(text_tokenizer::iterator it=tok.begin(),it_end=tok.end();
+ it!=it_end;++it){
+ /* Insert the word into the container. If duplicate, wit will point to
+ * the preexistent entry.
+ */
+
+ ++total_occurrences;
+ word_counter::iterator wit=wc.insert(*it).first;
+
+ /* Increment occurrences.
+ * In a lambda-capable compiler, this can be written as:
+ * wc.modify_key(wit,++_1);
+ */
+
+ wc.modify_key(wit,increment<unsigned int>());
+ }
+
+ /* list words by frequency of appearance */
+
+ std::cout<<std::fixed<<std::setprecision(2);
+ for(word_counter::iterator wit=wc.begin(),wit_end=wc.end();
+ wit!=wit_end;++wit){
+ std::cout<<std::setw(11)<<wit->word<<": "
+ <<std::setw(5) <<100.0*wit->occurrences/total_occurrences<<"%"
+ <<std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/ip_allocator.cpp b/src/boost/libs/multi_index/example/ip_allocator.cpp
new file mode 100644
index 000000000..f2c6d677d
--- /dev/null
+++ b/src/boost/libs/multi_index/example/ip_allocator.cpp
@@ -0,0 +1,293 @@
+/* Boost.MultiIndex example of use of Boost.Interprocess allocators.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/containers/string.hpp>
+#include <boost/interprocess/managed_mapped_file.hpp>
+#include <boost/interprocess/sync/named_mutex.hpp>
+#include <boost/interprocess/sync/scoped_lock.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/member.hpp>
+#include <iostream>
+#include <iterator>
+#include <sstream>
+#include <string>
+
+using boost::multi_index_container;
+using namespace boost::multi_index;
+namespace bip=boost::interprocess;
+
+/* shared_string is a string type placeable in shared memory,
+ * courtesy of Boost.Interprocess.
+ */
+
+typedef bip::basic_string<
+ char,std::char_traits<char>,
+ bip::allocator<char,bip::managed_mapped_file::segment_manager>
+> shared_string;
+
+/* Book record. All its members can be placed in shared memory,
+ * hence the structure itself can too.
+ */
+
+struct book
+{
+ shared_string name;
+ shared_string author;
+ unsigned pages;
+ unsigned prize;
+
+ book(const shared_string::allocator_type& al):
+ name(al),author(al),pages(0),prize(0)
+ {}
+
+ friend std::ostream& operator<<(std::ostream& os,const book& b)
+ {
+ os<<b.author<<": \""<<b.name<<"\", $"<<b.prize<<", "<<b.pages<<" pages\n";
+ return os;
+ }
+};
+
+/* partial_str_less allows for partial searches taking into account
+ * only the first n chars of the strings compared against. See
+ * Tutorial: Basics: Special lookup operations for more info on this
+ * type of comparison functors.
+ */
+
+/* partial_string is a mere string holder used to differentiate from
+ * a plain string.
+ */
+
+struct partial_string
+{
+ partial_string(const shared_string& str):str(str){}
+ shared_string str;
+};
+
+struct partial_str_less
+{
+ bool operator()(const shared_string& x,const shared_string& y)const
+ {
+ return x<y;
+ }
+
+ bool operator()(const shared_string& x,const partial_string& y)const
+ {
+ return x.substr(0,y.str.size())<y.str;
+ }
+
+ bool operator()(const partial_string& x,const shared_string& y)const
+ {
+ return x.str<y.substr(0,x.str.size());
+ }
+};
+
+/* Define a multi_index_container of book records with indices on
+ * author, name and prize. The index on names allows for partial
+ * searches. This container can be placed in shared memory because:
+ * * book can be placed in shared memory.
+ * * We are using a Boost.Interprocess specific allocator.
+ */
+
+/* see Compiler specifics: Use of member_offset for info on
+ * BOOST_MULTI_INDEX_MEMBER
+ */
+
+typedef multi_index_container<
+ book,
+ indexed_by<
+ ordered_non_unique<
+ BOOST_MULTI_INDEX_MEMBER(book,shared_string,author)
+ >,
+ ordered_non_unique<
+ BOOST_MULTI_INDEX_MEMBER(book,shared_string,name),
+ partial_str_less
+ >,
+ ordered_non_unique<
+ BOOST_MULTI_INDEX_MEMBER(book,unsigned,prize)
+ >
+ >,
+ bip::allocator<book,bip::managed_mapped_file::segment_manager>
+> book_container;
+
+/* A small utility to get data entered via std::cin */
+
+template<typename T>
+void enter(const char* msg,T& t)
+{
+ std::cout<<msg;
+ std::string str;
+ std::getline(std::cin,str);
+ std::istringstream iss(str);
+ iss>>t;
+}
+
+void enter(const char* msg,std::string& str)
+{
+ std::cout<<msg;
+ std::getline(std::cin,str);
+}
+
+void enter(const char* msg,shared_string& str)
+{
+ std::cout<<msg;
+ std::string stdstr;
+ std::getline(std::cin,stdstr);
+ str=stdstr.c_str();
+}
+
+int main()
+{
+ /* Create (or open) the memory mapped file where the book container
+ * is stored, along with a mutex for synchronized access.
+ */
+
+ bip::managed_mapped_file seg(
+ bip::open_or_create,"./book_container.db",
+ 65536);
+ bip::named_mutex mutex(
+ bip::open_or_create,"7FD6D7E8-320B-11DC-82CF-F0B655D89593");
+
+ /* create or open the book container in shared memory */
+
+ book_container* pbc=seg.find_or_construct<book_container>("book container")(
+ book_container::ctor_args_list(),
+ book_container::allocator_type(seg.get_segment_manager()));
+
+ std::string command_info=
+ "1. list books by author\n"
+ "2. list all books by prize\n"
+ "3. insert a book\n"
+ "4. delete a book\n"
+ "0. exit\n";
+
+ std::cout<<command_info;
+
+ /* main loop */
+
+ for(bool exit=false;!exit;){
+ int command=-1;
+ enter("command: ",command);
+
+ switch(command){
+ case 0:{ /* exit */
+ exit=true;
+ break;
+ }
+ case 1:{ /* list books by author */
+ std::string author;
+ enter("author (empty=all authors): ",author);
+
+ /* operations with the container must be mutex protected */
+
+ bip::scoped_lock<bip::named_mutex> lock(mutex);
+
+ std::pair<book_container::iterator,book_container::iterator> rng;
+ if(author.empty()){
+ rng=std::make_pair(pbc->begin(),pbc->end());
+ }
+ else{
+ rng=pbc->equal_range(
+ shared_string(
+ author.c_str(),
+ shared_string::allocator_type(seg.get_segment_manager())));
+ }
+
+ if(rng.first==rng.second){
+ std::cout<<"no entries\n";
+ }
+ else{
+ std::copy(
+ rng.first,rng.second,std::ostream_iterator<book>(std::cout));
+ }
+ break;
+ }
+ case 2:{ /* list all books by prize */
+ bip::scoped_lock<bip::named_mutex> lock(mutex);
+
+ std::copy(
+ get<2>(*pbc).begin(),get<2>(*pbc).end(),
+ std::ostream_iterator<book>(std::cout));
+ break;
+ }
+ case 3:{ /* insert a book */
+ book b(shared_string::allocator_type(seg.get_segment_manager()));
+
+ enter("author: ",b.author);
+ enter("name: " ,b.name);
+ enter("prize: " ,b.prize);
+ enter("pages: " ,b.pages);
+
+ std::cout<<"insert the following?\n"<<b<<"(y/n): ";
+ char yn='n';
+ enter("",yn);
+ if(yn=='y'||yn=='Y'){
+ bip::scoped_lock<bip::named_mutex> lock(mutex);
+ pbc->insert(b);
+ }
+
+ break;
+ }
+ case 4:{ /* delete a book */
+ shared_string name(
+ shared_string::allocator_type(seg.get_segment_manager()));
+ enter(
+ "name of the book (you can enter\nonly the first few characters): ",
+ name);
+
+ typedef nth_index<book_container,1>::type index_by_name;
+ index_by_name& idx=get<1>(*pbc);
+ index_by_name::iterator it;
+ book b(shared_string::allocator_type(seg.get_segment_manager()));
+
+ {
+ /* Look for a book whose title begins with name. Note that we
+ * are unlocking after doing the search so as to not leave the
+ * container blocked during user prompting. That is also why a
+ * local copy of the book is done.
+ */
+
+ bip::scoped_lock<bip::named_mutex> lock(mutex);
+
+ it=idx.find(partial_string(name));
+ if(it==idx.end()){
+ std::cout<<"no such book found\n";
+ break;
+ }
+ b=*it;
+ }
+
+ std::cout<<"delete the following?\n"<<b<<"(y/n): ";
+ char yn='n';
+ enter("",yn);
+ if(yn=='y'||yn=='Y'){
+ bip::scoped_lock<bip::named_mutex> lock(mutex);
+ idx.erase(it);
+ }
+
+ break;
+ }
+ default:{
+ std::cout<<"select one option:\n"<<command_info;
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/non_default_ctor.cpp b/src/boost/libs/multi_index/example/non_default_ctor.cpp
new file mode 100644
index 000000000..afdbd5133
--- /dev/null
+++ b/src/boost/libs/multi_index/example/non_default_ctor.cpp
@@ -0,0 +1,96 @@
+/* Boost.MultiIndex example of use of multi_index_container::ctor_args_list.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+
+using boost::multi_index_container;
+using namespace boost::multi_index;
+
+/* modulo_less order numbers according to their division residual.
+ * For instance, if modulo==10 then 22 is less than 15 as 22%10==2 and
+ * 15%10==5.
+ */
+
+template<typename IntegralType>
+struct modulo_less
+{
+ modulo_less(IntegralType m):modulo(m){}
+
+ bool operator()(IntegralType x,IntegralType y)const
+ {
+ return (x%modulo)<(y%modulo);
+ }
+
+private:
+ IntegralType modulo;
+};
+
+/* multi_index_container of unsigned ints holding a "natural" index plus
+ * an ordering based on modulo_less.
+ */
+
+typedef multi_index_container<
+ unsigned int,
+ indexed_by<
+ ordered_unique<identity<unsigned int> >,
+ ordered_non_unique<identity<unsigned int>, modulo_less<unsigned int> >
+ >
+> modulo_indexed_set;
+
+int main()
+{
+ /* define a modulo_indexed_set with modulo==10 */
+
+ modulo_indexed_set::ctor_args_list args_list=
+ boost::make_tuple(
+ /* ctor_args for index #0 is default constructible */
+ nth_index<modulo_indexed_set,0>::type::ctor_args(),
+
+ /* first parm is key_from_value, second is our sought for key_compare */
+ boost::make_tuple(identity<unsigned int>(),modulo_less<unsigned int>(10))
+ );
+
+ modulo_indexed_set m(args_list);
+ /* this could have be written online without the args_list variable,
+ * left as it is for explanatory purposes. */
+
+ /* insert some numbers */
+
+ unsigned int numbers[]={0,1,20,40,33,68,11,101,60,34,88,230,21,4,7,17};
+ const std::size_t numbers_length(sizeof(numbers)/sizeof(numbers[0]));
+
+ m.insert(&numbers[0],&numbers[numbers_length]);
+
+ /* lists all numbers in order, along with their "equivalence class", that is,
+ * the equivalent numbers under modulo_less
+ */
+
+ for(modulo_indexed_set::iterator it=m.begin();it!=m.end();++it){
+ std::cout<<*it<<" -> ( ";
+
+ nth_index<modulo_indexed_set,1>::type::iterator it0,it1;
+ boost::tie(it0,it1)=get<1>(m).equal_range(*it);
+ std::copy(it0,it1,std::ostream_iterator<unsigned int>(std::cout," "));
+
+ std::cout<<")"<<std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/random_access.cpp b/src/boost/libs/multi_index/example/random_access.cpp
new file mode 100644
index 000000000..7532c6d9d
--- /dev/null
+++ b/src/boost/libs/multi_index/example/random_access.cpp
@@ -0,0 +1,102 @@
+/* Boost.MultiIndex example of use of random access indices.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/tokenizer.hpp>
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <string>
+
+using boost::multi_index_container;
+using namespace boost::multi_index;
+
+/* text_container holds words as inserted and also keep them indexed
+ * by dictionary order.
+ */
+
+typedef multi_index_container<
+ std::string,
+ indexed_by<
+ random_access<>,
+ ordered_non_unique<identity<std::string> >
+ >
+> text_container;
+
+/* ordered index */
+
+typedef nth_index<text_container,1>::type ordered_text;
+
+/* Helper function for obtaining the position of an element in the
+ * container.
+ */
+
+template<typename IndexIterator>
+text_container::size_type text_position(
+ const text_container& tc,IndexIterator it)
+{
+ /* project to the base index and calculate offset from begin() */
+
+ return project<0>(tc,it)-tc.begin();
+}
+
+typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
+
+int main()
+{
+ std::string text=
+ "'Oh, you wicked little thing!' cried Alice, catching up the kitten, "
+ "and giving it a little kiss to make it understand that it was in "
+ "disgrace. 'Really, Dinah ought to have taught you better manners! You "
+ "ought, Dinah, you know you ought!' she added, looking reproachfully at "
+ "the old cat, and speaking in as cross a voice as she could manage "
+ "-- and then she scrambled back into the armchair, taking the kitten and "
+ "the worsted with her, and began winding up the ball again. But she "
+ "didn't get on very fast, as she was talking all the time, sometimes to "
+ "the kitten, and sometimes to herself. Kitty sat very demurely on her "
+ "knee, pretending to watch the progress of the winding, and now and then "
+ "putting out one paw and gently touching the ball, as if it would be glad "
+ "to help, if it might.";
+
+ /* feed the text into the container */
+
+ text_container tc;
+ tc.reserve(text.size()); /* makes insertion faster */
+ text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
+ std::copy(tok.begin(),tok.end(),std::back_inserter(tc));
+
+ std::cout<<"enter a position (0-"<<tc.size()-1<<"):";
+ text_container::size_type pos=tc.size();
+ std::cin>>pos;
+ if(pos>=tc.size()){
+ std::cout<<"out of bounds"<<std::endl;
+ }
+ else{
+ std::cout<<"the word \""<<tc[pos]<<"\" appears at position(s): ";
+
+ std::pair<ordered_text::iterator,ordered_text::iterator> p=
+ get<1>(tc).equal_range(tc[pos]);
+ while(p.first!=p.second){
+ std::cout<<text_position(tc,p.first++)<<" ";
+ }
+
+ std::cout<<std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/rearrange.cpp b/src/boost/libs/multi_index/example/rearrange.cpp
new file mode 100644
index 000000000..31388513d
--- /dev/null
+++ b/src/boost/libs/multi_index/example/rearrange.cpp
@@ -0,0 +1,265 @@
+/* Boost.MultiIndex example of use of rearrange facilities.
+ *
+ * Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/config.hpp>
+#include <boost/detail/iterator.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/random/binomial_distribution.hpp>
+#include <boost/random/uniform_real.hpp>
+#include <boost/random/mersenne_twister.hpp>
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <vector>
+
+#if !defined(BOOST_NO_CXX11_HDR_RANDOM)
+#include <random>
+#endif
+
+using boost::multi_index_container;
+using namespace boost::multi_index;
+
+/* We model a card deck with a random access array containing
+ * card numbers (from 0 to 51), supplemented with an additional
+ * index which retains the start ordering.
+ */
+
+class deck
+{
+ BOOST_STATIC_CONSTANT(std::size_t,num_cards=52);
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ random_access<>, /* base index */
+ random_access<> /* "start" index */
+ >
+ > container_type;
+ container_type cont;
+
+public:
+ deck()
+ {
+ cont.reserve(num_cards);
+ get<1>(cont).reserve(num_cards);
+ for(std::size_t i=0;i<num_cards;++i)cont.push_back(i);
+ }
+
+ typedef container_type::iterator iterator;
+ typedef container_type::size_type size_type;
+
+ iterator begin()const{return cont.begin();}
+ iterator end()const{return cont.end();}
+ size_type size()const{return cont.size();}
+
+ template<typename InputIterator>
+ void rearrange(InputIterator it)
+ {
+ cont.rearrange(it);
+ }
+
+ void reset()
+ {
+ /* simply rearrange the base index like the start index */
+
+ cont.rearrange(get<1>(cont).begin());
+ }
+
+ std::size_t position(int i)const
+ {
+ /* The position of a card in the deck is calculated by locating
+ * the card through the start index (which is ordered), projecting
+ * to the base index and diffing with the begin position.
+ * Resulting complexity: constant.
+ */
+
+ return project<0>(cont,get<1>(cont).begin()+i)-cont.begin();
+ }
+
+ std::size_t rising_sequences()const
+ {
+ /* Iterate through all cards and increment the sequence count
+ * when the current position is left to the previous.
+ * Resulting complexity: O(n), n=num_cards.
+ */
+
+ std::size_t s=1;
+ std::size_t last_pos=0;
+
+ for(std::size_t i=0;i<num_cards;++i){
+ std::size_t pos=position(i);
+ if(pos<last_pos)++s;
+ last_pos=pos;
+ }
+
+ return s;
+ }
+};
+
+/* A vector of reference_wrappers to deck elements can be used
+ * as a view to the deck container.
+ * We use a special implicit_reference_wrapper having implicit
+ * ctor from its base type, as this simplifies the use of generic
+ * techniques on the resulting data structures.
+ */
+
+template<typename T>
+class implicit_reference_wrapper:public boost::reference_wrapper<T>
+{
+private:
+ typedef boost::reference_wrapper<T> super;
+public:
+ implicit_reference_wrapper(T& t):super(t){}
+};
+
+typedef std::vector<implicit_reference_wrapper<const int> > deck_view;
+
+/* Riffle shuffle is modeled like this: A cut is selected in the deck
+ * following a binomial distribution. Then, cards are randomly selected
+ * from one packet or the other with probability proportional to
+ * packet size.
+ */
+
+template<typename RandomAccessIterator,typename OutputIterator>
+void riffle_shuffle(
+ RandomAccessIterator first,RandomAccessIterator last,
+ OutputIterator out)
+{
+ static boost::mt19937 rnd_gen;
+
+ typedef typename boost::detail::iterator_traits<
+ RandomAccessIterator>::difference_type difference_type;
+ typedef boost::binomial_distribution<
+ difference_type> rnd_cut_select_type;
+ typedef boost::uniform_real<> rnd_deck_select_type;
+
+ rnd_cut_select_type cut_select(last-first);
+ RandomAccessIterator middle=first+cut_select(rnd_gen);
+ difference_type s0=middle-first;
+ difference_type s1=last-middle;
+ rnd_deck_select_type deck_select;
+
+ while(s0!=0&&s1!=0){
+ if(deck_select(rnd_gen)<(double)s0/(s0+s1)){
+ *out++=*first++;
+ --s0;
+ }
+ else{
+ *out++=*middle++;
+ --s1;
+ }
+ }
+ std::copy(first,first+s0,out);
+ std::copy(middle,middle+s1,out);
+}
+
+struct riffle_shuffler
+{
+ void operator()(deck& d)const
+ {
+ dv.clear();
+ dv.reserve(d.size());
+ riffle_shuffle(
+ d.begin(),d.end(),std::back_inserter(dv)); /* do the shuffling */
+ d.rearrange(dv.begin()); /* apply to the deck */
+ }
+
+private:
+ mutable deck_view dv;
+};
+
+/* A truly random shuffle (up to stdlib implementation quality) using
+ * std::shuffle.
+ */
+
+struct random_shuffler
+{
+ void operator()(deck& d)
+ {
+ dv.clear();
+ dv.reserve(d.size());
+ std::copy(d.begin(),d.end(),std::back_inserter(dv));
+ shuffle_view();
+ d.rearrange(dv.begin()); /* apply to the deck */
+ }
+
+private:
+ deck_view dv;
+
+#if !defined(BOOST_NO_CXX11_HDR_RANDOM)
+ std::mt19937 e;
+
+ void shuffle_view()
+ {
+ std::shuffle(dv.begin(),dv.end(),e);
+ }
+#else
+ /* for pre-C++11 compilers we use std::random_shuffle */
+
+ void shuffle_view()
+ {
+ std::random_shuffle(dv.begin(),dv.end());
+ }
+#endif
+};
+
+/* Repeat a given shuffling algorithm repeats_num times
+ * and obtain the resulting rising sequences number. Average
+ * for tests_num trials.
+ */
+
+template<typename Shuffler>
+double shuffle_test(
+ unsigned int repeats_num,unsigned int tests_num
+ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Shuffler))
+{
+ deck d;
+ Shuffler sh;
+ unsigned long total=0;
+
+ for(unsigned int n=0;n<tests_num;++n){
+ for(unsigned m=0;m<repeats_num;++m)sh(d);
+ total+=d.rising_sequences();
+ d.reset();
+ }
+
+ return (double)total/tests_num;
+}
+
+int main()
+{
+ unsigned rifs_num=0;
+ unsigned tests_num=0;
+
+ std::cout<<"number of riffle shuffles (vg 5):";
+ std::cin>>rifs_num;
+ std::cout<<"number of tests (vg 1000):";
+ std::cin>>tests_num;
+
+ std::cout<<"shuffling..."<<std::endl;
+
+ std::cout<<"riffle shuffling\n"
+ " avg number of rising sequences: "
+ <<shuffle_test<riffle_shuffler>(rifs_num,tests_num)
+ <<std::endl;
+
+ std::cout<<"random shuffling\n"
+ " avg number of rising sequences: "
+ <<shuffle_test<random_shuffler>(1,tests_num)
+ <<std::endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/sequenced.cpp b/src/boost/libs/multi_index/example/sequenced.cpp
new file mode 100644
index 000000000..14651da4f
--- /dev/null
+++ b/src/boost/libs/multi_index/example/sequenced.cpp
@@ -0,0 +1,100 @@
+/* Boost.MultiIndex example of use of sequenced indices.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/tokenizer.hpp>
+#include <algorithm>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <string>
+
+using boost::multi_index_container;
+using namespace boost::multi_index;
+
+/* text_container holds words as inserted and also keep them indexed
+ * by dictionary order.
+ */
+
+typedef multi_index_container<
+ std::string,
+ indexed_by<
+ sequenced<>,
+ ordered_non_unique<identity<std::string> >
+ >
+> text_container;
+
+/* ordered index */
+
+typedef nth_index<text_container,1>::type ordered_text;
+
+typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
+
+int main()
+{
+ std::string text=
+ "Alice was beginning to get very tired of sitting by her sister on the "
+ "bank, and of having nothing to do: once or twice she had peeped into the "
+ "book her sister was reading, but it had no pictures or conversations in "
+ "it, 'and what is the use of a book,' thought Alice 'without pictures or "
+ "conversation?'";
+
+ /* feed the text into the container */
+
+ text_container tc;
+ text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
+ std::copy(tok.begin(),tok.end(),std::back_inserter(tc));
+
+ /* list all words in alphabetical order along with their number
+ * of occurrences
+ */
+
+ ordered_text& ot=get<1>(tc);
+ for(ordered_text::iterator it=ot.begin();it!=ot.end();){
+ std::cout<<std::left<<std::setw(14)<<*it<<":"; /* print the word */
+ ordered_text::iterator it2=ot.upper_bound(*it); /* jump to next */
+ std::cout<<std::right<<std::setw(3) /* and compute the distance */
+ <<std::distance(it,it2)<<" times"<<std::endl;
+ it=it2;
+ }
+
+ /* reverse the text and print it out */
+
+ tc.reverse();
+ std::cout<<std::endl;
+ std::copy(
+ tc.begin(),tc.end(),std::ostream_iterator<std::string>(std::cout," "));
+ std::cout<<std::endl;
+ tc.reverse(); /* undo */
+
+ /* delete most common English words and print the result */
+
+ std::string common_words[]=
+ {"the","of","and","a","to","in","is","you","that","it",
+ "he","for","was","on","are","as","with","his","they","at"};
+
+ for(std::size_t n=0;n<sizeof(common_words)/sizeof(common_words[0]);++n){
+ ot.erase(common_words[n]);
+ }
+ std::cout<<std::endl;
+ std::copy(
+ tc.begin(),tc.end(),std::ostream_iterator<std::string>(std::cout," "));
+ std::cout<<std::endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/example/serialization.cpp b/src/boost/libs/multi_index/example/serialization.cpp
new file mode 100644
index 000000000..46ccf508e
--- /dev/null
+++ b/src/boost/libs/multi_index/example/serialization.cpp
@@ -0,0 +1,144 @@
+/* Boost.MultiIndex example of serialization of a MRU list.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#if !defined(NDEBUG)
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <sstream>
+#include <string>
+
+using namespace boost::multi_index;
+
+/* An MRU (most recently used) list keeps record of the last n
+ * inserted items, listing first the newer ones. Care has to be
+ * taken when a duplicate item is inserted: instead of letting it
+ * appear twice, the MRU list relocates it to the first position.
+ */
+
+template <typename Item>
+class mru_list
+{
+ typedef multi_index_container<
+ Item,
+ indexed_by<
+ sequenced<>,
+ hashed_unique<identity<Item> >
+ >
+ > item_list;
+
+public:
+ typedef Item item_type;
+ typedef typename item_list::iterator iterator;
+
+ mru_list(std::size_t max_num_items_):max_num_items(max_num_items_){}
+
+ void insert(const item_type& item)
+ {
+ std::pair<iterator,bool> p=il.push_front(item);
+
+ if(!p.second){ /* duplicate item */
+ il.relocate(il.begin(),p.first); /* put in front */
+ }
+ else if(il.size()>max_num_items){ /* keep the length <= max_num_items */
+ il.pop_back();
+ }
+ }
+
+ iterator begin(){return il.begin();}
+ iterator end(){return il.end();}
+
+ /* Utilities to save and load the MRU list, internally
+ * based on Boost.Serialization.
+ */
+
+ void save_to_file(const char* file_name)const
+ {
+ std::ofstream ofs(file_name);
+ boost::archive::text_oarchive oa(ofs);
+ oa<<boost::serialization::make_nvp("mru",*this);
+ }
+
+ void load_from_file(const char* file_name)
+ {
+ std::ifstream ifs(file_name);
+ if(ifs){
+ boost::archive::text_iarchive ia(ifs);
+ ia>>boost::serialization::make_nvp("mru",*this);
+ }
+ }
+
+private:
+ item_list il;
+ std::size_t max_num_items;
+
+ /* serialization support */
+
+ friend class boost::serialization::access;
+
+ template<class Archive>
+ void serialize(Archive& ar,const unsigned int)
+ {
+ ar&BOOST_SERIALIZATION_NVP(il);
+ ar&BOOST_SERIALIZATION_NVP(max_num_items);
+ }
+};
+
+int main()
+{
+ const char* mru_store="mru_store";
+
+ /* Construct a MRU limited to 10 items and retrieve its
+ * previous contents.
+ */
+
+ mru_list<std::string> mru(10);
+ mru.load_from_file(mru_store);
+
+ /* main loop */
+
+ for(;;){
+ std::cout<<"enter a term: ";
+
+ std::string line;
+ std::getline(std::cin,line);
+ if(line.empty())break;
+
+ std::string term;
+ std::istringstream iss(line);
+ iss>>term;
+ if(term.empty())break;
+
+ mru.insert(term);
+
+ std::cout<<"most recently entered terms:"<<std::endl;
+ std::copy(
+ mru.begin(),mru.end(),
+ std::ostream_iterator<std::string>(std::cout,"\n"));
+ }
+
+ /* persist the MRU list */
+
+ mru.save_to_file(mru_store);
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/index.html b/src/boost/libs/multi_index/index.html
new file mode 100644
index 000000000..c190fc1e6
--- /dev/null
+++ b/src/boost/libs/multi_index/index.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
+<!--
+ Copyright 2003-2004 Joaquín M López Muñoz.
+ Distributed under 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)
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<meta http-equiv="refresh" content="0; URL=doc/index.html">
+<title>Boost.MultiIndex Documentation</title>
+<link rel="stylesheet" href="doc/style.css" type="text/css">
+</head>
+
+<body>
+Automatic redirection failed, please go to
+<a href="doc/index.html">doc/index.html</a>
+</body>
+</html>
diff --git a/src/boost/libs/multi_index/meta/libraries.json b/src/boost/libs/multi_index/meta/libraries.json
new file mode 100644
index 000000000..8f0df7493
--- /dev/null
+++ b/src/boost/libs/multi_index/meta/libraries.json
@@ -0,0 +1,15 @@
+{
+ "key": "multi_index",
+ "name": "Multi-Index",
+ "authors": [
+ "Joaqu\u00edn M L\u00f3pez Mu\u00f1oz"
+ ],
+ "description": "The Boost Multi-index Containers Library provides a class template named multi_index_container which enables the construction of containers maintaining one or more indices with different sorting and access semantics.",
+ "category": [
+ "Containers",
+ "Data"
+ ],
+ "maintainers": [
+ "Joaquin M Lopez Munoz <joaquin.lopezmunoz -at- gmail.com>"
+ ]
+}
diff --git a/src/boost/libs/multi_index/perf/Jamfile.v2 b/src/boost/libs/multi_index/perf/Jamfile.v2
new file mode 100644
index 000000000..c9aea9c7c
--- /dev/null
+++ b/src/boost/libs/multi_index/perf/Jamfile.v2
@@ -0,0 +1,14 @@
+# Boost.MultiIndex performance tests Jamfile
+#
+# Copyright 2003-2006 Joaquín M López Muñoz.
+# Distributed under 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)
+#
+# See http://www.boost.org/libs/multi_index for library home page.
+
+exe test_perf
+ : test_perf.cpp
+ : <include>$(BOOST_ROOT)
+ : release
+ ;
diff --git a/src/boost/libs/multi_index/perf/test_perf.cpp b/src/boost/libs/multi_index/perf/test_perf.cpp
new file mode 100644
index 000000000..7b2441787
--- /dev/null
+++ b/src/boost/libs/multi_index/perf/test_perf.cpp
@@ -0,0 +1,545 @@
+/* Boost.MultiIndex performance test.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+
+#include <algorithm>
+#include <assert.h>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/next_prior.hpp>
+#include <climits>
+#include <ctime>
+#include <iomanip>
+#include <iostream>
+#include <list>
+#include <set>
+#include <string>
+#include <vector>
+
+using namespace std;
+using namespace boost::multi_index;
+
+/* Measurement harness by Andrew Koenig, extracted from companion code to
+ * Stroustrup, B.: "Wrapping C++ Member Function Calls", The C++ Report,
+ * June 2000, Vol 12/No 6.
+ * Original code retrievable at: http://www.research.att.com/~bs/wrap_code.cpp
+ */
+
+// How many clock units does it take to interrogate the clock?
+static double clock_overhead()
+{
+ clock_t k = clock(), start, limit;
+
+ // Wait for the clock to tick
+ do start = clock();
+ while (start == k);
+
+ // interrogate the clock until it has advanced at least a second
+ // (for reasonable accuracy)
+ limit = start + CLOCKS_PER_SEC;
+
+ unsigned long r = 0;
+ while ((k = clock()) < limit)
+ ++r;
+
+ return double(k - start) / r;
+}
+
+// We'd like the odds to be factor:1 that the result is
+// within percent% of the median
+const int factor = 10;
+const int percent = 20;
+
+// Measure a function (object) factor*2 times,
+// appending the measurements to the second argument
+template<class F>
+void measure_aux(F f, vector<double>& mv)
+{
+ static double ovhd = clock_overhead();
+
+ // Ensure we don't reallocate in mid-measurement
+ mv.reserve(mv.size() + factor*2);
+
+ // Wait for the clock to tick
+ clock_t k = clock();
+ clock_t start;
+
+ do start = clock();
+ while (start == k);
+
+ // Do 2*factor measurements
+ for (int i = 2*factor; i; --i) {
+ unsigned long count = 0, limit = 1, tcount = 0;
+
+ // Original code used CLOCKS_PER_SEC/100
+ const clock_t clocklimit = start + CLOCKS_PER_SEC/10;
+ clock_t t;
+
+ do {
+ while (count < limit) {
+ f();
+ ++count;
+ }
+ limit *= 2;
+ ++tcount;
+ } while ((t = clock()) < clocklimit);
+
+ // Wait for the clock to tick again;
+ clock_t t2;
+ do ++tcount;
+ while ((t2 = clock()) == t);
+
+ // Append the measurement to the vector
+ mv.push_back(((t2 - start) - (tcount * ovhd)) / count);
+
+ // Establish a new starting point
+ start = t2;
+ }
+}
+
+// Returns the number of clock units per iteration
+// With odds of factor:1, the measurement is within percent% of
+// the value returned, which is also the median of all measurements.
+template<class F>
+double measure(F f)
+{
+ vector<double> mv;
+
+ int n = 0; // iteration counter
+ do {
+ ++n;
+
+ // Try 2*factor measurements
+ measure_aux(f, mv);
+ assert(mv.size() == 2*n*factor);
+
+ // Compute the median. We know the size is even, so we cheat.
+ sort(mv.begin(), mv.end());
+ double median = (mv[n*factor] + mv[n*factor-1])/2;
+
+ // If the extrema are within threshold of the median, we're done
+ if (mv[n] > (median * (100-percent))/100 &&
+ mv[mv.size() - n - 1] < (median * (100+percent))/100)
+ return median;
+
+ } while (mv.size() < factor * 200);
+
+ // Give up!
+ clog << "Help!\n\n";
+ exit(1);
+}
+
+/* dereferencing compare predicate */
+
+template <typename Iterator,typename Compare>
+struct it_compare
+{
+ bool operator()(const Iterator& x,const Iterator& y)const{return comp(*x,*y);}
+
+private:
+ Compare comp;
+};
+
+/* list_wrapper and multiset_wrapper adapt std::lists and std::multisets
+ * to make them conform to a set-like insert interface which test
+ * routines do assume.
+ */
+
+template <typename List>
+struct list_wrapper:List
+{
+ typedef typename List::value_type value_type;
+ typedef typename List::iterator iterator;
+
+ pair<iterator,bool> insert(const value_type& v)
+ {
+ List::push_back(v);
+ return pair<iterator,bool>(boost::prior(List::end()),true);
+ }
+};
+
+template <typename Multiset>
+struct multiset_wrapper:Multiset
+{
+ typedef typename Multiset::value_type value_type;
+ typedef typename Multiset::iterator iterator;
+
+ pair<iterator,bool> insert(const value_type& v)
+ {
+ return pair<iterator,bool>(Multiset::insert(v),true);
+ }
+};
+
+/* space comsumption of manual simulations is determined by checking
+ * the node sizes of the containers involved. This cannot be done in a
+ * portable manner, so node_size has to be written on a per stdlibrary
+ * basis. Add your own versions if necessary.
+ */
+
+#if defined(BOOST_DINKUMWARE_STDLIB)
+
+template<typename Container>
+size_t node_size(const Container&)
+{
+ return sizeof(*Container().begin()._Mynode());
+}
+
+#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
+
+template<typename Container>
+size_t node_size(const Container&)
+{
+ typedef typename Container::iterator::_Link_type node_ptr;
+ node_ptr p=0;
+ return sizeof(*p);
+}
+
+template<typename Value,typename Allocator>
+size_t node_size(const list<Value,Allocator>&)
+{
+ return sizeof(typename list<Value,Allocator>::iterator::_Node);
+}
+
+template<typename List>
+size_t node_size(const list_wrapper<List>&)
+{
+ return sizeof(typename List::iterator::_Node);
+}
+
+#else
+
+/* default version returns 0 by convention */
+
+template<typename Container>
+size_t node_size(const Container&)
+{
+ return 0;
+}
+
+#endif
+
+/* mono_container runs the tested routine on multi_index and manual
+ * simulations comprised of one standard container.
+ * bi_container and tri_container run the equivalent routine for manual
+ * compositions of two and three standard containers, respectively.
+ */
+
+template <typename Container>
+struct mono_container
+{
+ mono_container(int n_):n(n_){}
+
+ void operator()()
+ {
+ typedef typename Container::iterator iterator;
+
+ Container c;
+
+ for(int i=0;i<n;++i)c.insert(i);
+ for(iterator it=c.begin();it!=c.end();)c.erase(it++);
+ }
+
+ static size_t multi_index_node_size()
+ {
+ return sizeof(*Container().begin().get_node());
+ }
+
+ static size_t node_size()
+ {
+ return ::node_size(Container());
+ }
+
+private:
+ int n;
+};
+
+template <typename Container1,typename Container2>
+struct bi_container
+{
+ bi_container(int n_):n(n_){}
+
+ void operator()()
+ {
+ typedef typename Container1::iterator iterator1;
+ typedef typename Container2::iterator iterator2;
+
+ Container1 c1;
+ Container2 c2;
+
+ for(int i=0;i<n;++i){
+ iterator1 it1=c1.insert(i).first;
+ c2.insert(it1);
+ }
+ for(iterator2 it2=c2.begin();it2!=c2.end();)
+ {
+ c1.erase(*it2);
+ c2.erase(it2++);
+ }
+ }
+
+ static size_t node_size()
+ {
+ return ::node_size(Container1())+::node_size(Container2());
+ }
+
+private:
+ int n;
+};
+
+template <typename Container1,typename Container2,typename Container3>
+struct tri_container
+{
+ tri_container(int n_):n(n_){}
+
+ void operator()()
+ {
+ typedef typename Container1::iterator iterator1;
+ typedef typename Container2::iterator iterator2;
+ typedef typename Container3::iterator iterator3;
+
+ Container1 c1;
+ Container2 c2;
+ Container3 c3;
+
+ for(int i=0;i<n;++i){
+ iterator1 it1=c1.insert(i).first;
+ iterator2 it2=c2.insert(it1).first;
+ c3.insert(it2);
+ }
+ for(iterator3 it3=c3.begin();it3!=c3.end();)
+ {
+ c1.erase(**it3);
+ c2.erase(*it3);
+ c3.erase(it3++);
+ }
+ }
+
+ static size_t node_size()
+ {
+ return ::node_size(Container1())+
+ ::node_size(Container2())+::node_size(Container3());
+ }
+
+private:
+ int n;
+};
+
+/* measure and compare two routines for several numbers of elements
+ * and also estimates relative memory consumption.
+ */
+
+template <typename IndexedTest,typename ManualTest>
+void run_tests(const char* title)
+{
+ cout<<fixed<<setprecision(2);
+ cout<<title<<endl;
+ int n=1000;
+ for(int i=0;i<3;++i){
+ double indexed_t=measure(IndexedTest(n));
+ double manual_t=measure(ManualTest(n));
+ cout<<" 10^"<<i+3<<" elmts: "
+ <<setw(6)<<100.0*indexed_t/manual_t<<"% "
+ <<"("
+ <<setw(6)<<1000.0*indexed_t/CLOCKS_PER_SEC<<" ms / "
+ <<setw(6)<<1000.0*manual_t/CLOCKS_PER_SEC<<" ms)"
+ <<endl;
+ n*=10;
+ }
+
+ size_t indexed_t_node_size=IndexedTest::multi_index_node_size();
+ size_t manual_t_node_size=ManualTest::node_size();
+
+ if(manual_t_node_size){
+ cout<<" space gain: "
+ <<setw(6)<<100.0*indexed_t_node_size/manual_t_node_size<<"%"<<endl;
+ }
+}
+
+/* compare_structures accept a multi_index_container instantiation and
+ * several standard containers, builds a manual simulation out of the
+ * latter and run the tests.
+ */
+
+template <typename IndexedType,typename ManualType>
+void compare_structures(const char* title)
+{
+ run_tests<
+ mono_container<IndexedType>,
+ mono_container<ManualType>
+ >(title);
+}
+
+template <typename IndexedType,typename ManualType1,typename ManualType2>
+void compare_structures2(const char* title)
+{
+ run_tests<
+ mono_container<IndexedType>,
+ bi_container<ManualType1,ManualType2>
+ >(title);
+}
+
+template <
+ typename IndexedType,
+ typename ManualType1,typename ManualType2,typename ManualType3
+>
+void compare_structures3(const char* title)
+{
+ run_tests<
+ mono_container<IndexedType>,
+ tri_container<ManualType1,ManualType2,ManualType3>
+ >(title);
+}
+
+int main()
+{
+ /* some stdlibs provide the discussed but finally rejected std::identity */
+ using boost::multi_index::identity;
+
+ {
+ /* 1 ordered index */
+
+ typedef multi_index_container<int> indexed_t;
+ typedef set<int> manual_t;
+
+ compare_structures<indexed_t,manual_t>(
+ "1 ordered index");
+ }
+ {
+ /* 1 sequenced index */
+
+ typedef list_wrapper<
+ multi_index_container<
+ int,
+ indexed_by<sequenced<> >
+ >
+ > indexed_t;
+ typedef list_wrapper<list<int> > manual_t;
+
+ compare_structures<indexed_t,manual_t>(
+ "1 sequenced index");
+ }
+ {
+ /* 2 ordered indices */
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ordered_unique<identity<int> >,
+ ordered_non_unique<identity<int> >
+ >
+ > indexed_t;
+ typedef set<int> manual_t1;
+ typedef multiset<
+ manual_t1::iterator,
+ it_compare<
+ manual_t1::iterator,
+ manual_t1::key_compare
+ >
+ > manual_t2;
+
+ compare_structures2<indexed_t,manual_t1,manual_t2>(
+ "2 ordered indices");
+ }
+ {
+ /* 1 ordered index + 1 sequenced index */
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ boost::multi_index::ordered_unique<identity<int> >,
+ sequenced<>
+ >
+ > indexed_t;
+ typedef list_wrapper<
+ list<int>
+ > manual_t1;
+ typedef multiset<
+ manual_t1::iterator,
+ it_compare<
+ manual_t1::iterator,
+ std::less<int>
+ >
+ > manual_t2;
+
+ compare_structures2<indexed_t,manual_t1,manual_t2>(
+ "1 ordered index + 1 sequenced index");
+ }
+ {
+ /* 3 ordered indices */
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ordered_unique<identity<int> >,
+ ordered_non_unique<identity<int> >,
+ ordered_non_unique<identity<int> >
+ >
+ > indexed_t;
+ typedef set<int> manual_t1;
+ typedef multiset_wrapper<
+ multiset<
+ manual_t1::iterator,
+ it_compare<
+ manual_t1::iterator,
+ manual_t1::key_compare
+ >
+ >
+ > manual_t2;
+ typedef multiset<
+ manual_t2::iterator,
+ it_compare<
+ manual_t2::iterator,
+ manual_t2::key_compare
+ >
+ > manual_t3;
+
+ compare_structures3<indexed_t,manual_t1,manual_t2,manual_t3>(
+ "3 ordered indices");
+ }
+ {
+ /* 2 ordered indices + 1 sequenced index */
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ordered_unique<identity<int> >,
+ ordered_non_unique<identity<int> >,
+ sequenced<>
+ >
+ > indexed_t;
+ typedef list_wrapper<
+ list<int>
+ > manual_t1;
+ typedef multiset_wrapper<
+ multiset<
+ manual_t1::iterator,
+ it_compare<
+ manual_t1::iterator,
+ std::less<int>
+ >
+ >
+ > manual_t2;
+ typedef multiset<
+ manual_t2::iterator,
+ it_compare<
+ manual_t2::iterator,
+ manual_t2::key_compare
+ >
+ > manual_t3;
+
+ compare_structures3<indexed_t,manual_t1,manual_t2,manual_t3>(
+ "2 ordered indices + 1 sequenced index");
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/multi_index/test/Jamfile.v2 b/src/boost/libs/multi_index/test/Jamfile.v2
new file mode 100644
index 000000000..405dc7656
--- /dev/null
+++ b/src/boost/libs/multi_index/test/Jamfile.v2
@@ -0,0 +1,75 @@
+# Boost.MultiIndex tests Jamfile
+#
+# Copyright 2003-2020 Joaquín M López Muñoz.
+# Distributed under 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)
+#
+# See http://www.boost.org/libs/multi_index for library home page.
+
+import os ;
+import type ;
+
+# Windows Vista UAC has an heuristic by which executable files whose name
+# contains any of the words "install", "setup", "update", etc. are assumed
+# to be installation packages needing administrative rights, which causes
+# the system to bring up a window asking for execution confirmation by the
+# user, thus interferring in the unattended bjam process.
+# Problem bypassed by changing the EXE names containing a taboo word.
+# Thanks to Rene Rivera for guidance on the use of the <tag> feature.
+
+rule change-test_update-exe-name ( name : type ? : property-set )
+{
+ if [ os.on-windows ] && [ type.is-subtype $(type) EXE ]
+ {
+ return test_updat.exe ;
+ }
+}
+
+project
+ : requirements
+ <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
+ <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS
+ <toolset>msvc:<define>_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
+ <toolset>msvc:<cxxflags>/wd4494
+ ;
+
+obj boost_multi_index_key_supported : check_bmi_key_supported.cpp ;
+explicit boost_multi_index_key_supported ;
+
+test-suite "multi_index" :
+ [ run test_alloc_awareness.cpp test_alloc_awareness_main.cpp ]
+ [ run test_basic.cpp test_basic_main.cpp ]
+ [ run test_capacity.cpp test_capacity_main.cpp ]
+ [ run test_comparison.cpp test_comparison_main.cpp ]
+ [ run test_composite_key.cpp test_composite_key_main.cpp ]
+ [ run test_conv_iterators.cpp test_conv_iterators_main.cpp ]
+ [ run test_copy_assignment.cpp test_copy_assignment_main.cpp ]
+ [ run test_hash_ops.cpp test_hash_ops_main.cpp ]
+ [ run test_iterators.cpp test_iterators_main.cpp ]
+ [ run test_key.cpp test_key_main.cpp
+ : : :
+ [ check-target-builds boost_multi_index_key_supported
+ "BOOST_MULTI_INDEX_KEY_SUPPORTED defined"
+ : : <build>no ] ]
+ [ run test_key_extractors.cpp test_key_extractors_main.cpp ]
+ [ run test_list_ops.cpp test_list_ops_main.cpp ]
+ [ run test_modifiers.cpp test_modifiers_main.cpp ]
+ [ run test_mpl_ops.cpp test_mpl_ops_main.cpp ]
+ [ run test_observers.cpp test_observers_main.cpp ]
+ [ run test_projection.cpp test_projection_main.cpp ]
+ [ run test_range.cpp test_range_main.cpp ]
+ [ run test_rank_ops.cpp test_rank_ops_main.cpp ]
+ [ run test_rearrange.cpp test_rearrange_main.cpp ]
+ [ run test_safe_mode.cpp test_safe_mode_main.cpp ]
+ [ run test_serialization.cpp test_serialization1.cpp
+ test_serialization2.cpp test_serialization3.cpp
+ test_serialization_main.cpp
+ /boost/serialization//boost_serialization ]
+ [ run test_set_ops.cpp test_set_ops_main.cpp ]
+ [ run test_special_set_ops.cpp test_special_set_ops_main.cpp ]
+ [ run test_update.cpp test_update_main.cpp
+ : : :
+ -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
+ <tag>@change-test_update-exe-name ]
+ ;
diff --git a/src/boost/libs/multi_index/test/check_bmi_key_supported.cpp b/src/boost/libs/multi_index/test/check_bmi_key_supported.cpp
new file mode 100644
index 000000000..99ce8694b
--- /dev/null
+++ b/src/boost/libs/multi_index/test/check_bmi_key_supported.cpp
@@ -0,0 +1,13 @@
+/* Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/multi_index/key.hpp>
+
+#if !defined(BOOST_MULTI_INDEX_KEY_SUPPORTED)
+#error BOOST_MULTI_INDEX_KEY_SUPPORTED macro not defined
+#endif
diff --git a/src/boost/libs/multi_index/test/employee.hpp b/src/boost/libs/multi_index/test/employee.hpp
new file mode 100644
index 000000000..3a63c02e8
--- /dev/null
+++ b/src/boost/libs/multi_index/test/employee.hpp
@@ -0,0 +1,152 @@
+/* Used in Boost.MultiIndex tests.
+ *
+ * Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_TEST_EMPLOYEE_HPP
+#define BOOST_MULTI_INDEX_TEST_EMPLOYEE_HPP
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/move/core.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/multi_index/ranked_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <ostream>
+#include <string>
+#include "non_std_allocator.hpp"
+
+struct employee
+{
+ int id;
+ std::string name;
+ int age;
+ int ssn;
+
+ employee(int id_,std::string name_,int age_,int ssn_):
+ id(id_),name(name_),age(age_),ssn(ssn_)
+ {}
+
+ employee(const employee& x):
+ id(x.id),name(x.name),age(x.age),ssn(x.ssn)
+ {}
+
+ employee(BOOST_RV_REF(employee) x):
+ id(x.id),name(boost::move(x.name)),age(x.age),ssn(x.ssn)
+ {}
+
+ employee& operator=(BOOST_COPY_ASSIGN_REF(employee) x)
+ {
+ id=x.id;
+ name=x.name;
+ age=x.age;
+ ssn=x.ssn;
+ return *this;
+ };
+
+ employee& operator=(BOOST_RV_REF(employee) x)
+ {
+ id=x.id;
+ name=boost::move(x.name);
+ age=x.age;
+ ssn=x.ssn;
+ return *this;
+ }
+
+ 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;
+ }
+
+private:
+ BOOST_COPYABLE_AND_MOVABLE(employee)
+};
+
+struct name{};
+struct by_name{};
+struct age{};
+struct as_inserted{};
+struct ssn{};
+struct randomly{};
+
+struct employee_set_indices:
+ boost::mpl::vector<
+ boost::multi_index::ordered_unique<
+ boost::multi_index::identity<employee> >,
+ boost::multi_index::hashed_non_unique<
+ boost::multi_index::tag<name,by_name>,
+ BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>,
+ boost::multi_index::ranked_non_unique<
+ boost::multi_index::tag<age>,
+ BOOST_MULTI_INDEX_MEMBER(employee,int,age)>,
+ boost::multi_index::sequenced<
+ boost::multi_index::tag<as_inserted> >,
+ boost::multi_index::hashed_unique<
+ boost::multi_index::tag<ssn>,
+ BOOST_MULTI_INDEX_MEMBER(employee,int,ssn)>,
+ boost::multi_index::random_access<
+ boost::multi_index::tag<randomly> > >
+{};
+
+typedef
+ boost::multi_index::multi_index_container<
+ employee,
+ employee_set_indices,
+ non_std_allocator<employee> > employee_set;
+
+#if defined(BOOST_NO_MEMBER_TEMPLATES)
+typedef boost::multi_index::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;
+typedef boost::multi_index::index<
+ employee_set,ssn>::type employee_set_by_ssn;
+
+#if defined(BOOST_NO_MEMBER_TEMPLATES)
+typedef boost::multi_index::index<
+ employee_set,randomly>::type employee_set_randomly;
+#else
+typedef employee_set::index<
+ randomly>::type employee_set_randomly;
+#endif
+
+#endif
diff --git a/src/boost/libs/multi_index/test/non_std_allocator.hpp b/src/boost/libs/multi_index/test/non_std_allocator.hpp
new file mode 100644
index 000000000..80f366ca0
--- /dev/null
+++ b/src/boost/libs/multi_index/test/non_std_allocator.hpp
@@ -0,0 +1,141 @@
+/* Used in Boost.MultiIndex tests.
+ *
+ * Copyright 2003-2020 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_TEST_NON_STD_ALLOCATOR_HPP
+#define BOOST_MULTI_INDEX_TEST_NON_STD_ALLOCATOR_HPP
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/throw_exception.hpp>
+#include <iterator>
+#include <cstddef>
+#include <stdexcept>
+
+template<typename T>
+class non_raw_pointer
+{
+public:
+ typedef std::ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T* pointer;
+ typedef T& reference;
+ typedef std::random_access_iterator_tag iterator_category;
+
+ non_raw_pointer(){}
+ explicit non_raw_pointer(T* p_):p(p_){}
+
+ T& operator*()const
+ {
+#if !defined(BOOST_NO_EXCEPTIONS)
+ if(!p)boost::throw_exception(std::runtime_error("null indirection"));
+#endif
+
+ return *p;
+ }
+
+ T* operator->()const{return p;}
+ non_raw_pointer& operator++(){++p;return *this;}
+ non_raw_pointer operator++(int){non_raw_pointer t(*this);++p;return t;}
+ non_raw_pointer& operator--(){--p;return *this;}
+ non_raw_pointer operator--(int){non_raw_pointer t(*this);--p;return t;}
+ non_raw_pointer& operator+=(std::ptrdiff_t n){p+=n;return *this;}
+ non_raw_pointer& operator-=(std::ptrdiff_t n){p-=n;return *this;}
+ T& operator[](std::ptrdiff_t n)const{return p[n];}
+
+ T* raw_ptr()const{return p;}
+
+private:
+ T* p;
+};
+
+template<typename T>
+non_raw_pointer<T> operator+(const non_raw_pointer<T>& x,std::ptrdiff_t n)
+{return non_raw_pointer<T>(x.raw_ptr()+n);}
+
+template<typename T>
+non_raw_pointer<T> operator+(std::ptrdiff_t n,const non_raw_pointer<T>& x)
+{return non_raw_pointer<T>(n+x.raw_ptr());}
+
+template<typename T>
+non_raw_pointer<T> operator-(const non_raw_pointer<T>& x,std::ptrdiff_t n)
+{return non_raw_pointer<T>(x.raw_ptr()-n);}
+
+template<typename T>
+std::ptrdiff_t operator-(
+ const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
+{return x.raw_ptr()-y.raw_ptr();}
+
+template<typename T>
+bool operator==(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
+{return x.raw_ptr()==y.raw_ptr();}
+
+template<typename T>
+bool operator!=(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
+{return x.raw_ptr()!=y.raw_ptr();}
+
+template<typename T>
+bool operator<(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
+{return x.raw_ptr()<y.raw_ptr();}
+
+template<typename T>
+bool operator>(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
+{return x.raw_ptr()>y.raw_ptr();}
+
+template<typename T>
+bool operator>=(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
+{return x.raw_ptr()>=y.raw_ptr();}
+
+template<typename T>
+bool operator<=(const non_raw_pointer<T>& x,const non_raw_pointer<T>& y)
+{return x.raw_ptr()<=y.raw_ptr();}
+
+template<typename T>
+class non_std_allocator
+{
+public:
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef non_raw_pointer<T> pointer;
+ typedef non_raw_pointer<const T> const_pointer;
+ typedef void* void_pointer;
+ typedef const void* const_void_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef T value_type;
+ template<class U>struct rebind{typedef non_std_allocator<U> other;};
+
+ non_std_allocator(){}
+ non_std_allocator(const non_std_allocator<T>&){}
+ template<class U>non_std_allocator(const non_std_allocator<U>&,int=0){}
+ non_std_allocator& operator=(const non_std_allocator<T>&){return *this;}
+
+ pointer allocate(size_type n)
+ {
+ return pointer((T*)(new char[n*sizeof(T)]));
+ }
+
+ void deallocate(pointer p,size_type)
+ {
+ delete[](char *)&*p;
+ }
+
+ size_type max_size() const{return (size_type )(-1);}
+
+ friend bool operator==(const non_std_allocator&,const non_std_allocator&)
+ {
+ return true;
+ }
+
+ friend bool operator!=(const non_std_allocator&,const non_std_allocator&)
+ {
+ return false;
+ }
+};
+
+#endif
diff --git a/src/boost/libs/multi_index/test/pair_of_ints.hpp b/src/boost/libs/multi_index/test/pair_of_ints.hpp
new file mode 100644
index 000000000..6089ffc34
--- /dev/null
+++ b/src/boost/libs/multi_index/test/pair_of_ints.hpp
@@ -0,0 +1,78 @@
+/* Used in Boost.MultiIndex tests.
+ *
+ * Copyright 2003-2010 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_TEST_PAIR_OF_INTS_HPP
+#define BOOST_MULTI_INDEX_TEST_PAIR_OF_INTS_HPP
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/serialization/nvp.hpp>
+
+struct pair_of_ints
+{
+ pair_of_ints(int first_=0,int second_=0):first(first_),second(second_){}
+
+ bool operator==(const pair_of_ints& x)const
+ {
+ return first==x.first&&second==x.second;
+ }
+
+ bool operator!=(const pair_of_ints& x)const{return !(*this==x);}
+
+ int first,second;
+};
+
+inline void increment_first(pair_of_ints& p)
+{
+ ++p.first;
+}
+
+inline void increment_second(pair_of_ints& p)
+{
+ ++p.second;
+}
+
+inline void increment_int(int& x)
+{
+ ++x;
+}
+
+inline int decrement_first(pair_of_ints& p)
+{
+ return --p.first;
+}
+
+inline int decrement_second(pair_of_ints& p)
+{
+ return --p.second;
+}
+
+inline int decrement_int(int& x)
+{
+ return --x;
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+namespace serialization{
+#endif
+
+template<class Archive>
+void serialize(Archive& ar,pair_of_ints& p,const unsigned int)
+{
+ ar&boost::serialization::make_nvp("first",p.first);
+ ar&boost::serialization::make_nvp("second",p.second);
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace serialization */
+} /* namespace boost*/
+#endif
+
+#endif
diff --git a/src/boost/libs/multi_index/test/pre_multi_index.hpp b/src/boost/libs/multi_index/test/pre_multi_index.hpp
new file mode 100644
index 000000000..7fc5b9e92
--- /dev/null
+++ b/src/boost/libs/multi_index/test/pre_multi_index.hpp
@@ -0,0 +1,49 @@
+/* Used in Boost.MultiIndex tests.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_TEST_PRE_MULTI_INDEX_HPP
+#define BOOST_MULTI_INDEX_TEST_PRE_MULTI_INDEX_HPP
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/workaround.hpp>
+#include <boost/multi_index/safe_mode_errors.hpp>
+
+#if defined(__GNUC__)&&defined(__APPLE__)&&\
+ (__GNUC__==4)&&(__GNUC_MINOR__==0)&&(__APPLE_CC__<=4061)
+ /* Darwin 8.1 includes a prerelease version of GCC 4.0 that, alas,
+ * has a regression as described in
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17435
+ * This compiler bug (fixed in the official 4.0 release) ruins the
+ * mechanisms upon which invariant-checking scope guards are built,
+ * so we can't set the invariant checking mode.
+ */
+#else
+#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
+#endif
+
+#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
+
+#if BOOST_WORKAROUND(__IBMCPP__,<=600)
+#pragma info(nolan) /* suppress warnings about offsetof with non-POD types */
+#endif
+
+struct safe_mode_exception
+{
+ safe_mode_exception(boost::multi_index::safe_mode::error_code error_code_):
+ error_code(error_code_)
+ {}
+
+ boost::multi_index::safe_mode::error_code error_code;
+};
+
+#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) \
+if(!(expr)){throw safe_mode_exception(error_code);}
+
+#endif
diff --git a/src/boost/libs/multi_index/test/rooted_allocator.hpp b/src/boost/libs/multi_index/test/rooted_allocator.hpp
new file mode 100644
index 000000000..dc55c1999
--- /dev/null
+++ b/src/boost/libs/multi_index/test/rooted_allocator.hpp
@@ -0,0 +1,64 @@
+/* Used in Boost.MultiIndex tests.
+ *
+ * Copyright 2003-2020 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_TEST_ROOTED_ALLOCATOR_HPP
+#define BOOST_MULTI_INDEX_TEST_ROOTED_ALLOCATOR_HPP
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/type_traits/integral_constant.hpp>
+#include <memory>
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+#pragma warning(disable:4355) /* this used in base member initializer list */
+#endif
+
+template<typename T,bool Propagate,bool AlwaysEqual>
+class rooted_allocator:public std::allocator<T>
+{
+ typedef boost::integral_constant<bool,Propagate> propagate_type;
+ typedef boost::integral_constant<bool,AlwaysEqual> always_equal_type;
+
+public:
+ typedef propagate_type propagate_on_container_copy_assignment;
+ typedef propagate_type propagate_on_container_move_assignment;
+ typedef propagate_type propagate_on_container_swap;
+ typedef always_equal_type is_always_equal;
+ template<typename U>
+ struct rebind{typedef rooted_allocator<U,Propagate,AlwaysEqual> other;};
+
+ rooted_allocator():root(0){}
+ explicit rooted_allocator(int):root(this){}
+ template<typename U>
+ rooted_allocator(const rooted_allocator<U,Propagate,AlwaysEqual>& x):
+ root(x.root){}
+
+ template<typename U>
+ bool operator==(const rooted_allocator<U,Propagate,AlwaysEqual>& x)const
+ {return AlwaysEqual?true:root==x.root;}
+ template<typename U>
+ bool operator!=(const rooted_allocator<U,Propagate,AlwaysEqual>& x)const
+ {return !(*this==x);}
+
+ template<typename U>
+ bool comes_from(const rooted_allocator<U,Propagate,AlwaysEqual>& x)const
+ {return root==&x;}
+
+private:
+ template<typename,bool,bool> friend class rooted_allocator;
+
+ const void* root;
+};
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop) /* C4355 */
+#endif
+
+#endif
diff --git a/src/boost/libs/multi_index/test/small_allocator.hpp b/src/boost/libs/multi_index/test/small_allocator.hpp
new file mode 100644
index 000000000..7d1227b0f
--- /dev/null
+++ b/src/boost/libs/multi_index/test/small_allocator.hpp
@@ -0,0 +1,58 @@
+/* Used in Boost.MultiIndex tests.
+ *
+ * Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_TEST_SMALL_ALLOCATOR_HPP
+#define BOOST_MULTI_INDEX_TEST_SMALL_ALLOCATOR_HPP
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+
+template<typename T>
+class small_allocator
+{
+public:
+ typedef unsigned char size_type;
+ typedef signed char difference_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef void* void_pointer;
+ typedef const void* const_void_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef T value_type;
+ template<class U>struct rebind{typedef small_allocator<U> other;};
+
+ small_allocator(){}
+ small_allocator(const small_allocator<T>&){}
+ template<class U>small_allocator(const small_allocator<U>&,int=0){}
+
+ pointer allocate(size_type n)
+ {
+ return pointer((T*)(new char[n*sizeof(T)]));
+ }
+
+ void deallocate(pointer p,size_type)
+ {
+ delete[](char *)&*p;
+ }
+
+ size_type max_size()const{return (size_type)(-1);}
+
+ friend bool operator==(const small_allocator&,const small_allocator&)
+ {
+ return true;
+ }
+
+ friend bool operator!=(const small_allocator&,const small_allocator&)
+ {
+ return false;
+ }
+};
+
+#endif
diff --git a/src/boost/libs/multi_index/test/test_all_main.cpp b/src/boost/libs/multi_index/test/test_all_main.cpp
new file mode 100644
index 000000000..d4536183f
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_all_main.cpp
@@ -0,0 +1,65 @@
+/* Boost.MultiIndex test suite.
+ *
+ * Copyright 2003-2020 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_alloc_awareness.hpp"
+#include "test_basic.hpp"
+#include "test_capacity.hpp"
+#include "test_comparison.hpp"
+#include "test_composite_key.hpp"
+#include "test_conv_iterators.hpp"
+#include "test_copy_assignment.hpp"
+#include "test_hash_ops.hpp"
+#include "test_iterators.hpp"
+#include "test_key.hpp"
+#include "test_key_extractors.hpp"
+#include "test_list_ops.hpp"
+#include "test_modifiers.hpp"
+#include "test_mpl_ops.hpp"
+#include "test_observers.hpp"
+#include "test_projection.hpp"
+#include "test_range.hpp"
+#include "test_rank_ops.hpp"
+#include "test_rearrange.hpp"
+#include "test_safe_mode.hpp"
+#include "test_serialization.hpp"
+#include "test_set_ops.hpp"
+#include "test_special_set_ops.hpp"
+#include "test_update.hpp"
+
+int main()
+{
+ test_allocator_awareness();
+ test_basic();
+ test_capacity();
+ test_comparison();
+ test_composite_key();
+ test_conv_iterators();
+ test_copy_assignment();
+ test_hash_ops();
+ test_iterators();
+ test_key();
+ test_key_extractors();
+ test_list_ops();
+ test_modifiers();
+ test_mpl_ops();
+ test_observers();
+ test_projection();
+ test_range();
+ test_rank_ops();
+ test_rearrange();
+ test_safe_mode();
+ test_serialization();
+ test_set_ops();
+ test_special_set_ops();
+ test_update();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_alloc_awareness.cpp b/src/boost/libs/multi_index/test/test_alloc_awareness.cpp
new file mode 100644
index 000000000..af6075104
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_alloc_awareness.cpp
@@ -0,0 +1,159 @@
+/* Boost.MultiIndex test for allocator awareness.
+ *
+ * Copyright 2003-2020 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_alloc_awareness.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/move/core.hpp>
+#include "pre_multi_index.hpp"
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/multi_index/ranked_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include "rooted_allocator.hpp"
+
+struct move_tracker
+{
+ move_tracker(int n):n(n),move_cted(false){}
+ move_tracker(const move_tracker& x):n(x.n),move_cted(false){}
+ move_tracker(BOOST_RV_REF(move_tracker) x):n(x.n),move_cted(true){}
+ move_tracker& operator=(BOOST_COPY_ASSIGN_REF(move_tracker) x)
+ {n=x.n;return *this;}
+ move_tracker& operator=(BOOST_RV_REF(move_tracker) x){n=x.n;return *this;}
+
+ int n;
+ bool move_cted;
+
+private:
+ BOOST_COPYABLE_AND_MOVABLE(move_tracker)
+};
+
+inline bool operator==(const move_tracker& x,const move_tracker& y)
+{
+ return x.n==y.n;
+}
+
+inline bool operator<(const move_tracker& x,const move_tracker& y)
+{
+ return x.n<y.n;
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+#endif
+
+inline std::size_t hash_value(const move_tracker& x)
+{
+ boost::hash<int> h;
+ return h(x.n);
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace boost */
+#endif
+
+#if defined(BOOST_NO_CXX17_IF_CONSTEXPR)&&defined(BOOST_MSVC)
+#pragma warning(push)
+#pragma warning(disable:4127) /* conditional expression is constant */
+#endif
+
+template<bool Propagate,bool AlwaysEqual>
+void test_allocator_awareness_for()
+{
+ using namespace boost::multi_index;
+
+ typedef rooted_allocator<move_tracker,Propagate,AlwaysEqual> allocator;
+ typedef multi_index_container<
+ move_tracker,
+ indexed_by<
+ hashed_unique<identity<move_tracker> >,
+ ordered_unique<identity<move_tracker> >,
+ random_access<>,
+ ranked_unique<identity<move_tracker> >,
+ sequenced<>
+ >,
+ allocator
+ > container;
+
+ allocator root1(0),root2(0);
+ container c(root1);
+ for(int i=0;i<10;++i)c.emplace(i);
+
+ BOOST_TEST(c.get_allocator().comes_from(root1));
+
+ {
+ container c2(c,root2);
+ BOOST_TEST(c2.get_allocator().comes_from(root2));
+ BOOST_TEST(c2==c);
+ }
+ {
+ container c2(c);
+ const move_tracker* pfirst=&*c2.begin();
+ container c3(boost::move(c2),root2);
+ BOOST_TEST(c3.get_allocator().comes_from(root2));
+ BOOST_TEST(c3==c);
+ BOOST_TEST(c2.empty());
+ BOOST_TEST(AlwaysEqual==(&*c3.begin()==pfirst));
+ BOOST_TEST(!AlwaysEqual==(c3.begin()->move_cted));
+ }
+ {
+ container c2(root2);
+ c2=c;
+ BOOST_TEST(c2.get_allocator().comes_from(Propagate?root1:root2));
+ BOOST_TEST(c2==c);
+ }
+ {
+ const bool element_transfer=Propagate||AlwaysEqual;
+
+ container c2(c);
+ const move_tracker* pfirst=&*c2.begin();
+ container c3(root2);
+ c3=boost::move(c2);
+ BOOST_TEST(c3.get_allocator().comes_from(Propagate?root1:root2));
+ BOOST_TEST(c3==c);
+ BOOST_TEST(c2.empty());
+ BOOST_TEST(element_transfer==(&*c3.begin()==pfirst));
+ BOOST_TEST(!element_transfer==(c3.begin()->move_cted));
+ }
+ if(Propagate||AlwaysEqual){
+ container c2(c);
+ const move_tracker* pfirst=&*c2.begin();
+ container c3(root2);
+ c3.swap(c2);
+ BOOST_TEST(c2.get_allocator().comes_from(Propagate?root2:root1));
+ BOOST_TEST(c3.get_allocator().comes_from(Propagate?root1:root2));
+ BOOST_TEST(c3==c);
+ BOOST_TEST(c2.empty());
+ BOOST_TEST(&*c3.begin()==pfirst);
+ BOOST_TEST(!c3.begin()->move_cted);
+ }
+}
+
+#if defined(BOOST_NO_CXX17_IF_CONSTEXPR)&&defined(BOOST_MSVC)
+#pragma warning(pop) /* C4127 */
+#endif
+
+void test_allocator_awareness()
+{
+ test_allocator_awareness_for<false,false>();
+ test_allocator_awareness_for<false,true>();
+
+#if !defined(BOOST_NO_CXX11_ALLOCATOR)
+ /* only in C+11 onwards are allocators potentially expected to propagate */
+
+ test_allocator_awareness_for<true,false>();
+ test_allocator_awareness_for<true,true>();
+
+#endif
+}
diff --git a/src/boost/libs/multi_index/test/test_alloc_awareness.hpp b/src/boost/libs/multi_index/test/test_alloc_awareness.hpp
new file mode 100644
index 000000000..d659ef55f
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_alloc_awareness.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for allocator awareness.
+ *
+ * Copyright 2003-2020 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_allocator_awareness();
diff --git a/src/boost/libs/multi_index/test/test_alloc_awareness_main.cpp b/src/boost/libs/multi_index/test/test_alloc_awareness_main.cpp
new file mode 100644
index 000000000..8fed7f9c9
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_alloc_awareness_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for allocator awareness.
+ *
+ * Copyright 2003-2020 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_alloc_awareness.hpp"
+
+int main()
+{
+ test_allocator_awareness();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_basic.cpp b/src/boost/libs/multi_index/test/test_basic.cpp
new file mode 100644
index 000000000..dbfa9dada
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_basic.cpp
@@ -0,0 +1,158 @@
+/* Boost.MultiIndex basic test.
+ *
+ * Copyright 2003-2017 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_basic.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <vector>
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost::multi_index;
+
+struct less_by_employee_age
+{
+ bool operator()(const employee& e1,const employee& e2)const
+ {
+ return e1.age<e2.age;
+ }
+};
+
+struct no_addressof_type
+{
+ no_addressof_type(int n):n(n){}
+
+ void operator&()const{}
+
+ int n;
+};
+
+bool operator==(const no_addressof_type& x,const no_addressof_type& y)
+{
+ return x.n==y.n;
+}
+
+bool operator<(const no_addressof_type& x,const no_addressof_type& y)
+{
+ return x.n<y.n;
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+#endif
+
+inline std::size_t hash_value(const no_addressof_type& x)
+{
+ boost::hash<int> h;
+ return h(x.n);
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace boost */
+#endif
+
+void test_basic()
+{
+ employee_set es;
+ std::vector<employee> v;
+
+#if defined(BOOST_NO_MEMBER_TEMPLATES)
+ employee_set_by_name& i1=get<by_name>(es);
+#else
+ employee_set_by_name& i1=es.get<by_name>();
+#endif
+
+ const employee_set_by_age& i2=get<2>(es);
+ employee_set_as_inserted& i3=get<3>(es);
+ employee_set_by_ssn& i4=get<ssn>(es);
+ employee_set_randomly& i5=get<randomly>(es);
+
+ es.insert(employee(0,"Joe",31,1123));
+ es.insert(employee(5,"Anna",41,1123)); /* clash*/
+ i1.insert(employee(1,"Robert",27,5601));
+ es.insert(employee(2,"John",40,7889));
+ i3.push_back(employee(3,"Albert",20,9012));
+ i4.insert(employee(4,"John",57,1002));
+ i5.push_back(employee(0,"Andrew",60,2302)); /* clash */
+
+ v.push_back(employee(0,"Joe",31,1123));
+ v.push_back(employee(1,"Robert",27,5601));
+ v.push_back(employee(2,"John",40,7889));
+ v.push_back(employee(3,"Albert",20,9012));
+ v.push_back(employee(4,"John",57,1002));
+
+ {
+ /* by insertion order */
+
+ BOOST_TEST(std::equal(i3.begin(),i3.end(),v.begin()));
+ BOOST_TEST(std::equal(i5.begin(),i5.end(),v.begin()));
+ }
+
+ {
+ /* by id */
+
+ std::sort(v.begin(),v.end());
+ BOOST_TEST(std::equal(es.begin(),es.end(),v.begin()));
+ }
+
+ {
+ /* by age */
+
+ std::sort(v.begin(),v.end(),less_by_employee_age());
+ BOOST_TEST(std::equal(i2.begin(),i2.end(),v.begin()));
+ }
+
+ {
+ /* testcase for https://svn.boost.org/trac10/ticket/13307 */
+
+ typedef multi_index_container<
+ no_addressof_type,
+ indexed_by<
+ random_access<>,
+ ordered_non_unique<identity<no_addressof_type> >,
+ sequenced<>,
+ hashed_non_unique<identity<no_addressof_type> >
+ >
+ > multi_index_t;
+
+ multi_index_t c;
+ const multi_index_t& cc=c;
+ no_addressof_type x(0);
+ int a[]={1,2};
+ int b[]={6,7};
+ c.push_back(x);
+ c.insert(c.end(),a,a+2);
+ c.push_back(no_addressof_type(3));
+ c.emplace_back(4);
+ c.get<1>().emplace_hint(c.get<1>().begin(),5);
+ c.get<1>().insert(b,b+2);
+ (void)c.begin()->n;
+ (void)c.get<1>().begin()->n;
+ (void)c.get<2>().begin()->n;
+ (void)c.get<3>().begin()->n;
+ (void)c.get<3>().begin(0)->n;
+ (void)c.iterator_to(c.front());
+ (void)cc.iterator_to(c.front());
+ (void)c.get<1>().iterator_to(c.front());
+ (void)cc.get<1>().iterator_to(c.front());
+ (void)c.get<2>().iterator_to(c.front());
+ (void)cc.get<2>().iterator_to(c.front());
+ (void)c.get<3>().iterator_to(c.front());
+ (void)cc.get<3>().iterator_to(c.front());
+ (void)c.get<3>().local_iterator_to(c.front());
+ (void)cc.get<3>().local_iterator_to(c.front());
+ multi_index_t c2=c;(void)c2;
+ c.erase(c.begin());
+ c.erase(c.begin(),c.end());
+ }
+
+}
diff --git a/src/boost/libs/multi_index/test/test_basic.hpp b/src/boost/libs/multi_index/test/test_basic.hpp
new file mode 100644
index 000000000..652c0e090
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_basic.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex basic test.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_basic();
diff --git a/src/boost/libs/multi_index/test/test_basic_main.cpp b/src/boost/libs/multi_index/test/test_basic_main.cpp
new file mode 100644
index 000000000..a98132ac3
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_basic_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex basic test.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_basic.hpp"
+
+int main()
+{
+ test_basic();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_capacity.cpp b/src/boost/libs/multi_index/test/test_capacity.cpp
new file mode 100644
index 000000000..57774da8d
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_capacity.cpp
@@ -0,0 +1,97 @@
+/* Boost.MultiIndex test for capacity memfuns.
+ *
+ * Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_capacity.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost::multi_index;
+
+void test_capacity()
+{
+ employee_set es;
+
+ es.insert(employee(0,"Joe",31,1123));
+ es.insert(employee(1,"Robert",27,5601));
+ es.insert(employee(2,"John",40,7889));
+ es.insert(employee(3,"Albert",20,9012));
+ es.insert(employee(4,"John",57,1002));
+
+ BOOST_TEST(!es.empty());
+ BOOST_TEST(es.size()==5);
+ BOOST_TEST(es.size()<=es.max_size());
+
+ es.erase(es.begin());
+ BOOST_TEST(!get<name>(es).empty());
+ BOOST_TEST(get<name>(es).size()==4);
+ BOOST_TEST(get<name>(es).size()<=get<name>(es).max_size());
+
+ es.erase(es.begin());
+ BOOST_TEST(!get<as_inserted>(es).empty());
+ BOOST_TEST(get<as_inserted>(es).size()==3);
+ BOOST_TEST(get<as_inserted>(es).size()<=get<as_inserted>(es).max_size());
+
+ multi_index_container<int,indexed_by<sequenced<> > > ss;
+
+ ss.resize(10);
+ BOOST_TEST(ss.size()==10);
+ BOOST_TEST(ss.size()<=ss.max_size());
+
+ ss.resize(20,666);
+ BOOST_TEST(ss.size()==20);
+ BOOST_TEST(ss.back()==666);
+
+ ss.resize(5,10);
+ BOOST_TEST(ss.size()==5);
+
+ ss.resize(4);
+ BOOST_TEST(ss.size()==4);
+
+ multi_index_container<int,indexed_by<random_access<> > > rs;
+
+ rs.resize(10);
+ BOOST_TEST(rs.size()==10);
+ BOOST_TEST(rs.size()<=rs.max_size());
+ BOOST_TEST(rs.size()<=rs.capacity());
+
+ rs.resize(20,666);
+ BOOST_TEST(rs.size()==20);
+ BOOST_TEST(rs.back()==666);
+ BOOST_TEST(rs.size()<=rs.capacity());
+
+ employee_set::size_type c=rs.capacity();
+ rs.resize(10,20);
+ BOOST_TEST(rs.size()==10);
+ BOOST_TEST(rs.capacity()==c);
+
+ rs.resize(5);
+ BOOST_TEST(rs.size()==5);
+ BOOST_TEST(rs.capacity()==c);
+
+ rs.reserve(100);
+ BOOST_TEST(rs.size()==5);
+ BOOST_TEST(rs.capacity()>=100);
+
+ c=rs.capacity();
+ rs.reserve(99);
+ BOOST_TEST(rs.size()==5);
+ BOOST_TEST(rs.capacity()==c);
+
+ rs.shrink_to_fit();
+ BOOST_TEST(rs.size()==5);
+ BOOST_TEST(rs.capacity()==rs.size());
+
+ rs.clear();
+ rs.shrink_to_fit();
+ BOOST_TEST(rs.capacity()==0);
+}
diff --git a/src/boost/libs/multi_index/test/test_capacity.hpp b/src/boost/libs/multi_index/test/test_capacity.hpp
new file mode 100644
index 000000000..73bcf5e93
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_capacity.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for capacity memfuns.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_capacity();
diff --git a/src/boost/libs/multi_index/test/test_capacity_main.cpp b/src/boost/libs/multi_index/test/test_capacity_main.cpp
new file mode 100644
index 000000000..ff8024280
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_capacity_main.cpp
@@ -0,0 +1,19 @@
+/* Boost.MultiIndex test for capacity memfuns.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_capacity.hpp"
+
+int main()
+{
+ test_capacity();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/multi_index/test/test_comparison.cpp b/src/boost/libs/multi_index/test/test_comparison.cpp
new file mode 100644
index 000000000..15226196b
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_comparison.cpp
@@ -0,0 +1,151 @@
+/* Boost.MultiIndex test for comparison functions.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_comparison.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include "pair_of_ints.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost::multi_index;
+
+template<typename Value>
+struct lookup_list{
+ typedef multi_index_container<
+ Value,
+ indexed_by<
+ sequenced<>,
+ ordered_non_unique<identity<Value> >
+ >
+ > type;
+};
+
+template<typename Value>
+struct lookup_vector{
+ typedef multi_index_container<
+ Value,
+ indexed_by<
+ random_access<>,
+ ordered_non_unique<identity<Value> >
+ >
+ > type;
+};
+
+void test_comparison()
+{
+ employee_set es;
+ employee_set_by_name& i1=get<1>(es);
+ employee_set_by_age& i2=get<2>(es);
+ employee_set_as_inserted& i3=get<3>(es);
+ employee_set_by_ssn& i4=get<4>(es);
+ employee_set_randomly& i5=get<5>(es);
+ es.insert(employee(0,"Joe",31,1123));
+ es.insert(employee(1,"Robert",27,5601));
+ es.insert(employee(2,"John",40,7889));
+ es.insert(employee(3,"Albert",20,9012));
+ es.insert(employee(4,"John",57,1002));
+
+ employee_set es2;
+ employee_set_by_name& i12=get<by_name>(es2);
+ employee_set_by_age& i22=get<age>(es2);
+ employee_set_as_inserted& i32=get<3>(es2);
+ employee_set_by_ssn& i42=get<4>(es2);
+ employee_set_randomly& i52=get<5>(es2);
+ es2.insert(employee(0,"Joe",31,1123));
+ es2.insert(employee(1,"Robert",27,5601));
+ es2.insert(employee(2,"John",40,7889));
+ es2.insert(employee(3,"Albert",20,9012));
+
+ BOOST_TEST(es==es&&es<=es&&es>=es&&
+ i12==i12&&
+ i22==i22&&i22<=i22&&i22>=i22&&
+ i32==i32&&i32<=i32&&i32>=i32&&
+ i42==i42&&
+ i52==i52&&i52<=i52&&i52>=i52);
+ BOOST_TEST(es!=es2&&es2<es&&es>es2&&!(es<=es2)&&!(es2>=es));
+ BOOST_TEST(i1!=i12);
+ BOOST_TEST(i2!=i22&&i22<i2&&i2>i22&&!(i2<=i22)&&!(i22>=i2));
+ BOOST_TEST(i3!=i32&&i32<i3&&i3>i32&&!(i3<=i32)&&!(i32>=i3));
+ BOOST_TEST(i4!=i42);
+ BOOST_TEST(i5!=i52&&i52<i5&&i5>i52&&!(i5<=i52)&&!(i52>=i5));
+
+ multi_index_container<
+ pair_of_ints,
+ indexed_by<
+ hashed_non_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>
+ >
+ > hc1,hc2;
+ hc1.insert(pair_of_ints(0,0));
+ hc1.insert(pair_of_ints(0,1));
+ hc1.insert(pair_of_ints(0,2));
+ hc1.insert(pair_of_ints(0,3));
+ hc1.insert(pair_of_ints(1,0));
+ hc1.insert(pair_of_ints(1,1));
+
+ hc2.insert(pair_of_ints(0,2));
+ hc2.insert(pair_of_ints(0,1));
+ hc2.insert(pair_of_ints(1,1));
+ hc2.insert(pair_of_ints(1,0));
+ hc2.insert(pair_of_ints(0,3));
+ hc2.insert(pair_of_ints(0,0));
+ BOOST_TEST(hc1==hc2);
+
+ hc1.insert(pair_of_ints(0,4));
+ hc2.insert(pair_of_ints(0,5));
+ BOOST_TEST(hc1!=hc2);
+
+ lookup_list<int>::type l1;
+ lookup_list<char>::type l2;
+ lookup_vector<char>::type l3;
+ lookup_list<long>::type l4;
+ lookup_vector<long>::type l5;
+
+ l1.push_back(3);
+ l1.push_back(4);
+ l1.push_back(5);
+ l1.push_back(1);
+ l1.push_back(2);
+
+ l2.push_back(char(3));
+ l2.push_back(char(4));
+ l2.push_back(char(5));
+ l2.push_back(char(1));
+ l2.push_back(char(2));
+
+ l3.push_back(char(3));
+ l3.push_back(char(4));
+ l3.push_back(char(5));
+ l3.push_back(char(1));
+ l3.push_back(char(2));
+
+ l4.push_back(long(3));
+ l4.push_back(long(4));
+ l4.push_back(long(5));
+ l4.push_back(long(1));
+
+ l5.push_back(long(3));
+ l5.push_back(long(4));
+ l5.push_back(long(5));
+ l5.push_back(long(1));
+
+ BOOST_TEST(l1==l2&&l1<=l2&&l1>=l2);
+ BOOST_TEST(
+ get<1>(l1)==get<1>(l2)&&get<1>(l1)<=get<1>(l2)&&get<1>(l1)>=get<1>(l2));
+ BOOST_TEST(
+ get<1>(l1)==get<1>(l3)&&get<1>(l1)<=get<1>(l3)&&get<1>(l1)>=get<1>(l3));
+ BOOST_TEST(l1!=l4&&l4<l1&&l1>l4);
+ BOOST_TEST(
+ get<1>(l1)!=get<1>(l4)&&get<1>(l1)<get<1>(l4)&&get<1>(l4)>get<1>(l1));
+ BOOST_TEST(l3!=l5&&l5<l3&&l3>l5);
+ BOOST_TEST(
+ get<1>(l3)!=get<1>(l5)&&get<1>(l3)<get<1>(l5)&&get<1>(l5)>get<1>(l3));
+}
diff --git a/src/boost/libs/multi_index/test/test_comparison.hpp b/src/boost/libs/multi_index/test/test_comparison.hpp
new file mode 100644
index 000000000..4f0106922
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_comparison.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for comparison functions.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_comparison();
diff --git a/src/boost/libs/multi_index/test/test_comparison_main.cpp b/src/boost/libs/multi_index/test/test_comparison_main.cpp
new file mode 100644
index 000000000..aace1229e
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_comparison_main.cpp
@@ -0,0 +1,19 @@
+/* Boost.MultiIndex test for comparison functions.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_comparison.hpp"
+
+int main()
+{
+ test_comparison();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/multi_index/test/test_composite_key.cpp b/src/boost/libs/multi_index/test/test_composite_key.cpp
new file mode 100644
index 000000000..24049692a
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_composite_key.cpp
@@ -0,0 +1,670 @@
+/* Boost.MultiIndex test for composite_key.
+ *
+ * Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_composite_key.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp>
+#include "pre_multi_index.hpp"
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/composite_key.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+
+using namespace boost::multi_index;
+using namespace boost::tuples;
+
+struct is_composite_key_result_helper
+{
+ typedef char yes;
+ struct no{char m[2];};
+
+ static no test(void*);
+
+ template<typename CompositeKey>
+ static yes test(composite_key_result<CompositeKey>*);
+};
+
+template<typename T>
+struct is_composite_key_result
+{
+ typedef is_composite_key_result_helper helper;
+
+ BOOST_STATIC_CONSTANT(bool,
+ value=(
+ sizeof(helper::test((T*)0))==
+ sizeof(typename helper::yes)));
+};
+
+template<typename CompositeKeyResult>
+struct composite_key_result_length
+{
+ BOOST_STATIC_CONSTANT(int,
+ value=boost::tuples::length<
+ BOOST_DEDUCED_TYPENAME
+ CompositeKeyResult::composite_key_type::key_extractor_tuple
+ >::value);
+};
+
+#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
+ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+struct is_boost_tuple_helper
+{
+ typedef char yes;
+ struct no{char m[2];};
+
+ static no test(void*);
+
+ template<BOOST_PP_ENUM_PARAMS(10,typename T)>
+ static yes test(boost::tuple<BOOST_PP_ENUM_PARAMS(10,T)>*);
+};
+
+template<typename T>
+struct is_boost_tuple
+{
+ typedef is_boost_tuple_helper helper;
+
+ BOOST_STATIC_CONSTANT(bool,
+ value=(
+ sizeof(helper::test((T*)0))==
+ sizeof(typename helper::yes)));
+};
+
+template<typename T>
+struct composite_object_length
+{
+ typedef typename boost::mpl::if_c<
+ is_composite_key_result<T>::value,
+ composite_key_result_length<T>,
+ typename boost::mpl::if_c<
+ is_boost_tuple<T>::value,
+ boost::tuples::length<T>,
+ std::tuple_size<T>
+ >::type
+ >::type type;
+
+ BOOST_STATIC_CONSTANT(int,value=type::value);
+};
+#else
+template<typename T>
+struct composite_object_length
+{
+ typedef typename boost::mpl::if_c<
+ is_composite_key_result<T>::value,
+ composite_key_result_length<T>,
+ boost::tuples::length<T>
+ >::type type;
+
+ BOOST_STATIC_CONSTANT(int,value=type::value);
+};
+#endif
+
+template<typename CompositeKeyResult,typename T2>
+struct comparison_equal_length
+{
+ static bool is_less(const CompositeKeyResult& x,const T2& y)
+ {
+ composite_key_result_equal_to<CompositeKeyResult> eq;
+ composite_key_result_less<CompositeKeyResult> lt;
+ composite_key_result_greater<CompositeKeyResult> gt;
+ std::equal_to<CompositeKeyResult> std_eq;
+ std::less<CompositeKeyResult> std_lt;
+ std::greater<CompositeKeyResult> std_gt;
+
+ return (x< y) && !(y< x)&&
+ !(x==y) && !(y==x)&&
+ (x!=y) && (y!=x)&&
+ !(x> y) && (y> x)&&
+ !(x>=y) && (y>=x)&&
+ (x<=y) && !(y<=x)&&
+ !eq(x,y) && !eq(y,x)&&
+ lt(x,y) && !lt(y,x)&&
+ !gt(x,y) && gt(y,x)&&
+ !std_eq(x,y) && !std_eq(y,x)&&
+ std_lt(x,y) && !std_lt(y,x)&&
+ !std_gt(x,y) && std_gt(y,x);
+ }
+
+ static bool is_greater(const CompositeKeyResult& x,const T2& y)
+ {
+ composite_key_result_equal_to<CompositeKeyResult> eq;
+ composite_key_result_less<CompositeKeyResult> lt;
+ composite_key_result_greater<CompositeKeyResult> gt;
+ std::equal_to<CompositeKeyResult> std_eq;
+ std::less<CompositeKeyResult> std_lt;
+ std::greater<CompositeKeyResult> std_gt;
+
+ return !(x< y) && (y< x)&&
+ !(x==y) && !(y==x)&&
+ (x!=y) && (y!=x)&&
+ (x> y) && !(y> x)&&
+ (x>=y) && !(y>=x)&&
+ !(x<=y) && (y<=x)&&
+ !eq(x,y) && !eq(y,x)&&
+ !lt(x,y) && lt(y,x)&&
+ gt(x,y) && !gt(y,x)&&
+ !std_eq(x,y) && !std_eq(y,x)&&
+ !std_lt(x,y) && std_lt(y,x)&&
+ std_gt(x,y) && !std_gt(y,x);
+ }
+
+ static bool is_equiv(const CompositeKeyResult& x,const T2& y)
+ {
+ composite_key_result_equal_to<CompositeKeyResult> eq;
+ composite_key_result_less<CompositeKeyResult> lt;
+ composite_key_result_greater<CompositeKeyResult> gt;
+ std::equal_to<CompositeKeyResult> std_eq;
+ std::less<CompositeKeyResult> std_lt;
+ std::greater<CompositeKeyResult> std_gt;
+
+ return !(x< y) && !(y< x)&&
+ (x==y) && (y==x)&&
+ !(x!=y) && !(y!=x)&&
+ !(x> y) && !(y> x)&&
+ (x>=y) && (y>=x)&&
+ (x<=y) && (y<=x)&&
+ eq(x,y) && eq(y,x)&&
+ !lt(x,y) && !lt(y,x)&&
+ !gt(x,y) && !gt(y,x)&&
+ std_eq(x,y) && std_eq(y,x)&&
+ !std_lt(x,y) && !std_lt(y,x)&&
+ !std_gt(x,y) && !std_gt(y,x);
+ }
+};
+
+template<typename CompositeKeyResult,typename T2>
+struct comparison_different_length
+{
+ static bool is_less(const CompositeKeyResult& x,const T2& y)
+ {
+ composite_key_result_less<CompositeKeyResult> lt;
+ composite_key_result_greater<CompositeKeyResult> gt;
+ std::less<CompositeKeyResult> std_lt;
+ std::greater<CompositeKeyResult> std_gt;
+
+ return (x< y) && !(y< x)&&
+ !(x> y) && (y> x)&&
+ !(x>=y) && (y>=x)&&
+ (x<=y) && !(y<=x)&&
+ lt(x,y) && !lt(y,x)&&
+ !gt(x,y) && gt(y,x)&&
+ std_lt(x,y) && !std_lt(y,x)&&
+ !std_gt(x,y) && std_gt(y,x);
+ }
+
+ static bool is_greater(const CompositeKeyResult& x,const T2& y)
+ {
+ composite_key_result_less<CompositeKeyResult> lt;
+ composite_key_result_greater<CompositeKeyResult> gt;
+ std::less<CompositeKeyResult> std_lt;
+ std::greater<CompositeKeyResult> std_gt;
+
+ return !(x< y) && (y< x)&&
+ (x> y) && !(y> x)&&
+ (x>=y) && !(y>=x)&&
+ !(x<=y) && (y<=x)&&
+ !lt(x,y) && lt(y,x)&&
+ gt(x,y) && !gt(y,x)&&
+ !std_lt(x,y) && std_lt(y,x)&&
+ std_gt(x,y) && !std_gt(y,x);
+ }
+
+ static bool is_equiv(const CompositeKeyResult& x,const T2& y)
+ {
+ composite_key_result_less<CompositeKeyResult> lt;
+ composite_key_result_greater<CompositeKeyResult> gt;
+ std::less<CompositeKeyResult> std_lt;
+ std::greater<CompositeKeyResult> std_gt;
+
+ return !(x< y) && !(y< x)&&
+ !(x> y) && !(y> x)&&
+ (x>=y) && (y>=x)&&
+ (x<=y) && (y<=x)&&
+ !lt(x,y) && !lt(y,x)&&
+ !gt(x,y) && !gt(y,x)&&
+ !std_lt(x,y) && !std_lt(y,x)&&
+ !std_gt(x,y) && !std_gt(y,x);
+ }
+};
+
+template<typename CompositeKeyResult,typename T2>
+struct comparison_helper:
+ boost::mpl::if_c<
+ composite_key_result_length<CompositeKeyResult>::value==
+ composite_object_length<T2>::value,
+ comparison_equal_length<CompositeKeyResult,T2>,
+ comparison_different_length<CompositeKeyResult,T2>
+ >::type
+{
+};
+
+template<typename CompositeKeyResult,typename T2>
+static bool is_less(const CompositeKeyResult& x,const T2& y)
+{
+ return comparison_helper<CompositeKeyResult,T2>::is_less(x,y);
+}
+
+template<typename CompositeKeyResult,typename T2>
+static bool is_greater(const CompositeKeyResult& x,const T2& y)
+{
+ return comparison_helper<CompositeKeyResult,T2>::is_greater(x,y);
+}
+
+template<typename CompositeKeyResult,typename T2>
+static bool is_equiv(const CompositeKeyResult& x,const T2& y)
+{
+ return comparison_helper<CompositeKeyResult,T2>::is_equiv(x,y);
+}
+
+template<typename T1,typename T2,typename Compare>
+static bool is_less(const T1& x,const T2& y,const Compare& c)
+{
+ return c(x,y)&&!c(y,x);
+}
+
+template<typename T1,typename T2,typename Compare>
+static bool is_greater(const T1& x,const T2& y,const Compare& c)
+{
+ return c(y,x)&&!c(x,y);
+}
+
+template<typename T1,typename T2,typename Compare>
+static bool is_equiv(const T1& x,const T2& y,const Compare& c)
+{
+ return !c(x,y)&&!c(y,x);
+}
+
+template<typename T1,typename T2,typename Compare,typename Equiv>
+static bool is_less(
+ const T1& x,const T2& y,const Compare& c,const Equiv& eq)
+{
+ return c(x,y)&&!c(y,x)&&!eq(x,y)&&!eq(y,x);
+}
+
+template<typename T1,typename T2,typename Compare,typename Equiv>
+static bool is_greater(
+ const T1& x,const T2& y,const Compare& c,const Equiv& eq)
+{
+ return c(y,x)&&!c(x,y)&&!eq(x,y)&&!eq(y,x);
+}
+
+template<typename T1,typename T2,typename Compare,typename Equiv>
+static bool is_equiv(
+ const T1& x,const T2& y,const Compare& c,const Equiv& eq)
+{
+ return !c(x,y)&&!c(y,x)&&eq(x,y)&&eq(y,x);
+}
+
+struct xyz
+{
+ xyz(int x_=0,int y_=0,int z_=0):x(x_),y(y_),z(z_){}
+
+ int x;
+ int y;
+ int z;
+};
+
+struct modulo_equal
+{
+ modulo_equal(int i):i_(i){}
+ bool operator ()(int x,int y)const{return (x%i_)==(y%i_);}
+
+private:
+ int i_;
+};
+
+struct xystr
+{
+ xystr(int x_=0,int y_=0,std::string str_=0):x(x_),y(y_),str(str_){}
+
+ int x;
+ int y;
+ std::string str;
+};
+
+#define TUPLE_MAKER_CREATE(z,n,tuple) \
+template<BOOST_PP_ENUM_PARAMS(n,typename T)> \
+static tuple<BOOST_PP_ENUM_PARAMS(n,T)> \
+create(BOOST_PP_ENUM_BINARY_PARAMS(n,const T,& t)){ \
+ return tuple<BOOST_PP_ENUM_PARAMS(n,T)>( \
+ BOOST_PP_ENUM_PARAMS(n,t)); \
+}
+
+#define DEFINE_TUPLE_MAKER(name,tuple) \
+struct name \
+{ \
+ static tuple<> create(){return tuple<>();} \
+ BOOST_PP_REPEAT_FROM_TO(1,5,TUPLE_MAKER_CREATE,tuple) \
+};
+
+DEFINE_TUPLE_MAKER(boost_tuple_maker,boost::tuple)
+
+#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
+ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+DEFINE_TUPLE_MAKER(std_tuple_maker,std::tuple)
+#endif
+
+#undef DEFINE_TUPLE_MAKER
+#undef TUPLE_MAKER_CREATE
+
+template<typename TupleMaker>
+void test_composite_key_template()
+{
+ typedef composite_key<
+ xyz,
+ BOOST_MULTI_INDEX_MEMBER(xyz,int,x),
+ BOOST_MULTI_INDEX_MEMBER(xyz,int,y),
+ BOOST_MULTI_INDEX_MEMBER(xyz,int,z)
+ > ckey_t1;
+
+ typedef multi_index_container<
+ xyz,
+ indexed_by<
+ ordered_unique<ckey_t1>
+ >
+ > indexed_t1;
+
+ indexed_t1 mc1;
+ mc1.insert(xyz(0,0,0));
+ mc1.insert(xyz(0,0,1));
+ mc1.insert(xyz(0,1,0));
+ mc1.insert(xyz(0,1,1));
+ mc1.insert(xyz(1,0,0));
+ mc1.insert(xyz(1,0,1));
+ mc1.insert(xyz(1,1,0));
+ mc1.insert(xyz(1,1,1));
+
+ BOOST_TEST(mc1.size()==8);
+ BOOST_TEST(
+ std::distance(
+ mc1.find(mc1.key_extractor()(xyz(0,0,0))),
+ mc1.find(mc1.key_extractor()(xyz(1,0,0))))==4);
+ BOOST_TEST(
+ std::distance(
+ mc1.find(TupleMaker::create(0,0,0)),
+ mc1.find(TupleMaker::create(1,0,0)))==4);
+ BOOST_TEST(
+ std::distance(
+ mc1.lower_bound(TupleMaker::create(0,0)),
+ mc1.upper_bound(TupleMaker::create(1,0)))==6);
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+ BOOST_TEST(
+ std::distance(
+ mc1.lower_bound(1),
+ mc1.upper_bound(1))==4);
+#endif
+
+ ckey_t1 ck1;
+ ckey_t1 ck2(ck1);
+ ckey_t1 ck3(
+ boost::make_tuple(
+ BOOST_MULTI_INDEX_MEMBER(xyz,int,x)(),
+ BOOST_MULTI_INDEX_MEMBER(xyz,int,y)(),
+ BOOST_MULTI_INDEX_MEMBER(xyz,int,z)()));
+ ckey_t1 ck4(get<0>(ck1.key_extractors()));
+
+ (void)ck3; /* prevent unused var */
+
+ get<2>(ck4.key_extractors())=
+ get<2>(ck2.key_extractors());
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0))));
+ BOOST_TEST(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,1,0))));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0))));
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0)));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(1)));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(-1)));
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0)));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,1)));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,-1)));
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0)));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,1)));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1)));
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0,1)));
+
+ typedef composite_key_result_less<ckey_t1::result_type> ckey_comp_t1;
+ typedef composite_key_result_equal_to<ckey_t1::result_type> ckey_eq_t1;
+
+ ckey_comp_t1 cp1;
+ ckey_eq_t1 eq1;
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp1,eq1));
+ BOOST_TEST(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp1,eq1));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp1,eq1));
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0),cp1));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(1),cp1));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(-1),cp1));
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),0,cp1));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),1,cp1));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),-1,cp1));
+#endif
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0),cp1));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,1),cp1));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,-1),cp1));
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0),cp1,eq1));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,1),cp1,eq1));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1),cp1,eq1));
+
+ typedef composite_key_result_greater<ckey_t1::result_type> ckey_comp_t2;
+
+ ckey_comp_t2 cp2;
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp2));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp2));
+ BOOST_TEST(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp2));
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0),cp2));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(1),cp2));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(-1),cp2));
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0),cp2));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,1),cp2));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,-1),cp2));
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0),cp2));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,1),cp2));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1),cp2));
+
+ typedef composite_key_equal_to<
+ modulo_equal,
+ modulo_equal,
+ std::equal_to<int>,
+ std::equal_to<int>
+ > ckey_eq_t2;
+
+ ckey_eq_t2 eq2(
+ boost::make_tuple(
+ modulo_equal(2),
+ modulo_equal(3),
+ std::equal_to<int>(),
+ std::equal_to<int>()));
+ ckey_eq_t2 eq3(eq2);
+ ckey_eq_t2 eq4(
+ get<0>(eq3.key_eqs()),
+ get<1>(eq3.key_eqs()));
+
+ eq3=eq4; /* prevent unused var */
+ eq4=eq3; /* prevent unused var */
+
+ BOOST_TEST( eq2(ck1(xyz(0,0,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(0,1,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(0,2,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST( eq2(ck1(xyz(0,3,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(1,0,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(1,1,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(1,2,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(1,3,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST( eq2(ck1(xyz(2,0,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(2,1,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(2,2,0)),ck1(xyz(0,0,0))));
+ BOOST_TEST( eq2(ck1(xyz(2,3,0)),ck1(xyz(0,0,0))));
+
+ BOOST_TEST( eq2(TupleMaker::create(0,0,0),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(0,1,0)) ,TupleMaker::create(0,0,0)));
+ BOOST_TEST(!eq2(TupleMaker::create(0,2,0),ck1(xyz(0,0,0))));
+ BOOST_TEST( eq2(ck1(xyz(0,3,0)) ,TupleMaker::create(0,0,0)));
+ BOOST_TEST(!eq2(TupleMaker::create(1,0,0),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(1,1,0)) ,TupleMaker::create(0,0,0)));
+ BOOST_TEST(!eq2(TupleMaker::create(1,2,0),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(1,3,0)) ,TupleMaker::create(0,0,0)));
+ BOOST_TEST( eq2(TupleMaker::create(2,0,0),ck1(xyz(0,0,0))));
+ BOOST_TEST(!eq2(ck1(xyz(2,1,0)) ,TupleMaker::create(0,0,0)));
+ BOOST_TEST(!eq2(TupleMaker::create(2,2,0),ck1(xyz(0,0,0))));
+ BOOST_TEST( eq2(ck1(xyz(2,3,0)) ,TupleMaker::create(0,0,0)));
+
+ typedef composite_key_compare<
+ std::less<int>,
+ std::greater<int>, /* order reversed */
+ std::less<int>
+ > ckey_comp_t3;
+
+ ckey_comp_t3 cp3;
+ ckey_comp_t3 cp4(cp3);
+ ckey_comp_t3 cp5(
+ boost::make_tuple(
+ std::less<int>(),
+ std::greater<int>(),
+ std::less<int>()));
+ ckey_comp_t3 cp6(get<0>(cp3.key_comps()));
+
+ cp4=cp5; /* prevent unused var */
+ cp5=cp6; /* prevent unused var */
+ cp6=cp4; /* prevent unused var */
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp3));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp3));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp3));
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0),cp3));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(1),cp3));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(-1),cp3));
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0),cp3));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,-1),cp3));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,1),cp3));
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,0)),TupleMaker::create(0,0,0),cp3));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),TupleMaker::create(0,0,1),cp3));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),TupleMaker::create(0,0,-1),cp3));
+
+ typedef composite_key<
+ xyz,
+ BOOST_MULTI_INDEX_MEMBER(xyz,int,y), /* members reversed */
+ BOOST_MULTI_INDEX_MEMBER(xyz,int,x)
+ > ckey_t2;
+
+ ckey_t2 ck5;
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0))));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0))));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0))));
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp1));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp1));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp1));
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp2));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp2));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp2));
+
+ BOOST_TEST(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp3));
+ BOOST_TEST(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp3));
+ BOOST_TEST(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp3));
+
+ typedef multi_index_container<
+ xyz,
+ indexed_by<
+ hashed_unique<ckey_t1>
+ >
+ > indexed_t2;
+
+ indexed_t2 mc2;
+ mc2.insert(xyz(0,0,0));
+ mc2.insert(xyz(0,0,1));
+ mc2.insert(xyz(0,1,0));
+ mc2.insert(xyz(0,1,1));
+ mc2.insert(xyz(1,0,0));
+ mc2.insert(xyz(1,0,1));
+ mc2.insert(xyz(1,1,0));
+ mc2.insert(xyz(1,1,1));
+ mc2.insert(xyz(0,0,0));
+ mc2.insert(xyz(0,0,1));
+ mc2.insert(xyz(0,1,0));
+ mc2.insert(xyz(0,1,1));
+ mc2.insert(xyz(1,0,0));
+ mc2.insert(xyz(1,0,1));
+ mc2.insert(xyz(1,1,0));
+ mc2.insert(xyz(1,1,1));
+
+ BOOST_TEST(mc2.size()==8);
+ BOOST_TEST(mc2.find(TupleMaker::create(0,0,1))->z==1);
+ BOOST_TEST(ck1(*(mc2.find(TupleMaker::create(1,0,1))))==
+ TupleMaker::create(1,0,1));
+
+ typedef composite_key<
+ xystr,
+ BOOST_MULTI_INDEX_MEMBER(xystr,std::string,str),
+ BOOST_MULTI_INDEX_MEMBER(xystr,int,x),
+ BOOST_MULTI_INDEX_MEMBER(xystr,int,y)
+ > ckey_t3;
+
+ ckey_t3 ck6;
+
+ typedef composite_key_hash<
+ boost::hash<std::string>,
+ boost::hash<int>,
+ boost::hash<int>
+ > ckey_hash_t;
+
+ ckey_hash_t ch1;
+ ckey_hash_t ch2(ch1);
+ ckey_hash_t ch3(
+ boost::make_tuple(
+ boost::hash<std::string>(),
+ boost::hash<int>(),
+ boost::hash<int>()));
+ ckey_hash_t ch4(get<0>(ch1.key_hash_functions()));
+
+ ch2=ch3; /* prevent unused var */
+ ch3=ch4; /* prevent unused var */
+ ch4=ch2; /* prevent unused var */
+
+ BOOST_TEST(
+ ch1(ck6(xystr(0,0,"hello")))==
+ ch1(TupleMaker::create(std::string("hello"),0,0)));
+ BOOST_TEST(
+ ch1(ck6(xystr(4,5,"world")))==
+ ch1(TupleMaker::create(std::string("world"),4,5)));
+
+ typedef boost::hash<composite_key_result<ckey_t3> > ckeyres_hash_t;
+
+ ckeyres_hash_t crh;
+
+ BOOST_TEST(
+ ch1(ck6(xystr(0,0,"hello")))==crh(ck6(xystr(0,0,"hello"))));
+ BOOST_TEST(
+ ch1(ck6(xystr(4,5,"world")))==crh(ck6(xystr(4,5,"world"))));
+}
+
+void test_composite_key()
+{
+ test_composite_key_template<boost_tuple_maker>();
+
+#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\
+ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ test_composite_key_template<std_tuple_maker>();
+#endif
+}
diff --git a/src/boost/libs/multi_index/test/test_composite_key.hpp b/src/boost/libs/multi_index/test/test_composite_key.hpp
new file mode 100644
index 000000000..8a7ae5344
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_composite_key.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for composite_key.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_composite_key();
diff --git a/src/boost/libs/multi_index/test/test_composite_key_main.cpp b/src/boost/libs/multi_index/test/test_composite_key_main.cpp
new file mode 100644
index 000000000..79f7c2d4e
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_composite_key_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for composite_key.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_composite_key.hpp"
+
+int main()
+{
+ test_composite_key();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_conv_iterators.cpp b/src/boost/libs/multi_index/test/test_conv_iterators.cpp
new file mode 100644
index 000000000..24751e011
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_conv_iterators.cpp
@@ -0,0 +1,75 @@
+/* Boost.MultiIndex test for interconvertibilty between const and
+ * non-const iterators.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_conv_iterators.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost::multi_index;
+
+void test_conv_iterators()
+{
+ employee_set es;
+ es.insert(employee(2,"John",40,7889));
+
+ {
+ const employee_set& ces=es;
+ employee_set::iterator it=es.find(employee(2,"John",40,7889));
+ employee_set::const_iterator it1=es.find(employee(2,"John",40,7889));
+ employee_set::const_iterator it2=ces.find(employee(2,"John",40,7889));
+
+ BOOST_TEST(it==it1&&it1==it2&&it2==it);
+ BOOST_TEST(*it==*it1&&*it1==*it2&&*it2==*it);
+ }
+ {
+ employee_set_by_name& i1=get<1>(es);
+ const employee_set_by_name& ci1=get<1>(es);
+ employee_set_by_name::iterator it=i1.find("John");
+ employee_set_by_name::const_iterator it1=i1.find("John");
+ employee_set_by_name::const_iterator it2=ci1.find("John");
+
+ BOOST_TEST(it==it1&&it1==it2&&it2==it);
+ BOOST_TEST(*it==*it1&&*it1==*it2&&*it2==*it);
+ }
+ {
+ employee_set_by_name& i1=get<1>(es);
+ const employee_set_by_name& ci1=get<1>(es);
+ employee_set_by_name::local_iterator it=i1.begin(i1.bucket("John"));
+ employee_set_by_name::const_local_iterator it1=i1.begin(i1.bucket("John"));
+ employee_set_by_name::const_local_iterator it2=ci1.begin(ci1.bucket("John"));
+
+ BOOST_TEST(it==it1&&it1==it2&&it2==it);
+ BOOST_TEST(*it==*it1&&*it1==*it2&&*it2==*it);
+ }
+ {
+ employee_set_as_inserted& i3=get<3>(es);
+ const employee_set_as_inserted& ci3=get<3>(es);
+ employee_set_as_inserted::iterator it=i3.begin();
+ employee_set_as_inserted::const_iterator it1=i3.begin();
+ employee_set_as_inserted::const_iterator it2=ci3.begin();
+
+ BOOST_TEST(it==it1&&it1==it2&&it2==it);
+ BOOST_TEST(*it==*it1&&*it1==*it2&&*it2==*it);
+ }
+ {
+ employee_set_randomly& i5=get<5>(es);
+ const employee_set_randomly& ci5=get<5>(es);
+ employee_set_randomly::iterator it=i5.begin();
+ employee_set_randomly::const_iterator it1=i5.begin();
+ employee_set_randomly::const_iterator it2=ci5.begin();
+
+ BOOST_TEST(it==it1&&it1==it2&&it2==it);
+ BOOST_TEST(*it==*it1&&*it1==*it2&&*it2==*it);
+ }
+}
diff --git a/src/boost/libs/multi_index/test/test_conv_iterators.hpp b/src/boost/libs/multi_index/test/test_conv_iterators.hpp
new file mode 100644
index 000000000..1e493b52a
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_conv_iterators.hpp
@@ -0,0 +1,12 @@
+/* Boost.MultiIndex test for interconvertibilty between const and
+ * non-const iterators.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_conv_iterators();
diff --git a/src/boost/libs/multi_index/test/test_conv_iterators_main.cpp b/src/boost/libs/multi_index/test/test_conv_iterators_main.cpp
new file mode 100644
index 000000000..5d07f7fc1
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_conv_iterators_main.cpp
@@ -0,0 +1,21 @@
+/* Boost.MultiIndex test for interconvertibilty between const and
+ * non-const iterators.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_conv_iterators.hpp"
+
+int main()
+{
+ test_conv_iterators();
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/multi_index/test/test_copy_assignment.cpp b/src/boost/libs/multi_index/test/test_copy_assignment.cpp
new file mode 100644
index 000000000..fca40b267
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_copy_assignment.cpp
@@ -0,0 +1,365 @@
+/* Boost.MultiIndex test for copying and assignment.
+ *
+ * Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_copy_assignment.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <boost/move/utility_core.hpp>
+#include <list>
+#include <numeric>
+#include <vector>
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include "small_allocator.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost::multi_index;
+
+#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+/* The "ISO C++ Template Parser" option makes CW8.3 incorrectly fail at
+ * expressions of the form sizeof(x) where x is an array local to a
+ * template function.
+ */
+
+#pragma parse_func_templ off
+#endif
+
+typedef multi_index_container<int> copyable_and_movable;
+
+struct holder
+{
+ copyable_and_movable c;
+};
+
+template<typename Sequence>
+static void test_assign()
+{
+ Sequence s;
+
+ int a[]={0,1,2,3,4,5};
+ std::size_t sa=sizeof(a)/sizeof(a[0]);
+
+ s.assign(&a[0],&a[sa]);
+ BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
+
+ s.assign((const int*)(&a[0]),(const int*)(&a[sa]));
+ BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ s.assign({0,1,2,3,4,5});
+#else
+ s.assign(&a[0],&a[sa]);
+#endif
+
+ BOOST_TEST(s.size()==sa&&std::equal(s.begin(),s.end(),&a[0]));
+
+ s.assign((std::size_t)18,37);
+ BOOST_TEST(s.size()==18&&std::accumulate(s.begin(),s.end(),0)==666);
+
+ s.assign((std::size_t)12,167);
+ BOOST_TEST(s.size()==12&&std::accumulate(s.begin(),s.end(),0)==2004);
+}
+
+#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+#pragma parse_func_templ reset
+#endif
+
+template<typename Sequence>
+static void test_integral_assign()
+{
+ /* Special cases described in 23.1.1/9: integral types must not
+ * be taken as iterators in assign(f,l) and insert(p,f,l).
+ */
+
+ Sequence s;
+
+ s.assign(5,10);
+ BOOST_TEST(s.size()==5&&std::accumulate(s.begin(),s.end(),0)==50);
+ s.assign(2u,5u);
+ BOOST_TEST(s.size()==2&&std::accumulate(s.begin(),s.end(),0)==10);
+
+ s.clear();
+ s.insert(s.begin(),5,10);
+ BOOST_TEST(s.size()==5&&std::accumulate(s.begin(),s.end(),0)==50);
+ s.insert(s.begin(),2u,5u);
+ BOOST_TEST(s.size()==7&&std::accumulate(s.begin(),s.end(),0)==60);
+}
+
+employee_set produce_employee_set()
+{
+ employee_set es;
+ es.insert(employee(0,"Petr",60,2837));
+ es.insert(employee(1,"Jiri",25,2143));
+ es.insert(employee(2,"Radka",40,4875));
+ es.insert(employee(3,"Milan",38,3474));
+ return es;
+}
+
+void test_copy_assignment()
+{
+ employee_set es;
+ employee_set es2(es);
+
+ employee_set::allocator_type al=es.get_allocator();
+ al=get<1>(es).get_allocator();
+ al=get<2>(es).get_allocator();
+ al=get<3>(es).get_allocator();
+ al=get<4>(es).get_allocator();
+ al=get<5>(es).get_allocator();
+
+ BOOST_TEST(es2.empty());
+
+ es2.insert(employee(0,"Joe",31,1123));
+ es2.insert(employee(1,"Robert",27,5601));
+ es2.insert(employee(2,"John",40,7889));
+ es2.insert(employee(2,"Aristotle",2388,3357)); /* clash */
+ es2.insert(employee(3,"Albert",20,9012));
+ es2.insert(employee(4,"John",57,1002));
+ es2.insert(employee(0,"Andrew",60,2302)); /* clash */
+
+ employee_set es3(es2);
+
+ BOOST_TEST(es2==es3);
+ BOOST_TEST(get<2>(es2)==get<2>(es3));
+ BOOST_TEST(get<3>(es2)==get<3>(es3));
+ BOOST_TEST(get<5>(es2)==get<5>(es3));
+
+ employee_set es4=employee_set(non_std_allocator<employee>());
+ employee_set_by_name& i1=get<name>(es4);
+ i1=get<1>(es2);
+
+ BOOST_TEST(es4==es2);
+
+ employee_set es5=employee_set(employee_set::ctor_args_list());
+ employee_set_by_age& i2=get<age>(es5);
+ i2=get<2>(es2);
+
+ BOOST_TEST(i2==get<2>(es2));
+
+ employee_set es6;
+ employee_set_as_inserted& i3=get<as_inserted>(es6);
+ i3=get<3>(es2);
+
+ BOOST_TEST(i3==get<3>(es2));
+
+ employee_set es7;
+ employee_set_randomly& i5=get<randomly>(es7);
+ i5=get<5>(es2);
+
+ BOOST_TEST(i5==get<5>(es2));
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)&&\
+ !BOOST_WORKAROUND(BOOST_MSVC,==1800) /* MSVC 12.0 chokes on what follows */
+ employee_set es8({{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102}});
+ employee_set es9;
+ es9={{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102},
+ {0,"Rose",40,4512}};
+
+ BOOST_TEST(es8.size()==3);
+ BOOST_TEST(es9==es8);
+
+ es9.clear();
+ get<0>(es9)={{0,"Rose",40,4512},{1,"Mary",38,3345},{2,"Jo",25,7102},
+ {0,"Rose",40,4512}};
+ BOOST_TEST(es9==es8);
+
+ es9.clear();
+ get<0>(es9)={{0,"Rose",40,4512},{2,"Jo",25,7102},{1,"Mary",38,3345}};
+ BOOST_TEST(es9==es8);
+
+ es9.clear();
+ get<1>(es9)={{1,"Mary",38,3345},{0,"Rose",40,4512},{2,"Jo",25,7102},
+ {0,"Rose",40,4512}};
+ BOOST_TEST(es9==es8);
+
+ es9.clear();
+ get<2>(es9)={{2,"Jo",25,7102},{0,"Rose",40,4512},{1,"Mary",38,3345}};
+ BOOST_TEST(es9==es8);
+
+ es9.clear();
+ get<3>(es9)={{0,"Rose",40,4512},{1,"Mary",38,3345},{1,"Mary",38,3345},
+ {2,"Jo",25,7102}};
+ BOOST_TEST(es9==es8);
+
+ es9.clear();
+ get<4>(es9)={{1,"Mary",38,3345},{2,"Jo",25,7102},{0,"Rose",40,4512}};
+ BOOST_TEST(es9==es8);
+
+ es9.clear();
+ get<5>(es9)={{1,"Mary",38,3345},{2,"Jo",25,7102},{0,"Rose",40,4512},
+ {2,"Jo",25,7102}};
+ BOOST_TEST(es9==es8);
+#endif
+
+ employee_set es10(produce_employee_set()),es11(produce_employee_set());
+ BOOST_TEST(es10==es11);
+
+ employee_set es12(boost::move(es10));
+ BOOST_TEST(es10.empty());
+ BOOST_TEST(es11==es12);
+
+ es10=boost::move(es12);
+ BOOST_TEST(es12.empty());
+ BOOST_TEST(es11==es10);
+
+ std::list<employee> l;
+ l.push_back(employee(3,"Anna",31,5388));
+ l.push_back(employee(1,"Rachel",27,9012));
+ l.push_back(employee(2,"Agatha",40,1520));
+
+ employee_set es13(l.begin(),l.end());
+
+ l.sort();
+
+ BOOST_TEST(es13.size()==l.size()&&
+ std::equal(es13.begin(),es13.end(),l.begin()));
+
+ test_assign<multi_index_container<int,indexed_by<sequenced<> > > >();
+ test_integral_assign<
+ multi_index_container<int,indexed_by<sequenced<> > > >();
+
+ test_assign<multi_index_container<int,indexed_by<random_access<> > > >();
+ test_integral_assign<
+ multi_index_container<int,indexed_by<random_access<> > > >();
+
+ /* Testcase for problem described at http://www.boost.org/doc/html/move/
+ * emulation_limitations.html#move.emulation_limitations.assignment_operator
+ */
+
+ holder h((holder()));
+ h=holder();
+
+#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
+{
+ /* testcase for https://svn.boost.org/trac10/ticket/13518 */
+
+ multi_index_container<int> x={};
+}
+#endif
+
+ typedef small_allocator<int> small_alloc;
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ordered_unique<identity<int> >,
+ ranked_unique<identity<int> >,
+ hashed_unique<identity<int> >,
+ sequenced<>,
+ random_access<>
+ >,
+ small_alloc
+ > small_container;
+ typedef small_container::nth_index<0>::type small_container_0;
+ typedef small_container::nth_index<1>::type small_container_1;
+ typedef small_container::nth_index<2>::type small_container_2;
+ typedef small_container::nth_index<3>::type small_container_3;
+ typedef small_container::nth_index<4>::type small_container_4;
+
+ BOOST_STATIC_ASSERT((
+ boost::is_same<small_container::size_type,small_alloc::size_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<
+ small_container::difference_type,small_alloc::difference_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<small_container_0::size_type,small_alloc::size_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<
+ small_container_0::difference_type,small_alloc::difference_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<small_container_1::size_type,small_alloc::size_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<
+ small_container_1::difference_type,small_alloc::difference_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<small_container_2::size_type,small_alloc::size_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<
+ small_container_2::difference_type,small_alloc::difference_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<small_container_3::size_type,small_alloc::size_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<
+ small_container_3::difference_type,small_alloc::difference_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<small_container_4::size_type,small_alloc::size_type>::value));
+ BOOST_STATIC_ASSERT((
+ boost::is_same<
+ small_container_4::difference_type,small_alloc::difference_type>::value));
+
+ small_container sc;
+ small_container_0& sc0=sc.get<0>();
+ small_container_1& sc1=sc.get<1>();
+ small_container_2& sc2=sc.get<2>();
+ small_container_3& sc3=sc.get<3>();
+ small_container_4& sc4=sc.get<4>();
+ small_alloc::size_type s,
+ ms=(small_alloc::size_type)(-1);
+
+ sc.insert(0);
+
+ s=sc0.size();
+ BOOST_TEST(sc0.max_size()<=ms);
+ s=sc0.erase(1);
+ s=sc0.count(0);
+ s=sc0.count(0,std::less<int>());
+
+ s=sc1.size();
+ BOOST_TEST(sc1.max_size()<=ms);
+ s=sc1.erase(1);
+ s=sc1.count(0);
+ s=sc1.count(0,std::less<int>());
+ (void)sc1.nth(s);
+ s=sc1.rank(sc1.begin());
+ s=sc1.find_rank(0);
+ s=sc1.find_rank(0,std::less<int>());
+ s=sc1.lower_bound_rank(0);
+ s=sc1.lower_bound_rank(0,std::less<int>());
+ s=sc1.upper_bound_rank(0);
+ s=sc1.upper_bound_rank(0,std::less<int>());
+ s=sc1.equal_range_rank(0).first;
+ s=sc1.equal_range_rank(0).second;
+ s=sc1.range_rank(unbounded,unbounded).first;
+ s=sc1.range_rank(unbounded,unbounded).second;
+
+ s=sc2.size();
+ BOOST_TEST(sc2.max_size()<=ms);
+ s=sc2.erase(1);
+ s=sc2.count(0);
+ s=sc2.count(0,boost::hash<int>(),std::equal_to<int>());
+ s=sc2.bucket_count();
+ BOOST_TEST(sc2.max_bucket_count()<=ms);
+ BOOST_TEST(sc2.bucket_size((small_alloc::size_type)(0))<=ms);
+ BOOST_TEST(sc2.bucket_size(0)<=ms);
+ (void)sc2.begin(0);
+ (void)sc2.end(0);
+ (void)sc2.cbegin(0);
+ (void)sc2.cend(0);
+ sc2.rehash(2);
+ sc2.reserve(2);
+
+ s=sc3.size();
+ BOOST_TEST(sc3.max_size()<=ms);
+ sc3.resize(0);
+ sc3.resize(0,0);
+ sc3.assign((small_alloc::size_type)(1),0);
+ sc3.insert(sc3.begin(),(small_alloc::size_type)(0),0);
+
+ s=sc4.size();
+ BOOST_TEST(sc4.max_size()<=ms);
+ BOOST_TEST(sc4.capacity()<=ms);
+ sc4.reserve(0);
+ sc4.resize(0);
+ sc4.resize(0,0);
+ sc4.assign((small_alloc::size_type)(1),0);
+ (void)sc4[0];
+ (void)sc4.at(0);
+ sc4.insert(sc4.begin(),(small_alloc::size_type)(0),0);
+}
diff --git a/src/boost/libs/multi_index/test/test_copy_assignment.hpp b/src/boost/libs/multi_index/test/test_copy_assignment.hpp
new file mode 100644
index 000000000..59a1ed5b5
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_copy_assignment.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for copying and assignment.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_copy_assignment();
diff --git a/src/boost/libs/multi_index/test/test_copy_assignment_main.cpp b/src/boost/libs/multi_index/test/test_copy_assignment_main.cpp
new file mode 100644
index 000000000..e14bd973d
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_copy_assignment_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for copying and assignment.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_copy_assignment.hpp"
+
+int main()
+{
+ test_copy_assignment();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_hash_ops.cpp b/src/boost/libs/multi_index/test/test_hash_ops.cpp
new file mode 100644
index 000000000..e85d905aa
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_hash_ops.cpp
@@ -0,0 +1,118 @@
+/* Boost.MultiIndex test for standard hash operations.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_hash_ops.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <iterator>
+#include <boost/detail/lightweight_test.hpp>
+#include "pre_multi_index.hpp"
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <vector>
+
+#include <iostream>
+
+using namespace boost::multi_index;
+
+template<typename HashedContainer>
+void check_load_factor(const HashedContainer& hc)
+{
+ float lf=(float)hc.size()/hc.bucket_count();
+ BOOST_TEST(lf<=hc.load_factor()+1.E-6);
+ BOOST_TEST(lf>=hc.load_factor()-1.E-6);
+ BOOST_TEST(lf<=hc.max_load_factor()+1.E-6);
+}
+
+typedef multi_index_container<
+ int,
+ indexed_by<
+ hashed_unique<identity<int> >
+ >
+> hash_container;
+
+void test_hash_ops()
+{
+ hash_container hc;
+
+ BOOST_TEST(hc.max_load_factor()==1.0f);
+ BOOST_TEST(hc.bucket_count()<=hc.max_bucket_count());
+
+ hc.insert(1000);
+ hash_container::size_type buc=hc.bucket(1000);
+ hash_container::local_iterator it0=hc.begin(buc);
+ hash_container::local_iterator it1=hc.end(buc);
+ BOOST_TEST(
+ (hash_container::size_type)std::distance(it0,it1)==hc.bucket_size(buc)&&
+ hc.bucket_size(buc)==1&&*it0==1000);
+
+ hc.clear();
+
+ for(hash_container::size_type s=2*hc.bucket_count();s--;){
+ hc.insert((int)s);
+ }
+ check_load_factor(hc);
+
+ hc.max_load_factor(0.5f);
+ BOOST_TEST(hc.max_load_factor()==0.5f);
+ hc.insert(-1);
+ check_load_factor(hc);
+
+ hc.rehash(1);
+ BOOST_TEST(hc.bucket_count()>=1);
+ check_load_factor(hc);
+
+ hc.max_load_factor(0.25f);
+ hc.rehash(1);
+ BOOST_TEST(hc.bucket_count()>=1);
+ check_load_factor(hc);
+
+ hash_container::size_type bc=4*hc.bucket_count();
+ hc.max_load_factor(0.125f);
+ hc.rehash(bc);
+ BOOST_TEST(hc.bucket_count()>=bc);
+ check_load_factor(hc);
+
+ bc=2*hc.bucket_count();
+ hc.rehash(bc);
+ BOOST_TEST(hc.bucket_count()>=bc);
+ check_load_factor(hc);
+
+ hc.clear();
+ hc.insert(0);
+ hc.rehash(1);
+ BOOST_TEST(hc.bucket_count()>=1);
+ check_load_factor(hc);
+
+ hash_container hc2;
+ hc2.insert(0);
+ hc2.max_load_factor(0.5f/hc2.bucket_count());
+ BOOST_TEST(hc2.load_factor()>hc2.max_load_factor());
+ hc2.reserve(1);
+ BOOST_TEST(hc2.load_factor()<hc2.max_load_factor());
+
+ hash_container hc3;
+ hc3.clear();
+ hc3.max_load_factor(1.0f);
+ hc3.reserve(1000);
+ hash_container::size_type bc3=hc3.bucket_count();
+ BOOST_TEST(bc3>=1000);
+ std::vector<int> v;
+ for(unsigned int n=0;n<bc3;++n)v.push_back(n);
+ hc3.insert(v.begin(),v.end());
+ BOOST_TEST(hc3.bucket_count()==bc3); /* LWG issue 2156 */
+ hc3.max_load_factor(0.25f);
+ hc3.reserve(100);
+ BOOST_TEST(hc3.bucket_count()>bc3);
+ bc3=hc3.bucket_count();
+ hc3.reserve((hash_container::size_type)(3.0f*hc3.max_load_factor()*bc3));
+ BOOST_TEST(hc3.bucket_count()>bc3);
+}
diff --git a/src/boost/libs/multi_index/test/test_hash_ops.hpp b/src/boost/libs/multi_index/test/test_hash_ops.hpp
new file mode 100644
index 000000000..37ebc4ada
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_hash_ops.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for standard hash operations.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_hash_ops();
diff --git a/src/boost/libs/multi_index/test/test_hash_ops_main.cpp b/src/boost/libs/multi_index/test/test_hash_ops_main.cpp
new file mode 100644
index 000000000..be237b37e
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_hash_ops_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for standard hash operations.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_hash_ops.hpp"
+
+int main()
+{
+ test_hash_ops();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_iterators.cpp b/src/boost/libs/multi_index/test/test_iterators.cpp
new file mode 100644
index 000000000..d9c7f7f20
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_iterators.cpp
@@ -0,0 +1,250 @@
+/* Boost.MultiIndex test for iterators.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_iterators.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/next_prior.hpp>
+
+using namespace boost::multi_index;
+
+template<typename Index>
+void test_non_const_iterators(Index& i,int target)
+{
+ typedef typename Index::iterator iterator;
+ typedef typename Index::reverse_iterator reverse_iterator;
+
+ int n=0;
+ for(iterator it=i.begin();it!=i.end();++it){
+ BOOST_TEST(i.iterator_to(*it)==it);
+ n+=it->id;
+ }
+ int m=0;
+ for(reverse_iterator rit=i.rbegin();rit!=i.rend();++rit){
+ m+=rit->id;
+ }
+ int p=0;
+ for(iterator it2=i.end();it2!=i.begin();){
+ --it2;
+ p+=it2->id;
+ }
+ int q=0;
+ for(reverse_iterator rit2=i.rend();rit2!=i.rbegin();){
+ --rit2;
+ q+=rit2->id;
+ }
+
+ BOOST_TEST(n==target&&n==m&&n==p&&n==q);
+}
+
+template<typename Index>
+void test_const_iterators(const Index& i,int target)
+{
+ typedef typename Index::const_iterator const_iterator;
+ typedef typename Index::const_reverse_iterator const_reverse_iterator;
+
+ BOOST_TEST(i.cbegin()==i.begin());
+ BOOST_TEST(i.cend()==i.end());
+ BOOST_TEST(i.crbegin()==i.rbegin());
+ BOOST_TEST(i.crend()==i.rend());
+
+ int n=0;
+ for(const_iterator it=i.begin();it!=i.end();++it){
+ BOOST_TEST(i.iterator_to(*it)==it);
+ n+=it->id;
+ }
+ int m=0;
+ for(const_reverse_iterator rit=i.rbegin();rit!=i.rend();++rit){
+ m+=rit->id;
+ }
+ int p=0;
+ for(const_iterator it2=i.end();it2!=i.begin();){
+ --it2;
+ p+=it2->id;
+ }
+ int q=0;
+ for(const_reverse_iterator rit2=i.rend();rit2!=i.rbegin();){
+ --rit2;
+ q+=rit2->id;
+ }
+
+ BOOST_TEST(n==target&&n==m&&n==p&&n==q);
+}
+
+template<typename Index>
+void test_non_const_hashed_iterators(Index& i,int target)
+{
+ typedef typename Index::iterator iterator;
+ typedef typename Index::local_iterator local_iterator;
+ typedef typename Index::size_type size_type;
+
+ int n=0;
+ for(iterator it=i.begin();it!=i.end();++it){
+ BOOST_TEST(i.iterator_to(*it)==it);
+ n+=it->id;
+ }
+ int m=0;
+ for(size_type buc=0;buc<i.bucket_count();++buc){
+ for(local_iterator it=i.begin(buc);it!=i.end(buc);++it){
+ BOOST_TEST(i.local_iterator_to(*it)==it);
+ m+=it->id;
+ }
+ }
+
+ BOOST_TEST(n==target&&n==m);
+}
+
+template<typename Index>
+void test_const_hashed_iterators(const Index& i,int target)
+{
+ typedef typename Index::const_iterator const_iterator;
+ typedef typename Index::const_local_iterator const_local_iterator;
+ typedef typename Index::size_type size_type;
+
+ BOOST_TEST(i.cbegin()==i.begin());
+ BOOST_TEST(i.cend()==i.end());
+
+ int n=0;
+ for(const_iterator it=i.begin();it!=i.end();++it){
+ BOOST_TEST(i.iterator_to(*it)==it);
+ n+=it->id;
+ }
+ int m=0;
+ for(size_type buc=0;buc<i.bucket_count();++buc){
+ BOOST_TEST(i.cbegin(buc)==i.begin(buc));
+ BOOST_TEST(i.cend(buc)==i.end(buc));
+ for(const_local_iterator it=i.begin(buc);it!=i.end(buc);++it){
+ BOOST_TEST(i.local_iterator_to(*it)==it);
+ m+=it->id;
+ }
+ }
+
+ BOOST_TEST(n==target&&n==m);
+}
+
+template<typename Index>
+void test_non_const_rnd_iterators(Index& i,int target)
+{
+ typedef typename Index::iterator iterator;
+ typedef typename Index::reverse_iterator reverse_iterator;
+ typedef typename Index::difference_type difference_type;
+
+ iterator middle=i.begin()+(i.end()-i.begin())/2;
+ difference_type off=middle-i.begin();
+ reverse_iterator rmiddle=i.rbegin()+off;
+ bool odd=((i.end()-i.begin())%2)!=0;
+
+ int n=0;
+ for(iterator it=i.begin();it!=middle;++it){
+ BOOST_TEST(i.iterator_to(*it)==it);
+ n+=it->id;
+ n+=it[off].id;
+ }
+ if(odd)n+=(boost::prior(i.end()))->id;
+ int m=0;
+ for(reverse_iterator rit=i.rbegin();rit!=rmiddle;++rit){
+ m+=rit->id;
+ m+=(rit+off)->id;
+ }
+ if(odd)m+=(boost::prior(i.rend()))->id;
+ int p=0;
+ for(iterator it2=i.end();it2!=middle;){
+ --it2;
+ p+=it2->id;
+ p+=(it2-off)->id;
+ }
+ if(odd)p-=middle->id;
+ int q=0;
+ for(reverse_iterator rit2=i.rend();rit2!=rmiddle;){
+ --rit2;
+ q+=rit2->id;
+ q+=(rit2-off)->id;
+ }
+ if(odd)q-=rmiddle->id;
+
+ BOOST_TEST(n==target&&n==m&&n==p&&n==q);
+}
+
+template<typename Index>
+void test_const_rnd_iterators(const Index& i,int target)
+{
+ typedef typename Index::const_iterator const_iterator;
+ typedef typename Index::const_reverse_iterator const_reverse_iterator;
+ typedef typename Index::difference_type difference_type;
+
+ BOOST_TEST(i.cbegin()==i.begin());
+ BOOST_TEST(i.cend()==i.end());
+ BOOST_TEST(i.crbegin()==i.rbegin());
+ BOOST_TEST(i.crend()==i.rend());
+
+ const_iterator middle=i.begin()+(i.end()-i.begin())/2;
+ difference_type off=middle-i.begin();
+ const_reverse_iterator rmiddle=i.rbegin()+off;
+ bool odd=((i.end()-i.begin())%2)!=0;
+
+ int n=0;
+ for(const_iterator it=i.begin();it!=middle;++it){
+ BOOST_TEST(i.iterator_to(*it)==it);
+ n+=it->id;
+ n+=it[off].id;
+ }
+ if(odd)n+=(boost::prior(i.end()))->id;
+ int m=0;
+ for(const_reverse_iterator rit=i.rbegin();rit!=rmiddle;++rit){
+ m+=rit->id;
+ m+=(rit+off)->id;
+ }
+ if(odd)m+=(boost::prior(i.rend()))->id;
+ int p=0;
+ for(const_iterator it2=i.end();it2!=middle;){
+ --it2;
+ p+=it2->id;
+ p+=(it2-off)->id;
+ }
+ if(odd)p-=middle->id;
+ int q=0;
+ for(const_reverse_iterator rit2=i.rend();rit2!=rmiddle;){
+ --rit2;
+ q+=rit2->id;
+ q+=(rit2-off)->id;
+ }
+ if(odd)q-=rmiddle->id;
+
+ BOOST_TEST(n==target&&n==m&&n==p&&n==q);
+}
+
+void test_iterators()
+{
+ employee_set es;
+
+ es.insert(employee(0,"Joe",31,1123));
+ es.insert(employee(1,"Robert",27,5601));
+ es.insert(employee(2,"John",40,7889));
+ es.insert(employee(3,"Albert",20,9012));
+ es.insert(employee(4,"John",57,1002));
+
+ int target=0+1+2+3+4;
+
+ test_non_const_iterators (es,target);
+ test_const_iterators (es,target);
+ test_non_const_hashed_iterators(get<1>(es),target);
+ test_const_hashed_iterators (get<1>(es),target);
+ test_non_const_iterators (get<2>(es),target);
+ test_const_iterators (get<2>(es),target);
+ test_non_const_iterators (get<3>(es),target);
+ test_const_iterators (get<3>(es),target);
+ test_non_const_hashed_iterators(get<4>(es),target);
+ test_const_hashed_iterators (get<4>(es),target);
+ test_non_const_rnd_iterators (get<5>(es),target);
+ test_const_rnd_iterators (get<5>(es),target);
+}
diff --git a/src/boost/libs/multi_index/test/test_iterators.hpp b/src/boost/libs/multi_index/test/test_iterators.hpp
new file mode 100644
index 000000000..01ffab21e
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_iterators.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for iterators.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_iterators();
diff --git a/src/boost/libs/multi_index/test/test_iterators_main.cpp b/src/boost/libs/multi_index/test/test_iterators_main.cpp
new file mode 100644
index 000000000..13bd39ae2
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_iterators_main.cpp
@@ -0,0 +1,19 @@
+/* Boost.MultiIndex test for iterators.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_iterators.hpp"
+
+int main()
+{
+ test_iterators();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/multi_index/test/test_key.cpp b/src/boost/libs/multi_index/test/test_key.cpp
new file mode 100644
index 000000000..10ebb37e7
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_key.cpp
@@ -0,0 +1,170 @@
+/* Boost.MultiIndex test for terse key specification syntax.
+ *
+ * Copyright 2003-2019 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_key.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp>
+#include "pre_multi_index.hpp"
+#include <boost/multi_index/key.hpp>
+
+#if !defined(BOOST_MULTI_INDEX_KEY_SUPPORTED)
+
+#include <boost/config/pragma_message.hpp>
+
+BOOST_PRAGMA_MESSAGE("boost::multi_index::key not supported, skipping test")
+
+void test_key()
+{
+}
+#else
+
+#include <functional>
+#include <type_traits>
+
+using namespace boost::multi_index;
+
+namespace {
+
+struct base
+{
+ int x;
+ const int cx;
+ int f(){return x;};
+ int cf()const{return x;};
+ int vf()volatile{return x;};
+ int cvf()const volatile{return x;};
+ int rf()&{return x;};
+ int crf()const&{return x;};
+ int vrf()volatile&{return x;};
+ int cvrf()const volatile&{return x;};
+ int nef()noexcept{return x;};
+ int cnef()const noexcept{return x;};
+ int vnef()volatile noexcept{return x;};
+ int cvnef()const volatile noexcept{return x;};
+ int rnef()& noexcept{return x;};
+ int crnef()const& noexcept{return x;};
+ int vrnef()volatile& noexcept{return x;};
+ int cvrnef()const volatile& noexcept{return x;};
+};
+
+int gf(const base& b){return b.x;}
+int negf(const base& b)noexcept{return b.x;}
+
+struct derived:base
+{
+ int y;
+};
+
+int gh(derived& d){return d.y;}
+int grh(std::reference_wrapper<derived>& d){return d.get().y;}
+
+} /* namespace */
+
+void test_key()
+{
+ BOOST_TEST((std::is_same<
+ key<&base::x>,member<base,int,&base::x>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::cx>,member<base,const int,&base::cx>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::f>,mem_fun<base,int,&base::f>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::cf>,const_mem_fun<base,int,&base::cf>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::vf>,volatile_mem_fun<base,int,&base::vf>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::cvf>,cv_mem_fun<base,int,&base::cvf>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::rf>,ref_mem_fun<base,int,&base::rf>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::crf>,cref_mem_fun<base,int,&base::crf>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::vrf>,vref_mem_fun<base,int,&base::vrf>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::cvrf>,cvref_mem_fun<base,int,&base::cvrf>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::nef>,mem_fun<base,int,&base::nef>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::cnef>,const_mem_fun<base,int,&base::cnef>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::vnef>,volatile_mem_fun<base,int,&base::vnef>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::cvnef>,cv_mem_fun<base,int,&base::cvnef>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::rnef>,ref_mem_fun<base,int,&base::rnef>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::crnef>,cref_mem_fun<base,int,&base::crnef>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::vrnef>,vref_mem_fun<base,int,&base::vrnef>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::cvrnef>,cvref_mem_fun<base,int,&base::cvrnef>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<gf>,global_fun<const base&,int,gf>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<negf>,global_fun<const base&,int,negf>
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::x,&base::cx,&base::f,&base::cf,gf>,
+ composite_key<
+ base,
+ member<base,int,&base::x>,
+ member<base,const int,&base::cx>,
+ mem_fun<base,int,&base::f>,
+ const_mem_fun<base,int,&base::cf>,
+ global_fun<const base&,int,gf>
+ >
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<&base::x,&derived::y>,
+ composite_key<
+ derived,
+ member<base,int,&base::x>,
+ member<derived,int,&derived::y>
+ >
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<gf,gh>,
+ composite_key<
+ derived,
+ global_fun<const base&,int,gf>,
+ global_fun<derived&,int,gh>
+ >
+ >::value));
+ BOOST_TEST((std::is_same<
+ key<gf,gh,grh>,
+ composite_key<
+ std::reference_wrapper<derived>,
+ global_fun<const base&,int,gf>,
+ global_fun<derived&,int,gh>,
+ global_fun<std::reference_wrapper<derived>&,int,grh>
+ >
+ >::value));
+}
+#endif
diff --git a/src/boost/libs/multi_index/test/test_key.hpp b/src/boost/libs/multi_index/test/test_key.hpp
new file mode 100644
index 000000000..9ebe4fe66
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_key.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for terse key specification syntax.
+ *
+ * Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_key();
diff --git a/src/boost/libs/multi_index/test/test_key_extractors.cpp b/src/boost/libs/multi_index/test/test_key_extractors.cpp
new file mode 100644
index 000000000..31eec101f
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_key_extractors.cpp
@@ -0,0 +1,604 @@
+/* Boost.MultiIndex test for key extractors.
+ *
+ * Copyright 2003-2020 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_key_extractors.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp>
+#include "pre_multi_index.hpp"
+#include <boost/multi_index/key_extractors.hpp>
+#include <boost/ref.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <list>
+
+using namespace boost::multi_index;
+using namespace boost::tuples;
+
+struct test_class
+{
+ int int_member;
+ const int int_cmember;
+
+ bool bool_mem_fun_const()const{return true;}
+ bool bool_mem_fun(){return false;}
+ bool bool_mem_fun_volatile()volatile{return false;}
+ bool bool_mem_fun_cv()const volatile{return true;}
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+
+ bool bool_mem_fun_cref()const&{return true;}
+ bool bool_mem_fun_ref()&{return false;}
+ bool bool_mem_fun_vref()volatile&{return false;}
+ bool bool_mem_fun_cvref()const volatile&{return true;}
+
+#endif
+
+ static bool bool_global_fun(test_class){return true;}
+ static bool bool_global_fun_const_ref(const test_class&){return false;}
+ static bool bool_global_fun_ref(test_class&){return true;}
+
+ test_class(int i=0):int_member(i),int_cmember(i){}
+ test_class(int i,int j):int_member(i),int_cmember(j){}
+ test_class(const test_class& x):
+ int_member(x.int_member),int_cmember(x.int_cmember){}
+
+ test_class& operator=(const test_class& x)
+ {
+ int_member=x.int_member;
+ return *this;
+ }
+
+ bool operator<(const test_class& x)const
+ {
+ if(int_member<x.int_member)return true;
+ if(x.int_member<int_member)return false;
+ return int_cmember<x.int_cmember;
+ }
+
+ bool operator==(const test_class& x)const
+ {
+ return int_member==x.int_member&&int_cmember==x.int_cmember;
+ }
+};
+
+struct test_derived_class:test_class
+{
+ test_derived_class(int i=0):test_class(i){}
+ test_derived_class(int i,int j):test_class(i,j){}
+};
+
+typedef identity<test_class> idn;
+typedef identity<const test_class> cidn;
+typedef BOOST_MULTI_INDEX_MEMBER(test_class,int,int_member) key_m;
+typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_member) ckey_m;
+typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_cmember) key_cm;
+typedef BOOST_MULTI_INDEX_MEM_FUN(test_class,bool,bool_mem_fun) key_mf;
+typedef BOOST_MULTI_INDEX_CONST_MEM_FUN(
+ test_class,bool,bool_mem_fun_const) key_cmf;
+typedef volatile_mem_fun<
+ test_class,bool,&test_class::bool_mem_fun_volatile> key_vmf;
+typedef cv_mem_fun<test_class,bool,&test_class::bool_mem_fun_cv> key_cvmf;
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+
+typedef cref_mem_fun<
+ test_class,bool,&test_class::bool_mem_fun_cref> key_crmf;
+typedef ref_mem_fun<test_class,bool,&test_class::bool_mem_fun_ref> key_rmf;
+typedef vref_mem_fun<
+ test_class,bool,&test_class::bool_mem_fun_vref> key_vrmf;
+typedef cvref_mem_fun<
+ test_class,bool,&test_class::bool_mem_fun_cvref> key_cvrmf;
+
+#endif
+
+typedef global_fun<test_class,bool,&test_class::bool_global_fun> key_gf;
+typedef global_fun<
+ const test_class&,bool,
+ &test_class::bool_global_fun_const_ref
+ > key_gcrf;
+typedef global_fun<
+ test_class&,bool,
+ &test_class::bool_global_fun_ref
+ > key_grf;
+typedef composite_key<
+ test_class,
+ idn,
+ key_m,
+ key_cm,
+ key_cmf
+ > compkey;
+typedef composite_key<
+ test_class,
+ cidn,
+ ckey_m
+ > ccompkey;
+typedef composite_key<
+ boost::reference_wrapper<test_class>,
+ key_mf
+ > ccompw_key;
+
+#if !defined(BOOST_NO_SFINAE)
+/* testcases for problems with non-copyable classes reported at
+ * http://lists.boost.org/Archives/boost/2006/04/103065.php
+ */
+
+struct test_nc_class
+{
+ int int_member;
+ const int int_cmember;
+
+ bool bool_mem_fun_const()const{return true;}
+ bool bool_mem_fun(){return false;}
+
+ static bool bool_global_fun_const_ref(const test_nc_class&){return false;}
+ static bool bool_global_fun_ref(test_nc_class&){return true;}
+
+ test_nc_class(int i=0):int_member(i),int_cmember(i){}
+ test_nc_class(int i,int j):int_member(i),int_cmember(j){}
+
+ bool operator==(const test_nc_class& x)const
+ {
+ return int_member==x.int_member&&int_cmember==x.int_cmember;
+ }
+
+private:
+ test_nc_class(const test_nc_class&);
+ test_nc_class& operator=(const test_nc_class&);
+};
+
+struct test_nc_derived_class:test_nc_class
+{
+ test_nc_derived_class(int i=0):test_nc_class(i){}
+ test_nc_derived_class(int i,int j):test_nc_class(i,j){}
+};
+
+typedef identity<test_nc_class> nc_idn;
+typedef identity<const test_nc_class> nc_cidn;
+typedef BOOST_MULTI_INDEX_MEMBER(test_nc_class,int,int_member) nc_key_m;
+typedef BOOST_MULTI_INDEX_MEMBER(
+ test_nc_class,const int,int_member) nc_ckey_m;
+typedef BOOST_MULTI_INDEX_CONST_MEM_FUN(
+ test_nc_class,bool,bool_mem_fun_const) nc_key_cmf;
+typedef BOOST_MULTI_INDEX_MEM_FUN(
+ test_nc_class,bool,bool_mem_fun) nc_key_mf;
+typedef global_fun<
+ const test_nc_class&,bool,
+ &test_nc_class::bool_global_fun_const_ref
+ > nc_key_gcrf;
+typedef global_fun<
+ test_nc_class&,bool,
+ &test_nc_class::bool_global_fun_ref
+ > nc_key_grf;
+typedef composite_key<
+ test_nc_class,
+ nc_idn,
+ nc_key_m,
+ nc_ckey_m,
+ nc_key_cmf
+ > nc_compkey;
+#endif
+
+void test_key_extractors()
+{
+ idn id;
+ cidn cid;
+ key_m k_m;
+ ckey_m ck_m;
+ key_cm k_cm;
+ key_cmf k_cmf;
+ key_mf k_mf;
+ key_vmf k_vmf;
+ key_cvmf k_cvmf;
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ key_crmf k_crmf;
+ key_rmf k_rmf;
+ key_vrmf k_vrmf;
+ key_cvrmf k_cvrmf;
+#endif
+ key_gf k_gf;
+ key_gcrf k_gcrf;
+ key_grf k_grf;
+ compkey cmpk;
+ ccompkey ccmpk;
+ ccompw_key ccmpk_w;
+
+ test_derived_class td(-1,0);
+ const test_derived_class& ctdr=td;
+
+ test_class& tr=td;
+ const test_class& ctr=tr;
+
+ test_derived_class* tdp=&td;
+ const test_derived_class* ctdp=&ctdr;
+
+ test_class* tp=&tr;
+ const test_class* ctp=&tr;
+
+ test_class** tpp=&tp;
+ const test_class** ctpp=&ctp;
+
+ boost::scoped_ptr<test_class*> tap(new test_class*(tp));
+ boost::scoped_ptr<const test_class*> ctap(new const test_class*(ctp));
+
+ boost::reference_wrapper<test_class> tw(tr);
+ boost::reference_wrapper<const test_class> ctw(tr);
+
+ id(tr).int_member=0;
+ BOOST_TEST(id(tr).int_member==0);
+ BOOST_TEST(cid(tr).int_member==0);
+ BOOST_TEST(k_m(tr)==0);
+ BOOST_TEST(ck_m(tr)==0);
+ BOOST_TEST(cmpk(tr)==make_tuple(test_class(0,0),0,0,true));
+ BOOST_TEST(ccmpk(tr)==make_tuple(test_class(0,0),0));
+ BOOST_TEST(id(ctr).int_member==0);
+ BOOST_TEST(cid(ctr).int_member==0);
+ BOOST_TEST(k_m(ctr)==0);
+ BOOST_TEST(ck_m(ctr)==0);
+ BOOST_TEST(cmpk(ctr)==make_tuple(test_class(0,0),0,0,true));
+ BOOST_TEST(ccmpk(ctr)==make_tuple(test_class(0,0),0));
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(id(td).int_member==0);
+ BOOST_TEST(cid(td).int_member==0);
+ BOOST_TEST(k_m(td)==0);
+ BOOST_TEST(ck_m(td)==0);
+ BOOST_TEST(cmpk(td)==make_tuple(test_class(0,0),0,0,true));
+ BOOST_TEST(ccmpk(td)==make_tuple(test_class(0,0),0));
+ BOOST_TEST(id(ctdr).int_member==0);
+ BOOST_TEST(cid(ctdr).int_member==0);
+ BOOST_TEST(k_m(ctdr)==0);
+ BOOST_TEST(ck_m(ctdr)==0);
+ BOOST_TEST(cmpk(ctdr)==make_tuple(test_class(0,0),0,0,true));
+ BOOST_TEST(ccmpk(ctdr)==make_tuple(test_class(0,0),0));
+#endif
+
+ k_m(tr)=1;
+ BOOST_TEST(id(tp).int_member==1);
+ BOOST_TEST(cid(tp).int_member==1);
+ BOOST_TEST(k_m(tp)==1);
+ BOOST_TEST(ck_m(tp)==1);
+ BOOST_TEST(cmpk(tp)==make_tuple(test_class(1,0),1,0,true));
+ BOOST_TEST(ccmpk(tp)==make_tuple(test_class(1,0),1));
+ BOOST_TEST(cid(ctp).int_member==1);
+ BOOST_TEST(ck_m(ctp)==1);
+ BOOST_TEST(cmpk(ctp)==make_tuple(test_class(1,0),1,0,true));
+ BOOST_TEST(ccmpk(ctp)==make_tuple(test_class(1,0),1));
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(id(tdp).int_member==1);
+ BOOST_TEST(cid(tdp).int_member==1);
+ BOOST_TEST(k_m(tdp)==1);
+ BOOST_TEST(ck_m(tdp)==1);
+ BOOST_TEST(cmpk(tdp)==make_tuple(test_class(1,0),1,0,true));
+ BOOST_TEST(ccmpk(tdp)==make_tuple(test_class(1,0),1));
+ BOOST_TEST(cid(ctdp).int_member==1);
+ BOOST_TEST(ck_m(ctdp)==1);
+ BOOST_TEST(cmpk(ctdp)==make_tuple(test_class(1,0),1,0,true));
+ BOOST_TEST(ccmpk(ctdp)==make_tuple(test_class(1,0),1));
+#endif
+
+ k_m(tp)=2;
+ BOOST_TEST(id(tpp).int_member==2);
+ BOOST_TEST(cid(tpp).int_member==2);
+ BOOST_TEST(k_m(tpp)==2);
+ BOOST_TEST(ck_m(tpp)==2);
+ BOOST_TEST(cmpk(tpp)==make_tuple(test_class(2,0),2,0,true));
+ BOOST_TEST(ccmpk(tpp)==make_tuple(test_class(2,0),2));
+ BOOST_TEST(cid(ctpp).int_member==2);
+ BOOST_TEST(ck_m(ctpp)==2);
+ BOOST_TEST(cmpk(ctpp)==make_tuple(test_class(2,0),2,0,true));
+ BOOST_TEST(ccmpk(ctpp)==make_tuple(test_class(2,0),2));
+
+ k_m(tpp)=3;
+ BOOST_TEST(id(tap).int_member==3);
+ BOOST_TEST(cid(tap).int_member==3);
+ BOOST_TEST(k_m(tap)==3);
+ BOOST_TEST(ck_m(tap)==3);
+ BOOST_TEST(cmpk(tap)==make_tuple(test_class(3,0),3,0,true));
+ BOOST_TEST(ccmpk(tap)==make_tuple(test_class(3,0),3));
+ BOOST_TEST(cid(ctap).int_member==3);
+ BOOST_TEST(ck_m(ctap)==3);
+ BOOST_TEST(cmpk(ctap)==make_tuple(test_class(3,0),3,0,true));
+ BOOST_TEST(ccmpk(ctap)==make_tuple(test_class(3,0),3));
+
+ k_m(tap)=4;
+ BOOST_TEST(id(tw).int_member==4);
+ BOOST_TEST(cid(tw).int_member==4);
+ BOOST_TEST(k_m(tw)==4);
+ BOOST_TEST(ck_m(tw)==4);
+ BOOST_TEST(cmpk(tw)==make_tuple(test_class(4,0),4,0,true));
+ BOOST_TEST(ccmpk(tw)==make_tuple(test_class(4,0),4));
+
+ k_m(tw)=5;
+ BOOST_TEST(id(ctw).int_member==5);
+ BOOST_TEST(cid(ctw).int_member==5);
+ BOOST_TEST(k_m(ctw)==5);
+ BOOST_TEST(ck_m(ctw)==5);
+ BOOST_TEST(cmpk(ctw)==make_tuple(test_class(5,0),5,0,true));
+ BOOST_TEST(ccmpk(ctw)==make_tuple(test_class(5,0),5));
+
+ BOOST_TEST(k_cm(tr)==0);
+ BOOST_TEST(k_cm(ctr)==0);
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(k_cm(td)==0);
+ BOOST_TEST(k_cm(ctdr)==0);
+#endif
+
+ BOOST_TEST(k_cm(tp)==0);
+ BOOST_TEST(k_cm(ctp)==0);
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(k_cm(tdp)==0);
+ BOOST_TEST(k_cm(ctdp)==0);
+#endif
+
+ BOOST_TEST(k_cm(tpp)==0);
+ BOOST_TEST(k_cm(ctpp)==0);
+ BOOST_TEST(k_cm(tap)==0);
+ BOOST_TEST(k_cm(ctap)==0);
+
+ BOOST_TEST(k_cm(tw)==0);
+ BOOST_TEST(k_cm(ctw)==0);
+
+ BOOST_TEST(k_cmf(tr));
+ BOOST_TEST(k_cmf(ctr));
+ BOOST_TEST(k_cvmf(tr));
+ BOOST_TEST(k_cvmf(ctr));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(k_crmf(tr));
+ BOOST_TEST(k_crmf(ctr));
+ BOOST_TEST(k_cvrmf(tr));
+ BOOST_TEST(k_cvrmf(ctr));
+#endif
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(k_cmf(td));
+ BOOST_TEST(k_cmf(ctdr));
+ BOOST_TEST(k_cvmf(td));
+ BOOST_TEST(k_cvmf(ctdr));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(k_crmf(td));
+ BOOST_TEST(k_crmf(ctdr));
+ BOOST_TEST(k_cvrmf(td));
+ BOOST_TEST(k_cvrmf(ctdr));
+#endif
+#endif
+
+ BOOST_TEST(k_cmf(tp));
+ BOOST_TEST(k_cmf(ctp));
+ BOOST_TEST(k_cvmf(tp));
+ BOOST_TEST(k_cvmf(ctp));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(k_crmf(tp));
+ BOOST_TEST(k_crmf(ctp));
+ BOOST_TEST(k_cvrmf(tp));
+ BOOST_TEST(k_cvrmf(ctp));
+#endif
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(k_cmf(tdp));
+ BOOST_TEST(k_cmf(ctdp));
+ BOOST_TEST(k_cvmf(tdp));
+ BOOST_TEST(k_cvmf(ctdp));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(k_crmf(tdp));
+ BOOST_TEST(k_crmf(ctdp));
+ BOOST_TEST(k_cvrmf(tdp));
+ BOOST_TEST(k_cvrmf(ctdp));
+#endif
+#endif
+
+ BOOST_TEST(k_cmf(tpp));
+ BOOST_TEST(k_cmf(ctpp));
+ BOOST_TEST(k_cmf(tap));
+ BOOST_TEST(k_cmf(ctap));
+ BOOST_TEST(k_cvmf(tpp));
+ BOOST_TEST(k_cvmf(ctpp));
+ BOOST_TEST(k_cvmf(tap));
+ BOOST_TEST(k_cvmf(ctap));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(k_crmf(tpp));
+ BOOST_TEST(k_crmf(ctpp));
+ BOOST_TEST(k_crmf(tap));
+ BOOST_TEST(k_crmf(ctap));
+ BOOST_TEST(k_cvrmf(tpp));
+ BOOST_TEST(k_cvrmf(ctpp));
+ BOOST_TEST(k_cvrmf(tap));
+ BOOST_TEST(k_cvrmf(ctap));
+#endif
+
+ BOOST_TEST(k_cmf(tw));
+ BOOST_TEST(k_cmf(ctw));
+ BOOST_TEST(k_cvmf(tw));
+ BOOST_TEST(k_cvmf(ctw));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(k_crmf(tw));
+ BOOST_TEST(k_crmf(ctw));
+ BOOST_TEST(k_cvrmf(tw));
+ BOOST_TEST(k_cvrmf(ctw));
+#endif
+
+ BOOST_TEST(!k_mf(tr));
+ BOOST_TEST(!k_vmf(tr));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(!k_rmf(tr));
+ BOOST_TEST(!k_vrmf(tr));
+#endif
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(!k_mf(td));
+ BOOST_TEST(!k_vmf(td));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(!k_rmf(td));
+ BOOST_TEST(!k_vrmf(td));
+#endif
+#endif
+
+ BOOST_TEST(!k_mf(tp));
+ BOOST_TEST(!k_vmf(tp));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(!k_rmf(tp));
+ BOOST_TEST(!k_vrmf(tp));
+#endif
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(!k_mf(tdp));
+ BOOST_TEST(!k_vmf(tdp));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(!k_rmf(tdp));
+ BOOST_TEST(!k_vrmf(tdp));
+#endif
+#endif
+
+ BOOST_TEST(!k_mf(tpp));
+ BOOST_TEST(!k_mf(tap));
+ BOOST_TEST(!k_mf(tw));
+ BOOST_TEST(!k_vmf(tpp));
+ BOOST_TEST(!k_vmf(tap));
+ BOOST_TEST(!k_vmf(tw));
+
+#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
+ BOOST_TEST(!k_rmf(tpp));
+ BOOST_TEST(!k_rmf(tap));
+ BOOST_TEST(!k_rmf(tw));
+ BOOST_TEST(!k_vrmf(tpp));
+ BOOST_TEST(!k_vrmf(tap));
+ BOOST_TEST(!k_vrmf(tw));
+#endif
+
+ BOOST_TEST(k_gf(tr));
+ BOOST_TEST(k_gf(ctr));
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(k_gf(td));
+ BOOST_TEST(k_gf(ctdr));
+#endif
+
+ BOOST_TEST(k_gf(tp));
+ BOOST_TEST(k_gf(ctp));
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(k_gf(tdp));
+ BOOST_TEST(k_gf(ctdp));
+#endif
+
+ BOOST_TEST(k_gf(tpp));
+ BOOST_TEST(k_gf(ctpp));
+ BOOST_TEST(k_gf(tap));
+ BOOST_TEST(k_gf(ctap));
+
+ BOOST_TEST(k_gf(tw));
+ BOOST_TEST(k_gf(ctw));
+
+ BOOST_TEST(!k_gcrf(tr));
+ BOOST_TEST(!k_gcrf(ctr));
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(!k_gcrf(td));
+ BOOST_TEST(!k_gcrf(ctdr));
+#endif
+
+ BOOST_TEST(!k_gcrf(tp));
+ BOOST_TEST(!k_gcrf(ctp));
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(!k_gcrf(tdp));
+ BOOST_TEST(!k_gcrf(ctdp));
+#endif
+
+ BOOST_TEST(!k_gcrf(tpp));
+ BOOST_TEST(!k_gcrf(ctpp));
+ BOOST_TEST(!k_gcrf(tap));
+ BOOST_TEST(!k_gcrf(ctap));
+
+ BOOST_TEST(!k_gcrf(tw));
+ BOOST_TEST(!k_gcrf(ctw));
+
+ BOOST_TEST(k_grf(tr));
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(k_grf(td));
+#endif
+
+ BOOST_TEST(k_grf(tp));
+
+#if !defined(BOOST_NO_SFINAE)
+ BOOST_TEST(k_grf(tdp));
+#endif
+
+ BOOST_TEST(k_grf(tpp));
+ BOOST_TEST(k_grf(tap));
+ BOOST_TEST(k_grf(tw));
+
+ BOOST_TEST(ccmpk_w(tw)==make_tuple(false));
+
+#if !defined(BOOST_NO_SFINAE)
+/* testcases for problems with non-copyable classes reported at
+ * http://lists.boost.org/Archives/boost/2006/04/103065.php
+ */
+
+ nc_idn nc_id;
+ nc_cidn nc_cid;
+ nc_key_m nc_k_m;
+ nc_ckey_m nc_ck_m;
+ nc_key_cmf nc_k_cmf;
+ nc_key_mf nc_k_mf;
+ nc_key_gcrf nc_k_gcrf;
+ nc_key_grf nc_k_grf;
+ nc_compkey nc_cmpk;
+
+ test_nc_derived_class nc_td(-1,0);
+
+ nc_id(nc_td).int_member=0;
+ BOOST_TEST(nc_id(nc_td).int_member==0);
+ BOOST_TEST(nc_cid(nc_td).int_member==0);
+
+ nc_k_m(&nc_td)=1;
+ BOOST_TEST(nc_k_m(&nc_td)==1);
+ BOOST_TEST(nc_ck_m(&nc_td)==1);
+
+ BOOST_TEST(nc_k_cmf(nc_td));
+ BOOST_TEST(!nc_k_mf(nc_td));
+
+ BOOST_TEST(!nc_k_gcrf(nc_td));
+ BOOST_TEST(nc_k_grf(nc_td));
+
+ test_nc_class nc_t(1,0);
+ BOOST_TEST(nc_cmpk(nc_td)==make_tuple(boost::cref(nc_t),1,1,true));
+#endif
+
+ std::list<test_class> tl;
+ for(int i=0;i<20;++i)tl.push_back(test_class(i));
+
+ int j=0;
+ for(std::list<test_class>::iterator it=tl.begin();it!=tl.end();++it){
+ BOOST_TEST(k_m(it)==j);
+ BOOST_TEST(k_cm(it)==j);
+ BOOST_TEST(k_cmf(it));
+ BOOST_TEST(!k_mf(it));
+ BOOST_TEST(k_gf(it));
+ BOOST_TEST(!k_gcrf(it));
+ BOOST_TEST(k_grf(it));
+ BOOST_TEST(cmpk(it)==make_tuple(test_class(j),j,j,true));
+ BOOST_TEST(ccmpk(it)==make_tuple(test_class(j),j));
+ ++j;
+ }
+}
diff --git a/src/boost/libs/multi_index/test/test_key_extractors.hpp b/src/boost/libs/multi_index/test/test_key_extractors.hpp
new file mode 100644
index 000000000..cee8ac099
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_key_extractors.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for key extractors.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_key_extractors();
diff --git a/src/boost/libs/multi_index/test/test_key_extractors_main.cpp b/src/boost/libs/multi_index/test/test_key_extractors_main.cpp
new file mode 100644
index 000000000..3887daff9
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_key_extractors_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for key extractors.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_key_extractors.hpp"
+
+int main()
+{
+ test_key_extractors();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_key_main.cpp b/src/boost/libs/multi_index/test/test_key_main.cpp
new file mode 100644
index 000000000..a4d012a85
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_key_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for terse key specification syntax.
+ *
+ * Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_key.hpp"
+
+int main()
+{
+ test_key();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_list_ops.cpp b/src/boost/libs/multi_index/test/test_list_ops.cpp
new file mode 100644
index 000000000..e67fda7f8
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_list_ops.cpp
@@ -0,0 +1,275 @@
+/* Boost.MultiIndex test for standard list operations.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_list_ops.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <vector>
+#include <boost/detail/lightweight_test.hpp>
+#include "pre_multi_index.hpp"
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
+
+using namespace boost::multi_index;
+
+#undef CHECK_EQUAL
+#define CHECK_EQUAL(p,check_seq) \
+{\
+ int v[]={BOOST_PP_SEQ_ENUM(check_seq)};\
+ std::size_t size_v=sizeof(v)/sizeof(int);\
+ BOOST_TEST(std::size_t(std::distance((p).begin(),(p).end()))==size_v);\
+ BOOST_TEST(std::equal((p).begin(),(p).end(),&v[0]));\
+}
+
+#undef CHECK_VOID_RANGE
+#define CHECK_VOID_RANGE(p) BOOST_TEST((p).first==(p).second)
+
+struct is_even
+{
+ bool operator()(int x)const{return x%2==0;}
+};
+
+template <int m>
+struct same_integral_div
+{
+ bool operator()(int x,int y)const{return (x/m)==(y/m);}
+};
+
+template <typename Container,typename Compare>
+bool is_sorted(
+ const Container& c,const Compare& comp=Compare())
+{
+ if(c.empty())return true;
+
+ typedef typename Container::const_iterator const_iterator;
+ for(const_iterator it(c.begin());;){
+ const_iterator it2=it;
+ ++it2;
+ if(it2==c.end())return true;
+ if(comp(*it2,*it))return false;
+ it=it2;
+ }
+}
+
+#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+/* The "ISO C++ Template Parser" option makes CW8.3 incorrectly fail at
+ * expressions of the form sizeof(x) where x is an array local to a
+ * template function.
+ */
+
+#pragma parse_func_templ off
+#endif
+
+template<typename Sequence>
+static void test_list_ops_unique_seq()
+{
+ typedef typename nth_index<Sequence,1>::type sequenced_index;
+
+ Sequence ss,ss2;
+ sequenced_index &si=get<1>(ss),&si2=get<1>(ss2);
+
+ si.push_front(0); /* 0 */
+ si.push_front(4); /* 40 */
+ ss.insert(2); /* 402 */
+ ss.insert(5); /* 4025 */
+ si.push_front(3); /* 34025 */
+ si.push_back(6); /* 340256 */
+ si.push_back(1); /* 3402561 */
+ si.insert(project<1>(ss,ss.find(2)),8); /* 34082561 */
+ si2=si;
+
+ CHECK_EQUAL(si,(3)(4)(0)(8)(2)(5)(6)(1));
+
+ si.remove(8);
+ CHECK_EQUAL(si,(3)(4)(0)(2)(5)(6)(1));
+
+ si.remove_if(is_even());
+
+ CHECK_EQUAL(si,(3)(5)(1));
+
+ si.splice(si.end(),si2);
+ CHECK_EQUAL(si,(3)(5)(1)(4)(0)(8)(2)(6));
+ CHECK_EQUAL(si2,(3)(5)(1));
+
+ si.splice(project<1>(ss,ss.find(4)),si,project<1>(ss,ss.find(8)));
+ CHECK_EQUAL(si,(3)(5)(1)(8)(4)(0)(2)(6));
+ si2.clear();
+ si2.splice(si2.begin(),si,si.begin());
+
+ si.splice(si.end(),si2,si2.begin());
+ CHECK_EQUAL(si,(5)(1)(8)(4)(0)(2)(6)(3));
+ BOOST_TEST(si2.empty());
+
+ si2.splice(si2.end(),si,project<1>(ss,ss.find(0)),project<1>(ss,ss.find(6)));
+ CHECK_EQUAL(si,(5)(1)(8)(4)(6)(3));
+ CHECK_EQUAL(si2,(0)(2));
+
+ si.splice(si.begin(),si,si.begin(),si.begin());
+ CHECK_EQUAL(si,(5)(1)(8)(4)(6)(3));
+
+ si.splice(project<1>(ss,ss.find(8)),si,project<1>(ss,ss.find(4)),si.end());
+ CHECK_EQUAL(si,(5)(1)(4)(6)(3)(8));
+
+ si.sort();
+ si2.sort();
+ BOOST_TEST(is_sorted(si,std::less<int>()));
+ BOOST_TEST(is_sorted(si2,std::less<int>()));
+
+ si.merge(si2);
+ BOOST_TEST(is_sorted(si,std::less<int>()));
+ BOOST_TEST(si2.empty());
+
+ {
+ Sequence ss3(ss);
+ sequenced_index &si3=get<1>(ss3);
+
+ si3.sort(std::greater<int>());
+ si.reverse();
+ BOOST_TEST(si==si3);
+ }
+
+ si2.splice(si2.end(),si,project<1>(ss,ss.find(6)),project<1>(ss,ss.find(3)));
+ CHECK_EQUAL(si2,(6)(5)(4));
+
+ si.merge(si2,std::greater<int>());
+ BOOST_TEST(is_sorted(si,std::greater<int>()));
+ BOOST_TEST(si2.empty());
+
+ /* testcase for bug reported at
+ * https://svn.boost.org/trac/boost/ticket/3076
+ */
+ {
+ Sequence ss3;
+ sequenced_index &si3=get<1>(ss3);
+ si3.sort();
+ }
+}
+
+template<typename Sequence>
+static void test_list_ops_non_unique_seq()
+{
+ typedef typename Sequence::iterator iterator;
+
+ Sequence ss;
+ for(int i=0;i<10;++i){
+ ss.push_back(i);
+ ss.push_back(i);
+ ss.push_front(i);
+ ss.push_front(i);
+ } /* 9988776655443322110000112233445566778899 */
+
+ ss.unique();
+ CHECK_EQUAL(
+ ss,
+ (9)(8)(7)(6)(5)(4)(3)(2)(1)(0)
+ (1)(2)(3)(4)(5)(6)(7)(8)(9));
+
+ iterator it=ss.begin();
+ for(int j=0;j<9;++j,++it){} /* it points to o */
+
+ Sequence ss2;
+ ss2.splice(ss2.end(),ss,ss.begin(),it);
+ ss2.reverse();
+ ss.merge(ss2);
+ CHECK_EQUAL(
+ ss,
+ (0)(1)(1)(2)(2)(3)(3)(4)(4)(5)(5)
+ (6)(6)(7)(7)(8)(8)(9)(9));
+
+ ss.unique(same_integral_div<3>());
+ CHECK_EQUAL(ss,(0)(3)(6)(9));
+
+ ss.unique(same_integral_div<1>());
+ CHECK_EQUAL(ss,(0)(3)(6)(9));
+
+ /* testcases for bugs reported at
+ * http://lists.boost.org/boost-users/2006/09/22604.php
+ */
+ {
+ Sequence ss_,ss2_;
+ ss_.push_back(0);
+ ss2_.push_back(0);
+ ss_.splice(ss_.end(),ss2_,ss2_.begin());
+ CHECK_EQUAL(ss_,(0)(0));
+ BOOST_TEST(ss2_.empty());
+
+ ss_.clear();
+ ss2_.clear();
+ ss_.push_back(0);
+ ss2_.push_back(0);
+ ss_.splice(ss_.end(),ss2_,ss2_.begin(),ss2_.end());
+ CHECK_EQUAL(ss_,(0)(0));
+ BOOST_TEST(ss2_.empty());
+
+ ss_.clear();
+ ss2_.clear();
+ ss_.push_back(0);
+ ss2_.push_back(0);
+ ss_.merge(ss2_);
+ CHECK_EQUAL(ss_,(0)(0));
+ BOOST_TEST(ss2_.empty());
+
+ typedef typename Sequence::value_type value_type;
+ ss_.clear();
+ ss2_.clear();
+ ss_.push_back(0);
+ ss2_.push_back(0);
+ ss_.merge(ss2_,std::less<value_type>());
+ CHECK_EQUAL(ss_,(0)(0));
+ BOOST_TEST(ss2_.empty());
+ }
+}
+
+#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+#pragma parse_func_templ reset
+#endif
+
+void test_list_ops()
+{
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ordered_unique<identity<int> >,
+ sequenced<>
+ >
+ > sequenced_set;
+
+ test_list_ops_unique_seq<sequenced_set>();
+
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ordered_unique<identity<int> >,
+ random_access<>
+ >
+ > random_access_set;
+
+ test_list_ops_unique_seq<random_access_set>();
+
+ typedef multi_index_container<
+ int,
+ indexed_by<sequenced<> >
+ > int_list;
+
+ test_list_ops_non_unique_seq<int_list>();
+
+ typedef multi_index_container<
+ int,
+ indexed_by<random_access<> >
+ > int_vector;
+
+ test_list_ops_non_unique_seq<int_vector>();
+}
diff --git a/src/boost/libs/multi_index/test/test_list_ops.hpp b/src/boost/libs/multi_index/test/test_list_ops.hpp
new file mode 100644
index 000000000..4547c88a6
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_list_ops.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for standard list operations.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_list_ops();
diff --git a/src/boost/libs/multi_index/test/test_list_ops_main.cpp b/src/boost/libs/multi_index/test/test_list_ops_main.cpp
new file mode 100644
index 000000000..ce79320a0
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_list_ops_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for standard list operations.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_list_ops.hpp"
+
+int main()
+{
+ test_list_ops();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_modifiers.cpp b/src/boost/libs/multi_index/test/test_modifiers.cpp
new file mode 100644
index 000000000..ea677ae15
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_modifiers.cpp
@@ -0,0 +1,581 @@
+/* Boost.MultiIndex test for modifier memfuns.
+ *
+ * Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_modifiers.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/move/core.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/shared_ptr.hpp>
+#include <iterator>
+#include <vector>
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+
+using namespace boost::multi_index;
+
+struct non_copyable_int
+{
+ explicit non_copyable_int(int n_):n(n_){}
+ non_copyable_int(BOOST_RV_REF(non_copyable_int) x):n(x.n){x.n=0;}
+ non_copyable_int& operator=(BOOST_RV_REF(non_copyable_int) x)
+ {
+ n=x.n;
+ x.n=0;
+ return *this;
+ }
+
+ int n;
+private:
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(non_copyable_int)
+};
+
+class always_one
+{
+public:
+ always_one():n(1){}
+ ~always_one(){n=0;}
+
+ int get()const{return n;}
+
+private:
+ int n;
+};
+
+inline bool operator==(const always_one& x,const always_one& y)
+{
+ return x.get()==y.get();
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+#endif
+
+inline std::size_t hash_value(const always_one& x)
+{
+ return static_cast<std::size_t>(x.get());
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace boost */
+#endif
+
+class linked_object
+{
+ struct impl:boost::enable_shared_from_this<impl>
+ {
+ typedef boost::shared_ptr<const impl> ptr;
+
+ impl(int n_,ptr next_=ptr()):n(n_),next(next_){}
+
+ int n;
+ ptr next;
+ };
+
+ typedef multi_index_container<
+ impl,
+ indexed_by<
+
+#if BOOST_WORKAROUND(__IBMCPP__,BOOST_TESTED_AT(1010))
+ ordered_unique<member<impl,int,&linked_object::impl::n> >,
+ hashed_non_unique<member<impl,int,&linked_object::impl::n> >,
+#else
+ ordered_unique<member<impl,int,&impl::n> >,
+ hashed_non_unique<member<impl,int,&impl::n> >,
+#endif
+
+ sequenced<>,
+ random_access<>
+ >
+ > impl_repository_t;
+
+ static impl_repository_t impl_repository;
+
+public:
+ linked_object(int n):pimpl(init(impl(n))){}
+ linked_object(int n,const linked_object& x):pimpl(init(impl(n,x.pimpl))){}
+
+private:
+ impl::ptr init(const impl& x)
+ {
+ std::pair<impl_repository_t::iterator,bool> p=impl_repository.insert(x);
+ if(p.second)return impl::ptr(&*p.first,&erase_impl);
+ else return p.first->shared_from_this();
+ }
+
+ static void erase_impl(const impl* p)
+ {
+ impl_repository.erase(p->n);
+ }
+
+ impl::ptr pimpl;
+};
+
+linked_object::impl_repository_t linked_object::impl_repository;
+
+struct tempvalue_iterator:
+ boost::iterator_facade<
+ tempvalue_iterator,int,boost::forward_traversal_tag,int>
+{
+ tempvalue_iterator(int n_):n(n_){}
+
+ void increment(){++n;}
+ bool equal(const tempvalue_iterator& x)const{return n==x.n;}
+ int dereference()const{return n;}
+
+ int n;
+};
+
+struct change_int
+{
+ change_int(int n):n(n){}
+
+ void operator()(int& x)const{x=n;}
+
+ int n;
+};
+
+#if !(defined BOOST_NO_EXCEPTIONS)
+struct change_int_and_throw
+{
+ change_int_and_throw(int n):n(n){}
+
+ void operator()(int& x)const{x=n;throw 0;}
+
+ int n;
+};
+#endif
+
+void test_modifiers()
+{
+ employee_set es;
+ employee_set_by_name& i1=get<name>(es);
+ employee_set_by_age& i2=get<age>(es);
+ employee_set_as_inserted& i3=get<as_inserted>(es);
+ employee_set_by_ssn& i4=get<ssn>(es);
+ employee_set_randomly& i5=get<randomly>(es);
+
+ es.insert(employee(0,"Joe",31,1123));
+ BOOST_TEST(es.emplace(0,"Joe",31,1123).second==false);
+ BOOST_TEST(i1.insert(employee(0,"Joe Jr.",5,2563)).second==false);
+ BOOST_TEST(i2.emplace_hint(i2.end(),1,"Victor",5,1123)->name!="Victor");
+ BOOST_TEST(i3.insert(i3.begin(),employee(1,"Victor",5,1123)).second
+ ==false);
+ BOOST_TEST(i3.push_front(employee(0,"Joe Jr.",5,2563)).second==false);
+ BOOST_TEST(i3.push_back(employee(0,"Joe Jr.",5,2563)).second==false);
+ BOOST_TEST(i5.emplace_front(1,"Victor",5,1123).second==false);
+ BOOST_TEST(i5.emplace_back(1,"Victor",5,1123).second==false);
+
+ employee_set_by_name::iterator it1=i1.find("Joe");
+ i1.insert(it1,employee(1,"Joe Jr.",5,2563));
+ BOOST_TEST(es.size()==2);
+
+ employee_set_by_age::iterator it2=i2.find(31);
+ i2.insert(it2,employee(2,"Grandda Joe",64,7881));
+ BOOST_TEST(es.size()==3);
+
+ employee_set_as_inserted::iterator it3=i3.begin();
+ i3.insert(it3,100,employee(3,"Judy",39,6201));
+ BOOST_TEST((--it3)->ssn==6201);
+ BOOST_TEST(es.size()==4);
+
+ employee_set_randomly::iterator it5=i5.begin();
+ i5.insert(it5,100,employee(4,"Jill",52,3379));
+ BOOST_TEST(i5.begin()->age==52);
+ BOOST_TEST(es.size()==5);
+
+ es.erase(employee(1,"Joe Jr.",5,2563));
+ BOOST_TEST(i3.size()==4&&i5.size()==4);
+
+ BOOST_TEST(i1.erase("Judy")==1);
+ BOOST_TEST(es.size()==3&&i2.size()==3);
+
+ BOOST_TEST(i2.erase(it2)->age==52);
+ BOOST_TEST(i3.size()==2&&i4.size()==2);
+
+ i3.pop_front();
+ BOOST_TEST(i1.size()==1&&i2.size()==1);
+
+ i5.erase(i5.begin(),i5.end());
+ BOOST_TEST(es.size()==0&&i3.size()==0);
+
+ i5.emplace(i5.end(),0,"Joe",31,1123);
+ BOOST_TEST(i1.erase(i1.begin())==i1.end());
+ BOOST_TEST(i1.size()==0);
+
+ i1.emplace(0,"Joe",31,1123);
+ i3.emplace(i3.begin(),1,"Jack",31,5032);
+ i4.emplace_hint(i4.end(),2,"James",31,3847);
+ BOOST_TEST(i2.erase(31)==3);
+ BOOST_TEST(i2.size()==0);
+
+ i3.emplace_front(1,"Jack",31,5032);
+ i3.emplace_back(0,"Joe",31,1123);
+ BOOST_TEST(i3.front()==employee(1,"Jack",31,5032));
+ BOOST_TEST(i3.back()==employee(0,"Joe",31,1123));
+
+ i3.pop_back();
+ BOOST_TEST(i3.back()==employee(1,"Jack",31,5032));
+ BOOST_TEST(es.size()==1);
+
+ i3.pop_front();
+ BOOST_TEST(es.size()==0);
+
+ i5.push_back(employee(1,"Jack",31,5032));
+ i5.push_front(employee(0,"Joe",31,1123));
+ i5.insert(i5.end()-1,employee(2,"Grandda Joe",64,7881));
+ BOOST_TEST(i5.back()==employee(1,"Jack",31,5032));
+ BOOST_TEST(i5.front()==employee(0,"Joe",31,1123));
+ BOOST_TEST(i5[0]==i5.front()&&i5.at(0)==i5.front());
+ BOOST_TEST(i5[i5.size()-1]==i5.back()&&i5.at(i5.size()-1)==i5.back());
+
+ i5.pop_front();
+ BOOST_TEST(i5.back()==employee(1,"Jack",31,5032));
+ BOOST_TEST(i5.front()==employee(2,"Grandda Joe",64,7881));
+ BOOST_TEST(es.size()==2);
+
+ i5.pop_back();
+ BOOST_TEST(i5.back()==employee(2,"Grandda Joe",64,7881));
+ BOOST_TEST(i5.front()==i5.front());
+ BOOST_TEST(es.size()==1);
+
+ i5.erase(i5.begin());
+ BOOST_TEST(es.size()==0);
+
+ std::vector<employee> ve;
+ ve.push_back(employee(3,"Anna",31,5388));
+ ve.push_back(employee(1,"Rachel",27,9012));
+ ve.push_back(employee(2,"Agatha",40,1520));
+
+ i1.insert(ve.begin(),ve.end());
+ BOOST_TEST(i2.size()==3);
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ i1.insert({{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
+ BOOST_TEST(i2.size()==5);
+#endif
+
+ BOOST_TEST(i2.erase(i2.begin(),i2.end())==i2.end());
+ BOOST_TEST(es.size()==0);
+
+ i2.insert(ve.begin(),ve.end());
+ BOOST_TEST(i3.size()==3);
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ i2.insert({{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
+ BOOST_TEST(i3.size()==5);
+#endif
+
+ BOOST_TEST(*(i3.erase(i3.begin()))==employee(1,"Rachel",27,9012));
+ BOOST_TEST(i3.erase(i3.begin(),i3.end())==i3.end());
+ BOOST_TEST(es.size()==0);
+
+ i3.insert(i3.end(),ve.begin(),ve.end());
+ BOOST_TEST(es.size()==3);
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ i3.insert(i3.begin(),{{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
+ BOOST_TEST(i3.front().name=="Vanessa");
+ BOOST_TEST(i4.size()==5);
+#endif
+
+ BOOST_TEST(i4.erase(9012)==1);
+ i4.erase(i4.begin());
+ BOOST_TEST(i4.erase(i4.begin(),i4.end())==i4.end());
+
+ i4.insert(ve.begin(),ve.end());
+ BOOST_TEST(i5.size()==3);
+
+ BOOST_TEST(i5.erase(i5.begin(),i5.end())==i5.end());
+ BOOST_TEST(es.size()==0);
+
+ i5.insert(i5.begin(),ve.begin(),ve.end());
+ BOOST_TEST(i1.size()==3);
+
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ i5.insert(i5.end(),{{4,"Vanessa",20,9236},{5,"Penelope",55,2358}});
+ BOOST_TEST(i5.back().name=="Penelope");
+ BOOST_TEST(i1.size()==5);
+#endif
+
+ BOOST_TEST(es.erase(es.begin(),es.end())==es.end());
+ BOOST_TEST(i2.size()==0);
+
+ es.insert(employee(0,"Joe",31,1123));
+ es.insert(employee(1,"Robert",27,5601));
+ es.insert(employee(2,"John",40,7889));
+ es.insert(employee(3,"Albert",20,9012));
+ es.insert(employee(4,"John",57,1002));
+
+ employee_set es_backup(es);
+
+ employee_set es2;
+ es2.insert(employee(3,"Anna",31,5388));
+ es2.insert(employee(1,"Rachel",27,9012));
+ es2.insert(employee(2,"Agatha",40,1520));
+
+ employee_set es2_backup(es2);
+
+ i1.swap(get<1>(es2));
+ BOOST_TEST(es==es2_backup&&es2==es_backup);
+
+ i2.swap(get<2>(es2));
+ BOOST_TEST(es==es_backup&&es2==es2_backup);
+
+ i3.swap(get<3>(es2));
+ BOOST_TEST(es==es2_backup&&es2==es_backup);
+
+ i4.swap(get<4>(es2));
+ BOOST_TEST(es==es_backup&&es2==es2_backup);
+
+ i5.swap(get<5>(es2));
+ BOOST_TEST(es==es2_backup&&es2==es_backup);
+
+#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
+ ::boost::multi_index::detail::swap(i1,get<1>(es2));
+#else
+ using std::swap;
+ swap(i1,get<1>(es2));
+#endif
+
+ BOOST_TEST(es==es_backup&&es2==es2_backup);
+
+#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
+ ::boost::multi_index::detail::swap(i2,get<2>(es2));
+#else
+ using std::swap;
+ swap(i2,get<2>(es2));
+#endif
+
+ BOOST_TEST(es==es2_backup&&es2==es_backup);
+
+#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
+ ::boost::multi_index::detail::swap(i3,get<3>(es2));
+#else
+ using std::swap;
+ swap(i3,get<3>(es2));
+#endif
+
+ BOOST_TEST(es==es_backup&&es2==es2_backup);
+
+#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
+ ::boost::multi_index::detail::swap(i4,get<4>(es2));
+#else
+ using std::swap;
+ swap(i4,get<4>(es2));
+#endif
+
+ BOOST_TEST(es==es2_backup&&es2==es_backup);
+
+#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
+ ::boost::multi_index::detail::swap(i5,get<5>(es2));
+#else
+ using std::swap;
+ swap(i5,get<5>(es2));
+#endif
+
+ BOOST_TEST(es==es_backup&&es2==es2_backup);
+
+ i3.clear();
+ BOOST_TEST(i3.size()==0);
+
+ es=es2;
+ i4.clear();
+ BOOST_TEST(i4.size()==0);
+
+ es=es2;
+ i5.clear();
+ BOOST_TEST(i5.size()==0);
+
+ es2.clear();
+ BOOST_TEST(es2.size()==0);
+
+ /* non-copyable elements */
+
+ multi_index_container<
+ non_copyable_int,
+ indexed_by<
+ ordered_non_unique<member<non_copyable_int,int,&non_copyable_int::n> >,
+ hashed_non_unique<member<non_copyable_int,int,&non_copyable_int::n> >,
+ sequenced<>,
+ random_access<>
+ >
+ > ncic,ncic2;
+
+ ncic.emplace(1);
+ get<1>(ncic).emplace(1);
+ get<2>(ncic).emplace_back(1);
+ get<3>(ncic).emplace_back(1);
+
+ non_copyable_int nci(1);
+ ncic.insert(boost::move(nci));
+ BOOST_TEST(nci.n==0);
+
+ nci.n=1;
+ get<1>(ncic).insert(boost::move(nci));
+ BOOST_TEST(nci.n==0);
+
+ nci.n=1;
+ get<2>(ncic).push_back(boost::move(nci));
+ BOOST_TEST(nci.n==0);
+
+ nci.n=1;
+ get<3>(ncic).push_back(boost::move(nci));
+ BOOST_TEST(nci.n==0);
+
+ std::vector<int> vi(4,1);
+ const std::vector<int>& cvi=vi;
+ ncic.insert(vi.begin(),vi.end());
+ ncic.insert(cvi.begin(),cvi.end());
+ get<2>(ncic).insert(get<2>(ncic).begin(),vi.begin(),vi.end());
+ get<2>(ncic).insert(get<2>(ncic).begin(),cvi.begin(),cvi.end());
+
+ BOOST_TEST(ncic.count(1)==24);
+
+ ncic.swap(ncic2);
+ BOOST_TEST(ncic.empty());
+ BOOST_TEST(ncic2.count(1)==24);
+
+ /* testcase for problem reported at
+ * http://lists.boost.org/boost-users/2006/12/24215.php
+ */
+
+ multi_index_container<
+ always_one,
+ indexed_by<
+ hashed_non_unique<identity<always_one> >
+ >
+ > aoc;
+
+ aoc.insert(always_one());
+ aoc.insert(always_one());
+ aoc.erase(*(aoc.begin()));
+ BOOST_TEST(aoc.empty());
+
+ /* Testcases for compliance with "as close to hint as possible"
+ * proposed behavior for associative containers:
+ * http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233
+ * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html
+ */
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ordered_non_unique<identity<int> >
+ >
+ > int_non_unique_container;
+
+ int_non_unique_container c;
+ c.insert(0);c.insert(0);
+ c.insert(1);c.insert(1);
+ c.insert(2);c.insert(2);
+
+ BOOST_TEST(std::distance(c.begin(),c.insert(c.begin(),1))==2);
+ BOOST_TEST(std::distance(c.begin(),c.insert(boost::next(c.begin()),1))==2);
+ BOOST_TEST(std::distance(c.begin(),c.insert(c.lower_bound(1),1))==2);
+ BOOST_TEST(
+ std::distance(c.begin(),c.insert(boost::next(c.lower_bound(1)),1))==3);
+ BOOST_TEST(std::distance(c.begin(),c.insert(c.upper_bound(1),1))==8);
+ BOOST_TEST(std::distance(c.begin(),c.insert(boost::prior(c.end()),1))==9);
+ BOOST_TEST(std::distance(c.begin(),c.insert(c.end(),1))==10);
+
+ /* testcase for erase() reentrancy */
+ {
+ linked_object o1(1);
+ linked_object o2(2,o1);
+ o1=o2;
+ }
+
+ /* testcases for bug reported at
+ * https://svn.boost.org/trac/boost/ticket/9665
+ */
+
+ {
+ multi_index_container<
+ int,
+ indexed_by<hashed_unique<identity<int> > >
+ > hc;
+ hc.insert(tempvalue_iterator(0),tempvalue_iterator(10));
+ BOOST_TEST(hc.size()==10);
+
+ multi_index_container<
+ int,
+ indexed_by<ordered_unique<identity<int> > >
+ > oc;
+ oc.insert(tempvalue_iterator(0),tempvalue_iterator(10));
+ BOOST_TEST(oc.size()==10);
+ }
+
+ /* testcases for https://svn.boost.org/trac10/ticket/12542 */
+
+ {
+ multi_index_container<
+ int,
+ indexed_by<
+ ordered_unique<identity<int> >,
+ hashed_unique<identity<int> >
+ >
+ > ohc;
+
+#if !(defined BOOST_NO_EXCEPTIONS)
+ ohc.insert(0);
+ ohc.insert(1);
+
+ try{
+ ohc.modify_key(ohc.begin(),change_int_and_throw(1));
+ }
+ catch(int){}
+ BOOST_TEST(ohc.size()==1);
+ ohc.clear();
+
+ ohc.insert(0);
+ ohc.insert(1);
+
+ try{
+ ohc.modify_key(ohc.begin(),change_int_and_throw(1),change_int(0));
+ }
+ catch(int){}
+ BOOST_TEST(ohc.size()==1);
+ ohc.clear();
+
+ ohc.insert(0);
+ ohc.insert(1);
+
+ try{
+ ohc.modify_key(
+ ohc.begin(),change_int_and_throw(1),change_int_and_throw(0));
+ }
+ catch(int){}
+ BOOST_TEST(ohc.size()==1);
+ ohc.clear();
+
+ ohc.insert(0);
+ ohc.insert(1);
+
+ try{
+ ohc.modify_key(ohc.begin(),change_int(1),change_int_and_throw(0));
+ }
+ catch(int){}
+ BOOST_TEST(ohc.size()==1);
+ ohc.clear();
+#endif
+
+ ohc.insert(0);
+ ohc.insert(1);
+
+ ohc.modify_key(ohc.begin(),change_int(1),change_int(1));
+ BOOST_TEST(ohc.size()==1);
+ ohc.clear();
+ }
+}
diff --git a/src/boost/libs/multi_index/test/test_modifiers.hpp b/src/boost/libs/multi_index/test/test_modifiers.hpp
new file mode 100644
index 000000000..c5d28f818
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_modifiers.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for modifier memfuns.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_modifiers();
diff --git a/src/boost/libs/multi_index/test/test_modifiers_main.cpp b/src/boost/libs/multi_index/test/test_modifiers_main.cpp
new file mode 100644
index 000000000..795289f87
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_modifiers_main.cpp
@@ -0,0 +1,20 @@
+/* Boost.MultiIndex test for modifier memfuns.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_modifiers.hpp"
+
+int main()
+{
+ test_modifiers();
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/multi_index/test/test_mpl_ops.cpp b/src/boost/libs/multi_index/test/test_mpl_ops.cpp
new file mode 100644
index 000000000..21b86072f
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_mpl_ops.cpp
@@ -0,0 +1,75 @@
+/* Boost.MultiIndex test for MPL operations.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_mpl_ops.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include "pre_multi_index.hpp"
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/list.hpp>
+
+using namespace boost::multi_index;
+
+void test_mpl_ops()
+{
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ordered_unique<identity<int> >,
+ ordered_non_unique<identity<int> >
+ >
+ > indexed_t1;
+
+ BOOST_STATIC_ASSERT((boost::is_same<
+ boost::mpl::at_c<indexed_t1::index_specifier_type_list,0>::type,
+ ordered_unique<identity<int> > >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<
+ boost::mpl::at_c<indexed_t1::index_specifier_type_list,1>::type,
+ ordered_non_unique<identity<int> > >::value));
+
+ typedef boost::mpl::push_front<
+ indexed_t1::index_specifier_type_list,
+ sequenced<>
+ >::type index_list_t;
+
+ typedef multi_index_container<
+ int,
+ index_list_t
+ > indexed_t2;
+
+ BOOST_STATIC_ASSERT((boost::is_same<
+ boost::mpl::at_c<indexed_t2::index_specifier_type_list,0>::type,
+ sequenced<> >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<
+ boost::mpl::at_c<indexed_t2::index_specifier_type_list,1>::type,
+ boost::mpl::at_c<indexed_t1::index_specifier_type_list,0>::type>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<
+ boost::mpl::at_c<indexed_t2::index_specifier_type_list,2>::type,
+ boost::mpl::at_c<indexed_t1::index_specifier_type_list,1>::type>::value));
+
+ typedef multi_index_container<
+ int,
+ boost::mpl::list<
+ ordered_unique<identity<int> >,
+ ordered_non_unique<identity<int> >
+ >
+ > indexed_t3;
+
+ BOOST_STATIC_ASSERT((boost::is_same<
+ boost::mpl::at_c<indexed_t3::index_specifier_type_list,0>::type,
+ boost::mpl::at_c<indexed_t1::index_specifier_type_list,0>::type>::value));
+ BOOST_STATIC_ASSERT((boost::is_same<
+ boost::mpl::at_c<indexed_t3::index_specifier_type_list,1>::type,
+ boost::mpl::at_c<indexed_t1::index_specifier_type_list,1>::type>::value));
+}
diff --git a/src/boost/libs/multi_index/test/test_mpl_ops.hpp b/src/boost/libs/multi_index/test/test_mpl_ops.hpp
new file mode 100644
index 000000000..320600bac
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_mpl_ops.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for for MPL operations.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_mpl_ops();
diff --git a/src/boost/libs/multi_index/test/test_mpl_ops_main.cpp b/src/boost/libs/multi_index/test/test_mpl_ops_main.cpp
new file mode 100644
index 000000000..fe1879b25
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_mpl_ops_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for for MPL operations.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_mpl_ops.hpp"
+
+int main()
+{
+ test_mpl_ops();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_observers.cpp b/src/boost/libs/multi_index/test/test_observers.cpp
new file mode 100644
index 000000000..8013408a4
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_observers.cpp
@@ -0,0 +1,56 @@
+/* Boost.MultiIndex test for observer memfuns.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_observers.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <vector>
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost::multi_index;
+
+void test_observers()
+{
+ employee_set es;
+ const employee_set_by_name& i1=get<by_name>(es);
+ const employee_set_by_age& i2=get<age>(es);
+
+ es.insert(employee(0,"Joe",31,1123));
+ es.insert(employee(1,"Robert",27,5601));
+ es.insert(employee(2,"John",40,7889));
+ es.insert(employee(3,"Albert",20,9012));
+ es.insert(employee(4,"John",57,1002));
+
+ {
+ employee_set_by_name::key_from_value k=i1.key_extractor();
+ employee_set_by_name::hasher h=i1.hash_function();
+ employee_set_by_name::key_equal eq=i1.key_eq();
+
+ employee_set_by_name::const_iterator it0=i1.equal_range("John").first;
+ employee_set_by_name::const_iterator it1=it0;++it1;
+ BOOST_TEST(k(*it0)=="John"&&k(*it1)=="John");
+ BOOST_TEST(h(k(*it0))==h(k(*it1)));
+ BOOST_TEST(eq(k(*it0),k(*it1))==true);
+ }
+ {
+ employee_set_by_age::key_from_value k=i2.key_extractor();
+ employee_set_by_age::key_compare c=i2.key_comp();
+ employee_set_by_age::value_compare vc=i2.value_comp();
+
+ employee_set_by_age::const_iterator it0=i2.find(31);
+ employee_set_by_age::const_iterator it1=i2.find(40);
+ BOOST_TEST(k(*it0)==31&&k(*it1)==40);
+ BOOST_TEST(c(k(*it0),k(*it1))==true);
+ BOOST_TEST(vc(*it0,*it1)==true);
+ }
+}
diff --git a/src/boost/libs/multi_index/test/test_observers.hpp b/src/boost/libs/multi_index/test/test_observers.hpp
new file mode 100644
index 000000000..f9a0a1129
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_observers.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for observer memfuns.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_observers();
diff --git a/src/boost/libs/multi_index/test/test_observers_main.cpp b/src/boost/libs/multi_index/test/test_observers_main.cpp
new file mode 100644
index 000000000..2d92fe626
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_observers_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for observer memfuns.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_observers.hpp"
+
+int main()
+{
+ test_observers();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_projection.cpp b/src/boost/libs/multi_index/test/test_projection.cpp
new file mode 100644
index 000000000..324a04583
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_projection.cpp
@@ -0,0 +1,135 @@
+/* Boost.MultiIndex test for projection capabilities.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_projection.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost::multi_index;
+
+void test_projection()
+{
+ employee_set es;
+ es.insert(employee(0,"Joe",31,1123));
+ es.insert(employee(1,"Robert",27,5601));
+ es.insert(employee(2,"John",40,7889));
+ es.insert(employee(3,"Albert",20,9012));
+ es.insert(employee(4,"John",57,1002));
+
+ employee_set::iterator it,itbis;
+ employee_set_by_name::iterator it1;
+ employee_set_by_age::iterator it2;
+ employee_set_as_inserted::iterator it3;
+ employee_set_by_ssn::iterator it4;
+ employee_set_randomly::iterator it5;
+
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set::iterator,
+ nth_index_iterator<employee_set,0>::type >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_by_name::iterator,
+ nth_index_iterator<employee_set,1>::type >::value));
+#if defined(BOOST_NO_MEMBER_TEMPLATES)
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_by_age::iterator,
+ index_iterator<employee_set,age>::type >::value));
+#else
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_by_age::iterator,
+ employee_set::index_iterator<age>::type >::value));
+#endif
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_as_inserted::iterator,
+ nth_index_iterator<employee_set,3>::type >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_by_ssn::iterator,
+ nth_index_iterator<employee_set,4>::type >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_randomly::iterator,
+ nth_index_iterator<employee_set,5>::type >::value));
+
+ it= es.find(employee(1,"Robert",27,5601));
+ it1= project<name>(es,it);
+ it2= project<age>(es,it1);
+ it3= project<as_inserted>(es,it2);
+ it4= project<ssn>(es,it3);
+ it5= project<randomly>(es,it4);
+#if defined(BOOST_NO_MEMBER_TEMPLATES)
+ itbis=project<0>(es,it5);
+#else
+ itbis=es.project<0>(it5);
+#endif
+
+ BOOST_TEST(
+ *it==*it1&&*it1==*it2&&*it2==*it3&&*it3==*it4&&*it4==*it5&&itbis==it);
+
+ BOOST_TEST(project<name>(es,es.end())==get<name>(es).end());
+ BOOST_TEST(project<age>(es,es.end())==get<age>(es).end());
+ BOOST_TEST(project<as_inserted>(es,es.end())==get<as_inserted>(es).end());
+ BOOST_TEST(project<ssn>(es,es.end())==get<ssn>(es).end());
+ BOOST_TEST(project<randomly>(es,es.end())==get<randomly>(es).end());
+
+ const employee_set& ces=es;
+
+ employee_set::const_iterator cit,citbis;
+ employee_set_by_name::const_iterator cit1;
+ employee_set_by_age::const_iterator cit2;
+ employee_set_as_inserted::const_iterator cit3;
+ employee_set_by_ssn::const_iterator cit4;
+ employee_set_randomly::const_iterator cit5;
+
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set::const_iterator,
+ nth_index_const_iterator<employee_set,0>::type >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_by_name::const_iterator,
+ nth_index_const_iterator<employee_set,1>::type >::value));
+#if defined(BOOST_NO_MEMBER_TEMPLATES)
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_by_age::const_iterator,
+ index_const_iterator<employee_set,age>::type >::value));
+#else
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_by_age::const_iterator,
+ employee_set::index_const_iterator<age>::type >::value));
+#endif
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_as_inserted::const_iterator,
+ nth_index_const_iterator<employee_set,3>::type >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_by_ssn::const_iterator,
+ nth_index_const_iterator<employee_set,4>::type >::value));
+ BOOST_STATIC_ASSERT((boost::is_same<
+ employee_set_randomly::const_iterator,
+ nth_index_const_iterator<employee_set,5>::type >::value));
+
+ cit= ces.find(employee(4,"John",57,1002));
+#if defined(BOOST_NO_MEMBER_TEMPLATES)
+ cit1= project<by_name>(ces,cit);
+#else
+ cit1= ces.project<by_name>(cit);
+#endif
+ cit2= project<age>(ces,cit1);
+#if defined(BOOST_NO_MEMBER_TEMPLATES)
+ cit3= project<as_inserted>(ces,cit2);
+#else
+ cit3= ces.project<as_inserted>(cit2);
+#endif
+ cit4= project<ssn>(ces,cit3);
+ cit5= project<randomly>(ces,cit4);
+ citbis=project<0>(ces,cit5);
+
+ BOOST_TEST(
+ *cit==*cit1&&*cit1==*cit2&&*cit2==*cit3&&*cit3==*cit4&&*cit4==*cit5&&
+ citbis==cit);
+}
diff --git a/src/boost/libs/multi_index/test/test_projection.hpp b/src/boost/libs/multi_index/test/test_projection.hpp
new file mode 100644
index 000000000..660ecb232
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_projection.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for projection capabilities.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_projection();
diff --git a/src/boost/libs/multi_index/test/test_projection_main.cpp b/src/boost/libs/multi_index/test/test_projection_main.cpp
new file mode 100644
index 000000000..560316a65
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_projection_main.cpp
@@ -0,0 +1,20 @@
+/* Boost.MultiIndex test for projection capabilities.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_projection.hpp"
+
+int main()
+{
+ test_projection();
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/multi_index/test/test_range.cpp b/src/boost/libs/multi_index/test/test_range.cpp
new file mode 100644
index 000000000..0d6ab13a3
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_range.cpp
@@ -0,0 +1,125 @@
+/* Boost.MultiIndex test for range().
+ *
+ * Copyright 2003-2020 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_range.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <boost/bind/bind.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "pre_multi_index.hpp"
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
+#include <functional>
+
+using namespace boost::multi_index;
+
+typedef multi_index_container<int> int_set;
+typedef int_set::iterator int_set_iterator;
+
+#undef CHECK_RANGE
+#define CHECK_RANGE(p,check_seq) \
+{\
+ int v[]={BOOST_PP_SEQ_ENUM(check_seq)};\
+ std::size_t size_v=sizeof(v)/sizeof(int);\
+ BOOST_TEST(std::size_t(std::distance((p).first,(p).second))==size_v);\
+ BOOST_TEST(std::equal((p).first,(p).second,&v[0]));\
+}
+
+#undef CHECK_VOID_RANGE
+#define CHECK_VOID_RANGE(p) BOOST_TEST((p).first==(p).second)
+
+#undef BIND1ST
+#define BIND1ST(f,x) ::boost::bind(f,x,::boost::arg<1>())
+
+#undef BIND2ND
+#define BIND2ND(f,x) ::boost::bind(f,::boost::arg<1>(),x)
+
+void test_range()
+{
+ int_set is;
+
+ for(int i=1;i<=10;++i)is.insert(i);
+
+ std::pair<int_set::iterator,int_set::iterator> p;
+
+ p=is.range(unbounded,unbounded);
+ CHECK_RANGE(p,(1)(2)(3)(4)(5)(6)(7)(8)(9)(10));
+
+ p=is.range(
+ BIND1ST(std::less<int>(),5), /* 5 < x */
+ unbounded);
+ CHECK_RANGE(p,(6)(7)(8)(9)(10));
+
+ p=is.range(
+ BIND1ST(std::less_equal<int>(),8), /* 8 <= x */
+ unbounded);
+ CHECK_RANGE(p,(8)(9)(10));
+
+ p=is.range(
+ BIND1ST(std::less_equal<int>(),11), /* 11 <= x */
+ unbounded);
+ CHECK_VOID_RANGE(p);
+
+ p=is.range(
+ unbounded,
+ BIND2ND(std::less<int>(),8)); /* x < 8 */
+ CHECK_RANGE(p,(1)(2)(3)(4)(5)(6)(7));
+
+ p=is.range(
+ unbounded,
+ BIND2ND(std::less_equal<int>(),4)); /* x <= 4 */
+ CHECK_RANGE(p,(1)(2)(3)(4));
+
+ p=is.range(
+ unbounded,
+ BIND2ND(std::less_equal<int>(),0)); /* x <= 0 */
+ CHECK_VOID_RANGE(p);
+
+ p=is.range(
+ BIND1ST(std::less<int>(),6), /* 6 < x */
+ BIND2ND(std::less_equal<int>(),9)); /* x <= 9 */
+ CHECK_RANGE(p,(7)(8)(9));
+
+ p=is.range(
+ BIND1ST(std::less_equal<int>(),4), /* 4 <= x */
+ BIND2ND(std::less<int>(),5)); /* x < 5 */
+ CHECK_RANGE(p,(4));
+
+ p=is.range(
+ BIND1ST(std::less_equal<int>(),10), /* 10 <= x */
+ BIND2ND(std::less_equal<int>(),10)); /* x <= 10 */
+ CHECK_RANGE(p,(10));
+
+ p=is.range(
+ BIND1ST(std::less<int>(),0), /* 0 < x */
+ BIND2ND(std::less<int>(),11)); /* x < 11 */
+ CHECK_RANGE(p,(1)(2)(3)(4)(5)(6)(7)(8)(9)(10));
+
+ p=is.range(
+ BIND1ST(std::less<int>(),7), /* 7 < x */
+ BIND2ND(std::less_equal<int>(),7)); /* x <= 7 */
+ CHECK_VOID_RANGE(p);
+ BOOST_TEST(p.first==is.upper_bound(7));
+
+ p=is.range(
+ BIND1ST(std::less_equal<int>(),8), /* 8 <= x */
+ BIND2ND(std::less<int>(),2)); /* x < 2 */
+ CHECK_VOID_RANGE(p);
+ BOOST_TEST(p.first==is.lower_bound(8));
+
+ p=is.range(
+ BIND1ST(std::less<int>(),4), /* 4 < x */
+ BIND2ND(std::less<int>(),5)); /* x < 5 */
+ CHECK_VOID_RANGE(p);
+ BOOST_TEST(p.first!=is.end());
+}
diff --git a/src/boost/libs/multi_index/test/test_range.hpp b/src/boost/libs/multi_index/test/test_range.hpp
new file mode 100644
index 000000000..2706e8dbd
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_range.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for range().
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_range();
diff --git a/src/boost/libs/multi_index/test/test_range_main.cpp b/src/boost/libs/multi_index/test/test_range_main.cpp
new file mode 100644
index 000000000..8c916687c
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_range_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for range().
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_range.hpp"
+
+int main()
+{
+ test_range();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_rank_ops.cpp b/src/boost/libs/multi_index/test/test_rank_ops.cpp
new file mode 100644
index 000000000..670540143
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_rank_ops.cpp
@@ -0,0 +1,154 @@
+/* Boost.MultiIndex test for rank operations.
+ *
+ * Copyright 2003-2017 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_rank_ops.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <iterator>
+#include <set>
+#include <boost/detail/lightweight_test.hpp>
+#include "pre_multi_index.hpp"
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/ranked_index.hpp>
+
+using namespace boost::multi_index;
+
+template<
+ typename Sequence1,typename Iterator2,typename Sequence2
+>
+bool same_position(
+ std::size_t n1,const Sequence1& s1,Iterator2 it2,const Sequence2& s2)
+{
+ typedef typename Sequence1::const_iterator const_iterator1;
+ typedef typename Sequence2::const_iterator const_iterator2;
+
+ const_iterator1 cit1=s1.begin();
+ std::advance(cit1,n1);
+ const_iterator2 cit2=it2;
+ return std::distance(s1.begin(),cit1)==std::distance(s2.begin(),cit2);
+}
+
+struct less_equal_than
+{
+ less_equal_than(int n_):n(n_){}
+ bool operator()(int x)const{return x<=n;}
+ int n;
+};
+
+struct greater_equal_than
+{
+ greater_equal_than(int n_):n(n_){}
+ bool operator()(int x)const{return x>=n;}
+ int n;
+};
+
+template<typename Sequence>
+static void local_test_rank_ops()
+{
+ int data[]={2,2,1,5,6,7,9,10,9,6,9,6,9};
+ Sequence s(data,data+sizeof(data)/sizeof(data[0]));
+ std::multiset<int> ss(s.begin(),s.end());
+
+ typedef typename Sequence::iterator iterator;
+
+ iterator it=s.begin();
+ for(std::size_t n=0;n<=s.size()+1;++n){
+ BOOST_TEST(s.nth(n)==it);
+ BOOST_TEST(s.rank(it)==(std::min)(s.size(),n));
+ if(it!=s.end())++it;
+ }
+
+ std::pair<std::size_t,std::size_t> p1;
+ std::pair<iterator,iterator> p2;
+
+ p1=s.range_rank(unbounded,unbounded);
+ p2=s.range(unbounded,unbounded);
+ BOOST_TEST(same_position(p1.first,s,p2.first,s));
+ BOOST_TEST(same_position(p1.second,s,p2.second,s));
+
+ for(int i=0;i<12;++i){
+ std::size_t pos=s.find_rank(i);
+ BOOST_TEST((pos==s.size()&&ss.find(i)==ss.end())||(*s.nth(pos)==i));
+ BOOST_TEST(same_position(s.lower_bound_rank(i),s,ss.lower_bound(i),ss));
+ BOOST_TEST(same_position(s.upper_bound_rank(i),s,ss.upper_bound(i),ss));
+ std::pair<std::size_t,std::size_t> posp=s.equal_range_rank(i);
+ BOOST_TEST(same_position(posp.first,s,ss.lower_bound(i),ss));
+ BOOST_TEST(same_position(posp.second,s,ss.upper_bound(i),ss));
+
+ p1=s.range_rank(greater_equal_than(i),unbounded);
+ p2=s.range(greater_equal_than(i),unbounded);
+ BOOST_TEST(same_position(p1.first,s,p2.first,s));
+ BOOST_TEST(same_position(p1.second,s,p2.second,s));
+ p1=s.range_rank(unbounded,less_equal_than(i));
+ p2=s.range(unbounded,less_equal_than(i));
+ BOOST_TEST(same_position(p1.first,s,p2.first,s));
+ BOOST_TEST(same_position(p1.second,s,p2.second,s));
+
+ for(int j=0;j<12;++j){
+ p1=s.range_rank(greater_equal_than(i),less_equal_than(j));
+ p2=s.range(greater_equal_than(i),less_equal_than(j));
+ BOOST_TEST(same_position(p1.first,s,p2.first,s));
+ BOOST_TEST(same_position(p1.second,s,p2.second,s));
+ }
+ }
+
+ Sequence se; /* empty */
+ BOOST_TEST(se.nth(0)==se.end());
+ BOOST_TEST(se.nth(1)==se.end());
+ BOOST_TEST(se.rank(se.end())==0);
+ BOOST_TEST(se.find_rank(0)==0);
+ BOOST_TEST(se.lower_bound_rank(0)==0);
+ BOOST_TEST(se.upper_bound_rank(0)==0);
+ p1=se.equal_range_rank(0);
+ BOOST_TEST(p1.first==0&&p1.second==0);
+ p1=se.range_rank(unbounded,unbounded);
+ BOOST_TEST(p1.first==0&&p1.second==0);
+ p1=se.range_rank(greater_equal_than(0),unbounded);
+ BOOST_TEST(p1.first==0&&p1.second==0);
+ p1=se.range_rank(unbounded,less_equal_than(0));
+ BOOST_TEST(p1.first==0&&p1.second==0);
+ p1=se.range_rank(greater_equal_than(0),less_equal_than(0));
+ BOOST_TEST(p1.first==0&&p1.second==0);
+}
+
+void test_rank_ops()
+{
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ranked_unique<identity<int> >
+ >
+ > ranked_set;
+
+ local_test_rank_ops<ranked_set>();
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ranked_non_unique<identity<int> >
+ >
+ > ranked_multiset;
+
+ local_test_rank_ops<ranked_multiset>();
+
+ /* testcase for https://svn.boost.org/trac/boost/ticket/12955 */
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ranked_unique<identity<int> >,
+ ranked_non_unique<identity<int> >
+ >
+ > biranked_set;
+
+ local_test_rank_ops<biranked_set>();
+}
diff --git a/src/boost/libs/multi_index/test/test_rank_ops.hpp b/src/boost/libs/multi_index/test/test_rank_ops.hpp
new file mode 100644
index 000000000..d410bd6e3
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_rank_ops.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for rank operations.
+ *
+ * Copyright 2003-20015 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_rank_ops();
diff --git a/src/boost/libs/multi_index/test/test_rank_ops_main.cpp b/src/boost/libs/multi_index/test/test_rank_ops_main.cpp
new file mode 100644
index 000000000..b51de6be0
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_rank_ops_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for rank operations.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_rank_ops.hpp"
+
+int main()
+{
+ test_rank_ops();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_rearrange.cpp b/src/boost/libs/multi_index/test/test_rearrange.cpp
new file mode 100644
index 000000000..9a5ddaec4
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_rearrange.cpp
@@ -0,0 +1,132 @@
+/* Boost.MultiIndex test for rearrange operations.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_rearrange.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <iterator>
+#include <boost/detail/lightweight_test.hpp>
+#include "pre_multi_index.hpp"
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/preprocessor/seq/enum.hpp>
+#include <boost/ref.hpp>
+#include <vector>
+
+using namespace boost::multi_index;
+
+#undef CHECK_EQUAL
+#define CHECK_EQUAL(p,check_seq) \
+{\
+ int v[]={BOOST_PP_SEQ_ENUM(check_seq)};\
+ std::size_t size_v=sizeof(v)/sizeof(int);\
+ BOOST_TEST(std::size_t(std::distance((p).begin(),(p).end()))==size_v);\
+ BOOST_TEST(std::equal((p).begin(),(p).end(),&v[0]));\
+}
+
+#undef CHECK_VOID_RANGE
+#define CHECK_VOID_RANGE(p) BOOST_TEST((p).first==(p).second)
+
+#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+/* The "ISO C++ Template Parser" option makes CW8.3 incorrectly fail at
+ * expressions of the form sizeof(x) where x is an array local to a
+ * template function.
+ */
+
+#pragma parse_func_templ off
+#endif
+
+template<typename Sequence>
+static void local_test_rearrange()
+{
+ typedef typename Sequence::iterator iterator;
+ typedef typename Sequence::value_type value_type;
+
+ Sequence sc;
+ sc.push_back(0);
+ sc.push_back(1);
+ sc.push_back(2);
+ sc.push_back(3);
+ sc.push_back(4);
+ sc.push_back(5);
+
+ iterator it;
+
+ it=sc.begin();
+ std::advance(it,3);
+ sc.relocate(sc.begin(),it);
+ CHECK_EQUAL(sc,(3)(0)(1)(2)(4)(5));
+ BOOST_TEST(it==sc.begin());
+
+ sc.relocate(it,it);
+ CHECK_EQUAL(sc,(3)(0)(1)(2)(4)(5));
+
+ std::advance(it,3);
+ sc.relocate(sc.end(),it,sc.end());
+ CHECK_EQUAL(sc,(3)(0)(1)(2)(4)(5));
+
+ sc.relocate(sc.begin(),it,it);
+ CHECK_EQUAL(sc,(3)(0)(1)(2)(4)(5));
+
+ iterator it2;
+
+ it2=sc.begin();
+ ++it2;
+ sc.relocate(it2,it,sc.end());
+ CHECK_EQUAL(sc,(3)(2)(4)(5)(0)(1));
+ BOOST_TEST(std::distance(it,it2)==3);
+
+ sc.relocate(boost::prior(sc.end()),it,it2);
+ CHECK_EQUAL(sc,(3)(0)(2)(4)(5)(1));
+
+ std::vector<boost::reference_wrapper<const value_type> > v;
+ for(iterator it3=sc.begin();it3!=sc.end();++it3){
+ v.push_back(boost::cref(*it3));
+ }
+
+ sc.rearrange(v.begin());
+ BOOST_TEST(std::equal(sc.begin(),sc.end(),v.begin()));
+
+ std::reverse(v.begin(),v.end());
+ sc.rearrange(v.begin());
+ BOOST_TEST(std::equal(sc.begin(),sc.end(),v.begin()));
+
+ std::sort(v.begin(),v.end());
+ sc.rearrange(v.begin());
+ BOOST_TEST(std::equal(sc.begin(),sc.end(),v.begin()));
+
+ std::reverse(v.begin(),v.begin()+v.size()/2);
+ sc.rearrange(v.begin());
+ BOOST_TEST(std::equal(sc.begin(),sc.end(),v.begin()));
+}
+
+#if BOOST_WORKAROUND(__MWERKS__,<=0x3003)
+#pragma parse_func_templ reset
+#endif
+
+void test_rearrange()
+{
+ typedef multi_index_container<
+ int,
+ indexed_by<sequenced<> >
+ > int_list;
+
+ local_test_rearrange<int_list>();
+
+ typedef multi_index_container<
+ int,
+ indexed_by<random_access<> >
+ > int_vector;
+
+ local_test_rearrange<int_vector>();
+}
diff --git a/src/boost/libs/multi_index/test/test_rearrange.hpp b/src/boost/libs/multi_index/test/test_rearrange.hpp
new file mode 100644
index 000000000..f3ec8457c
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_rearrange.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for rearrange operations.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_rearrange();
diff --git a/src/boost/libs/multi_index/test/test_rearrange_main.cpp b/src/boost/libs/multi_index/test/test_rearrange_main.cpp
new file mode 100644
index 000000000..9fe5a65be
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_rearrange_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for rearrange operations.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_rearrange.hpp"
+
+int main()
+{
+ test_rearrange();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_safe_mode.cpp b/src/boost/libs/multi_index/test/test_safe_mode.cpp
new file mode 100644
index 000000000..b5a7e796d
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_safe_mode.cpp
@@ -0,0 +1,472 @@
+/* Boost.MultiIndex test for safe_mode.
+ *
+ * Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_safe_mode.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include "pair_of_ints.hpp"
+#include <stdexcept>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost::multi_index;
+
+#define TRY_SAFE_MODE \
+try{
+
+#define CATCH_SAFE_MODE(err) \
+ throw std::runtime_error("safe mode violation not detected");\
+}catch(const safe_mode_exception& e){\
+ if(e.error_code!=(err))throw std::runtime_error(\
+ "safe mode violation not expected");\
+}
+
+template<typename T> void prevent_unused_var_warning(const T&){}
+
+template<typename Policy>
+static void local_test_safe_mode(
+ std::forward_iterator_tag
+ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy))
+{
+ typedef typename Policy::container container;
+ typedef typename Policy::index_type index_type;
+ typedef typename index_type::value_type value_type;
+ typedef typename index_type::iterator iterator;
+
+ container c,c2;
+ index_type& i=Policy::index_from_container(c);
+ index_type& i2=Policy::index_from_container(c2);
+ Policy::insert(i,Policy::some_value());
+
+ TRY_SAFE_MODE
+ iterator it;
+ iterator it2=i.begin();
+ it2=it;
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ iterator it;
+ value_type e=*it;
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ iterator it=i.end();
+ value_type e=*it;
+ CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator)
+
+ TRY_SAFE_MODE
+ iterator it=i.end();
+ ++it;
+ CATCH_SAFE_MODE(safe_mode::not_incrementable_iterator)
+
+ TRY_SAFE_MODE
+ iterator it;
+ iterator it2;
+ bool b=(it==it2);
+ prevent_unused_var_warning(b);
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ iterator it=i.begin();
+ iterator it2;
+ bool b=(it==it2);
+ prevent_unused_var_warning(b);
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ iterator it=i.begin();
+ iterator it2=i2.begin();
+ bool b=(it==it2);
+ prevent_unused_var_warning(b);
+ CATCH_SAFE_MODE(safe_mode::not_same_owner)
+
+ TRY_SAFE_MODE
+ i.erase(i.end(),i.begin());
+ CATCH_SAFE_MODE(safe_mode::invalid_range)
+
+ TRY_SAFE_MODE
+ iterator it;
+ Policy::insert(i,it,Policy::some_value());
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ i.erase(i.end());
+ CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator)
+
+ TRY_SAFE_MODE
+ iterator it=i.begin();
+ Policy::insert(i2,it,Policy::some_value());
+ CATCH_SAFE_MODE(safe_mode::not_owner)
+
+ TRY_SAFE_MODE
+ iterator it=i.begin();
+ iterator it2=i2.end();
+ i2.erase(it,it2);
+ CATCH_SAFE_MODE(safe_mode::not_owner)
+
+ TRY_SAFE_MODE
+ iterator it=Policy::insert(i,Policy::another_value());
+ i.erase(it);
+ i.erase(it);
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ container c3(c);
+ index_type& i3=Policy::index_from_container(c3);
+ iterator it=Policy::insert(i3,Policy::another_value());
+ i3.clear();
+ i3.erase(it);
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ iterator it;
+ {
+ container c3;
+ index_type& i3=Policy::index_from_container(c3);
+ it=i3.end();
+ }
+ iterator it2;
+ it2=it;
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ iterator it;
+ {
+ container c3;
+ index_type& i3=Policy::index_from_container(c3);
+ it=Policy::insert(i3,Policy::some_value());
+ }
+ value_type e=*it;
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ iterator it;
+ {
+ container c3;
+ index_type& i3=Policy::index_from_container(c3);
+ it=Policy::insert(i3,Policy::some_value());
+ }
+ iterator it2;
+ it2=it;
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ container c3(c);
+ container c4;
+ index_type& i3=Policy::index_from_container(c3);
+ index_type& i4=Policy::index_from_container(c4);
+ iterator it=i3.begin();
+ i3.swap(i4);
+ i3.erase(it);
+ CATCH_SAFE_MODE(safe_mode::not_owner)
+
+ /* this, unlike the previous case, is indeed correct, test safe mode
+ * gets it right
+ */
+ {
+ container c3(c);
+ container c4;
+ index_type& i3=Policy::index_from_container(c3);
+ index_type& i4=Policy::index_from_container(c4);
+ iterator it=i3.begin();
+ i3.swap(i4);
+ i4.erase(it);
+ }
+
+ TRY_SAFE_MODE
+ iterator it=i.end();
+ typename container::iterator it2=project<0>(c2,it);
+ CATCH_SAFE_MODE(safe_mode::not_owner)
+
+ TRY_SAFE_MODE
+ iterator it=Policy::insert(i,Policy::another_value());
+ typename container::iterator it2=project<0>(c,it);
+ i.erase(it);
+ value_type e=*it2;
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ /* testcase for bug reported at
+ * http://lists.boost.org/boost-users/2006/02/17230.php
+ */
+ {
+ container c3(c);
+ index_type& i3=Policy::index_from_container(c3);
+ iterator it=i3.end();
+ i3.clear();
+ it=i3.end();
+ }
+
+ /* testcase for doppelganger bug of that discovered for STLport at
+ * http://lists.boost.org/Archives/boost/2006/04/102740.php
+ */
+ {
+ container c3;
+ index_type& i3=Policy::index_from_container(c3);
+ iterator it=i3.end();
+ i3.clear();
+ iterator it2=it;
+ BOOST_TEST(it2==i3.end());
+ }
+}
+
+template<typename Policy>
+static void local_test_safe_mode(
+ std::bidirectional_iterator_tag
+ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy))
+{
+ ::local_test_safe_mode<Policy>(std::forward_iterator_tag());
+
+ typedef typename Policy::container container;
+ typedef typename Policy::index_type index_type;
+ typedef typename index_type::iterator iterator;
+
+ container c;
+ index_type& i=Policy::index_from_container(c);
+ Policy::insert(i,Policy::some_value());
+
+ TRY_SAFE_MODE
+ iterator it=i.begin();
+ --it;
+ CATCH_SAFE_MODE(safe_mode::not_decrementable_iterator)
+}
+
+template<typename Policy>
+static void local_test_safe_mode(
+ std::random_access_iterator_tag
+ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Policy))
+{
+ ::local_test_safe_mode<Policy>(std::bidirectional_iterator_tag());
+
+ typedef typename Policy::container container;
+ typedef typename Policy::index_type index_type;
+ typedef typename index_type::iterator iterator;
+
+ container c;
+ index_type& i=Policy::index_from_container(c);
+ Policy::insert(i,Policy::some_value());
+
+ TRY_SAFE_MODE
+ iterator it=i.begin();
+ it+=2;
+ CATCH_SAFE_MODE(safe_mode::out_of_bounds)
+
+ TRY_SAFE_MODE
+ iterator it=i.begin();
+ it-=1;
+ CATCH_SAFE_MODE(safe_mode::out_of_bounds)
+}
+
+template<typename Policy>
+static void local_test_safe_mode()
+{
+ typedef typename Policy::index_type::iterator::iterator_category category;
+ ::local_test_safe_mode<Policy>(category());
+}
+
+template<typename Policy>
+static void local_test_safe_mode_with_rearrange()
+{
+ ::local_test_safe_mode<Policy>();
+
+ typedef typename Policy::container container;
+ typedef typename Policy::index_type index_type;
+ typedef typename index_type::iterator iterator;
+
+ container c;
+ index_type& i=Policy::index_from_container(c);
+ Policy::insert(i,Policy::some_value());
+
+ TRY_SAFE_MODE
+ iterator it;
+ i.splice(it,i,i.begin(),i.end());
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ container c2(c);
+ index_type& i2=Policy::index_from_container(c2);
+ iterator it2=i2.begin();
+ iterator it=i.begin();
+ i.splice(it2,i2,it);
+ CATCH_SAFE_MODE(safe_mode::not_owner)
+
+ TRY_SAFE_MODE
+ i.splice(i.begin(),i,i.begin(),i.end());
+ CATCH_SAFE_MODE(safe_mode::inside_range)
+
+ TRY_SAFE_MODE
+ i.splice(i.begin(),i,i.end(),i.begin());
+ CATCH_SAFE_MODE(safe_mode::invalid_range)
+
+ TRY_SAFE_MODE
+ i.splice(i.begin(),i);
+ CATCH_SAFE_MODE(safe_mode::same_container)
+
+ TRY_SAFE_MODE
+ iterator it;
+ i.relocate(it,i.begin(),i.end());
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ i.relocate(i.begin(),i.begin(),i.end());
+ CATCH_SAFE_MODE(safe_mode::inside_range)
+
+ TRY_SAFE_MODE
+ i.relocate(i.begin(),i.end(),i.begin());
+ CATCH_SAFE_MODE(safe_mode::invalid_range)
+}
+
+template<typename MultiIndexContainer,int N>
+struct index_policy_base
+{
+ typedef MultiIndexContainer container;
+ typedef typename nth_index<container,N>::type index_type;
+
+ static index_type& index_from_container(container& c){return get<N>(c);}
+};
+
+template<typename MultiIndexContainer,int N>
+struct key_based_index_policy_base:
+ index_policy_base<MultiIndexContainer,N>
+{
+ typedef index_policy_base<MultiIndexContainer,N> super;
+
+ typedef typename super::container container;
+ typedef typename super::index_type index_type;
+ typedef typename index_type::value_type value_type;
+ typedef typename index_type::iterator iterator;
+
+ static iterator insert(index_type& i,const value_type& v)
+ {
+ return i.insert(v).first;
+ }
+
+ static iterator insert(index_type& i,iterator it,const value_type& v)
+ {
+ return i.insert(it,v);
+ }
+};
+
+template<typename MultiIndexContainer,int N>
+struct non_key_based_index_policy_base:
+ index_policy_base<MultiIndexContainer,N>
+{
+ typedef index_policy_base<MultiIndexContainer,N> super;
+
+ typedef typename super::container container;
+ typedef typename super::index_type index_type;
+ typedef typename index_type::value_type value_type;
+ typedef typename index_type::iterator iterator;
+
+ static iterator insert(index_type& i,const value_type& v)
+ {
+ return i.push_back(v).first;
+ }
+
+ static iterator insert(index_type& i,iterator it,const value_type& v)
+ {
+ return i.insert(it,v).first;
+ }
+};
+
+struct employee_set_policy_base
+{
+ static employee some_value(){return employee(0,"Joe",31,1123);}
+ static employee another_value(){return employee(1,"Robert",27,5601);}
+};
+
+struct employee_set_policy:
+ employee_set_policy_base,
+ key_based_index_policy_base<employee_set,0>
+{};
+
+struct employee_set_by_name_policy:
+ employee_set_policy_base,
+ key_based_index_policy_base<employee_set,1>
+{};
+
+struct employee_set_as_inserted_policy:
+ employee_set_policy_base,
+ non_key_based_index_policy_base<employee_set,3>
+{};
+
+struct employee_set_randomly_policy:
+ employee_set_policy_base,
+ non_key_based_index_policy_base<employee_set,5>
+{};
+
+template<typename IntegralBimap>
+static void test_integral_bimap()
+{
+ typedef typename IntegralBimap::value_type value_type;
+ typedef typename IntegralBimap::iterator iterator;
+
+ TRY_SAFE_MODE
+ IntegralBimap bm;
+ iterator it=bm.insert(value_type(0,0)).first;
+ bm.insert(value_type(1,1));
+ bm.modify(it,increment_first);
+ value_type v=*it;
+ prevent_unused_var_warning(v);
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+
+ TRY_SAFE_MODE
+ IntegralBimap bm;
+ iterator it=bm.insert(value_type(0,0)).first;
+ bm.insert(value_type(1,1));
+ bm.modify(it,increment_second);
+ pair_of_ints v=*it;
+ prevent_unused_var_warning(v);
+ CATCH_SAFE_MODE(safe_mode::invalid_iterator)
+}
+
+void test_safe_mode()
+{
+ local_test_safe_mode<employee_set_policy>();
+ local_test_safe_mode<employee_set_by_name_policy>();
+ local_test_safe_mode_with_rearrange<employee_set_as_inserted_policy>();
+ local_test_safe_mode_with_rearrange<employee_set_randomly_policy>();
+
+ typedef multi_index_container<
+ pair_of_ints,
+ indexed_by<
+ ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
+ ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
+ > bimap0_type;
+
+ test_integral_bimap<bimap0_type>();
+
+ typedef multi_index_container<
+ pair_of_ints,
+ indexed_by<
+ ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
+ hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
+ > bimap1_type;
+
+ test_integral_bimap<bimap1_type>();
+
+ typedef multi_index_container<
+ pair_of_ints,
+ indexed_by<
+ hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
+ ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
+ > bimap2_type;
+
+ test_integral_bimap<bimap2_type>();
+
+ typedef multi_index_container<
+ pair_of_ints,
+ indexed_by<
+ hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
+ hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> >
+ > bimap3_type;
+
+ test_integral_bimap<bimap3_type>();
+}
diff --git a/src/boost/libs/multi_index/test/test_safe_mode.hpp b/src/boost/libs/multi_index/test/test_safe_mode.hpp
new file mode 100644
index 000000000..156d7b275
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_safe_mode.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for safe mode.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_safe_mode();
diff --git a/src/boost/libs/multi_index/test/test_safe_mode_main.cpp b/src/boost/libs/multi_index/test/test_safe_mode_main.cpp
new file mode 100644
index 000000000..4bb892c6c
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_safe_mode_main.cpp
@@ -0,0 +1,19 @@
+/* Boost.MultiIndex test for safe mode.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_safe_mode.hpp"
+
+int main()
+{
+ test_safe_mode();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/multi_index/test/test_serialization.cpp b/src/boost/libs/multi_index/test/test_serialization.cpp
new file mode 100644
index 000000000..6c5b8f6e7
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_serialization.cpp
@@ -0,0 +1,21 @@
+/* Boost.MultiIndex test for serialization.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_serialization.hpp"
+#include "test_serialization1.hpp"
+#include "test_serialization2.hpp"
+#include "test_serialization3.hpp"
+
+void test_serialization()
+{
+ test_serialization1();
+ test_serialization2();
+ test_serialization3();
+}
diff --git a/src/boost/libs/multi_index/test/test_serialization.hpp b/src/boost/libs/multi_index/test/test_serialization.hpp
new file mode 100644
index 000000000..8e66535fe
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_serialization.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for serialization.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_serialization();
diff --git a/src/boost/libs/multi_index/test/test_serialization1.cpp b/src/boost/libs/multi_index/test/test_serialization1.cpp
new file mode 100644
index 000000000..f41c9ca5a
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_serialization1.cpp
@@ -0,0 +1,66 @@
+/* Boost.MultiIndex test for serialization, part 1.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_serialization1.hpp"
+#include "test_serialization_template.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/multi_index/key_extractors.hpp>
+#include "non_std_allocator.hpp"
+
+using namespace boost::multi_index;
+
+void test_serialization1()
+{
+ {
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ sequenced<>,
+ sequenced<>,
+ random_access<>
+ >
+ > multi_index_t;
+
+ multi_index_t m;
+ for(int i=0;i<100;++i)m.push_back(i);
+ m.reverse();
+ test_serialization(m);
+
+ m.clear();
+ for(int j=50;j<100;++j)m.push_back(j);
+ for(int k=0;k<50;++k)m.push_back(k);
+ m.sort();
+ test_serialization(m);
+ }
+ {
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ random_access<>,
+ sequenced<>,
+ ordered_non_unique<identity<int> >
+ >,
+ non_std_allocator<int>
+ > multi_index_t;
+
+ multi_index_t m;
+ for(int i=0;i<100;++i){
+ m.push_back(i);
+ m.push_back(i);
+ m.push_back(i);
+ }
+ m.reverse();
+ test_serialization(m);
+ }
+}
diff --git a/src/boost/libs/multi_index/test/test_serialization1.hpp b/src/boost/libs/multi_index/test/test_serialization1.hpp
new file mode 100644
index 000000000..2db6ec8d3
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_serialization1.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for serialization, part 1.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_serialization1();
diff --git a/src/boost/libs/multi_index/test/test_serialization2.cpp b/src/boost/libs/multi_index/test/test_serialization2.cpp
new file mode 100644
index 000000000..1c93c5fa6
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_serialization2.cpp
@@ -0,0 +1,81 @@
+/* Boost.MultiIndex test for serialization, part 2.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_serialization2.hpp"
+#include "test_serialization_template.hpp"
+
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/multi_index/key_extractors.hpp>
+#include "non_std_allocator.hpp"
+#include "pair_of_ints.hpp"
+
+using namespace boost::multi_index;
+
+void test_serialization2()
+{
+ {
+ typedef multi_index_container<
+ pair_of_ints,
+ indexed_by<
+ ordered_unique<
+ BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)
+ >,
+ ordered_non_unique<
+ BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)
+ >,
+ random_access<>,
+ sequenced<>
+ >,
+ non_std_allocator<pair_of_ints>
+ > multi_index_t;
+
+ multi_index_t m;
+ test_serialization(m);
+
+ m.insert(pair_of_ints(4,0));
+ test_serialization(m);
+
+ m.insert(pair_of_ints(3,1));
+ m.insert(pair_of_ints(2,1));
+ test_serialization(m);
+
+ m.insert(pair_of_ints(1,1));
+ test_serialization(m);
+
+ m.insert(pair_of_ints(0,0));
+ test_serialization(m);
+
+ m.insert(pair_of_ints(5,1));
+ m.insert(pair_of_ints(7,1));
+ m.insert(pair_of_ints(6,1));
+ test_serialization(m);
+
+ m.insert(pair_of_ints(8,1));
+ m.insert(pair_of_ints(9,1));
+ m.insert(pair_of_ints(12,1));
+ m.insert(pair_of_ints(11,1));
+ m.insert(pair_of_ints(10,1));
+ test_serialization(m);
+
+ /* testcase for bug reported at
+ * http://lists.boost.org/boost-users/2006/05/19362.php
+ */
+
+ m.clear();
+ m.insert(pair_of_ints(0,0));
+ m.insert(pair_of_ints(1,0));
+ m.insert(pair_of_ints(2,1));
+ m.insert(pair_of_ints(4,2));
+ m.insert(pair_of_ints(3,2));
+ test_serialization(m);
+ }
+}
diff --git a/src/boost/libs/multi_index/test/test_serialization2.hpp b/src/boost/libs/multi_index/test/test_serialization2.hpp
new file mode 100644
index 000000000..6382882f6
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_serialization2.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for serialization, part 2.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_serialization2();
diff --git a/src/boost/libs/multi_index/test/test_serialization3.cpp b/src/boost/libs/multi_index/test/test_serialization3.cpp
new file mode 100644
index 000000000..5a759c1d5
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_serialization3.cpp
@@ -0,0 +1,216 @@
+/* Boost.MultiIndex test for serialization, part 3.
+ *
+ * Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_serialization3.hpp"
+#include "test_serialization_template.hpp"
+
+#include <boost/move/core.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/key_extractors.hpp>
+#include "non_std_allocator.hpp"
+
+struct non_default_ctble
+{
+ non_default_ctble(int n_):n(n_){}
+
+ bool operator==(const non_default_ctble& x)const{return n==x.n;}
+
+ int n;
+};
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+namespace serialization{
+#endif
+
+template<class Archive>
+void save_construct_data(
+ Archive& ar,const non_default_ctble* p,const unsigned int version)
+{
+ if(version<3)return;
+
+ ar<<boost::serialization::make_nvp("n",p->n);
+}
+
+template<class Archive>
+void load_construct_data(
+ Archive& ar,non_default_ctble* p,const unsigned int version)
+{
+ if(version<3)return;
+
+ int n=0;
+ ar>>boost::serialization::make_nvp("n",n);
+ ::new(p)non_default_ctble(n);
+}
+
+template<class Archive>
+void serialize(Archive&,non_default_ctble&,const unsigned int)
+{
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace serialization */
+} /* namespace boost*/
+#endif
+
+namespace boost{
+namespace serialization{
+template<> struct version<non_default_ctble>
+{
+ BOOST_STATIC_CONSTANT(int,value=3);
+};
+} /* namespace serialization */
+} /* namespace boost*/
+
+struct non_copyable
+{
+ non_copyable(int n_=0):n(n_){}
+ non_copyable(BOOST_RV_REF(non_copyable) x):n(x.n){}
+
+ bool operator==(const non_copyable& x)const{return n==x.n;}
+ bool operator<(const non_copyable& x)const{return n<x.n;}
+
+ int n;
+
+private:
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(non_copyable)
+};
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+namespace serialization{
+#endif
+
+template<class Archive>
+void serialize(Archive& ar,non_copyable& x,const unsigned int)
+{
+ ar&boost::serialization::make_nvp("n",x.n);
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace serialization */
+} /* namespace boost*/
+#endif
+
+using namespace boost::multi_index;
+
+void test_serialization3()
+{
+ const int N=100;
+ const int SHUFFLE=10232;
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ hashed_unique<identity<int> >,
+ sequenced<>
+ >,
+ non_std_allocator<int>
+ > hashed_set;
+
+ typedef hashed_set::iterator iterator;
+ typedef hashed_set::local_iterator local_iterator;
+
+ hashed_set hs;
+
+ for(int i=0;i<N;++i){
+ hs.insert(i*SHUFFLE);
+ }
+
+ std::ostringstream oss;
+ {
+ boost::archive::text_oarchive oa(oss);
+ oa<<const_cast<const hashed_set&>(hs);
+
+ std::vector<iterator> its(N);
+ for(int i=0;i<N;++i){
+ iterator it=hs.find(i*SHUFFLE);
+ its.push_back(it);
+ oa<<const_cast<const iterator&>(its.back());
+ }
+ iterator it=hs.end();
+ oa<<const_cast<const iterator&>(it);
+
+ std::vector<local_iterator> lits(2*N);
+ for(std::size_t buc=0;buc<hs.bucket_count();++buc){
+ for(local_iterator lit=hs.begin(buc),lit_end=hs.end(buc);
+ lit!=lit_end;++lit){
+ oa<<*lit;
+ lits.push_back(lit);
+ oa<<const_cast<const local_iterator&>(lits.back());
+ }
+ local_iterator lit2=hs.end(buc);
+ lits.push_back(lit2);
+ oa<<const_cast<const local_iterator&>(lits.back());
+ }
+ }
+
+ hashed_set hs2;
+ std::istringstream iss(oss.str());
+ boost::archive::text_iarchive ia(iss);
+ ia>>hs2;
+ BOOST_TEST(boost::multi_index::get<1>(hs)==boost::multi_index::get<1>(hs2));
+
+ for(int j=0;j<N;++j){
+ iterator it;
+ ia>>it;
+ BOOST_TEST(*it==j*SHUFFLE);
+ }
+ iterator it;
+ ia>>it;
+ BOOST_TEST(it==hs2.end());
+
+ for(std::size_t buc=0;buc<hs2.bucket_count();++buc){
+ for(std::size_t k=0;k<hs2.bucket_size(buc);++k){
+ int n;
+ local_iterator it_;
+ ia>>n;
+ ia>>it_;
+ BOOST_TEST(*it_==n);
+ }
+ local_iterator it2;
+ ia>>it2;
+ BOOST_TEST(it2==hs2.end(buc));
+ }
+
+ {
+ typedef multi_index_container<
+ non_default_ctble,
+ indexed_by<
+ ordered_unique<
+ BOOST_MULTI_INDEX_MEMBER(non_default_ctble,int,n)
+ >
+ >
+ > multi_index_t;
+
+ multi_index_t m;
+ for(int i=0;i<100;++i)m.insert(non_default_ctble(i));
+ test_serialization(m);
+ }
+
+ {
+ /* testcase for https://svn.boost.org/trac10/ticket/13478 */
+
+ typedef multi_index_container<
+ non_copyable,
+ indexed_by<
+ ordered_unique<
+ BOOST_MULTI_INDEX_MEMBER(non_copyable,int,n)
+ >
+ >
+ > multi_index_t;
+
+ multi_index_t m;
+ for(int i=0;i<100;++i)m.emplace(i);
+ test_serialization(m);
+ }
+}
diff --git a/src/boost/libs/multi_index/test/test_serialization3.hpp b/src/boost/libs/multi_index/test/test_serialization3.hpp
new file mode 100644
index 000000000..bb620c0b6
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_serialization3.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for serialization, part 3.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_serialization3();
diff --git a/src/boost/libs/multi_index/test/test_serialization_main.cpp b/src/boost/libs/multi_index/test/test_serialization_main.cpp
new file mode 100644
index 000000000..43a698a77
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_serialization_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for serialization.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_serialization.hpp"
+
+int main()
+{
+ test_serialization();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_serialization_template.hpp b/src/boost/libs/multi_index/test/test_serialization_template.hpp
new file mode 100644
index 000000000..b7a9a9c92
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_serialization_template.hpp
@@ -0,0 +1,105 @@
+/* Boost.MultiIndex serialization tests template.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/mpl/size.hpp>
+#include "pre_multi_index.hpp"
+#include <boost/multi_index_container.hpp>
+#include <string>
+#include <sstream>
+#include <vector>
+
+template<int N>
+struct all_indices_equal_helper
+{
+ template<class MultiIndexContainer>
+ static bool compare(
+ const MultiIndexContainer& m1,const MultiIndexContainer& m2)
+ {
+ if(!(boost::multi_index::get<N>(m1)==boost::multi_index::get<N>(m2))){
+ return false;
+ }
+ return all_indices_equal_helper<N-1>::compare(m1,m2);
+ }
+};
+
+template<>
+struct all_indices_equal_helper<0>
+{
+ template<class MultiIndexContainer>
+ static bool compare(
+ const MultiIndexContainer&,const MultiIndexContainer&)
+ {
+ return true;
+ }
+};
+
+template<class MultiIndexContainer>
+bool all_indices_equal(
+ const MultiIndexContainer& m1,const MultiIndexContainer& m2)
+{
+ BOOST_STATIC_CONSTANT(int,
+ N=boost::mpl::size<
+ BOOST_DEDUCED_TYPENAME MultiIndexContainer::index_type_list>::type::value);
+
+ return all_indices_equal_helper<N-1>::compare(m1,m2);
+}
+
+template<class MultiIndexContainer>
+void test_serialization(const MultiIndexContainer& m)
+{
+ typedef typename MultiIndexContainer::iterator iterator;
+ typedef typename MultiIndexContainer::const_iterator const_iterator;
+
+ std::ostringstream oss;
+ {
+ boost::archive::text_oarchive oa(oss);
+ oa<<m;
+
+ std::vector<const_iterator> its(m.size());
+ const_iterator it_end=m.end();
+ for(const_iterator it=m.begin();it!=it_end;++it){
+ its.push_back(it);
+ oa<<const_cast<const const_iterator&>(its.back());
+ }
+ oa<<const_cast<const const_iterator&>(it_end);
+ }
+
+ MultiIndexContainer m2;
+ std::istringstream iss(oss.str());
+ boost::archive::text_iarchive ia(iss);
+ ia>>m2;
+ BOOST_TEST(all_indices_equal(m,m2));
+
+ iterator it_end=m2.end();
+ for(iterator it=m2.begin();it!=it_end;++it){
+ iterator it2;
+ ia>>it2;
+ BOOST_TEST(it==it2);
+
+ /* exercise safe mode with this (unchecked) iterator */
+ BOOST_TEST(*it==*it2);
+ m2.erase(it,it2);
+ m2.erase(it2,it2);
+ m2.erase(it2,it);
+ iterator it3(++it2);
+ iterator it4;
+ it4=--it2;
+ BOOST_TEST(it==it4);
+ BOOST_TEST(it==boost::multi_index::project<0>(m2,it4));
+ }
+ iterator it2;
+ ia>>it2;
+ BOOST_TEST(it_end==it2);
+ BOOST_TEST(it_end==boost::multi_index::project<0>(m2,it2));
+}
diff --git a/src/boost/libs/multi_index/test/test_set_ops.cpp b/src/boost/libs/multi_index/test/test_set_ops.cpp
new file mode 100644
index 000000000..0e9a70da8
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_set_ops.cpp
@@ -0,0 +1,127 @@
+/* Boost.MultiIndex test for standard set operations.
+ *
+ * Copyright 2003-2014 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_set_ops.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <vector>
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost::multi_index;
+
+struct type1{};
+
+struct type2
+{
+private:
+ operator type1()const{return type1();}
+};
+
+struct type3
+{
+ operator type1()const{return type1();}
+};
+
+struct less_type12
+{
+ bool operator()(type1,type1)const{return false;}
+ bool operator()(type1,type2)const{return false;}
+ bool operator()(type2,type1)const{return false;}
+};
+
+bool less_type1_f(type1,type1){return false;}
+
+struct hash_type12
+{
+ std::size_t operator()(type1)const{return 0;}
+ std::size_t operator()(type2)const{return 0;}
+};
+
+struct eq_type12
+{
+ bool operator()(type1,type1)const{return true;}
+ bool operator()(type1,type2)const{return true;}
+ bool operator()(type2,type1)const{return true;}
+};
+
+void test_set_ops()
+{
+ employee_set es;
+ employee_set_by_name& i1=get<by_name>(es);
+ const employee_set_by_age& i2=get<age>(es);
+ employee_set_by_ssn& i4=get<ssn>(es);
+
+ es.insert(employee(0,"Joe",31,1123));
+ es.insert(employee(1,"Robert",27,5601));
+ es.insert(employee(2,"John",40,7889));
+ es.insert(employee(3,"Albert",20,9012));
+ es.insert(employee(4,"John",57,1002));
+
+ BOOST_TEST(i1.find("John")->name=="John");
+ BOOST_TEST(i2.find(41)==i2.end());
+ BOOST_TEST(i4.find(5601)->name=="Robert");
+
+ BOOST_TEST(i1.count("John")==2);
+ BOOST_TEST(es.count(employee(10,"",-1,0))==0);
+ BOOST_TEST(i4.count(7881)==0);
+
+ BOOST_TEST(
+ std::distance(
+ i2.lower_bound(31),
+ i2.upper_bound(60))==3);
+
+ std::pair<employee_set_by_name::iterator,employee_set_by_name::iterator> p=
+ i1.equal_range("John");
+ BOOST_TEST(std::distance(p.first,p.second)==2);
+
+ p=i1.equal_range("Serena");
+ BOOST_TEST(p.first==i1.end()&&p.second==i1.end());
+
+ std::pair<employee_set_by_age::iterator,employee_set_by_age::iterator> p2=
+ i2.equal_range(30);
+ BOOST_TEST(p2.first==p2.second&&p2.first->age==31);
+
+ /* check promotion detection plays nice with private conversion */
+
+ multi_index_container<
+ type1,
+ indexed_by<
+ ordered_unique<identity<type1>,less_type12>,
+ hashed_unique<identity<type1>,hash_type12,eq_type12>
+ >
+ > c;
+ c.insert(type1());
+
+ BOOST_TEST(c.find(type2())==c.begin());
+ BOOST_TEST(c.count(type2())==1);
+ BOOST_TEST(c.lower_bound(type2())==c.begin());
+ BOOST_TEST(c.upper_bound(type2())==c.end());
+ BOOST_TEST(c.equal_range(type2())==std::make_pair(c.begin(),c.end()));
+
+ BOOST_TEST(c.get<1>().find(type2())==c.get<1>().begin());
+ BOOST_TEST(c.get<1>().count(type2())==1);
+ BOOST_TEST(c.get<1>().equal_range(type2())==
+ std::make_pair(c.get<1>().begin(),c.get<1>().end()));
+
+ /* check promotion detection does not break with functions */
+
+ multi_index_container<
+ type1,
+ indexed_by<
+ ordered_unique<identity<type1>,bool(*)(type1,type1)>
+ >
+ > c2(boost::make_tuple(boost::make_tuple(identity<type1>(),&less_type1_f)));
+ c2.insert(type1());
+
+ BOOST_TEST(c2.find(type3())==c2.begin());
+}
diff --git a/src/boost/libs/multi_index/test/test_set_ops.hpp b/src/boost/libs/multi_index/test/test_set_ops.hpp
new file mode 100644
index 000000000..dc333c887
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_set_ops.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for standard set operations.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_set_ops();
diff --git a/src/boost/libs/multi_index/test/test_set_ops_main.cpp b/src/boost/libs/multi_index/test/test_set_ops_main.cpp
new file mode 100644
index 000000000..9a45a73e2
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_set_ops_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for standard set operations.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_set_ops.hpp"
+
+int main()
+{
+ test_set_ops();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_special_set_ops.cpp b/src/boost/libs/multi_index/test/test_special_set_ops.cpp
new file mode 100644
index 000000000..516a2cc6a
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_special_set_ops.cpp
@@ -0,0 +1,95 @@
+/* Boost.MultiIndex test for special set operations.
+ *
+ * Copyright 2003-2015 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_special_set_ops.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <sstream>
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost::multi_index;
+
+static int string_to_int(const std::string& str)
+{
+ std::istringstream iss(str);
+ int res;
+ iss>>res;
+ return res;
+}
+
+struct comp_int_string
+{
+ bool operator()(int x,const std::string& y)const
+ {
+ return x<string_to_int(y);
+ }
+
+ bool operator()(const std::string& x,int y)const
+ {
+ return string_to_int(x)<y;
+ }
+};
+
+struct hash_string_as_int
+{
+ int operator()(const std::string& x)const
+ {
+ return static_cast<int>(boost::hash<int>()(string_to_int(x)));
+ }
+};
+
+struct eq_string_int
+{
+ bool operator()(int x,const std::string& y)const
+ {
+ return x==string_to_int(y);
+ }
+
+ bool operator()(const std::string& x,int y)const
+ {
+ return operator()(y,x);
+ }
+};
+
+void test_special_set_ops()
+{
+ employee_set es;
+
+ es.insert(employee(0,"Joe",31,1123));
+ es.insert(employee(1,"Robert",27,5601));
+ es.insert(employee(2,"John",40,7889));
+ es.insert(employee(3,"Albert",20,9012));
+ es.insert(employee(4,"John",57,1002));
+
+ std::pair<employee_set_by_ssn::iterator,employee_set_by_ssn::iterator> p=
+ get<ssn>(es).equal_range(
+ "7889",hash_string_as_int(),eq_string_int());
+
+ BOOST_TEST(std::distance(p.first,p.second)==1&&(p.first)->id==2);
+
+ BOOST_TEST(
+ get<ssn>(es).count(
+ "5601",hash_string_as_int(),eq_string_int())==1);
+
+ BOOST_TEST(
+ get<ssn>(es).find(
+ "1123",hash_string_as_int(),eq_string_int())->name=="Joe");
+
+ BOOST_TEST(
+ std::distance(
+ get<age>(es).lower_bound("27",comp_int_string()),
+ get<age>(es).upper_bound("40",comp_int_string()))==3);
+
+ BOOST_TEST(es.count(2,employee::comp_id())==1);
+ BOOST_TEST(es.count(5,employee::comp_id())==0);
+}
diff --git a/src/boost/libs/multi_index/test/test_special_set_ops.hpp b/src/boost/libs/multi_index/test/test_special_set_ops.hpp
new file mode 100644
index 000000000..a9434de58
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_special_set_ops.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for special set operations.
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_special_set_ops();
diff --git a/src/boost/libs/multi_index/test/test_special_set_ops_main.cpp b/src/boost/libs/multi_index/test/test_special_set_ops_main.cpp
new file mode 100644
index 000000000..843f86d0c
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_special_set_ops_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for special set operations.
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_special_set_ops.hpp"
+
+int main()
+{
+ test_special_set_ops();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test/test_update.cpp b/src/boost/libs/multi_index/test/test_update.cpp
new file mode 100644
index 000000000..56e9c827f
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_update.cpp
@@ -0,0 +1,281 @@
+/* Boost.MultiIndex test for replace(), modify() and modify_key().
+ *
+ * Copyright 2003-2018 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include "test_update.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <cstddef>
+#include "pre_multi_index.hpp"
+#include "employee.hpp"
+#include "pair_of_ints.hpp"
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/next_prior.hpp>
+
+struct do_nothing
+{
+ template<typename T>
+ void operator()(const T&)const{}
+};
+
+struct null_hash
+{
+ template<typename T>
+ std::size_t operator()(const T&)const{return 0;}
+};
+
+struct assign_value
+{
+ assign_value(int n):n_(n){}
+
+ void operator()(int& x)const{x=n_;}
+
+ int n_;
+};
+
+template<class MultiIndexContainer>
+void test_stable_update()
+{
+ typedef typename MultiIndexContainer::iterator iterator;
+ typedef typename MultiIndexContainer::size_type size_type;
+ typedef typename MultiIndexContainer::difference_type difference_type;
+
+ MultiIndexContainer c;
+ c.insert(0);
+ c.insert(1);c.insert(1);
+ c.insert(2);c.insert(2);c.insert(2);c.insert(2);
+ c.insert(3);
+ c.insert(4);c.insert(4);c.insert(4);
+ c.insert(5);c.insert(5);
+ c.insert(6);
+ c.insert(7);
+ size_type num_elems=
+ c.count(0)+c.count(1)+c.count(2)+c.count(3)+
+ c.count(4)+c.count(5)+c.count(6)+c.count(7);
+
+ for(size_type n=c.size();n--;){
+ iterator it=boost::next(c.begin(),(difference_type)n);
+
+ c.replace(it,*it);
+ BOOST_TEST((size_type)std::distance(c.begin(),it)==n);
+
+ c.modify(it,do_nothing());
+ BOOST_TEST((size_type)std::distance(c.begin(),it)==n);
+
+ c.modify(it,do_nothing(),do_nothing());
+ BOOST_TEST((size_type)std::distance(c.begin(),it)==n);
+
+ for(int i=0;i<=8;++i){
+ MultiIndexContainer cpy(c);
+ bool b=c.modify(it,assign_value(i),assign_value(*it));
+ BOOST_TEST(b||(size_type)std::distance(c.begin(),it)==n);
+ BOOST_TEST(c.count(0)+c.count(1)+c.count(2)+c.count(3)+c.count(4)+
+ c.count(5)+c.count(6)+c.count(7)+c.count(8)==num_elems);
+ if(b){
+ c=cpy;
+ it=boost::next(c.begin(),(difference_type)n);
+ }
+ }
+ }
+}
+
+using namespace boost::multi_index;
+
+void test_update()
+{
+ employee_set es;
+ employee_set_as_inserted& i=get<as_inserted>(es);
+ employee_set_randomly& r=get<randomly>(es);
+
+ es.insert(employee(0,"Joe",31,1123));
+ es.insert(employee(1,"Robert",27,5601));
+ es.insert(employee(2,"John",40,7889));
+ es.insert(employee(3,"Olbert",20,9012));
+ es.insert(employee(4,"John",57,1002));
+
+ employee_set::iterator it=es.find(employee(0,"Joe",31,1123));
+ employee_set_as_inserted::iterator it1=
+ project<as_inserted>(es,get<name>(es).find("Olbert"));
+ employee_set_randomly::iterator it2=
+ project<randomly>(es,get<age>(es).find(57));
+
+ BOOST_TEST(es.replace(it,*it));
+ BOOST_TEST(i.replace(it1,*it1));
+ BOOST_TEST(r.replace(it2,*it2));
+ BOOST_TEST(!es.replace(it,employee(3,"Joe",31,1123))&&it->id==0);
+ BOOST_TEST(es.replace(it,employee(0,"Joe",32,1123))&&it->age==32);
+ BOOST_TEST(i.replace(it1,employee(3,"Albert",20,9012))&&it1->name==
+ "Albert");
+ BOOST_TEST(!r.replace(it2,employee(4,"John",57,5601)));
+
+ {
+ typedef multi_index_container<
+ pair_of_ints,
+ indexed_by<
+ ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
+ hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)>,
+ sequenced<> > >
+ int_int_set;
+
+ int_int_set iis;
+ nth_index<int_int_set,1>::type& ii1=get<1>(iis);
+ nth_index<int_int_set,2>::type& ii2=get<2>(iis);
+ iis.insert(pair_of_ints(0,0));
+ iis.insert(pair_of_ints(5,5));
+ iis.insert(pair_of_ints(10,10));
+
+ BOOST_TEST(!iis.replace(iis.begin(),pair_of_ints(5,0)));
+ BOOST_TEST(!ii2.replace(ii2.begin(),pair_of_ints(0,5)));
+ BOOST_TEST(!ii1.replace(project<1>(iis,iis.begin()),pair_of_ints(5,11)));
+ BOOST_TEST(!iis.replace(iis.begin(),pair_of_ints(11,5)));
+ BOOST_TEST(!iis.replace(boost::next(iis.begin()),pair_of_ints(10,5)));
+ BOOST_TEST(!ii1.replace(
+ project<1>(iis,boost::next(iis.begin())),pair_of_ints(5,10)));
+ BOOST_TEST(!iis.replace(boost::prior(iis.end()),pair_of_ints(5,10)));
+ BOOST_TEST(!ii2.replace(boost::prior(ii2.end()),pair_of_ints(10,5)));
+
+ BOOST_TEST(iis.modify(iis.begin(),increment_first));
+ BOOST_TEST(ii2.modify(ii2.begin(),increment_first));
+ BOOST_TEST(ii1.modify(project<1>(iis,iis.begin()),increment_first));
+ BOOST_TEST(ii2.modify(ii2.begin(),increment_first,decrement_first));
+
+ BOOST_TEST(!iis.modify(iis.begin(),increment_first,decrement_first));
+ BOOST_TEST(iis.size()==3);
+
+ BOOST_TEST(!iis.modify(iis.begin(),increment_first));
+ BOOST_TEST(iis.size()==2);
+
+ iis.insert(pair_of_ints(0,0));
+ BOOST_TEST(ii2.modify(boost::prior(ii2.end()),increment_second));
+ BOOST_TEST(iis.modify(iis.begin(),increment_second));
+ BOOST_TEST(ii2.modify(boost::prior(ii2.end()),increment_second));
+ BOOST_TEST(iis.modify(iis.begin(),increment_second,decrement_second));
+
+ BOOST_TEST(!ii2.modify(
+ boost::prior(ii2.end()),increment_second,decrement_second));
+ BOOST_TEST(ii2.size()==3);
+
+ BOOST_TEST(!ii2.modify(boost::prior(ii2.end()),increment_second));
+ BOOST_TEST(ii2.size()==2);
+
+ iis.insert(pair_of_ints(0,0));
+ BOOST_TEST(iis.modify_key(iis.begin(),increment_int));
+ BOOST_TEST(iis.modify_key(iis.begin(),increment_int,decrement_int));
+ BOOST_TEST(iis.modify_key(iis.begin(),increment_int));
+ BOOST_TEST(iis.modify_key(iis.begin(),increment_int));
+
+ BOOST_TEST(!iis.modify_key(iis.begin(),increment_int,decrement_int));
+ BOOST_TEST(iis.size()==3);
+
+ BOOST_TEST(!iis.modify_key(iis.begin(),increment_int));
+ BOOST_TEST(iis.size()==2);
+
+ nth_index_iterator<int_int_set,1>::type it_=ii1.find(5);
+ BOOST_TEST(ii1.modify_key(it_,increment_int));
+ BOOST_TEST(ii1.modify_key(it_,increment_int));
+ BOOST_TEST(ii1.modify_key(it_,increment_int,decrement_int));
+ BOOST_TEST(ii1.modify_key(it_,increment_int));
+
+ BOOST_TEST(!ii1.modify_key(it_,increment_int,decrement_int));
+ BOOST_TEST(ii1.size()==2);
+
+ BOOST_TEST(!ii1.modify_key(it_,increment_int));
+ BOOST_TEST(ii1.size()==1);
+ }
+ {
+ typedef multi_index_container<
+ pair_of_ints,
+ indexed_by<
+ hashed_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first)>,
+ random_access<>,
+ ordered_unique<BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second)> > >
+ int_int_set;
+
+ int_int_set iis;
+ nth_index<int_int_set,1>::type& ii1=get<1>(iis);
+ int_int_set::iterator p1=iis.insert(pair_of_ints(0,0)).first;
+ int_int_set::iterator p2=iis.insert(pair_of_ints(5,5)).first;
+ int_int_set::iterator p3=iis.insert(pair_of_ints(10,10)).first;
+
+ BOOST_TEST(!iis.replace(p1,pair_of_ints(5,0)));
+ BOOST_TEST(!ii1.replace(ii1.begin(),pair_of_ints(0,5)));
+ BOOST_TEST(!iis.replace(p1,pair_of_ints(5,11)));
+ BOOST_TEST(!iis.replace(p1,pair_of_ints(11,5)));
+ BOOST_TEST(!iis.replace(p2,pair_of_ints(10,5)));
+ BOOST_TEST(!iis.replace(p2,pair_of_ints(5,10)));
+ BOOST_TEST(!iis.replace(p3,pair_of_ints(5,10)));
+ BOOST_TEST(!ii1.replace(boost::prior(ii1.end()),pair_of_ints(10,5)));
+
+ BOOST_TEST(iis.modify(p1,increment_first));
+ BOOST_TEST(ii1.modify(ii1.begin(),increment_first));
+ BOOST_TEST(iis.modify(p1,increment_first));
+ BOOST_TEST(ii1.modify(ii1.begin(),increment_first,decrement_first));
+
+ BOOST_TEST(!iis.modify(p1,increment_first,decrement_first));
+ BOOST_TEST(iis.size()==3);
+
+ BOOST_TEST(!iis.modify(p1,increment_first));
+ BOOST_TEST(iis.size()==2);
+
+ p1=iis.insert(pair_of_ints(0,0)).first;
+ BOOST_TEST(ii1.modify(boost::prior(ii1.end()),increment_second));
+ BOOST_TEST(iis.modify(p1,increment_second,decrement_second));
+ BOOST_TEST(ii1.modify(boost::prior(ii1.end()),increment_second));
+ BOOST_TEST(iis.modify(p1,increment_second));
+
+ BOOST_TEST(!ii1.modify(
+ boost::prior(ii1.end()),increment_second,decrement_second));
+ BOOST_TEST(ii1.size()==3);
+
+ BOOST_TEST(!ii1.modify(boost::prior(ii1.end()),increment_second));
+ BOOST_TEST(ii1.size()==2);
+ }
+ {
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ ordered_non_unique<identity<int> >
+ >
+ > int_multiset;
+ test_stable_update<int_multiset>();
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ hashed_unique<identity<int> >
+ >
+ > int_hashed_set;
+ test_stable_update<int_hashed_set>();
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ hashed_unique<identity<int> >
+ >
+ > int_hashed_multiset;
+ test_stable_update<int_hashed_multiset>();
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ hashed_unique<identity<int>,null_hash>
+ >
+ > degenerate_int_hashed_set;
+ test_stable_update<degenerate_int_hashed_set>();
+
+ typedef multi_index_container<
+ int,
+ indexed_by<
+ hashed_non_unique<identity<int>,null_hash>
+ >
+ > degenerate_int_hashed_multiset;
+ test_stable_update<degenerate_int_hashed_multiset>();
+ }
+}
diff --git a/src/boost/libs/multi_index/test/test_update.hpp b/src/boost/libs/multi_index/test/test_update.hpp
new file mode 100644
index 000000000..ec7424b64
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_update.hpp
@@ -0,0 +1,11 @@
+/* Boost.MultiIndex test for replace(), modify() and modify_key().
+ *
+ * Copyright 2003-2008 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+void test_update();
diff --git a/src/boost/libs/multi_index/test/test_update_main.cpp b/src/boost/libs/multi_index/test/test_update_main.cpp
new file mode 100644
index 000000000..4fa2dba1b
--- /dev/null
+++ b/src/boost/libs/multi_index/test/test_update_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.MultiIndex test for replace(), modify() and modify_key().
+ *
+ * Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under 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)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#include <boost/detail/lightweight_test.hpp>
+#include "test_update.hpp"
+
+int main()
+{
+ test_update();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/multi_index/test_results.svg b/src/boost/libs/multi_index/test_results.svg
new file mode 100644
index 000000000..d3d613ffd
--- /dev/null
+++ b/src/boost/libs/multi_index/test_results.svg
@@ -0,0 +1,26 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="95" height="20">
+ <linearGradient id="b" x2="0" y2="100%">
+ <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
+ <stop offset="1" stop-opacity=".1"/>
+ </linearGradient>
+ <clipPath id="a">
+ <rect width="95" height="20" rx="3" fill="#fff"/>
+ </clipPath>
+ <g clip-path="url(#a)">
+ <path fill="#555" d="M0 0h48v20H0z"/>
+ <path fill="#4c1" d="M48 0h47v20H48z"/>
+ <path fill="url(#b)" d="M0 0h95v20H0z"/>
+ </g>
+ <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110">
+ <path fill="#fff" d="M 10.8566 9.70598 l -3.60307 0 l -0.0903426 0.15447 l -1.63598 2.79514 l -0.0919027 0.156812 l 0.0912783 0.157278 l 1.63599 2.82198 l 0.0901858 0.155564 l 3.60291 0 l 0.090498 -0.153378 l 1.64956 -2.79498 l 0.093151 -0.157907 l -0.0923709 -0.158212 l -1.64956 -2.82213 l -0.0903415 -0.154627 z m -5.06008 3.1072 l 1.63598 -2.79514 l 3.24498 0 l 1.64956 2.82213 l -1.64956 2.79498 l -3.24498 0 l -1.63598 -2.82198 z"/>
+ <path fill="#fff" d="M 16.6973 6.54947 l -3.6026 0 l -0.090185 0.155562 l -1.54689 2.67 l -0.0906544 0.156655 l 0.0908101 0.1565 l 1.72508 2.97067 l 0.0908101 0.156188 l 0.180528 -0.000780746 l 3.06679 -0.0137328 l 0.178187 -0.000780746 l 0.0898736 -0.153845 l 1.65658 -2.83383 l 0.0926823 -0.158528 l -0.093773 -0.15806 l -1.65658 -2.79311 l -0.0906529 -0.15291 z m -4.96959 2.98206 l 1.54689 -2.67 l 3.24498 0 l 1.65658 2.79311 l -1.65658 2.83383 l -3.06679 0.0137328 l -1.72508 -2.97067 z"/>
+ <path fill="#fff" d="M 12.4576 4.03269 l -3.56874 0 l -0.0898744 0.156967 l -1.61336 2.81683 l -0.0875335 0.152755 l 0.0855053 0.153848 l 0.991265 1.78437 l 0.0887818 0.160088 l 0.183024 0.000468606 l 2.38603 0.00686454 l 0.178812 0.000468606 l 0.0909666 -0.154003 l 1.72804 -2.92995 l 0.850837 0 l -0.265721 -0.466534 l -0.868311 -1.52458 l -0.0897187 -0.15759 z m -5.00126 3.12889 l 1.61336 -2.81683 l 3.20644 0 l 0.868313 1.52458 l -0.492278 0 l -1.81854 3.08348 l -2.38603 -0.00686454 l -0.991265 -1.78437 z"/>
+ <path fill="#cccccc" d="M 10.8566 9.70598 m -5.06008 3.1072 l 1.63598 -2.79514 l 3.24498 0 l 1.64956 2.82213 l -1.64956 2.79498 l -3.24498 0 l -1.63598 -2.82198 z"/>
+ <path fill="#cccccc" d="M 16.6973 6.54947 m -4.96959 2.98206 l 1.54689 -2.67 l 3.24498 0 l 1.65658 2.79311 l -1.65658 2.83383 l -3.06679 0.0137328 l -1.72508 -2.97067 z"/>
+ <path fill="#cccccc" d="M 12.4576 4.03269 m -5.00126 3.12889 l 1.61336 -2.81683 l 3.20644 0 l 0.868313 1.52458 l -0.492278 0 l -1.81854 3.08348 l -2.38603 -0.00686454 l -0.991265 -1.78437 z"/>
+ <text x="335" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="210">test</text>
+ <text x="335" y="140" transform="scale(.1)" textLength="210">test</text>
+ <text x="705" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">results</text>
+ <text x="705" y="140" transform="scale(.1)" textLength="370">results</text>
+ </g>
+</svg> \ No newline at end of file