From f40d275dc14d8fcecde23c077d36305232177d9a Mon Sep 17 00:00:00 2001 From: Andy Schwerin Date: Tue, 3 Jun 2014 18:27:14 -0400 Subject: SERVER-14152 Import sufficient components of boost 1.49 to support boost::container::list. --- .../boost/container/allocator/allocator_traits.hpp | 382 +++ .../boost/container/allocator/memory_util.hpp | 77 + .../boost/container/allocator/scoped_allocator.hpp | 651 ++++ src/third_party/boost/boost/container/deque.hpp | 2011 ++++++++++++ .../container/detail/adaptive_node_pool_impl.hpp | 648 ++++ .../boost/container/detail/advanced_insert_int.hpp | 428 +++ .../boost/boost/container/detail/algorithms.hpp | 60 + .../boost/container/detail/allocation_type.hpp | 54 + .../boost/boost/container/detail/config_begin.hpp | 48 + .../boost/boost/container/detail/config_end.hpp | 17 + .../boost/boost/container/detail/destroyers.hpp | 163 + .../boost/boost/container/detail/flat_tree.hpp | 822 +++++ .../boost/container/detail/function_detector.hpp | 88 + .../boost/boost/container/detail/iterators.hpp | 548 ++++ .../boost/container/detail/math_functions.hpp | 113 + .../boost/boost/container/detail/mpl.hpp | 160 + .../container/detail/multiallocation_chain.hpp | 254 ++ .../boost/container/detail/node_alloc_holder.hpp | 488 +++ .../boost/container/detail/node_pool_impl.hpp | 367 +++ .../boost/boost/container/detail/pair.hpp | 320 ++ .../boost/boost/container/detail/pool_common.hpp | 52 + .../boost/boost/container/detail/preprocessor.hpp | 178 ++ .../boost/boost/container/detail/stored_ref.hpp | 92 + .../boost/container/detail/transform_iterator.hpp | 176 ++ .../boost/boost/container/detail/tree.hpp | 1154 +++++++ .../boost/boost/container/detail/type_traits.hpp | 203 ++ .../boost/boost/container/detail/utilities.hpp | 271 ++ .../boost/boost/container/detail/value_init.hpp | 45 + .../container/detail/variadic_templates_tools.hpp | 153 + .../boost/boost/container/detail/version_type.hpp | 92 + .../boost/boost/container/detail/workaround.hpp | 31 + src/third_party/boost/boost/container/flat_map.hpp | 1457 +++++++++ src/third_party/boost/boost/container/flat_set.hpp | 1265 ++++++++ src/third_party/boost/boost/container/list.hpp | 1371 +++++++++ src/third_party/boost/boost/container/map.hpp | 1317 ++++++++ src/third_party/boost/boost/container/set.hpp | 1176 ++++++++ src/third_party/boost/boost/container/slist.hpp | 1549 ++++++++++ .../boost/boost/container/stable_vector.hpp | 1818 +++++++++++ src/third_party/boost/boost/container/string.hpp | 2895 ++++++++++++++++++ src/third_party/boost/boost/container/vector.hpp | 2036 +++++++++++++ src/third_party/boost/boost/intrusive/any_hook.hpp | 344 +++ src/third_party/boost/boost/intrusive/avl_set.hpp | 2358 +++++++++++++++ .../boost/boost/intrusive/avl_set_hook.hpp | 297 ++ src/third_party/boost/boost/intrusive/avltree.hpp | 1688 +++++++++++ .../boost/boost/intrusive/avltree_algorithms.hpp | 943 ++++++ .../boost/boost/intrusive/bs_set_hook.hpp | 296 ++ .../boost/intrusive/circular_list_algorithms.hpp | 413 +++ .../boost/intrusive/circular_slist_algorithms.hpp | 405 +++ .../boost/intrusive/derivation_value_traits.hpp | 70 + .../intrusive/detail/any_node_and_algorithms.hpp | 297 ++ .../boost/boost/intrusive/detail/assert.hpp | 41 + .../boost/boost/intrusive/detail/avltree_node.hpp | 185 ++ .../intrusive/detail/clear_on_destructor_base.hpp | 36 + .../intrusive/detail/common_slist_algorithms.hpp | 103 + .../boost/boost/intrusive/detail/config_begin.hpp | 52 + .../boost/boost/intrusive/detail/config_end.hpp | 15 + .../boost/intrusive/detail/ebo_functor_holder.hpp | 95 + .../boost/intrusive/detail/function_detector.hpp | 88 + .../boost/boost/intrusive/detail/generic_hook.hpp | 209 ++ .../detail/has_member_function_callable_with.hpp | 356 +++ .../boost/intrusive/detail/hashtable_node.hpp | 249 ++ .../intrusive/detail/is_stateful_value_traits.hpp | 77 + .../boost/boost/intrusive/detail/list_node.hpp | 190 ++ .../boost/boost/intrusive/detail/memory_util.hpp | 279 ++ .../boost/boost/intrusive/detail/mpl.hpp | 355 +++ .../boost/intrusive/detail/parent_from_member.hpp | 69 + .../boost/boost/intrusive/detail/preprocessor.hpp | 52 + .../boost/boost/intrusive/detail/rbtree_node.hpp | 177 ++ .../boost/boost/intrusive/detail/slist_node.hpp | 163 + .../boost/intrusive/detail/transform_iterator.hpp | 173 ++ .../boost/intrusive/detail/tree_algorithms.hpp | 1697 +++++++++++ .../boost/boost/intrusive/detail/tree_node.hpp | 190 ++ .../boost/boost/intrusive/detail/utilities.hpp | 879 ++++++ .../boost/boost/intrusive/detail/workaround.hpp | 22 + .../boost/boost/intrusive/hashtable.hpp | 3188 ++++++++++++++++++++ .../boost/boost/intrusive/intrusive_fwd.hpp | 542 ++++ .../boost/intrusive/linear_slist_algorithms.hpp | 327 ++ .../boost/boost/intrusive/link_mode.hpp | 46 + src/third_party/boost/boost/intrusive/list.hpp | 1525 ++++++++++ .../boost/boost/intrusive/list_hook.hpp | 290 ++ .../boost/boost/intrusive/member_value_traits.hpp | 70 + src/third_party/boost/boost/intrusive/options.hpp | 812 +++++ .../boost/boost/intrusive/parent_from_member.hpp | 42 + .../boost/boost/intrusive/pointer_plus_bits.hpp | 82 + .../boost/boost/intrusive/pointer_traits.hpp | 265 ++ .../boost/boost/intrusive/priority_compare.hpp | 39 + src/third_party/boost/boost/intrusive/rbtree.hpp | 1687 +++++++++++ .../boost/boost/intrusive/rbtree_algorithms.hpp | 910 ++++++ src/third_party/boost/boost/intrusive/set.hpp | 2384 +++++++++++++++ src/third_party/boost/boost/intrusive/set_hook.hpp | 300 ++ src/third_party/boost/boost/intrusive/sg_set.hpp | 2431 +++++++++++++++ src/third_party/boost/boost/intrusive/sgtree.hpp | 1911 ++++++++++++ .../boost/boost/intrusive/sgtree_algorithms.hpp | 782 +++++ src/third_party/boost/boost/intrusive/slist.hpp | 2134 +++++++++++++ .../boost/boost/intrusive/slist_hook.hpp | 294 ++ .../boost/boost/intrusive/splay_set.hpp | 2403 +++++++++++++++ .../boost/boost/intrusive/splay_set_hook.hpp | 292 ++ .../boost/boost/intrusive/splaytree.hpp | 1686 +++++++++++ .../boost/boost/intrusive/splaytree_algorithms.hpp | 973 ++++++ src/third_party/boost/boost/intrusive/treap.hpp | 1784 +++++++++++ .../boost/boost/intrusive/treap_algorithms.hpp | 895 ++++++ .../boost/boost/intrusive/treap_set.hpp | 2581 ++++++++++++++++ .../boost/boost/intrusive/trivial_value_traits.hpp | 46 + .../boost/boost/intrusive/unordered_set.hpp | 2115 +++++++++++++ .../boost/boost/intrusive/unordered_set_hook.hpp | 434 +++ src/third_party/boost/boost/move/move_helpers.hpp | 173 ++ .../boost/boost/preprocessor.textClipping | 0 .../boost/boost/preprocessor/arithmetic.hpp | 25 + .../boost/boost/preprocessor/arithmetic/div.hpp | 39 + .../boost/boost/preprocessor/arithmetic/mul.hpp | 53 + src/third_party/boost/boost/preprocessor/array.hpp | 32 + .../boost/boost/preprocessor/array/enum.hpp | 33 + .../boost/boost/preprocessor/array/insert.hpp | 55 + .../boost/boost/preprocessor/array/pop_back.hpp | 37 + .../boost/boost/preprocessor/array/pop_front.hpp | 38 + .../boost/boost/preprocessor/array/push_back.hpp | 33 + .../boost/boost/preprocessor/array/push_front.hpp | 33 + .../boost/boost/preprocessor/array/remove.hpp | 54 + .../boost/boost/preprocessor/array/replace.hpp | 49 + .../boost/boost/preprocessor/array/reverse.hpp | 29 + .../boost/boost/preprocessor/array/to_list.hpp | 33 + .../boost/boost/preprocessor/array/to_seq.hpp | 33 + .../boost/boost/preprocessor/array/to_tuple.hpp | 22 + .../boost/boost/preprocessor/assert_msg.hpp | 17 + src/third_party/boost/boost/preprocessor/comma.hpp | 17 + .../boost/boost/preprocessor/comparison.hpp | 24 + .../boost/boost/preprocessor/comparison/equal.hpp | 34 + .../boost/preprocessor/comparison/greater.hpp | 38 + .../preprocessor/comparison/greater_equal.hpp | 38 + .../boost/boost/preprocessor/comparison/less.hpp | 46 + .../boost/preprocessor/comparison/not_equal.hpp | 814 +++++ .../boost/boost/preprocessor/config/limits.hpp | 30 + .../boost/boost/preprocessor/control.hpp | 22 + src/third_party/boost/boost/preprocessor/debug.hpp | 18 + .../boost/boost/preprocessor/debug/assert.hpp | 44 + .../boost/boost/preprocessor/debug/line.hpp | 35 + .../boost/boost/preprocessor/detail/is_nullary.hpp | 30 + .../boost/boost/preprocessor/detail/null.hpp | 17 + .../boost/boost/preprocessor/detail/split.hpp | 35 + .../boost/boost/preprocessor/enum_shifted.hpp | 17 + .../boost/boost/preprocessor/expand.hpp | 17 + .../boost/boost/preprocessor/facilities.hpp | 23 + .../boost/boost/preprocessor/facilities/apply.hpp | 34 + .../boost/boost/preprocessor/facilities/expand.hpp | 28 + .../boost/boost/preprocessor/facilities/is_1.hpp | 23 + .../boost/preprocessor/facilities/is_empty.hpp | 43 + .../preprocessor/facilities/is_empty_or_1.hpp | 30 + src/third_party/boost/boost/preprocessor/for.hpp | 17 + .../boost/boost/preprocessor/iteration.hpp | 19 + .../boost/boost/preprocessor/library.hpp | 36 + .../boost/boost/preprocessor/limits.hpp | 17 + src/third_party/boost/boost/preprocessor/list.hpp | 37 + .../boost/boost/preprocessor/list/at.hpp | 39 + .../boost/boost/preprocessor/list/cat.hpp | 42 + .../boost/boost/preprocessor/list/enum.hpp | 41 + .../boost/boost/preprocessor/list/filter.hpp | 54 + .../boost/boost/preprocessor/list/first_n.hpp | 58 + .../boost/boost/preprocessor/list/for_each.hpp | 49 + .../boost/preprocessor/list/for_each_product.hpp | 141 + .../boost/boost/preprocessor/list/rest_n.hpp | 55 + .../boost/boost/preprocessor/list/size.hpp | 58 + .../boost/boost/preprocessor/list/to_array.hpp | 123 + .../boost/boost/preprocessor/list/to_seq.hpp | 32 + .../boost/boost/preprocessor/list/to_tuple.hpp | 38 + .../boost/boost/preprocessor/logical.hpp | 29 + .../boost/boost/preprocessor/logical/bitnor.hpp | 38 + .../boost/boost/preprocessor/logical/bitxor.hpp | 38 + .../boost/boost/preprocessor/logical/nor.hpp | 30 + .../boost/boost/preprocessor/logical/xor.hpp | 30 + src/third_party/boost/boost/preprocessor/max.hpp | 17 + src/third_party/boost/boost/preprocessor/min.hpp | 17 + .../boost/boost/preprocessor/punctuation.hpp | 20 + .../boost/preprocessor/punctuation/paren_if.hpp | 38 + .../boost/boost/preprocessor/repeat_2nd.hpp | 17 + .../boost/boost/preprocessor/repeat_3rd.hpp | 17 + .../boost/preprocessor/repeat_from_to_2nd.hpp | 17 + .../boost/preprocessor/repeat_from_to_3rd.hpp | 17 + .../boost/boost/preprocessor/repetition.hpp | 32 + .../boost/preprocessor/repetition/deduce_r.hpp | 22 + .../boost/preprocessor/repetition/deduce_z.hpp | 22 + .../boost/preprocessor/repetition/enum_shifted.hpp | 68 + .../repetition/enum_shifted_binary_params.hpp | 51 + .../repetition/enum_trailing_binary_params.hpp | 53 + .../boost/boost/preprocessor/selection.hpp | 18 + .../boost/boost/preprocessor/selection/max.hpp | 39 + .../boost/boost/preprocessor/selection/min.hpp | 39 + src/third_party/boost/boost/preprocessor/seq.hpp | 43 + .../preprocessor/seq/detail/binary_transform.hpp | 40 + .../boost/boost/preprocessor/seq/filter.hpp | 54 + .../boost/boost/preprocessor/seq/fold_right.hpp | 288 ++ .../boost/preprocessor/seq/for_each_product.hpp | 126 + .../boost/boost/preprocessor/seq/insert.hpp | 28 + .../boost/boost/preprocessor/seq/pop_back.hpp | 29 + .../boost/boost/preprocessor/seq/pop_front.hpp | 27 + .../boost/boost/preprocessor/seq/push_back.hpp | 19 + .../boost/boost/preprocessor/seq/push_front.hpp | 19 + .../boost/boost/preprocessor/seq/remove.hpp | 29 + .../boost/boost/preprocessor/seq/replace.hpp | 29 + .../boost/boost/preprocessor/seq/reverse.hpp | 39 + .../boost/boost/preprocessor/seq/to_array.hpp | 28 + .../boost/boost/preprocessor/seq/to_list.hpp | 29 + .../boost/boost/preprocessor/seq/to_tuple.hpp | 27 + src/third_party/boost/boost/preprocessor/slot.hpp | 17 + .../boost/boost/preprocessor/slot/counter.hpp | 25 + src/third_party/boost/boost/preprocessor/tuple.hpp | 28 + .../boost/boost/preprocessor/tuple/enum.hpp | 22 + .../boost/boost/preprocessor/tuple/reverse.hpp | 114 + .../boost/boost/preprocessor/tuple/size.hpp | 28 + .../boost/boost/preprocessor/tuple/to_array.hpp | 37 + .../boost/boost/preprocessor/tuple/to_seq.hpp | 114 + .../boost/boost/preprocessor/variadic.hpp | 23 + .../boost/boost/preprocessor/variadic/to_array.hpp | 32 + .../boost/boost/preprocessor/variadic/to_list.hpp | 25 + .../boost/boost/preprocessor/variadic/to_seq.hpp | 25 + .../boost/boost/preprocessor/variadic/to_tuple.hpp | 24 + src/third_party/boost/boost/preprocessor/while.hpp | 17 + .../boost/boost/preprocessor/wstringize.hpp | 29 + 217 files changed, 76347 insertions(+) create mode 100644 src/third_party/boost/boost/container/allocator/allocator_traits.hpp create mode 100644 src/third_party/boost/boost/container/allocator/memory_util.hpp create mode 100644 src/third_party/boost/boost/container/allocator/scoped_allocator.hpp create mode 100644 src/third_party/boost/boost/container/deque.hpp create mode 100644 src/third_party/boost/boost/container/detail/adaptive_node_pool_impl.hpp create mode 100644 src/third_party/boost/boost/container/detail/advanced_insert_int.hpp create mode 100644 src/third_party/boost/boost/container/detail/algorithms.hpp create mode 100644 src/third_party/boost/boost/container/detail/allocation_type.hpp create mode 100644 src/third_party/boost/boost/container/detail/config_begin.hpp create mode 100644 src/third_party/boost/boost/container/detail/config_end.hpp create mode 100644 src/third_party/boost/boost/container/detail/destroyers.hpp create mode 100644 src/third_party/boost/boost/container/detail/flat_tree.hpp create mode 100644 src/third_party/boost/boost/container/detail/function_detector.hpp create mode 100644 src/third_party/boost/boost/container/detail/iterators.hpp create mode 100644 src/third_party/boost/boost/container/detail/math_functions.hpp create mode 100644 src/third_party/boost/boost/container/detail/mpl.hpp create mode 100644 src/third_party/boost/boost/container/detail/multiallocation_chain.hpp create mode 100644 src/third_party/boost/boost/container/detail/node_alloc_holder.hpp create mode 100644 src/third_party/boost/boost/container/detail/node_pool_impl.hpp create mode 100644 src/third_party/boost/boost/container/detail/pair.hpp create mode 100644 src/third_party/boost/boost/container/detail/pool_common.hpp create mode 100644 src/third_party/boost/boost/container/detail/preprocessor.hpp create mode 100644 src/third_party/boost/boost/container/detail/stored_ref.hpp create mode 100644 src/third_party/boost/boost/container/detail/transform_iterator.hpp create mode 100644 src/third_party/boost/boost/container/detail/tree.hpp create mode 100644 src/third_party/boost/boost/container/detail/type_traits.hpp create mode 100644 src/third_party/boost/boost/container/detail/utilities.hpp create mode 100644 src/third_party/boost/boost/container/detail/value_init.hpp create mode 100644 src/third_party/boost/boost/container/detail/variadic_templates_tools.hpp create mode 100644 src/third_party/boost/boost/container/detail/version_type.hpp create mode 100644 src/third_party/boost/boost/container/detail/workaround.hpp create mode 100644 src/third_party/boost/boost/container/flat_map.hpp create mode 100644 src/third_party/boost/boost/container/flat_set.hpp create mode 100644 src/third_party/boost/boost/container/list.hpp create mode 100644 src/third_party/boost/boost/container/map.hpp create mode 100644 src/third_party/boost/boost/container/set.hpp create mode 100644 src/third_party/boost/boost/container/slist.hpp create mode 100644 src/third_party/boost/boost/container/stable_vector.hpp create mode 100644 src/third_party/boost/boost/container/string.hpp create mode 100644 src/third_party/boost/boost/container/vector.hpp create mode 100644 src/third_party/boost/boost/intrusive/any_hook.hpp create mode 100644 src/third_party/boost/boost/intrusive/avl_set.hpp create mode 100644 src/third_party/boost/boost/intrusive/avl_set_hook.hpp create mode 100644 src/third_party/boost/boost/intrusive/avltree.hpp create mode 100644 src/third_party/boost/boost/intrusive/avltree_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/bs_set_hook.hpp create mode 100644 src/third_party/boost/boost/intrusive/circular_list_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/circular_slist_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/derivation_value_traits.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/any_node_and_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/assert.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/avltree_node.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/clear_on_destructor_base.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/common_slist_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/config_begin.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/config_end.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/ebo_functor_holder.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/function_detector.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/generic_hook.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/has_member_function_callable_with.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/hashtable_node.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/is_stateful_value_traits.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/list_node.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/memory_util.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/mpl.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/parent_from_member.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/preprocessor.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/rbtree_node.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/slist_node.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/transform_iterator.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/tree_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/tree_node.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/utilities.hpp create mode 100644 src/third_party/boost/boost/intrusive/detail/workaround.hpp create mode 100644 src/third_party/boost/boost/intrusive/hashtable.hpp create mode 100644 src/third_party/boost/boost/intrusive/intrusive_fwd.hpp create mode 100644 src/third_party/boost/boost/intrusive/linear_slist_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/link_mode.hpp create mode 100644 src/third_party/boost/boost/intrusive/list.hpp create mode 100644 src/third_party/boost/boost/intrusive/list_hook.hpp create mode 100644 src/third_party/boost/boost/intrusive/member_value_traits.hpp create mode 100644 src/third_party/boost/boost/intrusive/options.hpp create mode 100644 src/third_party/boost/boost/intrusive/parent_from_member.hpp create mode 100644 src/third_party/boost/boost/intrusive/pointer_plus_bits.hpp create mode 100644 src/third_party/boost/boost/intrusive/pointer_traits.hpp create mode 100644 src/third_party/boost/boost/intrusive/priority_compare.hpp create mode 100644 src/third_party/boost/boost/intrusive/rbtree.hpp create mode 100644 src/third_party/boost/boost/intrusive/rbtree_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/set.hpp create mode 100644 src/third_party/boost/boost/intrusive/set_hook.hpp create mode 100644 src/third_party/boost/boost/intrusive/sg_set.hpp create mode 100644 src/third_party/boost/boost/intrusive/sgtree.hpp create mode 100644 src/third_party/boost/boost/intrusive/sgtree_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/slist.hpp create mode 100644 src/third_party/boost/boost/intrusive/slist_hook.hpp create mode 100644 src/third_party/boost/boost/intrusive/splay_set.hpp create mode 100644 src/third_party/boost/boost/intrusive/splay_set_hook.hpp create mode 100644 src/third_party/boost/boost/intrusive/splaytree.hpp create mode 100644 src/third_party/boost/boost/intrusive/splaytree_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/treap.hpp create mode 100644 src/third_party/boost/boost/intrusive/treap_algorithms.hpp create mode 100644 src/third_party/boost/boost/intrusive/treap_set.hpp create mode 100644 src/third_party/boost/boost/intrusive/trivial_value_traits.hpp create mode 100644 src/third_party/boost/boost/intrusive/unordered_set.hpp create mode 100644 src/third_party/boost/boost/intrusive/unordered_set_hook.hpp create mode 100644 src/third_party/boost/boost/move/move_helpers.hpp create mode 100644 src/third_party/boost/boost/preprocessor.textClipping create mode 100644 src/third_party/boost/boost/preprocessor/arithmetic.hpp create mode 100644 src/third_party/boost/boost/preprocessor/arithmetic/div.hpp create mode 100644 src/third_party/boost/boost/preprocessor/arithmetic/mul.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/enum.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/insert.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/pop_back.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/pop_front.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/push_back.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/push_front.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/remove.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/replace.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/reverse.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/to_list.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/to_seq.hpp create mode 100644 src/third_party/boost/boost/preprocessor/array/to_tuple.hpp create mode 100644 src/third_party/boost/boost/preprocessor/assert_msg.hpp create mode 100644 src/third_party/boost/boost/preprocessor/comma.hpp create mode 100644 src/third_party/boost/boost/preprocessor/comparison.hpp create mode 100644 src/third_party/boost/boost/preprocessor/comparison/equal.hpp create mode 100644 src/third_party/boost/boost/preprocessor/comparison/greater.hpp create mode 100644 src/third_party/boost/boost/preprocessor/comparison/greater_equal.hpp create mode 100644 src/third_party/boost/boost/preprocessor/comparison/less.hpp create mode 100644 src/third_party/boost/boost/preprocessor/comparison/not_equal.hpp create mode 100644 src/third_party/boost/boost/preprocessor/config/limits.hpp create mode 100644 src/third_party/boost/boost/preprocessor/control.hpp create mode 100644 src/third_party/boost/boost/preprocessor/debug.hpp create mode 100644 src/third_party/boost/boost/preprocessor/debug/assert.hpp create mode 100644 src/third_party/boost/boost/preprocessor/debug/line.hpp create mode 100644 src/third_party/boost/boost/preprocessor/detail/is_nullary.hpp create mode 100644 src/third_party/boost/boost/preprocessor/detail/null.hpp create mode 100644 src/third_party/boost/boost/preprocessor/detail/split.hpp create mode 100644 src/third_party/boost/boost/preprocessor/enum_shifted.hpp create mode 100644 src/third_party/boost/boost/preprocessor/expand.hpp create mode 100644 src/third_party/boost/boost/preprocessor/facilities.hpp create mode 100644 src/third_party/boost/boost/preprocessor/facilities/apply.hpp create mode 100644 src/third_party/boost/boost/preprocessor/facilities/expand.hpp create mode 100644 src/third_party/boost/boost/preprocessor/facilities/is_1.hpp create mode 100644 src/third_party/boost/boost/preprocessor/facilities/is_empty.hpp create mode 100644 src/third_party/boost/boost/preprocessor/facilities/is_empty_or_1.hpp create mode 100644 src/third_party/boost/boost/preprocessor/for.hpp create mode 100644 src/third_party/boost/boost/preprocessor/iteration.hpp create mode 100644 src/third_party/boost/boost/preprocessor/library.hpp create mode 100644 src/third_party/boost/boost/preprocessor/limits.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/at.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/cat.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/enum.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/filter.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/first_n.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/for_each.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/for_each_product.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/rest_n.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/size.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/to_array.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/to_seq.hpp create mode 100644 src/third_party/boost/boost/preprocessor/list/to_tuple.hpp create mode 100644 src/third_party/boost/boost/preprocessor/logical.hpp create mode 100644 src/third_party/boost/boost/preprocessor/logical/bitnor.hpp create mode 100644 src/third_party/boost/boost/preprocessor/logical/bitxor.hpp create mode 100644 src/third_party/boost/boost/preprocessor/logical/nor.hpp create mode 100644 src/third_party/boost/boost/preprocessor/logical/xor.hpp create mode 100644 src/third_party/boost/boost/preprocessor/max.hpp create mode 100644 src/third_party/boost/boost/preprocessor/min.hpp create mode 100644 src/third_party/boost/boost/preprocessor/punctuation.hpp create mode 100644 src/third_party/boost/boost/preprocessor/punctuation/paren_if.hpp create mode 100644 src/third_party/boost/boost/preprocessor/repeat_2nd.hpp create mode 100644 src/third_party/boost/boost/preprocessor/repeat_3rd.hpp create mode 100644 src/third_party/boost/boost/preprocessor/repeat_from_to_2nd.hpp create mode 100644 src/third_party/boost/boost/preprocessor/repeat_from_to_3rd.hpp create mode 100644 src/third_party/boost/boost/preprocessor/repetition.hpp create mode 100644 src/third_party/boost/boost/preprocessor/repetition/deduce_r.hpp create mode 100644 src/third_party/boost/boost/preprocessor/repetition/deduce_z.hpp create mode 100644 src/third_party/boost/boost/preprocessor/repetition/enum_shifted.hpp create mode 100644 src/third_party/boost/boost/preprocessor/repetition/enum_shifted_binary_params.hpp create mode 100644 src/third_party/boost/boost/preprocessor/repetition/enum_trailing_binary_params.hpp create mode 100644 src/third_party/boost/boost/preprocessor/selection.hpp create mode 100644 src/third_party/boost/boost/preprocessor/selection/max.hpp create mode 100644 src/third_party/boost/boost/preprocessor/selection/min.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/detail/binary_transform.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/filter.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/fold_right.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/for_each_product.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/insert.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/pop_back.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/pop_front.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/push_back.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/push_front.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/remove.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/replace.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/reverse.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/to_array.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/to_list.hpp create mode 100644 src/third_party/boost/boost/preprocessor/seq/to_tuple.hpp create mode 100644 src/third_party/boost/boost/preprocessor/slot.hpp create mode 100644 src/third_party/boost/boost/preprocessor/slot/counter.hpp create mode 100644 src/third_party/boost/boost/preprocessor/tuple.hpp create mode 100644 src/third_party/boost/boost/preprocessor/tuple/enum.hpp create mode 100644 src/third_party/boost/boost/preprocessor/tuple/reverse.hpp create mode 100644 src/third_party/boost/boost/preprocessor/tuple/size.hpp create mode 100644 src/third_party/boost/boost/preprocessor/tuple/to_array.hpp create mode 100644 src/third_party/boost/boost/preprocessor/tuple/to_seq.hpp create mode 100644 src/third_party/boost/boost/preprocessor/variadic.hpp create mode 100644 src/third_party/boost/boost/preprocessor/variadic/to_array.hpp create mode 100644 src/third_party/boost/boost/preprocessor/variadic/to_list.hpp create mode 100644 src/third_party/boost/boost/preprocessor/variadic/to_seq.hpp create mode 100644 src/third_party/boost/boost/preprocessor/variadic/to_tuple.hpp create mode 100644 src/third_party/boost/boost/preprocessor/while.hpp create mode 100644 src/third_party/boost/boost/preprocessor/wstringize.hpp diff --git a/src/third_party/boost/boost/container/allocator/allocator_traits.hpp b/src/third_party/boost/boost/container/allocator/allocator_traits.hpp new file mode 100644 index 00000000000..01921615cf8 --- /dev/null +++ b/src/third_party/boost/boost/container/allocator/allocator_traits.hpp @@ -0,0 +1,382 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Pablo Halpern 2009. 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) +// +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2011-2011. 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/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP +#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP + +#if (defined _MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include //numeric_limits<>::max() +#include //placement new +#include //std::allocator +#include + +///@cond + +namespace boost { +namespace container { +namespace container_detail { + +//workaround needed for C++03 compilers with no construct() +//supporting rvalue references +template +struct is_std_allocator +{ static const bool value = false; }; + +template +struct is_std_allocator< std::allocator > +{ static const bool value = true; }; + +} //namespace container_detail { + +///@endcond + +template +struct allocator_traits +{ + //allocator_type + typedef Alloc allocator_type; + //value_type + typedef typename Alloc::value_type value_type; + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //!Alloc::pointer if such a type exists; otherwise, value_type* + //! + typedef unspecified pointer; + //!Alloc::const_pointer if such a type exists ; otherwise, pointer_traits::rebind::rebind. + //! + typedef unspecified void_pointer; + //!Alloc::const_void_pointer if such a type exists ; otherwis e, pointer_traits::rebind::difference_type. + //! + typedef unspecified difference_type; + //!Alloc::size_type if such a type exists ; otherwise, make_unsigned::type + //! + typedef unspecified size_type; + //!Alloc::propagate_on_container_copy_assignment if such a type exists, otherwise an integral_constant + //!type with internal constant static member
value
== false. + typedef unspecified propagate_on_container_copy_assignment; + //!Alloc::propagate_on_container_move_assignment if such a type exists, otherwise an integral_constant + //!type with internal constant static member
value
== false. + typedef unspecified propagate_on_container_move_assignment; + //!Alloc::propagate_on_container_swap if such a type exists, otherwise an integral_constant + //!type with internal constant static member
value
== false. + typedef unspecified propagate_on_container_swap; + //!Defines an allocator: Alloc::rebind::other if such a type exists; otherwise, Alloc + //!if Alloc is a class template instantiation of the form Alloc, where Args is zero or + //!more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed. + //! + //!In C++03 compilers
rebind_alloc
is a struct derived from an allocator + //!deduced by previously detailed rules. + template using rebind_alloc = unspecified; + + //!In C++03 compilers
rebind_traits
is a struct derived from + //!
allocator_traits
, where `OtherAlloc` is
+      //!the allocator deduced by rules explained in `rebind_alloc`.
+      template  using rebind_traits = allocator_traits >;
+
+      //!Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
+      //!`type` is an allocator related to Alloc deduced deduced by rules explained in `rebind_alloc`.
+      template 
+      struct portable_rebind_alloc
+      {  typedef unspecified_type type;  };
+   #else
+      //pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         pointer, value_type*)
+            pointer;
+      //const_pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc, 
+         const_pointer, typename boost::intrusive::pointer_traits::template
+            rebind_pointer)
+               const_pointer;
+      //reference
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         reference, typename container_detail::unvoid::type&)
+            reference;
+      //const_reference
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc, 
+         const_reference, const typename container_detail::unvoid::type&)
+               const_reference;
+      //void_pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc, 
+         void_pointer, typename boost::intrusive::pointer_traits::template
+            rebind_pointer)
+               void_pointer;
+      //const_void_pointer
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
+         const_void_pointer, typename boost::intrusive::pointer_traits::template
+            rebind_pointer)
+               const_void_pointer;
+      //difference_type
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         difference_type, std::ptrdiff_t)
+            difference_type;
+      //size_type
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         size_type, std::size_t)
+            size_type;
+      //propagate_on_container_copy_assignment
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         propagate_on_container_copy_assignment, boost::false_type)
+            propagate_on_container_copy_assignment;
+      //propagate_on_container_move_assignment
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         propagate_on_container_move_assignment, boost::false_type)
+            propagate_on_container_move_assignment;
+      //propagate_on_container_swap
+      typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
+         propagate_on_container_swap, boost::false_type)
+            propagate_on_container_swap;
+
+      #if !defined(BOOST_NO_TEMPLATE_ALIASES)
+         //C++11
+         template  using rebind_alloc  = boost::intrusive::detail::type_rebinder::type;
+         template  using rebind_traits = allocator_traits< rebind_alloc >;
+      #else    //!defined(BOOST_NO_TEMPLATE_ALIASES)
+         //Some workaround for C++03 or C++11 compilers with no template aliases
+         template 
+         struct rebind_alloc : boost::intrusive::detail::type_rebinder::type
+         {
+            typedef typename boost::intrusive::detail::type_rebinder::type Base;
+            #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+            template 
+            rebind_alloc(Args&&... args)
+               : Base(boost::forward(args)...)
+            {}
+            #else    //!defined(BOOST_NO_VARIADIC_TEMPLATES)
+            #define BOOST_PP_LOCAL_MACRO(n)                                                        \
+            BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+            rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                       \
+               : Base(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))                       \
+            {}                                                                                     \
+            //
+            #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+            #include BOOST_PP_LOCAL_ITERATE()
+            #endif   //!defined(BOOST_NO_VARIADIC_TEMPLATES)
+         };
+
+         template 
+         struct rebind_traits
+            : allocator_traits::type>
+         {};
+      #endif   //!defined(BOOST_NO_TEMPLATE_ALIASES)
+      template 
+      struct portable_rebind_alloc
+      {  typedef typename boost::intrusive::detail::type_rebinder::type type;  };
+   #endif   //BOOST_CONTAINER_DOXYGEN_INVOKED
+
+   //!Returns: a.allocate(n)
+   //!
+   static pointer allocate(Alloc &a, size_type n)
+   {  return a.allocate(n);  }
+
+   //!Returns: a.deallocate(p, n)
+   //!
+   //!Throws: Nothing
+   static void deallocate(Alloc &a, pointer p, size_type n)
+   {  return a.deallocate(p, n);  }
+
+   //!Effects: calls `a.construct(p, std::forward(args)...)` if that call is well-formed;
+   //!otherwise, invokes `::new (static_cast(p)) T(std::forward(args)...)`
+   static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
+   {
+      const bool value = boost::container::container_detail::
+         has_member_function_callable_with_allocate
+            ::value;
+      ::boost::integral_constant flag;
+      return allocator_traits::priv_allocate(flag, a, n, p);
+   }
+
+   //!Effects: calls a.destroy(p) if that call is well-formed;
+   //!otherwise, invokes `p->~T()`.
+   template
+   static void destroy(Alloc &a, T*p)
+   {
+      typedef T* destroy_pointer;
+      const bool value = boost::container::container_detail::
+         has_member_function_callable_with_destroy
+            ::value;
+      ::boost::integral_constant flag;
+      allocator_traits::priv_destroy(flag, a, p);
+   }
+
+   //!Returns: a.max_size() if that expression is well-formed; otherwise,
+   //!`numeric_limits::max()`.
+   static size_type max_size(const Alloc &a)
+   {
+      const bool value = boost::container::container_detail::
+         has_member_function_callable_with_max_size
+            ::value;
+      ::boost::integral_constant flag;
+      return allocator_traits::priv_max_size(flag, a);
+   }
+
+   //!Returns: a.select_on_container_copy_construction() if that expres sion is well- formed;
+   //!otherwise, a.
+   static Alloc select_on_container_copy_construction(const Alloc &a)
+   {
+      const bool value = boost::container::container_detail::
+         has_member_function_callable_with_select_on_container_copy_construction
+            ::value;
+      ::boost::integral_constant flag;
+      return allocator_traits::priv_select_on_container_copy_construction(flag, a);
+   }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      //!Effects: calls a.construct(p, std::forward(args)...) if that call is well-formed; 
+      //!otherwise, invokes `::new (static_cast(p)) T(std::forward(args)...)`
+      template 
+      static void construct(Alloc & a, T* p, Args&&... args)
+      {
+         ::boost::integral_constant::value> flag;
+         allocator_traits::priv_construct(flag, a, p, ::boost::forward(args)...);
+      }
+   #endif
+
+   #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+      private:
+      static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p)
+      {  return a.allocate(n, p);  }
+
+      static pointer priv_allocate(boost::false_type, Alloc &a, size_type n, const_void_pointer)
+      {  return allocator_traits::allocate(a, n);  }
+
+      template
+      static void priv_destroy(boost::true_type, Alloc &a, T* p)
+      {  a.destroy(p);  }
+
+      template
+      static void priv_destroy(boost::false_type, Alloc &, T* p)
+      {  p->~T(); (void)p;  }
+
+      static size_type priv_max_size(boost::true_type, const Alloc &a)
+      {  return a.max_size();  }
+
+      static size_type priv_max_size(boost::false_type, const Alloc &)
+      {  return (std::numeric_limits::max)();  }
+
+      static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a)
+      {  return a.select_on_container_copy_construction();  }
+
+      static Alloc priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
+      {  return a;  }
+
+      #if defined(BOOST_CONTAINER_PERFECT_FORWARDING)
+         template
+         static void priv_construct(boost::false_type, Alloc &a, T *p, Args && ...args)                    
+         {                                                                                                  
+            const bool value = boost::container::container_detail::
+                  has_member_function_callable_with_construct
+                     < Alloc, T*, Args... >::value;
+            ::boost::integral_constant flag;
+            priv_construct_dispatch2(flag, a, p, ::boost::forward(args)...);
+         }
+
+         template
+         static void priv_construct(boost::true_type, Alloc &a, T *p, Args && ...args)
+         {
+            priv_construct_dispatch2(boost::false_type(), a, p, ::boost::forward(args)...);
+         }
+
+         template
+         static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p, Args && ...args)
+         {  a.construct( p, ::boost::forward(args)...);  }
+
+         template
+         static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, Args && ...args)
+         {  ::new((void*)p) T(::boost::forward(args)...); }
+      #else
+         public:
+         #define BOOST_PP_LOCAL_MACRO(n)                                                              \
+         template                                 \
+         static void construct(Alloc &a, T *p                                                         \
+                              BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))            \
+         {                                                                                            \
+            ::boost::integral_constant::value> flag;  \
+            allocator_traits::priv_construct(flag, a, p                                               \
+               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));                       \
+         }                                                                                            \
+         //
+         #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+         #include BOOST_PP_LOCAL_ITERATE()
+      
+         private:
+         #define BOOST_PP_LOCAL_MACRO(n)                                                                    \
+         template                                      \
+         static void priv_construct(boost::false_type, Alloc &a, T *p                                       \
+                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_))                         \
+         {                                                                                                  \
+            const bool value =                                                                              \
+               boost::container::container_detail::has_member_function_callable_with_construct              \
+                     < Alloc, T* BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_FWD_TYPE, _) >::value;        \
+            ::boost::integral_constant flag;                                                   \
+            priv_construct_dispatch2(flag, a, p                                                             \
+               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );                            \
+         }                                                                                                  \
+                                                                                                            \
+         template                                      \
+         static void priv_construct(boost::true_type, Alloc &a, T *p                                        \
+                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_))                         \
+         {                                                                                                  \
+            priv_construct_dispatch2(boost::false_type(), a, p                                              \
+               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );                            \
+         }                                                                                                  \
+                                                                                                            \
+         template                                      \
+         static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p                              \
+                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_))                         \
+         {  a.construct( p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );  }             \
+                                                                                                            \
+         template                                      \
+         static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p                              \
+                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) )                       \
+         {  ::new((void*)p) T(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }                     \
+         //
+         #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+         #include BOOST_PP_LOCAL_ITERATE()
+      #endif   //BOOST_CONTAINER_PERFECT_FORWARDING
+   #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   ///@endcond
+};
+
+}  //namespace container {
+}  //namespace boost {
+
+#include 
+
+#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP)
diff --git a/src/third_party/boost/boost/container/allocator/memory_util.hpp b/src/third_party/boost/boost/container/allocator/memory_util.hpp
new file mode 100644
index 00000000000..ea4bc05548c
--- /dev/null
+++ b/src/third_party/boost/boost/container/allocator/memory_util.hpp
@@ -0,0 +1,77 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
+#define BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+#include 
+#include 
+
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 2, ))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 3, ))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME max_size
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, ))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME select_on_container_copy_construction
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 0, ))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace container { namespace container_detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS+1, ))
+#include BOOST_PP_ITERATE()
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(void_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_void_pointer)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
+
+}  //namespace container_detail {
+}  //namespace container {
+}  //namespace boost {
+
+#include 
+
+#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP)
diff --git a/src/third_party/boost/boost/container/allocator/scoped_allocator.hpp b/src/third_party/boost/boost/container/allocator/scoped_allocator.hpp
new file mode 100644
index 00000000000..03e12d1d1ca
--- /dev/null
+++ b/src/third_party/boost/boost/container/allocator/scoped_allocator.hpp
@@ -0,0 +1,651 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Pablo Halpern 2009. 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)
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
+#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost { namespace container {
+
+template 
+class scoped_allocator_adaptor;
+
+template 
+scoped_allocator_adaptor make_scoped();
+
+template 
+class scoped_allocator_adaptor_base : public OuterAlloc
+{
+    typedef allocator_traits OuterTraits;
+
+public:
+    // Workaround for inability of gcc-4.4.1 to expand InnerAllocs...
+//    typedef scoped_allocator_adaptor inner_allocator_type;
+    typedef decltype(make_scoped()) inner_allocator_type;
+
+    scoped_allocator_adaptor_base();
+
+    template 
+      scoped_allocator_adaptor_base(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs);
+
+    template 
+      scoped_allocator_adaptor_base(const scoped_allocator_adaptor& other);
+    template 
+      scoped_allocator_adaptor_base(scoped_allocator_adaptor&& other);
+    
+    inner_allocator_type&       inner_allocator()
+        { return _M_inner_allocs; }
+    inner_allocator_type const& inner_allocator() const
+        { return _M_inner_allocs; }
+
+    // Allocator propagation functions.
+    scoped_allocator_adaptor
+    select_on_container_copy_construction() const;
+
+    typedef std::integral_constant<
+        bool,
+        OuterTraits::propagate_on_container_copy_assignment::value ||
+        inner_allocator_type::propagate_on_container_copy_assignment::value
+        > propagate_on_container_copy_assignment;
+    typedef std::integral_constant<
+        bool,
+        OuterTraits::propagate_on_container_move_assignment::value ||
+        inner_allocator_type::propagate_on_container_move_assignment::value
+        > propagate_on_container_move_assignment;
+    typedef std::integral_constant<
+        bool,
+        OuterTraits::propagate_on_container_swap::value ||
+        inner_allocator_type::propagate_on_container_swap::value
+        > propagate_on_container_swap;
+
+private:
+    inner_allocator_type _M_inner_allocs;
+};
+
+// Specialization with only one parameter.
+template 
+class scoped_allocator_adaptor_base : public OuterAlloc
+{
+    typedef allocator_traits OuterTraits;
+public:
+    typedef scoped_allocator_adaptor inner_allocator_type;
+
+    scoped_allocator_adaptor_base();
+
+    template 
+      scoped_allocator_adaptor_base(OuterA2&& outerAlloc);
+
+    template 
+      scoped_allocator_adaptor_base(const scoped_allocator_adaptor& other);
+    template 
+      scoped_allocator_adaptor_base(scoped_allocator_adaptor&& other);
+    
+    inner_allocator_type&       inner_allocator()
+        { return static_cast(*this); }
+
+    inner_allocator_type const& inner_allocator() const
+        { return static_cast(*this); }
+
+    // Allocator propagation functions.
+    scoped_allocator_adaptor
+      select_on_container_copy_construction() const;
+
+    typedef typename OuterTraits::propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
+    typedef typename OuterTraits::propagate_on_container_move_assignment propagate_on_container_move_assignment;
+    typedef typename OuterTraits::propagate_on_container_swap propagate_on_container_swap;
+};
+
+template 
+class scoped_allocator_adaptor
+    : public scoped_allocator_adaptor_base
+{
+    typedef scoped_allocator_adaptor_base _Base;
+    typedef allocator_traits                              _Traits;
+
+public:
+    typedef OuterAlloc                           outer_allocator_type;
+    typedef typename _Base::inner_allocator_type inner_allocator_type;
+    
+    typedef typename allocator_traits::size_type          size_type;
+    typedef typename allocator_traits::difference_type    difference_type;
+    typedef typename allocator_traits::pointer            pointer;
+    typedef typename allocator_traits::const_pointer      const_pointer;
+    typedef typename allocator_traits::void_pointer       void_pointer;
+    typedef typename allocator_traits::const_void_pointer const_void_pointer;
+    typedef typename allocator_traits::value_type          value_type;
+
+    template 
+    struct rebind {
+        typedef typename allocator_traits::template rebind_traits rebound_traits;
+        typedef typename rebound_traits::allocator_type rebound_outer; // exposition only
+        typedef scoped_allocator_adaptor other;
+    };
+
+    scoped_allocator_adaptor();
+    scoped_allocator_adaptor(const scoped_allocator_adaptor& other);
+
+    template 
+      scoped_allocator_adaptor(const scoped_allocator_adaptor& other);
+    template 
+      scoped_allocator_adaptor(scoped_allocator_adaptor&& other);
+    
+    template 
+      scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs);
+
+    ~scoped_allocator_adaptor();
+
+    inner_allocator_type      & inner_allocator()
+        { return _Base::inner_allocator(); }
+    inner_allocator_type const& inner_allocator() const
+        { return _Base::inner_allocator(); }
+    outer_allocator_type      & outer_allocator()
+        { return *this; }
+    outer_allocator_type const& outer_allocator() const
+        { return *this; }
+
+    pointer allocate(size_type n);
+    pointer allocate(size_type n, const_void_pointer hint);
+    void deallocate(pointer p, size_type n);
+    size_type max_size() const;
+
+    template 
+      void construct(T* p, Args&&... args);
+
+    // Specializations to pass inner_allocator to pair::first and pair::second
+    template 
+      void construct(std::pair* p);
+    template 
+      void construct(std::pair* p, U&& x, V&& y);
+    template 
+      void construct(std::pair* p, const std::pair& pr);
+    template 
+      void construct(std::pair* p, std::pair&& pr);
+
+    template 
+      void destroy(T* p);
+};
+
+template 
+inline
+bool operator==(const scoped_allocator_adaptor& a,
+                const scoped_allocator_adaptor& b);
+
+template 
+inline
+bool operator!=(const scoped_allocator_adaptor& a,
+                const scoped_allocator_adaptor& b);
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation of scoped_allocator_adaptor_base
+///////////////////////////////////////////////////////////////////////////////
+
+template 
+inline
+scoped_allocator_adaptor_base::
+    scoped_allocator_adaptor_base()
+{
+}
+
+template 
+  template 
+    scoped_allocator_adaptor_base::
+      scoped_allocator_adaptor_base(OuterA2&&        outerAlloc,
+                                    const InnerAllocs&... innerAllocs)
+          : OuterAlloc(std::forward(outerAlloc))
+          , _M_inner_allocs(innerAllocs...)
+{
+}
+
+template 
+  template 
+    scoped_allocator_adaptor_base::
+      scoped_allocator_adaptor_base(
+          const scoped_allocator_adaptor& other)
+          : OuterAlloc(other.outer_allocator())
+          , _M_inner_allocs(other.inner_allocator())
+{
+}
+
+template 
+  template 
+    scoped_allocator_adaptor_base::
+      scoped_allocator_adaptor_base(
+          scoped_allocator_adaptor&& other)
+          : OuterAlloc(std::move(other.outer_allocator()))
+          , _M_inner_allocs(std::move(other.inner_allocator()))
+{
+}
+
+template 
+inline
+scoped_allocator_adaptor
+scoped_allocator_adaptor_base::
+  select_on_container_copy_construction() const
+{
+    return scoped_allocator_adaptor(
+        allocator_traits::select_on_container_copy_construction(
+            this->outer_allocator()),
+        allocator_traits::select_on_container_copy_construction(
+            this->inner_allocator()));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation of scoped_allocator_adaptor_base specialization
+///////////////////////////////////////////////////////////////////////////////
+
+template 
+inline
+scoped_allocator_adaptor_base::
+    scoped_allocator_adaptor_base()
+{
+}
+
+template 
+  template 
+    scoped_allocator_adaptor_base::
+     scoped_allocator_adaptor_base(OuterA2&& outerAlloc)
+         : OuterAlloc(std::forward(outerAlloc))
+{
+}
+
+template 
+  template 
+    scoped_allocator_adaptor_base::
+      scoped_allocator_adaptor_base(
+          const scoped_allocator_adaptor& other)
+          : OuterAlloc(other.outer_allocator())
+{
+}
+
+template 
+  template 
+    scoped_allocator_adaptor_base::
+      scoped_allocator_adaptor_base(
+          scoped_allocator_adaptor&& other)
+          : OuterAlloc(std::move(other.outer_allocator()))
+{
+}
+
+// template 
+// inline
+// scoped_allocator_adaptor& 
+// scoped_allocator_adaptor_base::inner_allocator()
+// {
+//     return *this;
+// }
+
+// template 
+// inline
+// scoped_allocator_adaptor const& 
+// scoped_allocator_adaptor_base::inner_allocator() cosnt
+// {
+//     return *this;
+// }
+
+template 
+inline
+scoped_allocator_adaptor
+scoped_allocator_adaptor_base::
+select_on_container_copy_construction() const
+{
+    return
+        allocator_traits::select_on_container_copy_construction(
+            this->outer_allocator());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation of scoped_allocator_adaptor details
+///////////////////////////////////////////////////////////////////////////////
+
+namespace __details {
+
+    // Overload resolution for __has_ctor resolves to this function
+    // when _Tp is constructible with _Args.  Returns true_type().
+    
+    static void* __void_p; // Declared but not defined
+
+    template 
+    inline
+    auto __has_ctor(int, _Args&&... __args) ->
+        decltype((new (__void_p) _Tp(__args...), std::true_type()))
+        { return std::true_type(); }
+
+    // Overload resolution for __has_ctor resolves to this function
+    // when _Tp is not constructible with _Args. Returns false_type().
+    template 
+    auto __has_ctor(_LowPriorityConversion, _Args&&...) ->
+        std::false_type
+        { return std::false_type(); }
+
+    template 
+    struct __is_scoped_allocator_imp {
+        template 
+        static char test(int, typename T::outer_allocator_type*);
+        template 
+        static int test(_LowPriorityConversion, void*);
+        static const bool value = (1 == sizeof(test<_Alloc>(0, 0)));
+    };
+
+    template 
+    struct __is_scoped_allocator
+        : std::integral_constant::value>
+    {
+    };
+
+#if 0
+    // Called when outer_allocator_type is not a scoped allocator
+    // (recursion stop).
+    template 
+    inline
+    auto __outermost_alloc(_LowPriorityConversion, _Alloc& __a) ->
+        _Alloc&
+    {
+        return __a;
+    }
+
+    // Called when outer_allocator_type is a scoped allocator to
+    // return the outermost allocator type.
+    template 
+    inline auto __outermost_alloc(int, _Alloc& __a) ->
+        decltype(__outermost_alloc(0,__a.outer_allocator())) 
+    {
+        return __a.outer_allocator();
+    }
+#endif
+
+    template 
+    inline void __dispatch_scoped_construct(std::false_type __uses_alloc,
+                                            _Ignore         __use_alloc_prefix,
+                                            _OuterAlloc&    __outer_alloc,
+                                            _InnerAlloc&    __inner_alloc,
+                                            _Tp* __p, _Args&&... __args)
+    {
+        // _Tp doesn't use allocators.  Construct without an
+        // allocator argument.
+        allocator_traits<_OuterAlloc>::construct(__outer_alloc, __p,
+                                               std::forward<_Args>(__args)...);
+    }
+
+    template 
+    inline void __dispatch_scoped_construct(std::true_type  __uses_alloc,
+                                            std::true_type  __use_alloc_prefix,
+                                            _OuterAlloc&    __outer_alloc,
+                                            _InnerAlloc&    __inner_alloc,
+                                            _Tp* __p, _Args&&... __args)
+    {
+        // _Tp doesn't use allocators.  Construct without an
+        // allocator argument.
+        allocator_traits<_OuterAlloc>::construct(__outer_alloc, __p,
+                                                 allocator_arg, __inner_alloc,
+                                               std::forward<_Args>(__args)...);
+    }
+
+    template 
+    inline void __dispatch_scoped_construct(std::true_type  __uses_alloc,
+                                            std::false_type __use_alloc_prefix,
+                                            _OuterAlloc&    __outer_alloc,
+                                            _InnerAlloc&    __inner_alloc,
+                                            _Tp* __p, _Args&&... __args)
+    {
+        // If _Tp uses an allocator compatible with _InnerAlloc,
+        // but the specific constructor does not have a variant that
+        // takes an allocator argument, then program is malformed.
+//         static_assert(has_constructor<_Tp, _Args...>::value,
+//                       "Cannot pass inner allocator to this constructor");
+
+        allocator_traits<_OuterAlloc>::construct(
+            __outer_alloc, __p, std::forward<_Args>(__args)...,
+            __inner_alloc);
+    }
+
+    template 
+    inline void __do_scoped_construct(std::false_type __scoped_outer,
+                                      _OuterAlloc&    __outer_alloc,
+                                      _InnerAlloc&    __inner_alloc,
+                                      _Tp* __p, _Args&&... __args)
+    {
+        // Dispatch construction to the correct __dispatch_scoped_construct()
+        // function based on whether _Tp uses an allocator of type
+        // _InnerAlloc and, if so, whether there exists the following
+        // constructor:
+        //   _Tp(allocator_arg_t, _InnerAlloc, Args...).
+        auto __uses_alloc = uses_allocator<_Tp, _InnerAlloc>();
+        auto __use_alloc_prefix = __has_ctor<_Tp>(0, allocator_arg,
+                                               __inner_alloc,
+                                               std::forward<_Args>(__args)...);
+        __dispatch_scoped_construct(__uses_alloc, __use_alloc_prefix,
+                                    __outer_alloc,
+                                    __inner_alloc,
+                                    __p, std::forward<_Args>(__args)...);
+    }
+
+    template 
+    void __do_scoped_construct(std::true_type  __scoped_outer,
+                               _OuterAlloc&    __outer_alloc,
+                               _InnerAlloc&    __inner_alloc,
+                               _Tp* __p, _Args&&... __args)
+    {
+        // Use outermost allocator if __outer_alloc is scoped
+        typedef typename _OuterAlloc::outer_allocator_type outerouter;
+        __do_scoped_construct(__is_scoped_allocator(),
+                              __outer_alloc.outer_allocator(),
+                              __inner_alloc,
+                              __p, std::forward<_Args>(__args)...);
+    }
+
+} // end namespace __details
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation of scoped_allocator_adaptor
+///////////////////////////////////////////////////////////////////////////////
+
+template 
+scoped_allocator_adaptor::
+    scoped_allocator_adaptor()
+{
+}
+
+template 
+scoped_allocator_adaptor::
+    scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
+        : _Base(other)
+{
+}
+
+template 
+  template 
+    scoped_allocator_adaptor::
+      scoped_allocator_adaptor(const scoped_allocator_adaptor& other)
+        : _Base(other)
+{
+}
+
+template 
+  template 
+    scoped_allocator_adaptor::
+      scoped_allocator_adaptor(scoped_allocator_adaptor&& other)
+          : _Base(std::move(other))
+{
+}
+    
+template 
+  template 
+    scoped_allocator_adaptor::
+      scoped_allocator_adaptor(OuterA2&& outerAlloc, const InnerAllocs&... innerAllocs)
+          : _Base(std::forward(outerAlloc), innerAllocs...)
+{
+}
+
+template 
+scoped_allocator_adaptor::
+    ~scoped_allocator_adaptor()
+{
+}
+
+template 
+inline typename allocator_traits::pointer
+scoped_allocator_adaptor::
+    allocate(size_type n)
+{
+    return allocator_traits::allocate(outer_allocator(), n);
+}
+
+template 
+inline typename allocator_traits::pointer
+scoped_allocator_adaptor::
+    allocate(size_type n, const_void_pointer hint)
+{
+    return allocator_traits::allocate(outer_allocator(), n, hint);
+}
+
+template 
+inline void scoped_allocator_adaptor::
+    deallocate(pointer p, size_type n)
+{
+    allocator_traits::deallocate(outer_allocator(), p, n);
+}
+
+template 
+inline typename allocator_traits::size_type
+scoped_allocator_adaptor::max_size() const
+{
+    return allocator_traits::max_size(outer_allocator());
+}
+
+template 
+  template 
+    inline void scoped_allocator_adaptor::
+    destroy(T* p)
+{
+    allocator_traits::destroy(outer_allocator(), p);
+}
+
+template 
+  template 
+    inline
+    void scoped_allocator_adaptor::construct(T* p,
+                                                             Args&&... args)
+{
+    __do_scoped_construct(__details::__is_scoped_allocator(),
+                          this->outer_allocator(), this->inner_allocator(),
+                          p, std::forward(args)...);
+}
+
+template 
+  template 
+  void scoped_allocator_adaptor::construct(
+      std::pair* p)
+{
+    construct(addressof(p->first));
+    try {
+        construct(addressof(p->second));
+    }
+    catch (...) {
+        destroy(addressof(p->first));
+        throw;
+    }
+}
+
+template 
+  template 
+  void scoped_allocator_adaptor::construct(
+      std::pair* p, U&& x, V&& y)
+{
+    construct(addressof(p->first), std::forward(x));
+    try {
+        construct(addressof(p->second), std::forward(y));
+    }
+    catch (...) {
+        destroy(addressof(p->first));
+        throw;
+    }
+}
+
+template 
+  template 
+  void scoped_allocator_adaptor::construct(
+      std::pair* p, const std::pair& pr)
+{
+    construct(addressof(p->first), pr.first);
+    try {
+        construct(addressof(p->second), pr.second);
+    }
+    catch (...) {
+        destroy(addressof(p->first));
+        throw;
+    }
+}
+
+template 
+  template 
+  void scoped_allocator_adaptor::construct(
+      std::pair* p, std::pair&& pr)
+{
+    construct(addressof(p->first), std::move(pr.first));
+    try {
+        construct(addressof(p->second), std::move(pr.second));
+    }
+    catch (...) {
+        destroy(addressof(p->first));
+        throw;
+    }
+}
+
+template 
+inline
+bool operator==(const scoped_allocator_adaptor& a,
+                const scoped_allocator_adaptor& b)
+{
+    return a.outer_allocator() == b.outer_allocator()
+        && a.inner_allocator() == b.inner_allocator();
+}
+
+template 
+inline
+bool operator==(const scoped_allocator_adaptor& a,
+                const scoped_allocator_adaptor& b)
+{
+    return a.outer_allocator() == b.outer_allocator();
+}
+
+template 
+inline
+bool operator!=(const scoped_allocator_adaptor& a,
+                const scoped_allocator_adaptor& b)
+{
+    return ! (a == b);
+}
+
+}} // namespace boost { namespace container {
+
+#include 
+
+#endif //  BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
diff --git a/src/third_party/boost/boost/container/deque.hpp b/src/third_party/boost/boost/container/deque.hpp
new file mode 100644
index 00000000000..9ee0ee13715
--- /dev/null
+++ b/src/third_party/boost/boost/container/deque.hpp
@@ -0,0 +1,2011 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 1996,1997
+// Silicon Graphics Computer Systems, Inc.
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation.  Silicon Graphics makes no
+// representations about the suitability of this software for any
+// purpose.  It is provided "as is" without express or implied warranty.
+//
+//
+// Copyright (c) 1994
+// Hewlett-Packard Company
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation.  Hewlett-Packard Company makes no
+// representations about the suitability of this software for any
+// purpose.  It is provided "as is" without express or implied warranty.
+
+#ifndef BOOST_CONTAINER_DEQUE_HPP
+#define BOOST_CONTAINER_DEQUE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace container {
+
+/// @cond
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >
+#else
+template 
+#endif
+class deque;
+
+template 
+struct deque_value_traits
+{
+   typedef T value_type;
+   typedef A allocator_type;
+   static const bool trivial_dctr = boost::has_trivial_destructor::value;
+   static const bool trivial_dctr_after_move = false;
+      //::boost::has_trivial_destructor_after_move::value || trivial_dctr;
+   static const bool trivial_copy = has_trivial_copy::value;
+   static const bool nothrow_copy = has_nothrow_copy::value;
+   static const bool trivial_assign = has_trivial_assign::value;
+   //static const bool nothrow_assign = has_nothrow_assign::value;
+   static const bool nothrow_assign = false;
+};
+
+// Note: this function is simply a kludge to work around several compilers'
+//  bugs in handling constant expressions.
+inline std::size_t deque_buf_size(std::size_t size) 
+   {  return size < 512 ? std::size_t(512 / size) : std::size_t(1);  }
+
+// Deque base class.  It has two purposes.  First, its constructor
+//  and destructor allocate (but don't initialize) storage.  This makes
+//  exception safety easier.
+template 
+class deque_base
+{
+   BOOST_COPYABLE_AND_MOVABLE(deque_base)
+   public:
+   typedef allocator_traits                                     val_alloc_traits_type;
+   typedef typename val_alloc_traits_type::value_type              val_alloc_val;
+   typedef typename val_alloc_traits_type::pointer                 val_alloc_ptr;
+   typedef typename val_alloc_traits_type::const_pointer           val_alloc_cptr;
+   typedef typename val_alloc_traits_type::reference               val_alloc_ref;
+   typedef typename val_alloc_traits_type::const_reference         val_alloc_cref;
+   typedef typename val_alloc_traits_type::difference_type         val_alloc_diff;
+   typedef typename val_alloc_traits_type::size_type               val_alloc_size;
+   typedef typename val_alloc_traits_type::template
+      portable_rebind_alloc::type                   ptr_alloc_t;
+   typedef allocator_traits                           ptr_alloc_traits_type;
+   typedef typename ptr_alloc_traits_type::value_type             ptr_alloc_val;
+   typedef typename ptr_alloc_traits_type::pointer                ptr_alloc_ptr;
+   typedef typename ptr_alloc_traits_type::const_pointer          ptr_alloc_cptr;
+   typedef typename ptr_alloc_traits_type::reference              ptr_alloc_ref;
+   typedef typename ptr_alloc_traits_type::const_reference        ptr_alloc_cref;
+   typedef A                                                      allocator_type;
+   typedef allocator_type                                         stored_allocator_type;
+   typedef val_alloc_size                                         size_type;
+
+   protected:
+
+   typedef deque_value_traits             traits_t;
+   typedef ptr_alloc_t                          map_allocator_type;
+
+   static size_type s_buffer_size() { return deque_buf_size(sizeof(T)); }
+
+   val_alloc_ptr priv_allocate_node() 
+      {  return this->alloc().allocate(s_buffer_size());  }
+
+   void priv_deallocate_node(val_alloc_ptr p) 
+      {  this->alloc().deallocate(p, s_buffer_size());  }
+
+   ptr_alloc_ptr priv_allocate_map(size_type n) 
+      { return this->ptr_alloc().allocate(n); }
+
+   void priv_deallocate_map(ptr_alloc_ptr p, size_type n) 
+      { this->ptr_alloc().deallocate(p, n); }
+
+ public:
+   // Class invariants:
+   //  For any nonsingular iterator i:
+   //    i.node is the address of an element in the map array.  The
+   //      contents of i.node is a pointer to the beginning of a node.
+   //    i.first == //(i.node) 
+   //    i.last  == i.first + node_size
+   //    i.cur is a pointer in the range [i.first, i.last).  NOTE:
+   //      the implication of this is that i.cur is always a dereferenceable
+   //      pointer, even if i is a past-the-end iterator.
+   //  Start and Finish are always nonsingular iterators.  NOTE: this means
+   //    that an empty deque must have one node, and that a deque
+   //    with N elements, where N is the buffer size, must have two nodes.
+   //  For every node other than start.node and finish.node, every element
+   //    in the node is an initialized object.  If start.node == finish.node,
+   //    then [start.cur, finish.cur) are initialized objects, and
+   //    the elements outside that range are uninitialized storage.  Otherwise,
+   //    [start.cur, start.last) and [finish.first, finish.cur) are initialized
+   //    objects, and [start.first, start.cur) and [finish.cur, finish.last)
+   //    are uninitialized storage.
+   //  [map, map + map_size) is a valid, non-empty range.  
+   //  [start.node, finish.node] is a valid range contained within 
+   //    [map, map + map_size).  
+   //  A pointer in the range [map, map + map_size) points to an allocated node
+   //    if and only if the pointer is in the range [start.node, finish.node].
+   class const_iterator 
+      : public std::iterator
+   {
+      public:
+      static size_type s_buffer_size() { return deque_base::s_buffer_size(); }
+
+      typedef std::random_access_iterator_tag   iterator_category;
+      typedef val_alloc_val                     value_type;
+      typedef val_alloc_cptr                    pointer;
+      typedef val_alloc_cref                    reference;
+      typedef val_alloc_diff                    difference_type;
+
+      typedef ptr_alloc_ptr                     index_pointer;
+      typedef const_iterator                    self_t;
+
+      friend class deque;
+      friend class deque_base;
+
+      protected: 
+      val_alloc_ptr  m_cur;
+      val_alloc_ptr  m_first;
+      val_alloc_ptr  m_last;
+      index_pointer  m_node;
+
+      public: 
+      const_iterator(val_alloc_ptr x, index_pointer y) 
+         : m_cur(x), m_first(*y),
+           m_last(*y + s_buffer_size()), m_node(y) {}
+
+      const_iterator() : m_cur(0), m_first(0), m_last(0), m_node(0) {}
+
+      const_iterator(const const_iterator& x)
+         : m_cur(x.m_cur),   m_first(x.m_first), 
+           m_last(x.m_last), m_node(x.m_node) {}
+
+      reference operator*() const 
+         { return *this->m_cur; }
+
+      pointer operator->() const 
+         { return this->m_cur; }
+
+      difference_type operator-(const self_t& x) const 
+      {
+         if(!this->m_cur && !x.m_cur){
+            return 0;
+         }
+         return difference_type(this->s_buffer_size()) * (this->m_node - x.m_node - 1) +
+            (this->m_cur - this->m_first) + (x.m_last - x.m_cur);
+      }
+
+      self_t& operator++() 
+      {
+         ++this->m_cur;
+         if (this->m_cur == this->m_last) {
+            this->priv_set_node(this->m_node + 1);
+            this->m_cur = this->m_first;
+         }
+         return *this; 
+      }
+
+      self_t operator++(int)  
+      {
+         self_t tmp = *this;
+         ++*this;
+         return tmp;
+      }
+
+      self_t& operator--() 
+      {
+         if (this->m_cur == this->m_first) {
+            this->priv_set_node(this->m_node - 1);
+            this->m_cur = this->m_last;
+         }
+         --this->m_cur;
+         return *this;
+      }
+
+      self_t operator--(int) 
+      {
+         self_t tmp = *this;
+         --*this;
+         return tmp;
+      }
+
+      self_t& operator+=(difference_type n)
+      {
+         difference_type offset = n + (this->m_cur - this->m_first);
+         if (offset >= 0 && offset < difference_type(this->s_buffer_size()))
+            this->m_cur += n;
+         else {
+            difference_type node_offset =
+            offset > 0 ? offset / difference_type(this->s_buffer_size())
+                        : -difference_type((-offset - 1) / this->s_buffer_size()) - 1;
+            this->priv_set_node(this->m_node + node_offset);
+            this->m_cur = this->m_first + 
+            (offset - node_offset * difference_type(this->s_buffer_size()));
+         }
+         return *this;
+      }
+
+      self_t operator+(difference_type n) const
+         {  self_t tmp = *this; return tmp += n;  }
+
+      self_t& operator-=(difference_type n) 
+         { return *this += -n; }
+       
+      self_t operator-(difference_type n) const 
+         {  self_t tmp = *this; return tmp -= n;  }
+
+      reference operator[](difference_type n) const 
+         { return *(*this + n); }
+
+      bool operator==(const self_t& x) const 
+         { return this->m_cur == x.m_cur; }
+
+      bool operator!=(const self_t& x) const 
+         { return !(*this == x); }
+
+      bool operator<(const self_t& x) const 
+      {
+         return (this->m_node == x.m_node) ? 
+            (this->m_cur < x.m_cur) : (this->m_node < x.m_node);
+      }
+
+      bool operator>(const self_t& x) const  
+         { return x < *this; }
+
+      bool operator<=(const self_t& x) const 
+         { return !(x < *this); }
+
+      bool operator>=(const self_t& x) const 
+         { return !(*this < x); }
+
+      void priv_set_node(index_pointer new_node) 
+      {
+         this->m_node = new_node;
+         this->m_first = *new_node;
+         this->m_last = this->m_first + difference_type(this->s_buffer_size());
+      }
+
+      friend const_iterator operator+(difference_type n, const const_iterator& x)
+         {  return x + n;  }
+   };
+
+   //Deque iterator
+   class iterator : public const_iterator
+   {
+      public:
+      typedef std::random_access_iterator_tag   iterator_category;
+      typedef val_alloc_val                     value_type;
+      typedef val_alloc_ptr                     pointer;
+      typedef val_alloc_ref                     reference;
+      typedef val_alloc_diff                    difference_type;
+      typedef ptr_alloc_ptr                     index_pointer;
+      typedef const_iterator                    self_t;
+
+      friend class deque;
+      friend class deque_base;
+
+      private:
+      explicit iterator(const const_iterator& x) : const_iterator(x){}
+
+      public:
+      //Constructors
+      iterator(val_alloc_ptr x, index_pointer y) : const_iterator(x, y){}
+      iterator() : const_iterator(){}
+      //iterator(const const_iterator &cit) : const_iterator(cit){}
+      iterator(const iterator& x) : const_iterator(x){}
+
+      //Pointer like operators
+      reference operator*() const { return *this->m_cur; }
+      pointer operator->() const { return this->m_cur; }
+
+      reference operator[](difference_type n) const { return *(*this + n); }
+
+      //Increment / Decrement
+      iterator& operator++()  
+         { this->const_iterator::operator++(); return *this;  }
+
+      iterator operator++(int)
+         { iterator tmp = *this; ++*this; return tmp; }
+      
+      iterator& operator--()
+         {  this->const_iterator::operator--(); return *this;  }
+
+      iterator operator--(int)
+         {  iterator tmp = *this; --*this; return tmp; }
+
+      // Arithmetic
+      iterator& operator+=(difference_type off)
+         {  this->const_iterator::operator+=(off); return *this;  }
+
+      iterator operator+(difference_type off) const
+         {  return iterator(this->const_iterator::operator+(off));  }
+
+      friend iterator operator+(difference_type off, const iterator& right)
+         {  return iterator(off+static_cast(right)); }
+
+      iterator& operator-=(difference_type off)
+         {  this->const_iterator::operator-=(off); return *this;   }
+
+      iterator operator-(difference_type off) const
+         {  return iterator(this->const_iterator::operator-(off));  }
+
+      difference_type operator-(const const_iterator& right) const
+         {  return static_cast(*this) - right;   }
+   };
+
+   deque_base(size_type num_elements, const allocator_type& a)
+      :  members_(a)
+   { this->priv_initialize_map(num_elements); }
+
+   explicit deque_base(const allocator_type& a) 
+      :  members_(a)
+   {}
+
+   deque_base()
+      :  members_()
+   {}
+
+   explicit deque_base(BOOST_RV_REF(deque_base) x)
+      :  members_( boost::move(x.ptr_alloc())
+                 , boost::move(x.alloc()) )
+   {}
+
+   ~deque_base()
+   {
+      if (this->members_.m_map) {
+         this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
+         this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+      }
+   }
+
+   private:
+   deque_base(const deque_base&);
+  
+   protected:
+
+   void swap_members(deque_base &x)
+   {
+      std::swap(this->members_.m_start, x.members_.m_start);
+      std::swap(this->members_.m_finish, x.members_.m_finish);
+      std::swap(this->members_.m_map, x.members_.m_map);
+      std::swap(this->members_.m_map_size, x.members_.m_map_size);
+   }
+
+   void priv_initialize_map(size_type num_elements)
+   {
+//      if(num_elements){
+         size_type num_nodes = num_elements / s_buffer_size() + 1;
+
+         this->members_.m_map_size = container_detail::max_value((size_type) InitialMapSize, num_nodes + 2);
+         this->members_.m_map = this->priv_allocate_map(this->members_.m_map_size);
+
+         ptr_alloc_ptr nstart = this->members_.m_map + (this->members_.m_map_size - num_nodes) / 2;
+         ptr_alloc_ptr nfinish = nstart + num_nodes;
+             
+         BOOST_TRY {
+            this->priv_create_nodes(nstart, nfinish);
+         }
+         BOOST_CATCH(...){
+            this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+            this->members_.m_map = 0;
+            this->members_.m_map_size = 0;
+            BOOST_RETHROW
+         }
+         BOOST_CATCH_END
+
+         this->members_.m_start.priv_set_node(nstart);
+         this->members_.m_finish.priv_set_node(nfinish - 1);
+         this->members_.m_start.m_cur = this->members_.m_start.m_first;
+         this->members_.m_finish.m_cur = this->members_.m_finish.m_first +
+                        num_elements % s_buffer_size();
+//      }
+   }
+
+   void priv_create_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
+   {
+      ptr_alloc_ptr cur;
+      BOOST_TRY {
+         for (cur = nstart; cur < nfinish; ++cur)
+            *cur = this->priv_allocate_node();
+      }
+      BOOST_CATCH(...){
+         this->priv_destroy_nodes(nstart, cur);
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   void priv_destroy_nodes(ptr_alloc_ptr nstart, ptr_alloc_ptr nfinish)
+   {
+      for (ptr_alloc_ptr n = nstart; n < nfinish; ++n)
+         this->priv_deallocate_node(*n);
+   }
+
+   void priv_clear_map()
+   {
+      if (this->members_.m_map) {
+         this->priv_destroy_nodes(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1);
+         this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+         this->members_.m_map = 0;
+         this->members_.m_map_size = 0;
+         this->members_.m_start = iterator();
+         this->members_.m_finish = this->members_.m_start;
+      }
+   }
+
+   enum { InitialMapSize = 8 };
+
+   protected:
+   struct members_holder
+      :  public ptr_alloc_t
+      ,  public allocator_type
+   {
+      members_holder()
+         :  map_allocator_type(), allocator_type()
+         ,  m_map(0), m_map_size(0)
+         ,  m_start(), m_finish(m_start)
+      {}
+
+      explicit members_holder(const allocator_type &a)
+         :  map_allocator_type(a), allocator_type(a)
+         ,  m_map(0), m_map_size(0)
+         ,  m_start(), m_finish(m_start)
+      {}
+
+      template
+      members_holder(BOOST_FWD_REF(PtrAllocConvertible) pa, BOOST_FWD_REF(ValAllocConvertible) va)
+         : map_allocator_type(boost::forward(pa))
+         , allocator_type    (boost::forward(va))
+         , m_map(0), m_map_size(0)
+         , m_start(), m_finish(m_start)
+      {}
+
+      ptr_alloc_ptr   m_map;
+      val_alloc_size  m_map_size;
+      iterator        m_start;
+      iterator        m_finish;
+   } members_;
+
+   ptr_alloc_t &ptr_alloc() 
+   {  return members_;  }
+   
+   const ptr_alloc_t &ptr_alloc() const 
+   {  return members_;  }
+
+   allocator_type &alloc() 
+   {  return members_;  }
+   
+   const allocator_type &alloc() const 
+   {  return members_;  }
+};
+/// @endcond
+
+//! Deque class
+//!
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >
+#else
+template 
+#endif
+class deque : protected deque_base
+{
+   /// @cond
+   private:
+   typedef deque_base Base;
+   typedef typename Base::val_alloc_val            val_alloc_val;
+   typedef typename Base::val_alloc_ptr            val_alloc_ptr;
+   typedef typename Base::val_alloc_cptr           val_alloc_cptr;
+   typedef typename Base::val_alloc_ref            val_alloc_ref;
+   typedef typename Base::val_alloc_cref           val_alloc_cref;
+   typedef typename Base::val_alloc_size           val_alloc_size;
+   typedef typename Base::val_alloc_diff           val_alloc_diff;
+
+   typedef typename Base::ptr_alloc_t              ptr_alloc_t;
+   typedef typename Base::ptr_alloc_val            ptr_alloc_val;
+   typedef typename Base::ptr_alloc_ptr            ptr_alloc_ptr;
+   typedef typename Base::ptr_alloc_cptr           ptr_alloc_cptr;
+   typedef typename Base::ptr_alloc_ref            ptr_alloc_ref;
+   typedef typename Base::ptr_alloc_cref           ptr_alloc_cref;
+   /// @endcond
+
+   public:                         // Basic types
+   typedef T                                    value_type;
+   typedef val_alloc_ptr                        pointer;
+   typedef val_alloc_cptr                       const_pointer;
+   typedef val_alloc_ref                        reference;
+   typedef val_alloc_cref                       const_reference;
+   typedef val_alloc_size                       size_type;
+   typedef val_alloc_diff                       difference_type;
+   typedef typename Base::allocator_type        allocator_type;
+
+   public:                                // Iterators
+   typedef typename Base::iterator              iterator;
+   typedef typename Base::const_iterator        const_iterator;
+
+   typedef std::reverse_iterator const_reverse_iterator;
+   typedef std::reverse_iterator      reverse_iterator;
+
+   typedef allocator_type                       stored_allocator_type;
+
+   /// @cond
+
+   private:                      // Internal typedefs
+   BOOST_COPYABLE_AND_MOVABLE(deque)
+   typedef ptr_alloc_ptr index_pointer;
+   static size_type s_buffer_size() 
+      { return Base::s_buffer_size(); }
+   typedef container_detail::advanced_insert_aux_int advanced_insert_aux_int_t;
+   typedef repeat_iterator  r_iterator;
+   typedef boost::move_iterator     move_it;
+   typedef allocator_traits                  allocator_traits_type;
+
+   /// @endcond
+
+   public:
+
+   //! Effects: Returns a copy of the internal allocator.
+   //! 
+   //! Throws: If allocator's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+   { return Base::alloc(); }
+
+   //! Effects: Returns a reference to the internal allocator.
+   //! 
+   //! Throws: Nothing
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+   {  return Base::alloc(); }
+
+   //! Effects: Returns a reference to the internal allocator.
+   //! 
+   //! Throws: Nothing
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+   {  return Base::alloc(); }
+
+   //! Effects: Returns an iterator to the first element contained in the deque.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin() BOOST_CONTAINER_NOEXCEPT
+      { return this->members_.m_start; }
+
+   //! Effects: Returns an iterator to the end of the deque.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end() BOOST_CONTAINER_NOEXCEPT
+      { return this->members_.m_finish; }
+
+   //! Effects: Returns a const_iterator to the first element contained in the deque.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+      { return this->members_.m_start; }
+
+   //! Effects: Returns a const_iterator to the end of the deque.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+      { return this->members_.m_finish; }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed deque. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
+      { return reverse_iterator(this->members_.m_finish); }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed deque. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
+      { return reverse_iterator(this->members_.m_start); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed deque. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
+      { return const_reverse_iterator(this->members_.m_finish); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed deque. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
+      { return const_reverse_iterator(this->members_.m_start); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the deque.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+      { return this->members_.m_start; }
+
+   //! Effects: Returns a const_iterator to the end of the deque.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+      { return this->members_.m_finish; }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed deque. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+      { return const_reverse_iterator(this->members_.m_finish); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed deque. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+      { return const_reverse_iterator(this->members_.m_start); }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT
+      { return this->members_.m_start[difference_type(n)]; }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a const reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
+      { return this->members_.m_start[difference_type(n)]; }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: std::range_error if n >= size()
+   //! 
+   //! Complexity: Constant.
+   reference at(size_type n)
+      { this->priv_range_check(n); return (*this)[n]; }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a const reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: std::range_error if n >= size()
+   //! 
+   //! Complexity: Constant.
+   const_reference at(size_type n) const
+      { this->priv_range_check(n); return (*this)[n]; }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a reference to the first
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference front() BOOST_CONTAINER_NOEXCEPT
+      { return *this->members_.m_start; }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a const reference to the first element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference front() const BOOST_CONTAINER_NOEXCEPT
+      { return *this->members_.m_start; }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a reference to the last
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference back() BOOST_CONTAINER_NOEXCEPT
+      {  return *(end()-1); }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a const reference to the last
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference back() const BOOST_CONTAINER_NOEXCEPT
+      {  return *(cend()-1);  }
+
+   //! Effects: Returns the number of the elements contained in the deque.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const BOOST_CONTAINER_NOEXCEPT
+      { return this->members_.m_finish - this->members_.m_start; }
+
+   //! Effects: Returns the largest possible size of the deque.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+      { return allocator_traits_type::max_size(this->alloc()); }
+
+   //! Effects: Returns true if the deque contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const BOOST_CONTAINER_NOEXCEPT
+   { return this->members_.m_finish == this->members_.m_start; }
+
+   //! Effects: Default constructors a deque.
+   //! 
+   //! Throws: If allocator_type's default constructor throws.
+   //! 
+   //! Complexity: Constant.
+   deque() 
+      : Base()
+   {}
+
+   //! Effects: Constructs a deque taking the allocator as parameter.
+   //! 
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   explicit deque(const allocator_type& a) 
+      : Base(a)
+   {}
+
+   //! Effects: Constructs a deque that will use a copy of allocator a
+   //!   and inserts n default contructed values.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's default or copy constructor throws.
+   //! 
+   //! Complexity: Linear to n.
+   explicit deque(size_type n)
+      : Base(n, allocator_type())
+   {
+      container_detail::default_construct_aux_proxy proxy(this->alloc(), n);
+      proxy.uninitialized_copy_remaining_to(this->begin());
+      //deque_base will deallocate in case of exception...
+   }
+
+   //! Effects: Constructs a deque that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's default or copy constructor throws.
+   //! 
+   //! Complexity: Linear to n.
+   deque(size_type n, const value_type& value,
+         const allocator_type& a = allocator_type())
+      : Base(n, a)
+   { this->priv_fill_initialize(value); }
+
+   //! Effects: Copy constructs a deque.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   deque(const deque& x)
+      :  Base(allocator_traits_type::select_on_container_copy_construction(x.alloc()))
+   {
+      if(x.size()){
+         this->priv_initialize_map(x.size());
+         boost::container::uninitialized_copy_alloc
+            (this->alloc(), x.begin(), x.end(), this->members_.m_start);
+      }
+   }
+
+   //! Effects: Move constructor. Moves mx's resources to *this.
+   //!
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   deque(BOOST_RV_REF(deque) x) 
+      :  Base(boost::move(static_cast(x)))
+   {  this->swap_members(x);   }
+
+   //! Effects: Constructs a deque that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the deque.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's constructor taking an dereferenced InIt throws.
+   //!
+   //! Complexity: Linear to the range [first, last).
+   template 
+   deque(InpIt first, InpIt last, const allocator_type& a = allocator_type())
+      : Base(a) 
+   {
+      //Dispatch depending on integer/iterator
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_initialize_dispatch(first, last, Result());
+   }
+
+   //! Effects: Destroys the deque. All stored values are destroyed
+   //!   and used memory is deallocated.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements.
+   ~deque() BOOST_CONTAINER_NOEXCEPT
+   {
+      priv_destroy_range(this->members_.m_start, this->members_.m_finish);
+   }
+
+   //! Effects: Makes *this contain the same elements as x.
+   //!
+   //! Postcondition: this->size() == x.size(). *this contains a copy 
+   //! of each of x's elements. 
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the number of elements in x.
+   deque& operator= (BOOST_COPY_ASSIGN_REF(deque) x) 
+   {
+      if (&x != this){
+         allocator_type &this_alloc     = this->alloc();
+         const allocator_type &x_alloc  = x.alloc();
+         container_detail::bool_ flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+            this->shrink_to_fit();
+         }
+         container_detail::assign_alloc(this->alloc(), x.alloc(), flag);
+         container_detail::assign_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
+         this->assign(x.cbegin(), x.cend());
+      }
+      return *this;
+   }
+
+   //! Effects: Move assignment. All mx's values are transferred to *this.
+   //!
+   //! Postcondition: x.empty(). *this contains a the elements x had
+   //!   before the function.
+   //!
+   //! Throws: If allocator_type's copy constructor throws.
+   //!
+   //! Complexity: Linear.
+   deque& operator= (BOOST_RV_REF(deque) x)
+   {
+      if (&x != this){
+         allocator_type &this_alloc = this->alloc();
+         allocator_type &x_alloc    = x.alloc();
+         //If allocators are equal we can just swap pointers
+         if(this_alloc == x_alloc){
+            //Destroy objects but retain memory in case x reuses it in the future
+            this->clear();
+            this->swap_members(x);
+            //Move allocator if needed
+            container_detail::bool_ flag;
+            container_detail::move_alloc(this_alloc, x_alloc, flag);
+            container_detail::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
+         }
+         //If unequal allocators, then do a one by one move
+         else{
+            typedef typename std::iterator_traits::iterator_category ItCat;
+            this->assign( boost::make_move_iterator(x.begin())
+                        , boost::make_move_iterator(x.end()));
+         }
+      }
+      return *this;
+   }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(deque &x)
+   {
+      this->swap_members(x);
+      container_detail::bool_ flag;
+      container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
+      container_detail::swap_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
+   }
+
+   //! Effects: Assigns the n copies of val to *this.
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to n.
+   void assign(size_type n, const T& val)
+   {  this->priv_fill_assign(n, val);  }
+
+   //! Effects: Assigns the the range [first, last) to *this.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's constructor from dereferencing InpIt throws.
+   //!
+   //! Complexity: Linear to n.
+   template 
+   void assign(InpIt first, InpIt last)
+   {
+      //Dispatch depending on integer/iterator
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_assign_dispatch(first, last, Result());
+   }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Effects: Inserts a copy of x at the end of the deque.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_back(const T &x);
+
+   //! Effects: Constructs a new element in the end of the deque
+   //!   and moves the resources of mx to this new element.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_back(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Effects: Inserts a copy of x at the front of the deque.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_front(const T &x);
+
+   //! Effects: Constructs a new element in the front of the deque
+   //!   and moves the resources of mx to this new element.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_front(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
+   #endif
+
+   //! Effects: Removes the last element from the deque.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant time.
+   void pop_back() BOOST_CONTAINER_NOEXCEPT
+   {
+      if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
+         --this->members_.m_finish.m_cur;
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , container_detail::to_raw_pointer(this->members_.m_finish.m_cur)
+            );
+      }
+      else
+         this->priv_pop_back_aux();
+   }
+
+   //! Effects: Removes the first element from the deque.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant time.
+   void pop_front() BOOST_CONTAINER_NOEXCEPT
+   {
+      if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , container_detail::to_raw_pointer(this->members_.m_start.m_cur)
+            );
+         ++this->members_.m_start.m_cur;
+      }
+      else 
+         this->priv_pop_front_aux();
+   }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a copy of x before position.
+   //!
+   //! Throws: If memory allocation throws or x's copy constructor throws.
+   //!
+   //! Complexity: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator position, const T &x);
+
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a new element before position with mx's resources.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator position, T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
+   #endif
+
+   //! Requires: pos must be a valid iterator of *this.
+   //!
+   //! Effects: Insert n copies of x before pos.
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to n.
+   void insert(const_iterator pos, size_type n, const value_type& x)
+   { this->priv_fill_insert(pos, n, x); }
+
+   //! Requires: pos must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a copy of the [first, last) range before pos.
+   //!
+   //! Throws: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to std::distance [first, last).
+   template 
+   void insert(const_iterator pos, InpIt first, InpIt last) 
+   {
+      //Dispatch depending on integer/iterator
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_insert_dispatch(pos, first, last, Result());
+   }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the end of the deque.
+   //!
+   //! Throws: If memory allocation throws or the in-place constructor throws.
+   //!
+   //! Complexity: Amortized constant time
+   template 
+   void emplace_back(Args&&... args)
+   {
+      if(this->priv_push_back_simple_available()){
+         allocator_traits_type::construct
+            ( this->alloc()
+            , this->priv_push_back_simple_pos()
+            , boost::forward(args)...);
+         this->priv_push_back_simple_commit();
+      }
+      else{
+         typedef container_detail::advanced_insert_aux_non_movable_emplace type;
+         type &&proxy = type(this->alloc(), boost::forward(args)...);
+         this->priv_insert_back_aux_impl(1, proxy);
+      }
+   }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the beginning of the deque.
+   //!
+   //! Throws: If memory allocation throws or the in-place constructor throws.
+   //!
+   //! Complexity: Amortized constant time
+   template 
+   void emplace_front(Args&&... args)
+   {
+      if(this->priv_push_front_simple_available()){
+         allocator_traits_type::construct
+            ( this->alloc()
+            , this->priv_push_front_simple_pos()
+            , boost::forward(args)...);
+         this->priv_push_front_simple_commit();
+      }
+      else{
+         typedef container_detail::advanced_insert_aux_non_movable_emplace type;
+         type &&proxy = type(this->alloc(), boost::forward(args)...);
+         this->priv_insert_front_aux_impl(1, proxy);
+      }
+   }
+
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... before position
+   //!
+   //! Throws: If memory allocation throws or the in-place constructor throws.
+   //!
+   //! Complexity: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   template 
+   iterator emplace(const_iterator p, Args&&... args)
+   {
+      if(p == this->cbegin()){
+         this->emplace_front(boost::forward(args)...);
+         return this->begin();
+      }
+      else if(p == this->cend()){
+         this->emplace_back(boost::forward(args)...);
+         return (this->end()-1);
+      }
+      else{
+         size_type n = p - this->cbegin();
+         typedef container_detail::advanced_insert_aux_emplace type;
+         type &&proxy = type(this->alloc(), boost::forward(args)...);
+         this->priv_insert_aux_impl(p, 1, proxy);
+         return iterator(this->begin() + n);
+      }
+   }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //advanced_insert_int.hpp includes all necessary preprocessor machinery...
+   #define BOOST_PP_LOCAL_MACRO(n)                                                           \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)    \
+   void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                     \
+   {                                                                                         \
+      if(priv_push_back_simple_available()){                                                 \
+         allocator_traits_type::construct                                                    \
+            ( this->alloc()                                                                  \
+            , this->priv_push_back_simple_pos()                                              \
+              BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));               \
+         priv_push_back_simple_commit();                                                     \
+      }                                                                                      \
+      else{                                                                                  \
+         container_detail::BOOST_PP_CAT(BOOST_PP_CAT(                                        \
+            advanced_insert_aux_non_movable_emplace, n), arg)                                \
+                proxy                       \
+            (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));  \
+         priv_insert_back_aux_impl(1, proxy);                                                \
+      }                                                                                      \
+   }                                                                                         \
+                                                                                             \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >  )  \
+   void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                    \
+   {                                                                                         \
+      if(priv_push_front_simple_available()){                                                \
+         allocator_traits_type::construct                                                    \
+            ( this->alloc()                                                                  \
+            , this->priv_push_front_simple_pos()                                             \
+              BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));               \
+         priv_push_front_simple_commit();                                                    \
+      }                                                                                      \
+      else{                                                                                  \
+         container_detail::BOOST_PP_CAT(BOOST_PP_CAT                                         \
+            (advanced_insert_aux_non_movable_emplace, n), arg)                               \
+                proxy                       \
+            (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));  \
+         priv_insert_front_aux_impl(1, proxy);                                               \
+      }                                                                                      \
+   }                                                                                         \
+                                                                                             \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)    \
+   iterator emplace(const_iterator p                                                         \
+                    BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))             \
+   {                                                                                         \
+      if(p == this->cbegin()){                                                               \
+         this->emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));         \
+         return this->begin();                                                               \
+      }                                                                                      \
+      else if(p == cend()){                                                                  \
+         this->emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));          \
+         return (this->end()-1);                                                             \
+      }                                                                                      \
+      else{                                                                                  \
+         size_type pos_num = p - this->cbegin();                                             \
+         container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)   \
+             proxy                          \
+            (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));  \
+         this->priv_insert_aux_impl(p, 1, proxy);                                            \
+         return iterator(this->begin() + pos_num);                                           \
+      }                                                                                      \
+   }                                                                                         \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type new_size, const value_type& x) 
+   {
+      const size_type len = size();
+      if (new_size < len) 
+         this->erase(this->members_.m_start + new_size, this->members_.m_finish);
+      else
+         this->insert(this->members_.m_finish, new_size - len, x);
+   }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are default constructed.
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type new_size) 
+   {
+      const size_type len = size();
+      if (new_size < len) 
+         this->priv_erase_last_n(len - new_size);
+      else{
+         size_type n = new_size - this->size();
+         container_detail::default_construct_aux_proxy proxy(this->alloc(), n);
+         priv_insert_back_aux_impl(n, proxy);
+      }
+   }
+
+   //! Effects: Erases the element at position pos.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the elements between pos and the 
+   //!   last element (if pos is near the end) or the first element
+   //!   if(pos is near the beginning).
+   //!   Constant if pos is the first or the last element.
+   iterator erase(const_iterator pos) BOOST_CONTAINER_NOEXCEPT
+   {
+      const_iterator next = pos;
+      ++next;
+      difference_type index = pos - this->members_.m_start;
+      if (size_type(index) < (this->size() >> 1)) {
+         boost::move_backward(begin(), iterator(pos), iterator(next));
+         pop_front();
+      }
+      else {
+         boost::move(iterator(next), end(), iterator(pos));
+         pop_back();
+      }
+      return this->members_.m_start + index;
+   }
+
+   //! Effects: Erases the elements pointed by [first, last).
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the distance between first and
+   //!   last plus the elements between pos and the 
+   //!   last element (if pos is near the end) or the first element
+   //!   if(pos is near the beginning).
+   iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+   {
+      if (first == this->members_.m_start && last == this->members_.m_finish) {
+         this->clear();
+         return this->members_.m_finish;
+      }
+      else {
+         difference_type n = last - first;
+         difference_type elems_before = first - this->members_.m_start;
+         if (elems_before < static_cast(this->size() - n) - elems_before) {
+            boost::move_backward(begin(), iterator(first), iterator(last));
+            iterator new_start = this->members_.m_start + n;
+            if(!Base::traits_t::trivial_dctr_after_move)
+               this->priv_destroy_range(this->members_.m_start, new_start);
+            this->priv_destroy_nodes(this->members_.m_start.m_node, new_start.m_node);
+            this->members_.m_start = new_start;
+         }
+         else {
+            boost::move(iterator(last), end(), iterator(first));
+            iterator new_finish = this->members_.m_finish - n;
+            if(!Base::traits_t::trivial_dctr_after_move)
+               this->priv_destroy_range(new_finish, this->members_.m_finish);
+            this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
+            this->members_.m_finish = new_finish;
+         }
+         return this->members_.m_start + elems_before;
+      }
+   }
+
+   void priv_erase_last_n(size_type n)
+   {
+      if(n == this->size()) {
+         this->clear();
+      }
+      else {
+         iterator new_finish = this->members_.m_finish - n;
+         if(!Base::traits_t::trivial_dctr_after_move)
+            this->priv_destroy_range(new_finish, this->members_.m_finish);
+         this->priv_destroy_nodes(new_finish.m_node + 1, this->members_.m_finish.m_node + 1);
+         this->members_.m_finish = new_finish;
+      }
+   }
+
+   //! Effects: Erases all the elements of the deque.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements in the deque.
+   void clear() BOOST_CONTAINER_NOEXCEPT
+   {
+      for (index_pointer node = this->members_.m_start.m_node + 1;
+            node < this->members_.m_finish.m_node;
+            ++node) {
+         this->priv_destroy_range(*node, *node + this->s_buffer_size());
+         this->priv_deallocate_node(*node);
+      }
+
+      if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
+         this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last);
+         this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur);
+         this->priv_deallocate_node(this->members_.m_finish.m_first);
+      }
+      else
+         this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
+
+      this->members_.m_finish = this->members_.m_start;
+   }
+
+   //! Effects: Tries to deallocate the excess of memory created
+   //!   with previous allocations. The size of the deque is unchanged
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: Constant.
+   void shrink_to_fit()
+   {
+      //This deque implementation already
+      //deallocates excess nodes when erasing
+      //so there is nothing to do except for
+      //empty deque
+      if(this->empty()){
+         this->priv_clear_map();
+      }
+   }
+
+   /// @cond
+   private:
+   void priv_range_check(size_type n) const 
+      {  if (n >= this->size())  BOOST_RETHROW std::out_of_range("deque");   }
+
+   iterator priv_insert(const_iterator position, const value_type &x) 
+   {
+      if (position == cbegin()){
+         this->push_front(x);
+         return begin();
+      }
+      else if (position == cend()){
+         this->push_back(x);
+         return (end()-1);
+      }
+      else {
+         size_type n = position - cbegin();
+         this->priv_insert_aux(position, size_type(1), x);
+         return iterator(this->begin() + n);
+      }
+   }
+
+   iterator priv_insert(const_iterator position, BOOST_RV_REF(value_type) mx) 
+   {
+      if (position == cbegin()) {
+         this->push_front(boost::move(mx));
+         return begin();
+      }
+      else if (position == cend()) {
+         this->push_back(boost::move(mx));
+         return(end()-1);
+      }
+      else {
+         //Just call more general insert(pos, size, value) and return iterator
+         size_type n = position - begin();
+         this->priv_insert_aux(position, move_it(r_iterator(mx, 1)), move_it(r_iterator()));
+         return iterator(this->begin() + n);
+      }
+   }
+
+   void priv_push_front(const value_type &t)
+   {
+      if(this->priv_push_front_simple_available()){
+         allocator_traits_type::construct
+            ( this->alloc(), this->priv_push_front_simple_pos(), t);
+         this->priv_push_front_simple_commit();
+      }
+      else{
+         this->priv_insert_aux(cbegin(), size_type(1), t);
+      }
+   }
+
+   void priv_push_front(BOOST_RV_REF(value_type) t)
+   {
+      if(this->priv_push_front_simple_available()){
+         allocator_traits_type::construct
+            ( this->alloc(), this->priv_push_front_simple_pos(), boost::move(t));
+         this->priv_push_front_simple_commit();
+      }
+      else{
+         this->priv_insert_aux(cbegin(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+      }
+   }
+
+   void priv_push_back(const value_type &t)
+   {
+      if(this->priv_push_back_simple_available()){
+         allocator_traits_type::construct
+            ( this->alloc(), this->priv_push_back_simple_pos(), t);
+         this->priv_push_back_simple_commit();
+      }
+      else{
+         this->priv_insert_aux(cend(), size_type(1), t);
+      }
+   }
+
+   void priv_push_back(BOOST_RV_REF(T) t)
+   {
+      if(this->priv_push_back_simple_available()){
+         allocator_traits_type::construct
+            ( this->alloc(), this->priv_push_back_simple_pos(), boost::move(t));
+         this->priv_push_back_simple_commit();
+      }
+      else{
+         this->priv_insert_aux(cend(), move_it(r_iterator(t, 1)), move_it(r_iterator()));
+      }
+   }
+
+   bool priv_push_back_simple_available() const
+   {
+      return this->members_.m_map &&
+         (this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1));
+   }
+
+   T *priv_push_back_simple_pos() const
+   {
+      return container_detail::to_raw_pointer(this->members_.m_finish.m_cur);
+   }
+
+   void priv_push_back_simple_commit()
+   {
+      ++this->members_.m_finish.m_cur;
+   }
+
+   bool priv_push_front_simple_available() const
+   {
+      return this->members_.m_map &&
+         (this->members_.m_start.m_cur != this->members_.m_start.m_first);
+   }
+
+   T *priv_push_front_simple_pos() const
+   {  return container_detail::to_raw_pointer(this->members_.m_start.m_cur) - 1;  }
+
+   void priv_push_front_simple_commit()
+   {  --this->members_.m_start.m_cur;   }
+
+   template 
+   void priv_insert_aux(const_iterator pos, InpIt first, InpIt last, std::input_iterator_tag)
+   {
+      for(;first != last; ++first){
+         this->insert(pos, boost::move(value_type(*first)));
+      }
+   }
+
+   template 
+   void priv_insert_aux(const_iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag) 
+   {  this->priv_insert_aux(pos, first, last);  }
+
+  // assign(), a generalized assignment member function.  Two
+  // versions: one that takes a count, and one that takes a range.
+  // The range version is a member template, so we dispatch on whether
+  // or not the type is an integer.
+   void priv_fill_assign(size_type n, const T& val)
+   {
+      if (n > size()) {
+         std::fill(begin(), end(), val);
+         this->insert(cend(), n - size(), val);
+      }
+      else {
+         this->erase(cbegin() + n, cend());
+         std::fill(begin(), end(), val);
+      }
+   }
+
+   template 
+   void priv_initialize_dispatch(Integer n, Integer x, container_detail::true_) 
+   {
+      this->priv_initialize_map(n);
+      this->priv_fill_initialize(x);
+   }
+
+   template 
+   void priv_initialize_dispatch(InpIt first, InpIt last, container_detail::false_) 
+   {
+      typedef typename std::iterator_traits::iterator_category ItCat;
+      this->priv_range_initialize(first, last, ItCat());
+   }
+
+   void priv_destroy_range(iterator p, iterator p2)
+   {
+      for(;p != p2; ++p){
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , container_detail::to_raw_pointer(&*p)
+            );
+      }
+   }
+
+   void priv_destroy_range(pointer p, pointer p2)
+   {
+      for(;p != p2; ++p){
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , container_detail::to_raw_pointer(&*p)
+            );
+      }
+   }
+
+   template 
+   void priv_assign_dispatch(Integer n, Integer val, container_detail::true_)
+      { this->priv_fill_assign((size_type) n, (value_type)val); }
+
+   template 
+   void priv_assign_dispatch(InpIt first, InpIt last, container_detail::false_) 
+   {
+      typedef typename std::iterator_traits::iterator_category ItCat;
+      this->priv_assign_aux(first, last, ItCat());
+   }
+
+   template 
+   void priv_assign_aux(InpIt first, InpIt last, std::input_iterator_tag)
+   {
+      iterator cur = begin();
+      for ( ; first != last && cur != end(); ++cur, ++first)
+         *cur = *first;
+      if (first == last)
+         this->erase(cur, cend());
+      else
+         this->insert(cend(), first, last);
+   }
+
+   template 
+   void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
+   {
+      size_type len = std::distance(first, last);
+      if (len > size()) {
+         FwdIt mid = first;
+         std::advance(mid, size());
+         boost::copy_or_move(first, mid, begin());
+         this->insert(cend(), mid, last);
+      }
+      else
+         this->erase(boost::copy_or_move(first, last, begin()), cend());
+   }
+
+   template 
+   void priv_insert_dispatch(const_iterator pos, Integer n, Integer x, container_detail::true_) 
+   {  this->priv_fill_insert(pos, (size_type) n, (value_type)x); }
+
+   template 
+   void priv_insert_dispatch(const_iterator pos,InpIt first, InpIt last, container_detail::false_) 
+   {
+      typedef typename std::iterator_traits::iterator_category ItCat;
+      this->priv_insert_aux(pos, first, last, ItCat());
+   }
+
+   void priv_insert_aux(const_iterator pos, size_type n, const value_type& x)
+   {
+      typedef constant_iterator c_it;
+      this->priv_insert_aux(pos, c_it(x, n), c_it());
+   }
+
+   //Just forward all operations to priv_insert_aux_impl
+   template 
+   void priv_insert_aux(const_iterator p, FwdIt first, FwdIt last)
+   {
+      container_detail::advanced_insert_aux_proxy proxy(this->alloc(), first, last);
+      priv_insert_aux_impl(p, (size_type)std::distance(first, last), proxy);
+   }
+
+   void priv_insert_aux_impl(const_iterator p, size_type n, advanced_insert_aux_int_t &interf)
+   {
+      iterator pos(p);
+      if(!this->members_.m_map){
+         this->priv_initialize_map(0);
+         pos = this->begin();
+      }
+
+      const difference_type elemsbefore = pos - this->members_.m_start;
+      size_type length = this->size();
+      if (elemsbefore < static_cast(length / 2)) {
+         iterator new_start = this->priv_reserve_elements_at_front(n);
+         iterator old_start = this->members_.m_start;
+         pos = this->members_.m_start + elemsbefore;
+         if (elemsbefore >= difference_type(n)) {
+            iterator start_n = this->members_.m_start + difference_type(n); 
+            ::boost::container::uninitialized_move_alloc
+               (this->alloc(), this->members_.m_start, start_n, new_start);
+            this->members_.m_start = new_start;
+            boost::move(start_n, pos, old_start);
+            interf.copy_remaining_to(pos - difference_type(n));
+         }
+         else {
+            difference_type mid_count = (difference_type(n) - elemsbefore);
+            iterator mid_start = old_start - mid_count;
+            interf.uninitialized_copy_some_and_update(mid_start, mid_count, true);
+            this->members_.m_start = mid_start;
+            ::boost::container::uninitialized_move_alloc
+               (this->alloc(), old_start, pos, new_start);
+            this->members_.m_start = new_start;
+            interf.copy_remaining_to(old_start);
+         }
+      }
+      else {
+         iterator new_finish = this->priv_reserve_elements_at_back(n);
+         iterator old_finish = this->members_.m_finish;
+         const difference_type elemsafter = 
+            difference_type(length) - elemsbefore;
+         pos = this->members_.m_finish - elemsafter;
+         if (elemsafter >= difference_type(n)) {
+            iterator finish_n = this->members_.m_finish - difference_type(n);
+            ::boost::container::uninitialized_move_alloc
+               (this->alloc(), finish_n, this->members_.m_finish, this->members_.m_finish);
+            this->members_.m_finish = new_finish;
+            boost::move_backward(pos, finish_n, old_finish);
+            interf.copy_remaining_to(pos);
+         }
+         else {
+            interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+            this->members_.m_finish += n-elemsafter;
+            ::boost::container::uninitialized_move_alloc
+               (this->alloc(), pos, old_finish, this->members_.m_finish);
+            this->members_.m_finish = new_finish;
+            interf.copy_remaining_to(pos);
+         }
+      }
+   }
+
+   void priv_insert_back_aux_impl(size_type n, advanced_insert_aux_int_t &interf)
+   {
+      if(!this->members_.m_map){
+         this->priv_initialize_map(0);
+      }
+
+      iterator new_finish = this->priv_reserve_elements_at_back(n);
+      iterator old_finish = this->members_.m_finish;
+      interf.uninitialized_copy_some_and_update(old_finish, n, true);
+      this->members_.m_finish = new_finish;
+   }
+
+   void priv_insert_front_aux_impl(size_type n, advanced_insert_aux_int_t &interf)
+   {
+      if(!this->members_.m_map){
+         this->priv_initialize_map(0);
+      }
+
+      iterator new_start = this->priv_reserve_elements_at_front(n);
+      interf.uninitialized_copy_some_and_update(new_start, difference_type(n), true);
+      this->members_.m_start = new_start;
+   }
+
+
+   void priv_fill_insert(const_iterator pos, size_type n, const value_type& x)
+   {
+      typedef constant_iterator c_it;
+      this->insert(pos, c_it(x, n), c_it());
+   }
+
+   // Precondition: this->members_.m_start and this->members_.m_finish have already been initialized,
+   // but none of the deque's elements have yet been constructed.
+   void priv_fill_initialize(const value_type& value) 
+   {
+      index_pointer cur;
+      BOOST_TRY {
+         for (cur = this->members_.m_start.m_node; cur < this->members_.m_finish.m_node; ++cur){
+            boost::container::uninitialized_fill_alloc
+               (this->alloc(), *cur, *cur + this->s_buffer_size(), value);
+         }
+         boost::container::uninitialized_fill_alloc
+            (this->alloc(), this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value);
+      }
+      BOOST_CATCH(...){
+         this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur));
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   template 
+   void priv_range_initialize(InpIt first, InpIt last, std::input_iterator_tag)
+   {
+      this->priv_initialize_map(0);
+      BOOST_TRY {
+         for ( ; first != last; ++first)
+            this->push_back(*first);
+      }
+      BOOST_CATCH(...){
+         this->clear();
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   template 
+   void priv_range_initialize(FwdIt first, FwdIt last, std::forward_iterator_tag)
+   {
+      size_type n = 0;
+      n = std::distance(first, last);
+      this->priv_initialize_map(n);
+
+      index_pointer cur_node;
+      BOOST_TRY {
+         for (cur_node = this->members_.m_start.m_node; 
+               cur_node < this->members_.m_finish.m_node; 
+               ++cur_node) {
+            FwdIt mid = first;
+            std::advance(mid, this->s_buffer_size());
+            ::boost::container::uninitialized_copy_or_move_alloc
+               (this->alloc(), first, mid, *cur_node);
+            first = mid;
+         }
+         ::boost::container::uninitialized_copy_or_move_alloc
+            (this->alloc(), first, last, this->members_.m_finish.m_first);
+      }
+      BOOST_CATCH(...){
+         this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node));
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   // Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
+   void priv_pop_back_aux()
+   {
+      this->priv_deallocate_node(this->members_.m_finish.m_first);
+      this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1);
+      this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
+      allocator_traits_type::destroy
+         ( this->alloc()
+         , container_detail::to_raw_pointer(this->members_.m_finish.m_cur)
+         );
+   }
+
+   // Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1.  Note that 
+   // if the deque has at least one element (a precondition for this member 
+   // function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque 
+   // must have at least two nodes.
+   void priv_pop_front_aux()
+   {
+      allocator_traits_type::destroy
+         ( this->alloc()
+         , container_detail::to_raw_pointer(this->members_.m_start.m_cur)
+         );
+      this->priv_deallocate_node(this->members_.m_start.m_first);
+      this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1);
+      this->members_.m_start.m_cur = this->members_.m_start.m_first;
+   }      
+
+   iterator priv_reserve_elements_at_front(size_type n) 
+   {
+      size_type vacancies = this->members_.m_start.m_cur - this->members_.m_start.m_first;
+      if (n > vacancies){
+         size_type new_elems = n-vacancies;
+         size_type new_nodes = (new_elems + this->s_buffer_size() - 1) / 
+            this->s_buffer_size();
+         size_type s = (size_type)(this->members_.m_start.m_node - this->members_.m_map);
+         if (new_nodes > s){
+            this->priv_reallocate_map(new_nodes, true);
+         }
+         size_type i = 1;
+         BOOST_TRY {
+            for (; i <= new_nodes; ++i)
+               *(this->members_.m_start.m_node - i) = this->priv_allocate_node();
+         }
+         BOOST_CATCH(...) {
+            for (size_type j = 1; j < i; ++j)
+               this->priv_deallocate_node(*(this->members_.m_start.m_node - j));      
+            BOOST_RETHROW
+         }
+         BOOST_CATCH_END
+      }
+      return this->members_.m_start - difference_type(n);
+   }
+
+   iterator priv_reserve_elements_at_back(size_type n) 
+   {
+      size_type vacancies = (this->members_.m_finish.m_last - this->members_.m_finish.m_cur) - 1;
+      if (n > vacancies){
+         size_type new_elems = n - vacancies;
+         size_type new_nodes = (new_elems + this->s_buffer_size() - 1)/s_buffer_size();
+         size_type s = (size_type)(this->members_.m_map_size - (this->members_.m_finish.m_node - this->members_.m_map));
+         if (new_nodes + 1 > s){
+            this->priv_reallocate_map(new_nodes, false);
+         }
+         size_type i;
+         BOOST_TRY {
+            for (i = 1; i <= new_nodes; ++i)
+               *(this->members_.m_finish.m_node + i) = this->priv_allocate_node();
+         }
+         BOOST_CATCH(...) {
+            for (size_type j = 1; j < i; ++j)
+               this->priv_deallocate_node(*(this->members_.m_finish.m_node + j));      
+            BOOST_RETHROW
+         }
+         BOOST_CATCH_END
+      }
+      return this->members_.m_finish + difference_type(n);
+   }
+
+   void priv_reallocate_map(size_type nodes_to_add, bool add_at_front)
+   {
+      size_type old_num_nodes = this->members_.m_finish.m_node - this->members_.m_start.m_node + 1;
+      size_type new_num_nodes = old_num_nodes + nodes_to_add;
+
+      index_pointer new_nstart;
+      if (this->members_.m_map_size > 2 * new_num_nodes) {
+         new_nstart = this->members_.m_map + (this->members_.m_map_size - new_num_nodes) / 2 
+                           + (add_at_front ? nodes_to_add : 0);
+         if (new_nstart < this->members_.m_start.m_node)
+            boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+         else
+            boost::move_backward
+               (this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart + old_num_nodes);
+      }
+      else {
+         size_type new_map_size = 
+            this->members_.m_map_size + container_detail::max_value(this->members_.m_map_size, nodes_to_add) + 2;
+
+         index_pointer new_map = this->priv_allocate_map(new_map_size);
+         new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+                              + (add_at_front ? nodes_to_add : 0);
+         boost::move(this->members_.m_start.m_node, this->members_.m_finish.m_node + 1, new_nstart);
+         this->priv_deallocate_map(this->members_.m_map, this->members_.m_map_size);
+
+         this->members_.m_map = new_map;
+         this->members_.m_map_size = new_map_size;
+      }
+
+      this->members_.m_start.priv_set_node(new_nstart);
+      this->members_.m_finish.priv_set_node(new_nstart + old_num_nodes - 1);
+   }
+   /// @endcond
+};
+
+// Nonmember functions.
+template 
+inline bool operator==(const deque& x,
+                       const deque& y)
+{
+   return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
+}
+
+template 
+inline bool operator<(const deque& x,
+                      const deque& y) 
+{
+   return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template 
+inline bool operator!=(const deque& x,
+                       const deque& y) 
+   {  return !(x == y);   }
+
+template 
+inline bool operator>(const deque& x,
+                      const deque& y) 
+   {  return y < x; }
+
+template 
+inline bool operator<=(const deque& x,
+                       const deque& y) 
+   {  return !(y < x); }
+
+template 
+inline bool operator>=(const deque& x,
+                       const deque& y) 
+   {  return !(x < y); }
+
+
+template 
+inline void swap(deque& x, deque& y)
+{  x.swap(y);  }
+
+}}
+
+/// @cond
+
+namespace boost {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   enum {   value = has_trivial_destructor::value  };
+};
+*/
+}
+
+/// @endcond
+
+#include 
+
+#endif //   #ifndef  BOOST_CONTAINER_DEQUE_HPP
diff --git a/src/third_party/boost/boost/container/detail/adaptive_node_pool_impl.hpp b/src/third_party/boost/boost/container/detail/adaptive_node_pool_impl.hpp
new file mode 100644
index 00000000000..36495795fbb
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/adaptive_node_pool_impl.hpp
@@ -0,0 +1,648 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
+#define BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template
+struct hdr_offset_holder_t
+{
+   hdr_offset_holder_t(size_type offset = 0)
+      : hdr_offset(offset)
+   {}
+   size_type hdr_offset;
+};
+
+template
+struct adaptive_pool_types
+{
+   typedef VoidPointer void_pointer;
+   typedef typename bi::make_set_base_hook
+      < bi::void_pointer
+      , bi::optimize_size
+      , bi::constant_time_size
+      , bi::link_mode >::type multiset_hook_t;
+   
+   typedef hdr_offset_holder_t hdr_offset_holder;
+
+   struct block_info_t
+      :  
+         public hdr_offset_holder,
+         public multiset_hook_t
+   {
+      typedef typename node_slist::node_slist_t free_nodes_t;
+      //An intrusive list of free node from this block
+      free_nodes_t free_nodes;
+      friend bool operator <(const block_info_t &l, const block_info_t &r)
+      {
+//      {  return l.free_nodes.size() < r.free_nodes.size();   }
+         //Let's order blocks first by free nodes and then by address
+         //so that highest address fully free blocks are deallocated.
+         //This improves returning memory to the OS (trimming).
+         const bool is_less  = l.free_nodes.size() < r.free_nodes.size();
+         const bool is_equal = l.free_nodes.size() == r.free_nodes.size();
+         return is_less || (is_equal && (&l < &r));
+      }
+
+      friend bool operator ==(const block_info_t &l, const block_info_t &r)
+      {  return &l == &r;  }
+   };
+   typedef typename bi::make_multiset
+       >::type  block_multiset_t;
+};
+
+template
+inline size_type calculate_alignment
+   ( size_type overhead_percent, size_type real_node_size
+   , size_type hdr_size, size_type hdr_offset_size, size_type payload_per_allocation)
+{
+   //to-do: handle real_node_size != node_size
+   const size_type divisor  = overhead_percent*real_node_size;
+   const size_type dividend = hdr_offset_size*100;
+   size_type elements_per_subblock = (dividend - 1)/divisor + 1;
+   size_type candidate_power_of_2 = 
+      upper_power_of_2(elements_per_subblock*real_node_size + hdr_offset_size);
+   bool overhead_satisfied = false;
+   //Now calculate the wors-case overhead for a subblock
+   const size_type max_subblock_overhead  = hdr_size + payload_per_allocation;
+   while(!overhead_satisfied){
+      elements_per_subblock = (candidate_power_of_2 - max_subblock_overhead)/real_node_size;
+      const size_type overhead_size = candidate_power_of_2 - elements_per_subblock*real_node_size;
+      if(overhead_size*100/candidate_power_of_2 < overhead_percent){
+         overhead_satisfied = true;
+      }
+      else{
+         candidate_power_of_2 <<= 1;
+      }
+   }
+   return candidate_power_of_2;
+}
+
+template
+inline void calculate_num_subblocks
+   (size_type alignment, size_type real_node_size, size_type elements_per_block
+   , size_type &num_subblocks, size_type &real_num_node, size_type overhead_percent
+   , size_type hdr_size, size_type hdr_offset_size, size_type payload_per_allocation)
+{
+   size_type elements_per_subblock = (alignment - hdr_offset_size)/real_node_size;
+   size_type possible_num_subblock = (elements_per_block - 1)/elements_per_subblock + 1;
+   size_type hdr_subblock_elements = (alignment - hdr_size - payload_per_allocation)/real_node_size;
+   while(((possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements) < elements_per_block){
+      ++possible_num_subblock;
+   }
+   elements_per_subblock = (alignment - hdr_offset_size)/real_node_size;
+   bool overhead_satisfied = false;
+   while(!overhead_satisfied){
+      const size_type total_data = (elements_per_subblock*(possible_num_subblock-1) + hdr_subblock_elements)*real_node_size;
+      const size_type total_size = alignment*possible_num_subblock;
+      if((total_size - total_data)*100/total_size < overhead_percent){
+         overhead_satisfied = true;
+      }
+      else{
+         ++possible_num_subblock;
+      }
+   }
+   num_subblocks = possible_num_subblock;
+   real_num_node = (possible_num_subblock-1)*elements_per_subblock + hdr_subblock_elements;
+}
+
+template
+class private_adaptive_node_pool_impl
+{
+   //Non-copyable
+   private_adaptive_node_pool_impl();
+   private_adaptive_node_pool_impl(const private_adaptive_node_pool_impl &);
+   private_adaptive_node_pool_impl &operator=(const private_adaptive_node_pool_impl &);
+   typedef private_adaptive_node_pool_impl this_type;
+
+   typedef typename SegmentManagerBase::void_pointer void_pointer;
+   static const typename SegmentManagerBase::
+      size_type PayloadPerAllocation = SegmentManagerBase::PayloadPerAllocation;
+   typedef bool_            IsAlignOnly;
+   typedef true_                       AlignOnlyTrue;
+   typedef false_                      AlignOnlyFalse;
+
+   public:
+   typedef typename node_slist::node_t node_t;
+   typedef typename node_slist::node_slist_t free_nodes_t;
+   typedef typename SegmentManagerBase::multiallocation_chain     multiallocation_chain;
+   typedef typename SegmentManagerBase::size_type                 size_type;
+
+   private:
+   typedef typename adaptive_pool_types::block_info_t      block_info_t;
+   typedef typename adaptive_pool_types::block_multiset_t  block_multiset_t;
+   typedef typename block_multiset_t::iterator                                      block_iterator;
+   typedef typename adaptive_pool_types::hdr_offset_holder hdr_offset_holder;
+
+   static const size_type MaxAlign = alignment_of::value;
+   static const size_type HdrSize  = ((sizeof(block_info_t)-1)/MaxAlign+1)*MaxAlign;
+   static const size_type HdrOffsetSize = ((sizeof(hdr_offset_holder)-1)/MaxAlign+1)*MaxAlign;
+
+
+   public:
+   //!Segment manager typedef
+   typedef SegmentManagerBase                 segment_manager_base_type;
+
+   //!Constructor from a segment manager. Never throws
+   private_adaptive_node_pool_impl
+      ( segment_manager_base_type *segment_mngr_base
+      , size_type node_size
+      , size_type nodes_per_block
+      , size_type max_free_blocks
+      , unsigned char overhead_percent
+      )
+   :  m_max_free_blocks(max_free_blocks)
+   ,  m_real_node_size(lcm(node_size, size_type(alignment_of::value)))
+      //Round the size to a power of two value.
+      //This is the total memory size (including payload) that we want to
+      //allocate from the general-purpose allocator
+   ,  m_real_block_alignment
+         (AlignOnly ?
+            upper_power_of_2(HdrSize + m_real_node_size*nodes_per_block) :
+            calculate_alignment( (size_type)overhead_percent, m_real_node_size
+                               , HdrSize, HdrOffsetSize, PayloadPerAllocation))
+      //This is the real number of nodes per block
+   ,  m_num_subblocks(0)
+   ,  m_real_num_node(AlignOnly ? (m_real_block_alignment - PayloadPerAllocation - HdrSize)/m_real_node_size : 0)
+      //General purpose allocator
+   ,  mp_segment_mngr_base(segment_mngr_base)
+   ,  m_block_multiset()
+   ,  m_totally_free_blocks(0)
+   {
+      if(!AlignOnly){
+         calculate_num_subblocks
+            ( m_real_block_alignment
+            , m_real_node_size
+            , nodes_per_block
+            , m_num_subblocks
+            , m_real_num_node
+            , (size_type)overhead_percent
+            , HdrSize
+            , HdrOffsetSize
+            , PayloadPerAllocation);
+      }
+   }
+
+   //!Destructor. Deallocates all allocated blocks. Never throws
+   ~private_adaptive_node_pool_impl()
+   {  priv_clear();  }
+
+   size_type get_real_num_node() const
+   {  return m_real_num_node; }
+
+   //!Returns the segment manager. Never throws
+   segment_manager_base_type* get_segment_manager_base()const
+   {  return container_detail::to_raw_pointer(mp_segment_mngr_base);  }
+
+   //!Allocates array of count elements. Can throw
+   void *allocate_node()
+   {
+      priv_invariants();
+      //If there are no free nodes we allocate a new block
+      if (m_block_multiset.empty()){ 
+         priv_alloc_block(1);
+      }
+      //We take the first free node the multiset can't be empty
+      return priv_take_first_node();
+   }
+
+   //!Deallocates an array pointed by ptr. Never throws
+   void deallocate_node(void *pElem)
+   {
+      multiallocation_chain chain;
+      chain.push_front(void_pointer(pElem));
+      this->priv_reinsert_nodes_in_block(chain, 1);
+      //Update free block count<
+      if(m_totally_free_blocks > m_max_free_blocks){
+         this->priv_deallocate_free_blocks(m_max_free_blocks);
+      }
+      priv_invariants();
+   }
+
+   //!Allocates n nodes. 
+   //!Can throw
+   multiallocation_chain allocate_nodes(const size_type n)
+   {
+      multiallocation_chain chain;
+      size_type i = 0;
+      try{
+         priv_invariants();
+         while(i != n){
+            //If there are no free nodes we allocate all needed blocks
+            if (m_block_multiset.empty()){
+               priv_alloc_block(((n - i) - 1)/m_real_num_node + 1);
+            }
+            free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
+            const size_type free_nodes_count_before = free_nodes.size();
+            if(free_nodes_count_before == m_real_num_node){
+               --m_totally_free_blocks;
+            }
+            const size_type num_elems = ((n-i) < free_nodes_count_before) ? (n-i) : free_nodes_count_before;
+            for(size_type j = 0; j != num_elems; ++j){
+               void *new_node = &free_nodes.front();
+               free_nodes.pop_front();
+               chain.push_back(new_node);
+            }
+
+            if(free_nodes.empty()){
+               m_block_multiset.erase(m_block_multiset.begin());
+            }
+            i += num_elems;
+         }
+      }
+      catch(...){
+         this->deallocate_nodes(boost::move(chain));
+         throw;
+      }
+      priv_invariants();
+      return boost::move(chain);
+   }
+
+   //!Deallocates a linked list of nodes. Never throws
+   void deallocate_nodes(multiallocation_chain nodes)
+   {
+      this->priv_reinsert_nodes_in_block(nodes, nodes.size());
+      if(m_totally_free_blocks > m_max_free_blocks){
+         this->priv_deallocate_free_blocks(m_max_free_blocks);
+      }
+   }
+
+   void deallocate_free_blocks()
+   {  this->priv_deallocate_free_blocks(0);   }
+
+   size_type num_free_nodes()
+   {
+      typedef typename block_multiset_t::const_iterator citerator;
+      size_type count = 0;
+      citerator it (m_block_multiset.begin()), itend(m_block_multiset.end());
+      for(; it != itend; ++it){
+         count += it->free_nodes.size();
+      }
+      return count;
+   }
+
+   void swap(private_adaptive_node_pool_impl &other)
+   {
+      BOOST_ASSERT(m_max_free_blocks == other.m_max_free_blocks);
+      BOOST_ASSERT(m_real_node_size == other.m_real_node_size);
+      BOOST_ASSERT(m_real_block_alignment == other.m_real_block_alignment);
+      BOOST_ASSERT(m_real_num_node == other.m_real_num_node);
+      std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
+      std::swap(m_totally_free_blocks, other.m_totally_free_blocks);
+      m_block_multiset.swap(other.m_block_multiset);
+   }
+
+   //Deprecated, use deallocate_free_blocks
+   void deallocate_free_chunks()
+   {  this->priv_deallocate_free_blocks(0);   }
+
+   private:
+   void priv_deallocate_free_blocks(size_type max_free_blocks)
+   {
+      priv_invariants();
+      //Now check if we've reached the free nodes limit
+      //and check if we have free blocks. If so, deallocate as much
+      //as we can to stay below the limit
+      for( block_iterator itend = m_block_multiset.end()
+         ; m_totally_free_blocks > max_free_blocks
+         ; --m_totally_free_blocks
+         ){
+         BOOST_ASSERT(!m_block_multiset.empty());
+         block_iterator it = itend;
+         --it;
+         BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
+         m_block_multiset.erase_and_dispose(it, block_destroyer(this));
+      }
+   }
+
+   void priv_reinsert_nodes_in_block(multiallocation_chain &chain, size_type n)
+   {
+      block_iterator block_it(m_block_multiset.end());
+      while(n--){
+         void *pElem = container_detail::to_raw_pointer(chain.front());
+         chain.pop_front();
+         priv_invariants();
+         block_info_t *block_info = this->priv_block_from_node(pElem);
+         BOOST_ASSERT(block_info->free_nodes.size() < m_real_num_node);
+         //We put the node at the beginning of the free node list
+         node_t * to_deallocate = static_cast(pElem);
+         block_info->free_nodes.push_front(*to_deallocate);
+
+         block_iterator this_block(block_multiset_t::s_iterator_to(*block_info));
+         block_iterator next_block(this_block);
+         ++next_block;
+
+         //Cache the free nodes from the block
+         size_type this_block_free_nodes = this_block->free_nodes.size();
+
+         if(this_block_free_nodes == 1){
+            m_block_multiset.insert(m_block_multiset.begin(), *block_info);
+         }
+         else{
+            block_iterator next_block(this_block);
+            ++next_block;
+            if(next_block != block_it){
+               size_type next_free_nodes = next_block->free_nodes.size();
+               if(this_block_free_nodes > next_free_nodes){
+                  //Now move the block to the new position
+                  m_block_multiset.erase(this_block);
+                  m_block_multiset.insert(*block_info);
+               }
+            }
+         }
+         //Update free block count
+         if(this_block_free_nodes == m_real_num_node){
+            ++m_totally_free_blocks;
+         }
+         priv_invariants();
+      }
+   }
+
+   node_t *priv_take_first_node()
+   {
+      BOOST_ASSERT(m_block_multiset.begin() != m_block_multiset.end());
+      //We take the first free node the multiset can't be empty
+      free_nodes_t &free_nodes = m_block_multiset.begin()->free_nodes;
+      node_t *first_node = &free_nodes.front();
+      const size_type free_nodes_count = free_nodes.size();
+      BOOST_ASSERT(0 != free_nodes_count);
+      free_nodes.pop_front();
+      if(free_nodes_count == 1){
+         m_block_multiset.erase(m_block_multiset.begin());
+      }
+      else if(free_nodes_count == m_real_num_node){
+         --m_totally_free_blocks;
+      }
+      priv_invariants();
+      return first_node;
+   }
+
+   class block_destroyer;
+   friend class block_destroyer;
+
+   class block_destroyer
+   {
+      public:
+      block_destroyer(const this_type *impl)
+         :  mp_impl(impl)
+      {}
+
+      void operator()(typename block_multiset_t::pointer to_deallocate)
+      {  return this->do_destroy(to_deallocate, IsAlignOnly()); }
+
+      private:
+      void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyTrue)
+      {
+         size_type free_nodes = to_deallocate->free_nodes.size();
+         (void)free_nodes;
+         BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
+         mp_impl->mp_segment_mngr_base->deallocate(to_deallocate);
+      }
+
+      void do_destroy(typename block_multiset_t::pointer to_deallocate, AlignOnlyFalse)
+      {
+         size_type free_nodes = to_deallocate->free_nodes.size();
+         (void)free_nodes;
+         BOOST_ASSERT(free_nodes == mp_impl->m_real_num_node);
+         BOOST_ASSERT(0 == to_deallocate->hdr_offset);
+         hdr_offset_holder *hdr_off_holder = mp_impl->priv_first_subblock_from_block(container_detail::to_raw_pointer(to_deallocate));
+         mp_impl->mp_segment_mngr_base->deallocate(hdr_off_holder);
+      }
+
+      const this_type *mp_impl;
+   };
+
+   //This macro will activate invariant checking. Slow, but helpful for debugging the code.
+   //#define BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+   void priv_invariants()
+   #ifdef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+   #undef BOOST_CONTAINER_ADAPTIVE_NODE_POOL_CHECK_INVARIANTS
+   {
+      //We iterate through the block tree to free the memory
+      block_iterator it(m_block_multiset.begin()), 
+                     itend(m_block_multiset.end()), to_deallocate;
+      if(it != itend){
+         for(++it; it != itend; ++it){
+            block_iterator prev(it);
+            --prev;
+            size_type sp = prev->free_nodes.size(),
+                        si = it->free_nodes.size();
+            BOOST_ASSERT(sp <= si);
+            (void)sp;   (void)si;
+         }
+      }
+      //Check that the total free nodes are correct
+      it    = m_block_multiset.begin();
+      itend = m_block_multiset.end();
+      size_type total_free_nodes = 0;
+      for(; it != itend; ++it){
+         total_free_nodes += it->free_nodes.size();
+      }
+      BOOST_ASSERT(total_free_nodes >= m_totally_free_blocks*m_real_num_node);
+
+      //Check that the total totally free blocks are correct
+      it    = m_block_multiset.begin();
+      itend = m_block_multiset.end();
+      total_free = 0;
+      for(; it != itend; ++it){
+         total_free += it->free_nodes.size() == m_real_num_node;
+      }
+      BOOST_ASSERT(total_free >= m_totally_free_blocks);
+
+      if(!AlignOnly){
+         //Check that header offsets are correct
+         it = m_block_multiset.begin();
+         for(; it != itend; ++it){
+            hdr_offset_holder *hdr_off_holder = priv_first_subblock_from_block(&*it);
+            for(size_type i = 0, max = m_num_subblocks; i < max; ++i){
+               BOOST_ASSERT(hdr_off_holder->hdr_offset == size_type(reinterpret_cast(&*it)- reinterpret_cast(hdr_off_holder)));
+               BOOST_ASSERT(0 == ((size_type)hdr_off_holder & (m_real_block_alignment - 1)));
+               BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
+               hdr_off_holder = reinterpret_cast(reinterpret_cast(hdr_off_holder) + m_real_block_alignment);
+            }
+         }
+      }
+   }
+   #else
+   {} //empty
+   #endif
+
+   //!Deallocates all used memory. Never throws
+   void priv_clear()
+   {
+      #ifndef NDEBUG
+      block_iterator it    = m_block_multiset.begin();
+      block_iterator itend = m_block_multiset.end();
+      size_type num_free_nodes = 0;
+      for(; it != itend; ++it){
+         //Check for memory leak
+         BOOST_ASSERT(it->free_nodes.size() == m_real_num_node);
+         ++num_free_nodes;
+      }
+      BOOST_ASSERT(num_free_nodes == m_totally_free_blocks);
+      #endif
+      //Check for memory leaks
+      priv_invariants();
+      m_block_multiset.clear_and_dispose(block_destroyer(this));
+      m_totally_free_blocks = 0;
+   }
+
+   block_info_t *priv_block_from_node(void *node, AlignOnlyFalse) const
+   {
+      hdr_offset_holder *hdr_off_holder =
+         reinterpret_cast((std::size_t)node & size_type(~(m_real_block_alignment - 1)));
+      BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
+      BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
+      block_info_t *block = reinterpret_cast
+         (reinterpret_cast(hdr_off_holder) + hdr_off_holder->hdr_offset);
+      BOOST_ASSERT(block->hdr_offset == 0);
+      return block;
+   }
+
+   block_info_t *priv_block_from_node(void *node, AlignOnlyTrue) const
+   {
+      return (block_info_t *)((std::size_t)node & std::size_t(~(m_real_block_alignment - 1)));
+   }
+
+   block_info_t *priv_block_from_node(void *node) const
+   {  return priv_block_from_node(node, IsAlignOnly());   }
+
+   hdr_offset_holder *priv_first_subblock_from_block(block_info_t *block) const
+   {
+      hdr_offset_holder *hdr_off_holder = reinterpret_cast
+            (reinterpret_cast(block) - (m_num_subblocks-1)*m_real_block_alignment);
+      BOOST_ASSERT(hdr_off_holder->hdr_offset == size_type(reinterpret_cast(block) - reinterpret_cast(hdr_off_holder)));
+     BOOST_ASSERT(0 == ((std::size_t)hdr_off_holder & (m_real_block_alignment - 1)));
+      BOOST_ASSERT(0 == (hdr_off_holder->hdr_offset & (m_real_block_alignment - 1)));
+      return hdr_off_holder;
+   }
+
+   //!Allocates a several blocks of nodes. Can throw
+   void priv_alloc_block(size_type n, AlignOnlyTrue)
+   {
+      size_type real_block_size = m_real_block_alignment - PayloadPerAllocation;
+      for(size_type i = 0; i != n; ++i){
+         //We allocate a new NodeBlock and put it the last
+         //element of the tree
+         char *mem_address = static_cast
+            (mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
+         if(!mem_address)   throw std::bad_alloc();
+         ++m_totally_free_blocks;
+         block_info_t *c_info = new(mem_address)block_info_t();
+         m_block_multiset.insert(m_block_multiset.end(), *c_info);
+         
+         mem_address += HdrSize;
+         //We initialize all Nodes in Node Block to insert 
+         //them in the free Node list
+         typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
+         for(size_type i = 0; i < m_real_num_node; ++i){
+            prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *(node_t*)mem_address);
+            mem_address   += m_real_node_size;
+         }
+      }
+   }
+
+   void priv_alloc_block(size_type n, AlignOnlyFalse)
+   {
+      size_type real_block_size = m_real_block_alignment*m_num_subblocks - PayloadPerAllocation;
+      size_type elements_per_subblock = (m_real_block_alignment - HdrOffsetSize)/m_real_node_size;
+      size_type hdr_subblock_elements = (m_real_block_alignment - HdrSize - PayloadPerAllocation)/m_real_node_size;
+
+      for(size_type i = 0; i != n; ++i){
+         //We allocate a new NodeBlock and put it the last
+         //element of the tree
+         char *mem_address = static_cast
+            (mp_segment_mngr_base->allocate_aligned(real_block_size, m_real_block_alignment));
+         if(!mem_address)   throw std::bad_alloc();
+         ++m_totally_free_blocks;
+
+         //First initialize header information on the last subblock
+         char *hdr_addr = mem_address + m_real_block_alignment*(m_num_subblocks-1);
+         block_info_t *c_info = new(hdr_addr)block_info_t();
+         //Some structural checks
+         BOOST_ASSERT(static_cast(&static_cast(c_info)->hdr_offset) ==
+                static_cast(c_info));
+         typename free_nodes_t::iterator prev_insert_pos = c_info->free_nodes.before_begin();
+         for( size_type subblock = 0, maxsubblock = m_num_subblocks - 1
+            ; subblock < maxsubblock
+            ; ++subblock, mem_address += m_real_block_alignment){
+            //Initialize header offset mark
+            new(mem_address) hdr_offset_holder(size_type(hdr_addr - mem_address));
+            char *pNode = mem_address + HdrOffsetSize;
+            for(size_type i = 0; i < elements_per_subblock; ++i){
+               prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
+               pNode   += m_real_node_size;
+            }
+         }
+         {
+            char *pNode = hdr_addr + HdrSize;
+            //We initialize all Nodes in Node Block to insert 
+            //them in the free Node list
+            for(size_type i = 0; i < hdr_subblock_elements; ++i){
+               prev_insert_pos = c_info->free_nodes.insert_after(prev_insert_pos, *new (pNode) node_t);
+               pNode   += m_real_node_size;
+            }
+         }
+         //Insert the block after the free node list is full
+         m_block_multiset.insert(m_block_multiset.end(), *c_info);
+      }
+   }
+
+   //!Allocates a block of nodes. Can throw std::bad_alloc
+   void priv_alloc_block(size_type n)
+   {  return priv_alloc_block(n, IsAlignOnly());   }
+
+   private:
+   typedef typename boost::intrusive::pointer_traits
+      ::template rebind_pointer::type   segment_mngr_base_ptr_t;
+   const size_type m_max_free_blocks;
+   const size_type m_real_node_size;
+   //Round the size to a power of two value.
+   //This is the total memory size (including payload) that we want to
+   //allocate from the general-purpose allocator
+   const size_type m_real_block_alignment;
+   size_type m_num_subblocks;
+   //This is the real number of nodes per block
+   //const
+   size_type m_real_num_node;
+   segment_mngr_base_ptr_t                mp_segment_mngr_base;   //Segment manager
+   block_multiset_t                       m_block_multiset;       //Intrusive block list
+   size_type                            m_totally_free_blocks;  //Free blocks
+};
+
+}  //namespace container_detail {
+}  //namespace container {
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
diff --git a/src/third_party/boost/boost/container/detail/advanced_insert_int.hpp b/src/third_party/boost/boost/container/detail/advanced_insert_int.hpp
new file mode 100644
index 00000000000..58199c7aa8c
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/advanced_insert_int.hpp
@@ -0,0 +1,428 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
+#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+#include 
+#include 
+#include   //std::iterator_traits
+#include 
+
+namespace boost { namespace container { namespace container_detail {
+
+//This class will be interface for operations dependent on FwdIt types used advanced_insert_aux_impl
+template
+struct advanced_insert_aux_int
+{
+   typedef typename std::iterator_traits::difference_type difference_type;
+   virtual void copy_remaining_to(Iterator p) = 0;
+   virtual void uninitialized_copy_remaining_to(Iterator p) = 0;
+   virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
+   virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first) = 0;
+   virtual ~advanced_insert_aux_int() {}
+};
+
+//This class template will adapt each FwIt types to advanced_insert_aux_int
+template
+struct advanced_insert_aux_proxy
+   :  public advanced_insert_aux_int
+{
+   typedef boost::container::allocator_traits alloc_traits;
+   typedef typename allocator_traits::size_type size_type;
+   typedef typename allocator_traits::value_type value_type;
+   typedef typename advanced_insert_aux_int::difference_type difference_type;
+
+   advanced_insert_aux_proxy(A& a, FwdIt first, FwdIt last)
+      :  a_(a), first_(first), last_(last)
+   {}
+
+   virtual ~advanced_insert_aux_proxy()
+   {}
+
+   virtual void copy_remaining_to(Iterator p)
+   {  ::boost::copy_or_move(first_, last_, p);  }
+
+   virtual void uninitialized_copy_remaining_to(Iterator p)
+   {  ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, last_, p);  }
+
+   virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+   {
+      FwdIt mid = first_;
+      std::advance(mid, division_count);
+      if(first_n){
+         ::boost::container::uninitialized_copy_or_move_alloc(a_, first_, mid, pos);
+         first_ = mid;
+      }
+      else{
+         ::boost::container::uninitialized_copy_or_move_alloc(a_, mid, last_, pos);
+         last_ = mid;
+      }
+   }
+
+   virtual void copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+   {
+      FwdIt mid = first_;
+      std::advance(mid, division_count);
+      if(first_n){
+         ::boost::copy_or_move(first_, mid, pos);
+         first_ = mid;
+      }
+      else{
+         ::boost::copy_or_move(mid, last_, pos);
+         last_ = mid;
+      }
+   }
+   A &a_;
+   FwdIt first_, last_;
+};
+
+//This class template will adapt default construction insertions to advanced_insert_aux_int
+template
+struct default_construct_aux_proxy
+   :  public advanced_insert_aux_int
+{
+   typedef boost::container::allocator_traits alloc_traits;
+   typedef typename allocator_traits::size_type size_type;
+   typedef typename allocator_traits::value_type value_type;
+   typedef typename advanced_insert_aux_int::difference_type difference_type;
+
+   default_construct_aux_proxy(A &a, size_type count)
+      :  a_(a), count_(count)
+   {}
+
+   virtual ~default_construct_aux_proxy()
+   {}
+
+   virtual void copy_remaining_to(Iterator)
+   {  //This should never be called with any count
+      BOOST_ASSERT(count_ == 0);
+   }
+
+   virtual void uninitialized_copy_remaining_to(Iterator p)
+   {  this->priv_uninitialized_copy(p, count_); }
+
+   virtual void uninitialized_copy_some_and_update(Iterator pos, difference_type division_count, bool first_n)
+   {
+      size_type new_count;
+      if(first_n){
+         new_count = division_count;
+      }
+      else{
+         BOOST_ASSERT(difference_type(count_)>= division_count);
+         new_count = count_ - division_count;
+      }
+      this->priv_uninitialized_copy(pos, new_count);
+   }
+
+   virtual void copy_some_and_update(Iterator , difference_type division_count, bool first_n)
+   {
+      BOOST_ASSERT(count_ == 0);
+      size_type new_count;
+      if(first_n){
+         new_count = division_count;
+      }
+      else{
+         BOOST_ASSERT(difference_type(count_)>= division_count);
+         new_count = count_ - division_count;
+      }
+      //This function should never called with a count different to zero
+      BOOST_ASSERT(new_count == 0);
+      (void)new_count;
+   }
+
+   private:
+   void priv_uninitialized_copy(Iterator p, const size_type n)
+   {
+      BOOST_ASSERT(n <= count_);
+      Iterator orig_p = p;
+      size_type i = 0;
+      try{
+         for(; i < n; ++i, ++p){
+            alloc_traits::construct(a_, container_detail::to_raw_pointer(&*p));
+         }
+      }
+      catch(...){
+         while(i--){
+            alloc_traits::destroy(a_, container_detail::to_raw_pointer(&*orig_p++));
+         }
+         throw;
+      }
+      count_ -= n;
+   }
+   A &a_;
+   size_type count_;
+};
+
+}}}   //namespace boost { namespace container { namespace container_detail {
+
+#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+#include 
+#include 
+#include 
+#include 
+//#include  //For debugging purposes
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+
+//This class template will adapt emplace construction insertions of movable types 
+//to advanced_insert_aux_int
+template
+struct advanced_insert_aux_non_movable_emplace
+   :  public advanced_insert_aux_int
+{
+   typedef boost::container::allocator_traits alloc_traits;
+   typedef typename allocator_traits::size_type size_type;
+   typedef typename allocator_traits::value_type value_type;
+   typedef typename advanced_insert_aux_int::difference_type difference_type;
+   typedef typename build_number_seq::type             index_tuple_t;
+
+   explicit advanced_insert_aux_non_movable_emplace(A &a, Args&&... args)
+      : a_(a)
+      , args_(args...)
+      , used_(false)
+   {}
+
+   ~advanced_insert_aux_non_movable_emplace()
+   {}
+
+   virtual void copy_remaining_to(Iterator)
+   //This code can't be called since value_type is not movable or copyable
+   {  BOOST_ASSERT(false);   }
+
+   virtual void uninitialized_copy_remaining_to(Iterator p)
+   {  this->priv_uninitialized_copy_remaining_to(index_tuple_t(), p);   }
+
+   virtual void uninitialized_copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
+   {  this->priv_uninitialized_copy_some_and_update(index_tuple_t(), p, division_count, first_n);  }
+
+   virtual void copy_some_and_update(Iterator, difference_type, bool )
+   //This code can't be called since value_type is not movable or copyable
+   {  BOOST_ASSERT(false);   }
+
+   private:
+   template
+   void priv_uninitialized_copy_some_and_update(const index_tuple&, Iterator p, difference_type division_count, bool first_n)
+   {
+      BOOST_ASSERT(division_count <=1);
+      if((first_n && division_count == 1) || (!first_n && division_count == 0)){
+         if(!used_){
+            alloc_traits::construct( a_
+                                   , container_detail::to_raw_pointer(&*p)
+                                   , ::boost::container::container_detail::
+                                       stored_ref::forward(get(args_))...
+                                   );
+            used_ = true;
+         }
+      }
+   }
+
+   template
+   void priv_uninitialized_copy_remaining_to(const index_tuple&, Iterator p)
+   {
+      if(!used_){
+         alloc_traits::construct( a_
+                                , container_detail::to_raw_pointer(&*p)
+                                , ::boost::container::container_detail::
+                                    stored_ref::forward(get(args_))...
+                                );
+         used_ = true;
+      }
+   }
+
+   protected:
+   A &a_;
+   tuple args_;
+   bool used_;
+};
+
+//This class template will adapt emplace construction insertions of movable types 
+//to advanced_insert_aux_int
+template
+struct advanced_insert_aux_emplace
+   :  public advanced_insert_aux_non_movable_emplace
+{
+   typedef advanced_insert_aux_non_movable_emplace base_t;
+   typedef typename base_t::value_type       value_type;
+   typedef typename base_t::difference_type  difference_type;
+   typedef typename base_t::index_tuple_t    index_tuple_t;
+
+   explicit advanced_insert_aux_emplace(A &a, Args&&... args)
+      : base_t(a, boost::forward(args)...)
+   {}
+
+   ~advanced_insert_aux_emplace()
+   {}
+
+   //Override only needed functions
+   virtual void copy_remaining_to(Iterator p)
+   {  this->priv_copy_remaining_to(index_tuple_t(), p);   }
+
+   virtual void copy_some_and_update(Iterator p, difference_type division_count, bool first_n)
+   {  this->priv_copy_some_and_update(index_tuple_t(), p, division_count, first_n);  }
+
+   private:
+   template
+   void priv_copy_remaining_to(const index_tuple&, Iterator p)
+   {
+      if(!this->used_){
+         *p = boost::move(value_type (
+            ::boost::container::container_detail::stored_ref::forward(get(this->args_))...));
+         this->used_ = true;
+      }
+   }
+
+   template
+   void priv_copy_some_and_update(const index_tuple&, Iterator p, difference_type division_count, bool first_n)
+   {
+      BOOST_ASSERT(division_count <=1);
+      if((first_n && division_count == 1) || (!first_n && division_count == 0)){
+         if(!this->used_){
+            *p = boost::move(value_type(
+               ::boost::container::container_detail::stored_ref::forward(get(this->args_))...));
+            this->used_ = true;
+         }
+      }
+   }
+};
+
+}}}   //namespace boost { namespace container { namespace container_detail {
+
+#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+#include  
+#include 
+
+namespace boost {
+namespace container { 
+namespace container_detail {
+
+#define BOOST_PP_LOCAL_MACRO(n)                                                     \
+template        \
+struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), arg)  \
+   :  public advanced_insert_aux_int                                      \
+{                                                                                   \
+   typedef boost::container::allocator_traits alloc_traits;                      \
+   typedef typename allocator_traits::size_type size_type;                       \
+   typedef typename allocator_traits::value_type value_type;                     \
+   typedef typename advanced_insert_aux_int::difference_type              \
+      difference_type;                                                              \
+                                                                                    \
+   BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_non_movable_emplace, n), arg)      \
+      ( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) )          \
+      : a_(a)                                                                       \
+      , used_(false)                                                                \
+      BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_INIT, _)                   \
+    {}                                                                              \
+                                                                                    \
+   virtual void copy_remaining_to(Iterator)                                         \
+   {  BOOST_ASSERT(false);   }                                                      \
+                                                                                    \
+   virtual void uninitialized_copy_remaining_to(Iterator p)                         \
+   {                                                                                \
+      if(!used_){                                                                   \
+         alloc_traits::construct                                                    \
+            ( a_                                                                    \
+            , container_detail::to_raw_pointer(&*p)                                 \
+            BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)         \
+            );                                                                      \
+         used_ = true;                                                              \
+      }                                                                             \
+   }                                                                                \
+                                                                                    \
+   virtual void uninitialized_copy_some_and_update                                  \
+      (Iterator p, difference_type division_count, bool first_n)                    \
+   {                                                                                \
+      BOOST_ASSERT(division_count <=1);                                             \
+      if((first_n && division_count == 1) || (!first_n && division_count == 0)){    \
+         if(!used_){                                                                \
+            alloc_traits::construct                                                 \
+               ( a_                                                                 \
+               , container_detail::to_raw_pointer(&*p)                              \
+               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)      \
+               );                                                                   \
+            used_ = true;                                                           \
+         }                                                                          \
+      }                                                                             \
+   }                                                                                \
+                                                                                    \
+   virtual void copy_some_and_update(Iterator, difference_type, bool)               \
+   {  BOOST_ASSERT(false);   }                                                      \
+                                                                                    \
+   A &a_;                                                                           \
+   bool used_;                                                                      \
+   BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _)                           \
+};                                                                                  \
+                                                                                    \
+template        \
+struct BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)              \
+   : BOOST_PP_CAT(BOOST_PP_CAT(                                                     \
+      advanced_insert_aux_non_movable_emplace, n), arg)                             \
+         < A, Iterator BOOST_PP_ENUM_TRAILING_PARAMS(n, P) >                        \
+{                                                                                   \
+   typedef BOOST_PP_CAT(BOOST_PP_CAT(                                               \
+      advanced_insert_aux_non_movable_emplace, n), arg)                             \
+          base_t;                 \
+   typedef typename base_t::value_type       value_type;                            \
+   typedef typename base_t::difference_type  difference_type;                       \
+                                                                                    \
+   BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)                  \
+      ( A &a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) )          \
+      : base_t(a BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) )   \
+    {}                                                                              \
+                                                                                    \
+   virtual void copy_remaining_to(Iterator p)                                       \
+   {                                                                                \
+      if(!this->used_){                                                             \
+         value_type v BOOST_PP_LPAREN_IF(n)                                         \
+            BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)                  \
+            BOOST_PP_RPAREN_IF(n);                                                  \
+         *p = boost::move(v);                                                       \
+         this->used_ = true;                                                        \
+      }                                                                             \
+   }                                                                                \
+                                                                                    \
+   virtual void copy_some_and_update                                                \
+      (Iterator p, difference_type division_count, bool first_n)                    \
+   {                                                                                \
+      BOOST_ASSERT(division_count <=1);                                             \
+      if((first_n && division_count == 1) || (!first_n && division_count == 0)){    \
+         if(!this->used_){                                                          \
+            value_type v BOOST_PP_LPAREN_IF(n)                                      \
+                  BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _)            \
+                BOOST_PP_RPAREN_IF(n);                                              \
+            *p = boost::move(v);                                                    \
+            this->used_ = true;                                                     \
+         }                                                                          \
+      }                                                                             \
+   }                                                                                \
+};                                                                                  \
+//!
+
+#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+}}}   //namespace boost { namespace container { namespace container_detail {
+
+#endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+#include 
+
+#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
diff --git a/src/third_party/boost/boost/container/detail/algorithms.hpp b/src/third_party/boost/boost/container/detail/algorithms.hpp
new file mode 100644
index 00000000000..a2713f50f11
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/algorithms.hpp
@@ -0,0 +1,60 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
+#define BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+
+#include 
+
+namespace boost {
+namespace container {
+
+template
+inline void construct_in_place(A &a, T* dest, InpIt source)
+{     boost::container::allocator_traits::construct(a, dest, *source);  }
+//#endif
+
+template
+inline void construct_in_place(A &a, T *dest, default_construct_iterator)
+{
+   boost::container::allocator_traits::construct(a, dest);
+}
+
+template
+inline void construct_in_place(A &a, T *dest, emplace_iterator ei)
+{
+   ei.construct_in_place(a, dest);
+}
+
+}  //namespace container { 
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
+
diff --git a/src/third_party/boost/boost/container/detail/allocation_type.hpp b/src/third_party/boost/boost/container/detail/allocation_type.hpp
new file mode 100644
index 00000000000..edad487c57a
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/allocation_type.hpp
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP
+#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+
+namespace boost {
+namespace container {
+
+/// @cond
+enum allocation_type_v
+{   
+   // constants for allocation commands
+   allocate_new_v   = 0x01,
+   expand_fwd_v     = 0x02,
+   expand_bwd_v     = 0x04,
+//   expand_both    = expand_fwd | expand_bwd,
+//   expand_or_new  = allocate_new | expand_both,
+   shrink_in_place_v = 0x08,
+   nothrow_allocation_v = 0x10,
+   zero_memory_v = 0x20,
+   try_shrink_in_place_v = 0x40
+};
+
+typedef int allocation_type;
+/// @endcond
+static const allocation_type allocate_new       = (allocation_type)allocate_new_v;
+static const allocation_type expand_fwd         = (allocation_type)expand_fwd_v;
+static const allocation_type expand_bwd         = (allocation_type)expand_bwd_v;
+static const allocation_type shrink_in_place    = (allocation_type)shrink_in_place_v;
+static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v;
+static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v;
+static const allocation_type zero_memory        = (allocation_type)zero_memory_v;
+
+}  //namespace container {
+}  //namespace boost {
+
+#include 
+
+#endif   //BOOST_CONTAINER_ALLOCATION_TYPE_HPP
diff --git a/src/third_party/boost/boost/container/detail/config_begin.hpp b/src/third_party/boost/boost/container/detail/config_begin.hpp
new file mode 100644
index 00000000000..bd44daacfe5
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/config_begin.hpp
@@ -0,0 +1,48 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
+#define BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
+#include 
+
+#endif   //BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
+
+#ifdef BOOST_MSVC
+   #ifndef _CRT_SECURE_NO_DEPRECATE
+   #define  BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
+   #define _CRT_SECURE_NO_DEPRECATE
+   #endif
+   #pragma warning (push)
+   #pragma warning (disable : 4702) // unreachable code
+   #pragma warning (disable : 4706) // assignment within conditional expression
+   #pragma warning (disable : 4127) // conditional expression is constant
+   #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
+   #pragma warning (disable : 4284) // odd return type for operator->
+   #pragma warning (disable : 4244) // possible loss of data
+   #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
+   #pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
+   #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
+   #pragma warning (disable : 4355) // "this" : used in base member initializer list
+   #pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
+   #pragma warning (disable : 4511) // copy constructor could not be generated
+   #pragma warning (disable : 4512) // assignment operator could not be generated
+   #pragma warning (disable : 4514) // unreferenced inline removed
+   #pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
+   #pragma warning (disable : 4522) // "class" : multiple assignment operators specified
+   #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
+   #pragma warning (disable : 4710) // function not inlined
+   #pragma warning (disable : 4711) // function selected for automatic inline expansion
+   #pragma warning (disable : 4786) // identifier truncated in debug info
+   #pragma warning (disable : 4996) // "function": was declared deprecated
+   #pragma warning (disable : 4197) // top-level volatile in cast is ignored
+   #pragma warning (disable : 4541) // 'typeid' used on polymorphic type 'boost::exception'
+                                    //    with /GR-; unpredictable behavior may result
+   #pragma warning (disable : 4673) //  throwing '' the following types will not be considered at the catch site
+   #pragma warning (disable : 4671) //  the copy constructor is inaccessible
+#endif   //BOOST_MSVC
diff --git a/src/third_party/boost/boost/container/detail/config_end.hpp b/src/third_party/boost/boost/container/detail/config_end.hpp
new file mode 100644
index 00000000000..b71fabcdaec
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/config_end.hpp
@@ -0,0 +1,17 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#if defined BOOST_MSVC
+   #pragma warning (pop)
+   #ifdef BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
+   #undef BOOST_CONTAINER_DETAIL_CRT_SECURE_NO_DEPRECATE
+   #undef _CRT_SECURE_NO_DEPRECATE
+   #endif
+#endif
+
diff --git a/src/third_party/boost/boost/container/detail/destroyers.hpp b/src/third_party/boost/boost/container/detail/destroyers.hpp
new file mode 100644
index 00000000000..26ae089aa6a
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/destroyers.hpp
@@ -0,0 +1,163 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DESTROYERS_HPP
+#define BOOST_CONTAINER_DESTROYERS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace container { 
+namespace container_detail {
+
+//!A deleter for scoped_ptr that deallocates the memory
+//!allocated for an array of objects using a STL allocator.
+template 
+struct scoped_array_deallocator
+{
+   typedef boost::container::allocator_traits AllocTraits;
+   typedef typename AllocTraits::pointer    pointer;
+   typedef typename AllocTraits::size_type  size_type;
+
+   scoped_array_deallocator(pointer p, Allocator& a, size_type length)
+      : m_ptr(p), m_alloc(a), m_length(length) {}
+
+   ~scoped_array_deallocator()
+   {  if (m_ptr) m_alloc.deallocate(m_ptr, m_length);  }
+
+   void release()
+   {  m_ptr = 0; }
+
+   private:
+   pointer     m_ptr;
+   Allocator&  m_alloc;
+   size_type   m_length;
+};
+
+template 
+struct null_scoped_array_deallocator
+{
+   typedef boost::container::allocator_traits AllocTraits;
+   typedef typename AllocTraits::pointer    pointer;
+   typedef typename AllocTraits::size_type  size_type;
+
+   null_scoped_array_deallocator(pointer, Allocator&, size_type)
+   {}
+
+   void release()
+   {}
+};
+
+
+//!A deleter for scoped_ptr that destroys
+//!an object using a STL allocator.
+template 
+struct scoped_destructor_n
+{
+   typedef boost::container::allocator_traits AllocTraits;
+   typedef typename AllocTraits::pointer    pointer;
+   typedef typename AllocTraits::value_type value_type;
+   typedef typename AllocTraits::size_type  size_type;
+
+   scoped_destructor_n(pointer p, Allocator& a, size_type n)
+      : m_p(p), m_a(a), m_n(n)
+   {}
+
+   void release()
+   {  m_p = 0; }
+
+   void increment_size(size_type inc)
+   {  m_n += inc;   }
+   
+   ~scoped_destructor_n()
+   {
+      if(!m_p) return;
+      value_type *raw_ptr = container_detail::to_raw_pointer(m_p);
+      for(size_type i = 0; i < m_n; ++i, ++raw_ptr)
+         AllocTraits::destroy(m_a, raw_ptr);
+   }
+
+   private:
+   pointer     m_p;
+   Allocator & m_a;
+   size_type   m_n;
+};
+
+//!A deleter for scoped_ptr that destroys
+//!an object using a STL allocator.
+template 
+struct null_scoped_destructor_n
+{
+   typedef boost::container::allocator_traits AllocTraits;
+   typedef typename AllocTraits::pointer pointer;
+   typedef typename AllocTraits::size_type size_type;
+
+   null_scoped_destructor_n(pointer, Allocator&, size_type)
+   {}
+
+   void increment_size(size_type)
+   {}
+
+   void release()
+   {}
+};
+
+template 
+class allocator_destroyer
+{
+   typedef boost::container::allocator_traits AllocTraits;
+   typedef typename AllocTraits::value_type value_type;
+   typedef typename AllocTraits::pointer    pointer;
+   typedef container_detail::integral_constant::value>                           alloc_version;
+   typedef container_detail::integral_constant  allocator_v1;
+   typedef container_detail::integral_constant  allocator_v2;
+
+   private:
+   Allocator & a_;
+
+   private:
+   void priv_deallocate(const pointer &p, allocator_v1)
+   {  AllocTraits::deallocate(a_,p, 1); }
+
+   void priv_deallocate(const pointer &p, allocator_v2)
+   {  a_.deallocate_one(p); }
+
+   public:
+   allocator_destroyer(Allocator &a)
+      : a_(a)
+   {}
+
+   void operator()(const pointer &p)
+   {
+      AllocTraits::destroy(a_, container_detail::to_raw_pointer(p));
+      priv_deallocate(p, alloc_version());
+   }
+};
+
+
+}  //namespace container_detail { 
+}  //namespace container { 
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DESTROYERS_HPP
diff --git a/src/third_party/boost/boost/container/detail/flat_tree.hpp b/src/third_party/boost/boost/container/detail/flat_tree.hpp
new file mode 100644
index 00000000000..44438386a3a
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/flat_tree.hpp
@@ -0,0 +1,822 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_FLAT_TREE_HPP
+#define BOOST_CONTAINER_FLAT_TREE_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+
+namespace container {
+
+namespace container_detail {
+
+template
+class flat_tree_value_compare
+   : private Compare
+{
+   typedef Value              first_argument_type;
+   typedef Value              second_argument_type;
+   typedef bool               return_type;
+   public:     
+   flat_tree_value_compare()
+      : Compare()
+   {}
+
+   flat_tree_value_compare(const Compare &pred) 
+      : Compare(pred)
+   {}
+
+   bool operator()(const Value& lhs, const Value& rhs) const
+   { 
+      KeyOfValue key_extract;
+      return Compare::operator()(key_extract(lhs), key_extract(rhs)); 
+   }
+
+   const Compare &get_comp() const
+      {  return *this;  }
+   
+   Compare &get_comp()
+      {  return *this;  }
+};
+
+template
+struct get_flat_tree_iterators
+{
+   typedef typename container_detail::
+      vector_iterator                        iterator;
+   typedef typename container_detail::
+      vector_const_iterator                  const_iterator;
+   typedef std::reverse_iterator            reverse_iterator;
+   typedef std::reverse_iterator      const_reverse_iterator;
+};
+
+template 
+class flat_tree
+{
+   typedef boost::container::vector  vector_t;
+   typedef A                                   allocator_t;
+
+   public:
+   typedef flat_tree_value_compare value_compare;
+
+ private:
+   struct Data 
+      //Inherit from value_compare to do EBO
+      : public value_compare
+   {
+      BOOST_COPYABLE_AND_MOVABLE(Data)
+
+      public:
+      Data()
+         : value_compare(), m_vect()
+      {}
+
+      Data(const Data &d)
+         : value_compare(d), m_vect(d.m_vect)
+      {}
+
+      Data(BOOST_RV_REF(Data) d)
+         : value_compare(boost::move(d)), m_vect(boost::move(d.m_vect))
+      {}
+
+      Data(const Compare &comp) 
+         : value_compare(comp), m_vect()
+      {}
+
+      Data(const Compare &comp,
+           const allocator_t &alloc) 
+         : value_compare(comp), m_vect(alloc)
+      {}
+
+      Data& operator=(BOOST_COPY_ASSIGN_REF(Data) d)
+      {
+         this->value_compare::operator=(d);
+         m_vect = d.m_vect;
+         return *this;
+      }
+
+      Data& operator=(BOOST_RV_REF(Data) d)
+      {
+         this->value_compare::operator=(boost::move(static_cast(d)));
+         m_vect = boost::move(d.m_vect);
+         return *this;
+      }
+
+      void swap(Data &d)
+      {
+         value_compare& mycomp    = *this, & othercomp = d;
+         container_detail::do_swap(mycomp, othercomp);
+         this->m_vect.swap(d.m_vect);
+      }
+
+      vector_t m_vect;
+   };
+
+   Data m_data;
+   BOOST_COPYABLE_AND_MOVABLE(flat_tree)
+
+   public:
+
+   typedef typename vector_t::value_type              value_type;
+   typedef typename vector_t::pointer                 pointer;
+   typedef typename vector_t::const_pointer           const_pointer;
+   typedef typename vector_t::reference               reference;
+   typedef typename vector_t::const_reference         const_reference;
+   typedef Key                                        key_type;
+   typedef Compare                                    key_compare;
+   typedef typename vector_t::allocator_type          allocator_type;
+   typedef typename vector_t::size_type               size_type;
+   typedef typename vector_t::difference_type         difference_type;
+   typedef typename vector_t::iterator                iterator;
+   typedef typename vector_t::const_iterator          const_iterator;
+   typedef typename vector_t::reverse_iterator        reverse_iterator;
+   typedef typename vector_t::const_reverse_iterator  const_reverse_iterator;
+
+   //!Standard extension
+   typedef allocator_type                             stored_allocator_type;
+
+   flat_tree()
+      : m_data()
+   { }
+
+   explicit flat_tree(const Compare& comp)
+      : m_data(comp)
+   { }
+
+   flat_tree(const Compare& comp, const allocator_type& a)
+      : m_data(comp, a)
+   { }
+
+   flat_tree(const flat_tree& x) 
+      :  m_data(x.m_data)
+   { }
+
+   flat_tree(BOOST_RV_REF(flat_tree) x)
+      :  m_data(boost::move(x.m_data))
+   { }
+
+   template 
+   flat_tree( ordered_range_t, InputIterator first, InputIterator last
+            , const Compare& comp     = Compare()
+            , const allocator_type& a = allocator_type())
+      : m_data(comp, a)
+   { this->m_data.m_vect.insert(this->m_data.m_vect.end(), first, last); }
+
+   ~flat_tree()
+   { }
+
+   flat_tree&  operator=(BOOST_COPY_ASSIGN_REF(flat_tree) x)
+   {  m_data = x.m_data;   return *this;  }
+
+   flat_tree&  operator=(BOOST_RV_REF(flat_tree) mx)
+   {  m_data = boost::move(mx.m_data); return *this;  }
+
+   public:    
+   // accessors:
+   Compare key_comp() const 
+   { return this->m_data.get_comp(); }
+
+   allocator_type get_allocator() const 
+   { return this->m_data.m_vect.get_allocator(); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+   {  return this->m_data.m_vect.get_stored_allocator(); }
+
+   stored_allocator_type &get_stored_allocator()
+   {  return this->m_data.m_vect.get_stored_allocator(); }
+
+   iterator begin() 
+   { return this->m_data.m_vect.begin(); }
+
+   const_iterator begin() const 
+   { return this->cbegin(); }
+
+   const_iterator cbegin() const 
+   { return this->m_data.m_vect.begin(); }
+
+   iterator end() 
+   { return this->m_data.m_vect.end(); }
+
+   const_iterator end() const 
+   { return this->cend(); }
+
+   const_iterator cend() const 
+   { return this->m_data.m_vect.end(); }
+
+   reverse_iterator rbegin() 
+   { return reverse_iterator(this->end()); }
+
+   const_reverse_iterator rbegin() const 
+   {  return this->crbegin();  }
+
+   const_reverse_iterator crbegin() const 
+   {  return const_reverse_iterator(this->cend());  }
+
+   reverse_iterator rend() 
+   { return reverse_iterator(this->begin()); }
+
+   const_reverse_iterator rend() const 
+   { return this->crend(); } 
+
+   const_reverse_iterator crend() const 
+   { return const_reverse_iterator(this->cbegin()); } 
+
+   bool empty() const 
+   { return this->m_data.m_vect.empty(); }
+
+   size_type size() const 
+   { return this->m_data.m_vect.size(); }
+
+   size_type max_size() const 
+   { return this->m_data.m_vect.max_size(); }
+
+   void swap(flat_tree& other) 
+   {  this->m_data.swap(other.m_data);  }
+
+   public:
+   // insert/erase
+   std::pair insert_unique(const value_type& val)
+   {
+      insert_commit_data data;
+      std::pair ret = priv_insert_unique_prepare(val, data);
+      if(ret.second){
+         ret.first = priv_insert_commit(data, val);
+      }
+      return ret;
+   }
+
+   std::pair insert_unique(BOOST_RV_REF(value_type) val)
+   {
+      insert_commit_data data;
+      std::pair ret = priv_insert_unique_prepare(val, data);
+      if(ret.second){
+         ret.first = priv_insert_commit(data, boost::move(val));
+      }
+      return ret;
+   }
+
+
+   iterator insert_equal(const value_type& val)
+   {
+      iterator i = this->upper_bound(KeyOfValue()(val));
+      i = this->m_data.m_vect.insert(i, val);
+      return i;
+   }
+
+   iterator insert_equal(BOOST_RV_REF(value_type) mval)
+   {
+      iterator i = this->upper_bound(KeyOfValue()(mval));
+      i = this->m_data.m_vect.insert(i, boost::move(mval));
+      return i;
+   }
+
+   iterator insert_unique(const_iterator pos, const value_type& val)
+   {
+      insert_commit_data data;
+      std::pair ret = priv_insert_unique_prepare(pos, val, data);
+      if(ret.second){
+         ret.first = priv_insert_commit(data, val);
+      }
+      return ret.first;
+   }
+
+   iterator insert_unique(const_iterator pos, BOOST_RV_REF(value_type) mval)
+   {
+      insert_commit_data data;
+      std::pair ret = priv_insert_unique_prepare(pos, mval, data);
+      if(ret.second){
+         ret.first = priv_insert_commit(data, boost::move(mval));
+      }
+      return ret.first;
+   }
+
+   iterator insert_equal(const_iterator pos, const value_type& val)
+   {
+      insert_commit_data data;
+      priv_insert_equal_prepare(pos, val, data);
+      return priv_insert_commit(data, val);
+   }
+
+   iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval)
+   {
+      insert_commit_data data;
+      priv_insert_equal_prepare(pos, mval, data);
+      return priv_insert_commit(data, boost::move(mval));
+   }
+
+   template 
+   void insert_unique(InIt first, InIt last)
+   {
+      for ( ; first != last; ++first)
+         this->insert_unique(*first);
+   }
+
+   template 
+   void insert_equal(InIt first, InIt last)
+   {
+      typedef typename 
+         std::iterator_traits::iterator_category ItCat;
+      priv_insert_equal(first, last, ItCat());
+   }
+
+   #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   template 
+   std::pair emplace_unique(Args&&... args)
+   {
+      value_type && val = value_type(boost::forward(args)...);
+      insert_commit_data data;
+      std::pair ret =
+         priv_insert_unique_prepare(val, data);
+      if(ret.second){
+         ret.first = priv_insert_commit(data, boost::move(val));
+      }
+      return ret;
+   }
+
+   template 
+   iterator emplace_hint_unique(const_iterator hint, Args&&... args)
+   {
+      value_type && val = value_type(boost::forward(args)...);
+      insert_commit_data data;
+      std::pair ret = priv_insert_unique_prepare(hint, val, data);
+      if(ret.second){
+         ret.first = priv_insert_commit(data, boost::move(val));
+      }
+      return ret.first;
+   }
+
+   template 
+   iterator emplace_equal(Args&&... args)
+   {
+      value_type &&val = value_type(boost::forward(args)...);
+      iterator i = this->upper_bound(KeyOfValue()(val));
+      i = this->m_data.m_vect.insert(i, boost::move(val));
+      return i;
+   }
+
+   template 
+   iterator emplace_hint_equal(const_iterator hint, Args&&... args)
+   {
+      value_type &&val = value_type(boost::forward(args)...);
+      insert_commit_data data;
+      priv_insert_equal_prepare(hint, val, data);
+      return priv_insert_commit(data, boost::move(val));
+   }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                        \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+   std::pair                                                              \
+      emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                  \
+   {                                                                                      \
+      BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type         \
+         BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n)                  \
+            BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n);  \
+      value_type &val = vval;                                                             \
+      insert_commit_data data;                                                            \
+      std::pair ret = priv_insert_unique_prepare(val, data);               \
+      if(ret.second){                                                                     \
+         ret.first = priv_insert_commit(data, boost::move(val));                          \
+      }                                                                                   \
+      return ret;                                                                         \
+   }                                                                                      \
+                                                                                          \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+   iterator emplace_hint_unique(const_iterator hint                                       \
+                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))      \
+   {                                                                                      \
+      BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type         \
+         BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n)                  \
+            BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n);  \
+      value_type &val = vval;                                                             \
+      insert_commit_data data;                                                            \
+      std::pair ret = priv_insert_unique_prepare(hint, val, data);         \
+      if(ret.second){                                                                     \
+         ret.first = priv_insert_commit(data, boost::move(val));                          \
+      }                                                                                   \
+      return ret.first;                                                                   \
+   }                                                                                      \
+                                                                                          \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+   iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))             \
+   {                                                                                      \
+      BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type         \
+         BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n)                  \
+            BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n);  \
+      value_type &val = vval;                                                             \
+      iterator i = this->upper_bound(KeyOfValue()(val));                                  \
+      i = this->m_data.m_vect.insert(i, boost::move(val));                                \
+      return i;                                                                           \
+   }                                                                                      \
+                                                                                          \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+   iterator emplace_hint_equal(const_iterator hint                                        \
+                      BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))        \
+   {                                                                                      \
+      BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), container_detail::value_init<) value_type         \
+         BOOST_PP_EXPR_IF(BOOST_PP_NOT(n), >) vval BOOST_PP_LPAREN_IF(n)                  \
+            BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) BOOST_PP_RPAREN_IF(n);  \
+      value_type &val = vval;                                                             \
+      insert_commit_data data;                                                            \
+      priv_insert_equal_prepare(hint, val, data);                                         \
+      return priv_insert_commit(data, boost::move(val));                                  \
+   }                                                                                      \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   iterator erase(const_iterator position)
+   {  return this->m_data.m_vect.erase(position);  }
+
+   size_type erase(const key_type& k)
+   {
+      std::pair itp = this->equal_range(k);
+      size_type ret = static_cast(itp.second-itp.first);
+      if (ret){
+         this->m_data.m_vect.erase(itp.first, itp.second);
+      }
+      return ret;
+   }
+
+   iterator erase(const_iterator first, const_iterator last)
+   {  return this->m_data.m_vect.erase(first, last);  }
+
+   void clear()
+   {  this->m_data.m_vect.clear();  }
+
+   //! Effects: Tries to deallocate the excess of memory created
+   //    with previous allocations. The size of the vector is unchanged
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to size().
+   void shrink_to_fit()
+   {  this->m_data.m_vect.shrink_to_fit();  }
+
+   // set operations:
+   iterator find(const key_type& k)
+   {
+      const Compare &key_comp = this->m_data.get_comp();
+      iterator i = this->lower_bound(k);
+
+      if (i != this->end() && key_comp(k, KeyOfValue()(*i))){  
+         i = this->end();  
+      }
+      return i;
+   }
+
+   const_iterator find(const key_type& k) const
+   {
+      const Compare &key_comp = this->m_data.get_comp();
+      const_iterator i = this->lower_bound(k);
+
+      if (i != this->end() && key_comp(k, KeyOfValue()(*i))){  
+         i = this->end();  
+      }
+      return i;
+   }
+
+   size_type count(const key_type& k) const
+   {
+      std::pair p = this->equal_range(k);
+      size_type n = p.second - p.first;
+      return n;
+   }
+
+   iterator lower_bound(const key_type& k)
+   {  return this->priv_lower_bound(this->begin(), this->end(), k);  }
+
+   const_iterator lower_bound(const key_type& k) const
+   {  return this->priv_lower_bound(this->begin(), this->end(), k);  }
+
+   iterator upper_bound(const key_type& k)
+   {  return this->priv_upper_bound(this->begin(), this->end(), k);  }
+
+   const_iterator upper_bound(const key_type& k) const
+   {  return this->priv_upper_bound(this->begin(), this->end(), k);  }
+
+   std::pair equal_range(const key_type& k)
+   {  return this->priv_equal_range(this->begin(), this->end(), k);  }
+
+   std::pair equal_range(const key_type& k) const
+   {  return this->priv_equal_range(this->begin(), this->end(), k);  }
+
+   size_type capacity() const           
+   { return this->m_data.m_vect.capacity(); }
+
+   void reserve(size_type count)       
+   { this->m_data.m_vect.reserve(count);   }
+
+   private:
+   struct insert_commit_data
+   {
+      const_iterator position;
+   };
+
+   // insert/erase
+   void priv_insert_equal_prepare
+      (const_iterator pos, const value_type& val, insert_commit_data &data)
+   {
+      // N1780
+      //   To insert val at pos:
+      //   if pos == end || val <= *pos
+      //      if pos == begin || val >= *(pos-1)
+      //         insert val before pos
+      //      else
+      //         insert val before upper_bound(val)
+      //   else
+      //      insert val before lower_bound(val)
+      const value_compare &value_comp = this->m_data;
+
+      if(pos == this->cend() || !value_comp(*pos, val)){
+         if (pos == this->cbegin() || !value_comp(val, pos[-1])){
+            data.position = pos;
+         }
+         else{
+            data.position = 
+               this->priv_upper_bound(this->cbegin(), pos, KeyOfValue()(val));
+         }
+      }
+      else{
+         data.position = 
+            this->priv_lower_bound(pos, this->cend(), KeyOfValue()(val));
+      }
+   }
+
+   std::pair priv_insert_unique_prepare
+      (const_iterator beg, const_iterator end, const value_type& val, insert_commit_data &commit_data)
+   {
+      const value_compare &value_comp  = this->m_data;
+      commit_data.position = this->priv_lower_bound(beg, end, KeyOfValue()(val));
+      return std::pair
+         ( *reinterpret_cast(&commit_data.position)
+         , commit_data.position == end || value_comp(val, *commit_data.position));
+   }
+
+   std::pair priv_insert_unique_prepare
+      (const value_type& val, insert_commit_data &commit_data)
+   {  return priv_insert_unique_prepare(this->begin(), this->end(), val, commit_data);   }
+
+   std::pair priv_insert_unique_prepare
+      (const_iterator pos, const value_type& val, insert_commit_data &commit_data)
+   {
+      //N1780. Props to Howard Hinnant!
+      //To insert val at pos:
+      //if pos == end || val <= *pos
+      //   if pos == begin || val >= *(pos-1)
+      //      insert val before pos
+      //   else
+      //      insert val before upper_bound(val)
+      //else if pos+1 == end || val <= *(pos+1)
+      //   insert val after pos
+      //else
+      //   insert val before lower_bound(val)
+      const value_compare &value_comp = this->m_data;
+
+      if(pos == this->cend() || value_comp(val, *pos)){
+         if(pos != this->cbegin() && !value_comp(val, pos[-1])){
+            if(value_comp(pos[-1], val)){
+               commit_data.position = pos;
+               return std::pair(*reinterpret_cast(&pos), true);
+            }
+            else{
+               return std::pair(*reinterpret_cast(&pos), false);
+            }
+         }
+         return this->priv_insert_unique_prepare(this->cbegin(), pos, val, commit_data);
+      }
+
+      // Works, but increases code complexity
+      //Next check
+      //else if (value_comp(*pos, val) && !value_comp(pos[1], val)){
+      //   if(value_comp(val, pos[1])){
+      //      commit_data.position = pos+1;
+      //      return std::pair(pos+1, true);
+      //   }
+      //   else{
+      //      return std::pair(pos+1, false);
+      //   }
+      //}
+      else{
+         //[... pos ... val ... ]
+         //The hint is before the insertion position, so insert it
+         //in the remaining range
+         return this->priv_insert_unique_prepare(pos, this->end(), val, commit_data);
+      }
+   }
+
+   template
+   iterator priv_insert_commit
+      (insert_commit_data &commit_data, BOOST_FWD_REF(Convertible) convertible)
+   {
+      return this->m_data.m_vect.insert
+         ( commit_data.position
+         , boost::forward(convertible));
+   }
+
+   template 
+   RanIt priv_lower_bound(RanIt first, RanIt last,
+                          const key_type & key) const
+   {
+      const Compare &key_comp = this->m_data.get_comp();
+      KeyOfValue key_extract;
+      difference_type len = last - first, half;
+      RanIt middle;
+
+      while (len > 0) {
+         half = len >> 1;
+         middle = first;
+         middle += half;
+
+         if (key_comp(key_extract(*middle), key)) {
+            ++middle;
+            first = middle;
+            len = len - half - 1;
+         }
+         else
+            len = half;
+      }
+      return first;
+   }
+
+   template 
+   RanIt priv_upper_bound(RanIt first, RanIt last,
+                          const key_type & key) const
+   {
+      const Compare &key_comp = this->m_data.get_comp();
+      KeyOfValue key_extract;
+      difference_type len = last - first, half;
+      RanIt middle;
+
+      while (len > 0) {
+         half = len >> 1;
+         middle = first;
+         middle += half;
+
+         if (key_comp(key, key_extract(*middle))) {
+            len = half;
+         }
+         else{
+            first = ++middle;
+            len = len - half - 1;  
+         }
+      }
+      return first;
+   }
+
+   template 
+   std::pair
+      priv_equal_range(RanIt first, RanIt last, const key_type& key) const
+   {
+      const Compare &key_comp = this->m_data.get_comp();
+      KeyOfValue key_extract;
+      difference_type len = last - first, half;
+      RanIt middle, left, right;
+
+      while (len > 0) {
+         half = len >> 1;
+         middle = first;
+         middle += half;
+
+         if (key_comp(key_extract(*middle), key)){
+            first = middle;
+            ++first;
+            len = len - half - 1;
+         }
+         else if (key_comp(key, key_extract(*middle))){
+            len = half;
+         }
+         else {
+            left = this->priv_lower_bound(first, middle, key);
+            first += len;
+            right = this->priv_upper_bound(++middle, first, key);
+            return std::pair(left, right);
+         }
+      }
+      return std::pair(first, first);
+   }
+
+   template 
+   void priv_insert_equal(FwdIt first, FwdIt last, std::forward_iterator_tag)
+   {
+      size_type len = static_cast(std::distance(first, last));
+      this->reserve(this->size()+len);
+      this->priv_insert_equal(first, last, std::input_iterator_tag());
+   }
+
+   template 
+   void priv_insert_equal(InIt first, InIt last, std::input_iterator_tag)
+   {
+      for ( ; first != last; ++first)
+         this->insert_equal(*first);
+   }
+};
+
+template 
+inline bool 
+operator==(const flat_tree& x, 
+           const flat_tree& y)
+{
+  return x.size() == y.size() &&
+         std::equal(x.begin(), x.end(), y.begin());
+}
+
+template 
+inline bool 
+operator<(const flat_tree& x, 
+          const flat_tree& y)
+{
+  return std::lexicographical_compare(x.begin(), x.end(), 
+                                      y.begin(), y.end());
+}
+
+template 
+inline bool 
+operator!=(const flat_tree& x, 
+           const flat_tree& y) 
+   {  return !(x == y); }
+
+template 
+inline bool 
+operator>(const flat_tree& x, 
+          const flat_tree& y) 
+   {  return y < x;  }
+
+template 
+inline bool 
+operator<=(const flat_tree& x, 
+           const flat_tree& y) 
+   {  return !(y < x);  }
+
+template 
+inline bool 
+operator>=(const flat_tree& x, 
+           const flat_tree& y) 
+   {  return !(x < y);  }
+
+
+template 
+inline void 
+swap(flat_tree& x, 
+     flat_tree& y)
+   {  x.swap(y);  }
+
+}  //namespace container_detail {
+
+}  //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value && has_trivial_destructor::value;
+};
+*/
+}  //namespace boost {
+
+#include 
+
+#endif // BOOST_CONTAINER_FLAT_TREE_HPP
diff --git a/src/third_party/boost/boost/container/detail/function_detector.hpp b/src/third_party/boost/boost/container/detail/function_detector.hpp
new file mode 100644
index 00000000000..c37c766844f
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/function_detector.hpp
@@ -0,0 +1,88 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2009-2011.
+//
+// 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/container for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+//  This code was modified from the code posted by Alexandre Courpron in his
+//  article "Interface Detection" in The Code Project:
+//  http://www.codeproject.com/KB/architecture/Detector.aspx
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2007 Alexandre Courpron
+//
+// Permission to use, copy, modify, redistribute and sell this software, 
+// provided that this copyright notice appears on all copies of the software.
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
+#define BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
+
+#include 
+
+namespace boost {
+namespace container {
+namespace function_detector {
+
+    typedef char NotFoundType;
+    struct StaticFunctionType { NotFoundType x [2]; };
+    struct NonStaticFunctionType { NotFoundType x [3]; };
+
+    enum
+         { NotFound          = 0,
+           StaticFunction    = sizeof( StaticFunctionType )    - sizeof( NotFoundType ),
+           NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType )
+         };
+
+}  //namespace boost {
+}  //namespace container {
+}  //namespace function_detector {
+
+#define BOOST_CONTAINER_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \
+   namespace boost { \
+   namespace container { \
+   namespace function_detector { \
+   template < class T, \
+            class NonStaticType, \
+            class NonStaticConstType, \
+            class StaticType > \
+   class DetectMember_##InstantiationKey_##Identifier { \
+      template < NonStaticType > \
+      struct TestNonStaticNonConst ; \
+      \
+      template < NonStaticConstType > \
+      struct TestNonStaticConst ; \
+      \
+      template < StaticType > \
+      struct TestStatic ; \
+      \
+      template  \
+      static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \
+      \
+      template  \
+      static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \
+      \
+      template  \
+      static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \
+      \
+      template  \
+      static NotFoundType Test( ... ); \
+   public : \
+      static const int check = NotFound + (sizeof(Test(0, 0)) - sizeof(NotFoundType));\
+   };\
+}}} //namespace boost::container::function_detector { 
+
+#define BOOST_CONTAINER_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \
+    ::boost::container::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\
+                                         ReturnType (Class::*)Params,\
+                                         ReturnType (Class::*)Params const,\
+                                         ReturnType (*)Params \
+                                       >::check
+
+#include 
+
+#endif   //@ifndef BOOST_CONTAINER_DETAIL_FUNCTION_DETECTOR_HPP
diff --git a/src/third_party/boost/boost/container/detail/iterators.hpp b/src/third_party/boost/boost/container/detail/iterators.hpp
new file mode 100644
index 00000000000..899cbe43490
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/iterators.hpp
@@ -0,0 +1,548 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Gennaro Prota 2003 - 2004.
+//
+// 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
+#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+#include 
+#include 
+
+#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+#include 
+#include 
+#else
+#include 
+#endif
+
+#include 
+
+namespace boost {
+namespace container { 
+
+template 
+class constant_iterator
+  : public std::iterator
+      
+{
+   typedef  constant_iterator this_type;
+
+   public:
+   explicit constant_iterator(const T &ref, Difference range_size)
+      :  m_ptr(&ref), m_num(range_size){}
+
+   //Constructors
+   constant_iterator()
+      :  m_ptr(0), m_num(0){}
+
+   constant_iterator& operator++() 
+   { increment();   return *this;   }
+   
+   constant_iterator operator++(int)
+   {
+      constant_iterator result (*this);
+      increment();
+      return result;
+   }
+
+   constant_iterator& operator--() 
+   { decrement();   return *this;   }
+   
+   constant_iterator operator--(int)
+   {
+      constant_iterator result (*this);
+      decrement();
+      return result;
+   }
+
+   friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
+   { return !(i == i2); }
+
+   friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
+   { return i.less(i2); }
+
+   friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
+   { return !(i < i2); }
+
+   friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   constant_iterator& operator+=(Difference off)
+   {  this->advance(off); return *this;   }
+
+   constant_iterator operator+(Difference off) const
+   {
+      constant_iterator other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend constant_iterator operator+(Difference off, const constant_iterator& right)
+   {  return right + off; }
+
+   constant_iterator& operator-=(Difference off)
+   {  this->advance(-off); return *this;   }
+
+   constant_iterator operator-(Difference off) const
+   {  return *this + (-off);  }
+
+   const T& operator*() const
+   { return dereference(); }
+
+   const T& operator[] (Difference n) const
+   { return dereference(); }
+
+   const T* operator->() const
+   { return &(dereference()); }
+
+   private:
+   const T *   m_ptr;
+   Difference  m_num;
+
+   void increment()
+   { --m_num; }
+
+   void decrement()
+   { ++m_num; }
+
+   bool equal(const this_type &other) const
+   {  return m_num == other.m_num;   }
+
+   bool less(const this_type &other) const
+   {  return other.m_num < m_num;   }
+
+   const T & dereference() const
+   { return *m_ptr; }
+
+   void advance(Difference n)
+   {  m_num -= n; }
+
+   Difference distance_to(const this_type &other)const
+   {  return m_num - other.m_num;   }
+};
+
+template 
+class default_construct_iterator
+  : public std::iterator
+      
+{
+   typedef  default_construct_iterator this_type;
+
+   public:
+   explicit default_construct_iterator(Difference range_size)
+      :  m_num(range_size){}
+
+   //Constructors
+   default_construct_iterator()
+      :  m_num(0){}
+
+   default_construct_iterator& operator++() 
+   { increment();   return *this;   }
+   
+   default_construct_iterator operator++(int)
+   {
+      default_construct_iterator result (*this);
+      increment();
+      return result;
+   }
+
+   default_construct_iterator& operator--() 
+   { decrement();   return *this;   }
+   
+   default_construct_iterator operator--(int)
+   {
+      default_construct_iterator result (*this);
+      decrement();
+      return result;
+   }
+
+   friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2)
+   { return !(i == i2); }
+
+   friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2)
+   { return i.less(i2); }
+
+   friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2)
+   { return !(i < i2); }
+
+   friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   default_construct_iterator& operator+=(Difference off)
+   {  this->advance(off); return *this;   }
+
+   default_construct_iterator operator+(Difference off) const
+   {
+      default_construct_iterator other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right)
+   {  return right + off; }
+
+   default_construct_iterator& operator-=(Difference off)
+   {  this->advance(-off); return *this;   }
+
+   default_construct_iterator operator-(Difference off) const
+   {  return *this + (-off);  }
+
+   const T& operator*() const
+   { return dereference(); }
+
+   const T* operator->() const
+   { return &(dereference()); }
+
+   const T& operator[] (Difference n) const
+   { return dereference(); }
+
+   private:
+   Difference  m_num;
+
+   void increment()
+   { --m_num; }
+
+   void decrement()
+   { ++m_num; }
+
+   bool equal(const this_type &other) const
+   {  return m_num == other.m_num;   }
+
+   bool less(const this_type &other) const
+   {  return other.m_num < m_num;   }
+
+   const T & dereference() const
+   { 
+      static T dummy;
+      return dummy;
+   }
+
+   void advance(Difference n)
+   {  m_num -= n; }
+
+   Difference distance_to(const this_type &other)const
+   {  return m_num - other.m_num;   }
+};
+
+template 
+class repeat_iterator
+  : public std::iterator
+      
+{
+   typedef repeat_iterator this_type;
+   public:
+   explicit repeat_iterator(T &ref, Difference range_size)
+      :  m_ptr(&ref), m_num(range_size){}
+
+   //Constructors
+   repeat_iterator()
+      :  m_ptr(0), m_num(0){}
+
+   this_type& operator++() 
+   { increment();   return *this;   }
+   
+   this_type operator++(int)
+   {
+      this_type result (*this);
+      increment();
+      return result;
+   }
+
+   this_type& operator--() 
+   { increment();   return *this;   }
+   
+   this_type operator--(int)
+   {
+      this_type result (*this);
+      increment();
+      return result;
+   }
+
+   friend bool operator== (const this_type& i, const this_type& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const this_type& i, const this_type& i2)
+   { return !(i == i2); }
+
+   friend bool operator< (const this_type& i, const this_type& i2)
+   { return i.less(i2); }
+
+   friend bool operator> (const this_type& i, const this_type& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const this_type& i, const this_type& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const this_type& i, const this_type& i2)
+   { return !(i < i2); }
+
+   friend Difference operator- (const this_type& i, const this_type& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   this_type& operator+=(Difference off)
+   {  this->advance(off); return *this;   }
+
+   this_type operator+(Difference off) const
+   {
+      this_type other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend this_type operator+(Difference off, const this_type& right)
+   {  return right + off; }
+
+   this_type& operator-=(Difference off)
+   {  this->advance(-off); return *this;   }
+
+   this_type operator-(Difference off) const
+   {  return *this + (-off);  }
+
+   T& operator*() const
+   { return dereference(); }
+
+   T& operator[] (Difference n) const
+   { return dereference(); }
+
+   T *operator->() const
+   { return &(dereference()); }
+
+   private:
+   T *         m_ptr;
+   Difference  m_num;
+
+   void increment()
+   { --m_num; }
+
+   void decrement()
+   { ++m_num; }
+
+   bool equal(const this_type &other) const
+   {  return m_num == other.m_num;   }
+
+   bool less(const this_type &other) const
+   {  return other.m_num < m_num;   }
+
+   T & dereference() const
+   { return *m_ptr; }
+
+   void advance(Difference n)
+   {  m_num -= n; }
+
+   Difference distance_to(const this_type &other)const
+   {  return m_num - other.m_num;   }
+};
+
+template 
+class emplace_iterator
+  : public std::iterator
+      
+{
+   typedef emplace_iterator this_type;
+
+   public:
+   typedef Difference difference_type;
+   explicit emplace_iterator(EmplaceFunctor&e)
+      :  m_num(1), m_pe(&e){}
+
+   emplace_iterator()
+      :  m_num(0), m_pe(0){}
+
+   this_type& operator++() 
+   { increment();   return *this;   }
+   
+   this_type operator++(int)
+   {
+      this_type result (*this);
+      increment();
+      return result;
+   }
+
+   this_type& operator--() 
+   { decrement();   return *this;   }
+   
+   this_type operator--(int)
+   {
+      this_type result (*this);
+      decrement();
+      return result;
+   }
+
+   friend bool operator== (const this_type& i, const this_type& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const this_type& i, const this_type& i2)
+   { return !(i == i2); }
+
+   friend bool operator< (const this_type& i, const this_type& i2)
+   { return i.less(i2); }
+
+   friend bool operator> (const this_type& i, const this_type& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const this_type& i, const this_type& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const this_type& i, const this_type& i2)
+   { return !(i < i2); }
+
+   friend difference_type operator- (const this_type& i, const this_type& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   this_type& operator+=(difference_type off)
+   {  this->advance(off); return *this;   }
+
+   this_type operator+(difference_type off) const
+   {
+      this_type other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend this_type operator+(difference_type off, const this_type& right)
+   {  return right + off; }
+
+   this_type& operator-=(difference_type off)
+   {  this->advance(-off); return *this;   }
+
+   this_type operator-(difference_type off) const
+   {  return *this + (-off);  }
+
+   const T& operator*() const
+   { return dereference(); }
+
+   const T& operator[](difference_type) const
+   { return dereference(); }
+
+   const T* operator->() const
+   { return &(dereference()); }
+
+   template
+   void construct_in_place(A &a, T* ptr)
+   {  (*m_pe)(a, ptr);  }
+
+   private:
+   difference_type m_num;
+   EmplaceFunctor *            m_pe;
+
+   void increment()
+   { --m_num; }
+
+   void decrement()
+   { ++m_num; }
+
+   bool equal(const this_type &other) const
+   {  return m_num == other.m_num;   }
+
+   bool less(const this_type &other) const
+   {  return other.m_num < m_num;   }
+
+   const T & dereference() const
+   { 
+      static T dummy;
+      return dummy;
+   }
+
+   void advance(difference_type n)
+   {  m_num -= n; }
+
+   difference_type distance_to(const this_type &other)const
+   {  return difference_type(m_num - other.m_num);   }
+};
+
+#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+template
+struct emplace_functor
+{
+   typedef typename container_detail::build_number_seq::type index_tuple_t;
+
+   emplace_functor(Args&&... args)
+      : args_(args...)
+   {}
+
+   template
+   void operator()(A &a, T *ptr)
+   {  emplace_functor::inplace_impl(a, ptr, index_tuple_t());  }
+
+   template
+   void inplace_impl(A &a, T* ptr, const container_detail::index_tuple&)
+   {
+      allocator_traits::construct
+         (a, ptr, container_detail::stored_ref::forward
+          (container_detail::get(args_))...);
+   }
+
+   container_detail::tuple args_;
+};
+
+#else
+
+#define BOOST_PP_LOCAL_MACRO(n)                                                        \
+   BOOST_PP_EXPR_IF(n, template <)                                                     \
+      BOOST_PP_ENUM_PARAMS(n, class P)                                                 \
+         BOOST_PP_EXPR_IF(n, >)                                                        \
+   struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                          \
+   {                                                                                   \
+      BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                              \
+         ( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) )                       \
+      BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){}    \
+                                                                                       \
+      template                                                       \
+      void operator()(A &a, T *ptr)                                                    \
+      {                                                                                \
+         allocator_traits::construct                                                \
+            (a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) );\
+      }                                                                                \
+      BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _)                         \
+   };                                                                                  \
+   //!
+#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+#include BOOST_PP_LOCAL_ITERATE()
+
+#endif
+
+}  //namespace container { 
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
+
diff --git a/src/third_party/boost/boost/container/detail/math_functions.hpp b/src/third_party/boost/boost/container/detail/math_functions.hpp
new file mode 100644
index 00000000000..4613573d48b
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/math_functions.hpp
@@ -0,0 +1,113 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Stephen Cleary 2000.
+// (C) Copyright Ion Gaztanaga 2007-2011.
+//
+// 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/container for documentation.
+//
+// This file is a slightly modified file from Boost.Pool
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
+#define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
+
+#include "config_begin.hpp"
+#include 
+#include 
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+// Greatest common divisor and least common multiple
+
+//
+// gcd is an algorithm that calculates the greatest common divisor of two
+//  integers, using Euclid's algorithm.
+//
+// Pre: A > 0 && B > 0
+// Recommended: A > B
+template 
+inline Integer gcd(Integer A, Integer B)
+{
+   do
+   {
+      const Integer tmp(B);
+      B = A % B;
+      A = tmp;
+   } while (B != 0);
+
+   return A;
+}
+
+//
+// lcm is an algorithm that calculates the least common multiple of two
+//  integers.
+//
+// Pre: A > 0 && B > 0
+// Recommended: A > B
+template 
+inline Integer lcm(const Integer & A, const Integer & B)
+{
+   Integer ret = A;
+   ret /= gcd(A, B);
+   ret *= B;
+   return ret;
+}
+
+template 
+inline Integer log2_ceil(const Integer & A)
+{
+   Integer i = 0;
+   Integer power_of_2 = 1;
+
+   while(power_of_2 < A){
+      power_of_2 <<= 1;
+      ++i;
+   }
+   return i;
+}
+
+template 
+inline Integer upper_power_of_2(const Integer & A)
+{
+   Integer power_of_2 = 1;
+
+   while(power_of_2 < A){
+      power_of_2 <<= 1;
+   }
+   return power_of_2;
+}
+
+//This function uses binary search to discover the
+//highest set bit of the integer
+inline std::size_t floor_log2 (std::size_t x)
+{
+   const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
+   const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
+   BOOST_STATIC_ASSERT(((Size_t_Bits_Power_2)== true));
+
+   std::size_t n = x;
+   std::size_t log2 = 0;
+   
+   for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
+      std::size_t tmp = n >> shift;
+      if (tmp)
+         log2 += shift, n = tmp;
+   }
+
+   return log2;
+}
+
+} // namespace container_detail
+} // namespace container
+} // namespace boost
+
+#include 
+
+#endif
diff --git a/src/third_party/boost/boost/container/detail/mpl.hpp b/src/third_party/boost/boost/container/detail/mpl.hpp
new file mode 100644
index 00000000000..c2d0ce41bbd
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/mpl.hpp
@@ -0,0 +1,160 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
+#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+
+namespace boost {
+namespace container { 
+namespace container_detail {
+
+template 
+struct integral_constant
+{
+   static const T value = val;
+   typedef integral_constant type;
+};
+
+template< bool C_ >
+struct bool_ : integral_constant
+{
+   static const bool value = C_;
+   operator bool() const { return bool_::value; }
+};
+
+typedef bool_        true_;
+typedef bool_       false_;
+
+typedef true_  true_type;
+typedef false_ false_type;
+
+typedef char yes_type;
+struct no_type
+{
+   char padding[8];
+};
+
+template 
+struct enable_if_c {
+  typedef T type;
+};
+
+template 
+struct enable_if_c {};
+
+template 
+struct enable_if : public enable_if_c {};
+
+template 
+struct disable_if : public enable_if_c {};
+
+template 
+struct disable_if_c : public enable_if_c {};
+
+template 
+class is_convertible
+{
+   typedef char true_t;
+   class false_t { char dummy[2]; };
+   static true_t dispatch(U);
+   static false_t dispatch(...);
+   static T trigger();
+   public:
+   enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
+};
+
+template<
+      bool C
+    , typename T1
+    , typename T2
+    >
+struct if_c
+{
+    typedef T1 type;
+};
+
+template<
+      typename T1
+    , typename T2
+    >
+struct if_c
+{
+    typedef T2 type;
+};
+
+template<
+      typename T1
+    , typename T2
+    , typename T3
+    >
+struct if_
+{
+   typedef typename if_c<0 != T1::value, T2, T3>::type type;
+};
+
+
+template 
+struct select1st 
+//   : public std::unary_function 
+{
+   template
+   const typename Pair::first_type& operator()(const OtherPair& x) const 
+   {  return x.first;   }
+
+   const typename Pair::first_type& operator()(const typename Pair::first_type& x) const 
+   {  return x;   }
+};
+
+// identity is an extension: it is not part of the standard.
+template 
+struct identity 
+//   : public std::unary_function 
+{
+   typedef T type;
+   const T& operator()(const T& x) const 
+   { return x; }
+};
+
+template
+struct ls_zeros
+{
+   static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value);
+};
+
+template<>
+struct ls_zeros<0>
+{
+   static const std::size_t value = 0;
+};
+
+template<>
+struct ls_zeros<1>
+{
+   static const std::size_t value = 0;
+};
+
+template  struct unvoid { typedef T type; };
+template <> struct unvoid { struct type { }; };
+template <> struct unvoid { struct type { }; };
+
+}  //namespace container_detail { 
+}  //namespace container { 
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
+
diff --git a/src/third_party/boost/boost/container/detail/multiallocation_chain.hpp b/src/third_party/boost/boost/container/detail/multiallocation_chain.hpp
new file mode 100644
index 00000000000..a67fd770bd2
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/multiallocation_chain.hpp
@@ -0,0 +1,254 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
+#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
+
+#include "config_begin.hpp"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template
+class basic_multiallocation_chain
+{
+   private:
+   typedef bi::slist_base_hook
+                        ,bi::link_mode
+                        > node;
+
+   typedef typename boost::intrusive::pointer_traits
+      ::template rebind_pointer::type    char_ptr;
+   typedef typename boost::intrusive::
+      pointer_traits::difference_type             difference_type;
+
+   typedef bi::slist< node
+                    , bi::linear
+                    , bi::cache_last
+                    , bi::size_type::type>
+                    > slist_impl_t;
+   slist_impl_t slist_impl_;
+
+   static node & to_node(VoidPointer p)
+   {  return *static_cast(static_cast(container_detail::to_raw_pointer(p))); }
+
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain)
+
+   public:
+
+
+   typedef VoidPointer  void_pointer;
+   typedef typename slist_impl_t::iterator iterator;
+   typedef typename slist_impl_t::size_type size_type;
+
+   basic_multiallocation_chain()
+      :  slist_impl_()
+   {}
+
+   basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other)
+      :  slist_impl_()
+   {  slist_impl_.swap(other.slist_impl_); }
+
+   basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other)
+   {
+      basic_multiallocation_chain tmp(boost::move(other));
+      this->swap(tmp);
+      return *this;
+   }
+
+   bool empty() const
+   {  return slist_impl_.empty(); }
+
+   size_type size() const
+   {  return slist_impl_.size();  }
+
+   iterator before_begin()
+   {  return slist_impl_.before_begin(); }
+
+   iterator begin()
+   {  return slist_impl_.begin(); }
+
+   iterator end()
+   {  return slist_impl_.end(); }
+
+   iterator last()
+   {  return slist_impl_.last(); }
+
+   void clear()
+   {  slist_impl_.clear(); }
+
+   iterator insert_after(iterator it, void_pointer m)
+   {  return slist_impl_.insert_after(it, to_node(m));   }
+
+   void push_front(void_pointer m)
+   {  return slist_impl_.push_front(to_node(m));   }
+
+   void push_back(void_pointer m)
+   {  return slist_impl_.push_back(to_node(m));   }
+
+   void pop_front()
+   {  return slist_impl_.pop_front();   }
+
+   void *front()
+   {  return &*slist_impl_.begin();   }
+
+   void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end)
+   {  slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end);   }
+
+   void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_begin, iterator before_end, size_type n)
+   {  slist_impl_.splice_after(after_this, x.slist_impl_, before_begin, before_end, n);   }
+
+   void splice_after(iterator after_this, basic_multiallocation_chain &x)
+   {  slist_impl_.splice_after(after_this, x.slist_impl_);   }
+
+   void incorporate_after(iterator after_this, void_pointer begin , iterator before_end)
+   {  slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end));   }
+
+   void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n)
+   {  slist_impl_.incorporate_after(after_this, &to_node(begin), &to_node(before_end), n);   }
+
+   void swap(basic_multiallocation_chain &x)
+   {  slist_impl_.swap(x.slist_impl_);   }
+
+   static iterator iterator_to(void_pointer p)
+   {  return slist_impl_t::s_iterator_to(to_node(p));   }
+
+   std::pair extract_data()
+   {
+      std::pair ret
+         (slist_impl_.begin().operator->()
+         ,slist_impl_.last().operator->());
+      slist_impl_.clear();
+      return ret;
+   }
+};
+
+template
+struct cast_functor
+{
+   typedef typename container_detail::add_reference::type result_type;
+   template
+   result_type operator()(U &ptr) const
+   {  return *static_cast(static_cast(&ptr));  }
+};
+
+template
+class transform_multiallocation_chain
+{
+   private:
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain)
+
+   MultiallocationChain   holder_;
+   typedef typename MultiallocationChain::void_pointer   void_pointer;
+   typedef typename boost::intrusive::pointer_traits
+      ::template rebind_pointer::type   pointer;
+
+   static pointer cast(void_pointer p)
+   {
+      return pointer(static_cast(container_detail::to_raw_pointer(p)));
+   }
+
+   public:
+   typedef transform_iterator
+      < typename MultiallocationChain::iterator
+      , container_detail::cast_functor  >                 iterator;
+   typedef typename MultiallocationChain::size_type           size_type;
+
+   transform_multiallocation_chain()
+      : holder_()
+   {}
+
+   transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other)
+      : holder_()
+   {  this->swap(other); }
+
+   transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other)
+      : holder_(boost::move(other))
+   {}
+
+   transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other)
+   {
+      transform_multiallocation_chain tmp(boost::move(other));
+      this->swap(tmp);
+      return *this;
+   }
+
+   void push_front(pointer mem)
+   {  holder_.push_front(mem);  }
+
+   void swap(transform_multiallocation_chain &other_chain)
+   {  holder_.swap(other_chain.holder_); }
+
+   void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_begin, iterator before_end, size_type n)
+   {  holder_.splice_after(after_this.base(), x.holder_, before_begin.base(), before_end.base(), n);  }
+
+   void incorporate_after(iterator after_this, void_pointer begin, void_pointer before_end, size_type n)
+   {  holder_.incorporate_after(after_this.base(), begin, before_end, n);  }
+
+   void pop_front()
+   {  holder_.pop_front();  }
+
+   pointer front()
+   {  return cast(holder_.front());   }
+
+   bool empty() const
+   {  return holder_.empty(); }
+
+   iterator before_begin()
+   {  return iterator(holder_.before_begin());   }
+
+   iterator begin()
+   {  return iterator(holder_.begin());   }
+
+   iterator end()
+   {  return iterator(holder_.end());   }
+
+   iterator last()
+   {  return iterator(holder_.last());   }
+
+   size_type size() const
+   {  return holder_.size();  }
+
+   void clear()
+   {  holder_.clear(); }
+
+   iterator insert_after(iterator it, pointer m)
+   {  return iterator(holder_.insert_after(it.base(), m)); }
+
+   static iterator iterator_to(pointer p)
+   {  return iterator(MultiallocationChain::iterator_to(p));  }
+
+   std::pair extract_data()
+   {  return holder_.extract_data();  }
+
+   MultiallocationChain extract_multiallocation_chain()
+   {
+      return MultiallocationChain(boost::move(holder_));
+   }
+};
+
+}}}
+
+// namespace container_detail {
+// namespace container {
+// namespace boost {
+
+#include 
+
+#endif   //BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
diff --git a/src/third_party/boost/boost/container/detail/node_alloc_holder.hpp b/src/third_party/boost/boost/container/detail/node_alloc_holder.hpp
new file mode 100644
index 00000000000..9b0a0a524b0
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/node_alloc_holder.hpp
@@ -0,0 +1,488 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
+#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
+#include 
+#endif
+
+#include 
+
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+//!A deleter for scoped_ptr that deallocates the memory
+//!allocated for an object using a STL allocator.
+template 
+struct scoped_deallocator
+{
+   typedef allocator_traits allocator_traits_type;
+   typedef typename allocator_traits_type::pointer pointer;
+   typedef container_detail::integral_constant::value>                   alloc_version;
+   typedef container_detail::integral_constant     allocator_v1;
+   typedef container_detail::integral_constant     allocator_v2;
+
+   private:
+   void priv_deallocate(allocator_v1)
+   {  m_alloc.deallocate(m_ptr, 1); }
+
+   void priv_deallocate(allocator_v2)
+   {  m_alloc.deallocate_one(m_ptr); }
+
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator)
+
+   public:
+
+   pointer     m_ptr;
+   A&  m_alloc;
+
+   scoped_deallocator(pointer p, A& a)
+      : m_ptr(p), m_alloc(a)
+   {}
+
+   ~scoped_deallocator()
+   {  if (m_ptr)priv_deallocate(alloc_version());  }
+
+   scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o)
+      :  m_ptr(o.m_ptr), m_alloc(o.m_alloc)
+   {  o.release();  }
+
+   pointer get() const
+   {  return m_ptr;  }
+
+   void release()
+   {  m_ptr = 0; }
+};
+
+template 
+class allocator_destroyer_and_chain_builder
+{
+   typedef allocator_traits allocator_traits_type;
+   typedef typename allocator_traits_type::value_type value_type;
+   typedef typename A::multiallocation_chain    multiallocation_chain;
+
+   A & a_;
+   multiallocation_chain &c_;
+
+   public:
+   allocator_destroyer_and_chain_builder(A &a, multiallocation_chain &c)
+      :  a_(a), c_(c)
+   {}
+
+   void operator()(const typename A::pointer &p)
+   {
+      allocator_traits::destroy(a_, container_detail::to_raw_pointer(p));
+      c_.push_front(p);
+   }
+};
+
+template 
+class allocator_multialloc_chain_node_deallocator
+{
+   typedef allocator_traits allocator_traits_type;
+   typedef typename allocator_traits_type::value_type value_type;
+   typedef typename A::multiallocation_chain    multiallocation_chain;
+   typedef allocator_destroyer_and_chain_builder chain_builder;
+
+   A & a_;
+   multiallocation_chain c_;
+
+   public:
+   allocator_multialloc_chain_node_deallocator(A &a)
+      :  a_(a), c_()
+   {}
+
+   chain_builder get_chain_builder()
+   {  return chain_builder(a_, c_);  }
+
+   ~allocator_multialloc_chain_node_deallocator()
+   {
+      if(!c_.empty())
+         a_.deallocate_individual(boost::move(c_));
+   }
+};
+
+template
+struct node_compare
+   :  private ValueCompare
+{
+   typedef typename ValueCompare::key_type     key_type;
+   typedef typename ValueCompare::value_type   value_type;
+   typedef typename ValueCompare::key_of_value key_of_value;
+
+   node_compare(const ValueCompare &pred)
+      :  ValueCompare(pred)
+   {}
+
+   ValueCompare &value_comp()
+   {  return static_cast(*this);  }
+
+   ValueCompare &value_comp() const
+   {  return static_cast(*this);  }
+
+   bool operator()(const Node &a, const Node &b) const
+   {  return ValueCompare::operator()(a.get_data(), b.get_data());  }
+};
+
+template
+struct node_alloc_holder
+{
+   typedef allocator_traits                                    allocator_traits_type;
+   typedef node_alloc_holder                            self_t;
+   typedef typename allocator_traits_type::value_type             value_type;
+   typedef typename ICont::value_type                             Node;
+   typedef typename allocator_traits_type::template
+      portable_rebind_alloc::type                           NodeAlloc;
+   typedef allocator_traits                            node_allocator_traits_type;
+   typedef A                                                      ValAlloc;
+   typedef typename node_allocator_traits_type::pointer           NodePtr;
+   typedef container_detail::scoped_deallocator        Deallocator;
+   typedef typename node_allocator_traits_type::size_type         size_type;
+   typedef typename node_allocator_traits_type::difference_type   difference_type;
+   typedef container_detail::integral_constant       allocator_v1;
+   typedef container_detail::integral_constant       allocator_v2;
+   typedef container_detail::integral_constant::value>                   alloc_version;
+   typedef typename ICont::iterator                   icont_iterator;
+   typedef typename ICont::const_iterator             icont_citerator;
+   typedef allocator_destroyer             Destroyer;
+   typedef allocator_traits                NodeAllocTraits;
+
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder)
+
+   public:
+
+   //Constructors for sequence containers
+   node_alloc_holder() 
+      : members_()
+   {}
+
+   explicit node_alloc_holder(const ValAlloc &a) 
+      : members_(a)
+   {}
+
+   explicit node_alloc_holder(const node_alloc_holder &x)
+      : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()))
+   {}
+
+   explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x)
+      : members_(boost::move(x.node_alloc()))
+   {  this->icont().swap(x.icont());  }
+
+   //Constructors for associative containers
+   explicit node_alloc_holder(const ValAlloc &a, const Pred &c) 
+      : members_(a, c)
+   {}
+
+   explicit node_alloc_holder(const node_alloc_holder &x, const Pred &c)
+      : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
+   {}
+
+   explicit node_alloc_holder(const Pred &c)
+      : members_(c)
+   {}
+
+   //helpers for move assignments
+   explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const Pred &c)
+      : members_(boost::move(x.node_alloc()), c)
+   {  this->icont().swap(x.icont());  }
+
+   void copy_assign_alloc(const node_alloc_holder &x)
+   {  
+      container_detail::bool_ flag;
+      container_detail::assign_alloc( static_cast(this->members_)
+                                    , static_cast(x.members_), flag);
+   }
+
+   void move_assign_alloc( node_alloc_holder &x)
+   {
+      container_detail::bool_ flag;
+      container_detail::move_alloc( static_cast(this->members_)
+                                  , static_cast(x.members_), flag);
+   }
+
+   ~node_alloc_holder()
+   {  this->clear(alloc_version()); }
+
+   size_type max_size() const
+   {  return allocator_traits_type::max_size(this->node_alloc());  }
+
+   NodePtr allocate_one()
+   {  return this->allocate_one(alloc_version());   }
+
+   NodePtr allocate_one(allocator_v1)
+   {  return this->node_alloc().allocate(1);   }
+
+   NodePtr allocate_one(allocator_v2)
+   {  return this->node_alloc().allocate_one();   }
+
+   void deallocate_one(const NodePtr &p)
+   {  return this->deallocate_one(p, alloc_version());   }
+
+   void deallocate_one(const NodePtr &p, allocator_v1)
+   {  this->node_alloc().deallocate(p, 1);   }
+
+   void deallocate_one(const NodePtr &p, allocator_v2)
+   {  this->node_alloc().deallocate_one(p);   }
+/*
+   template
+   static void construct(A &a, const NodePtr &ptr,
+      BOOST_RV_REF_2_TEMPL_ARGS(std::pair, Convertible1, Convertible2) value)
+   {
+      typedef typename Node::hook_type                hook_type;
+      typedef typename Node::value_type::first_type   first_type;
+      typedef typename Node::value_type::second_type  second_type;
+      Node *nodeptr = container_detail::to_raw_pointer(ptr);
+
+      //Hook constructor does not throw
+      allocator_traits::construct(a, static_cast(nodeptr));
+
+      //Now construct pair members_holder
+      value_type *valueptr = &nodeptr->get_data();
+      allocator_traits::construct(a, &valueptr->first, boost::move(value.first));
+      BOOST_TRY{
+         allocator_traits::construct(a, &valueptr->second, boost::move(value.second));
+      }
+      BOOST_CATCH(...){
+         allocator_traits::destroy(a, &valueptr->first);
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+*/
+   #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+/*
+   template
+   static void construct(A &a, const NodePtr &ptr, Args &&...args)
+   {  
+   }
+*/
+   template
+   NodePtr create_node(Args &&...args)
+   {
+      NodePtr p = this->allocate_one();
+      Deallocator node_deallocator(p, this->node_alloc());
+      allocator_traits::construct
+         (this->node_alloc(), container_detail::to_raw_pointer(p), boost::forward(args)...);
+      node_deallocator.release();
+      return (p);
+   }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                        \
+                                                                                          \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
+   NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                \
+   {                                                                                      \
+      NodePtr p = this->allocate_one();                                                   \
+      Deallocator node_deallocator(p, this->node_alloc());                                \
+      allocator_traits::construct                                              \
+         (this->node_alloc(), container_detail::to_raw_pointer(p)                         \
+            BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));              \
+      node_deallocator.release();                                                         \
+      return (p);                                                                         \
+   }                                                                                      \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   template
+   NodePtr create_node_from_it(const It &it)
+   {
+      NodePtr p = this->allocate_one();
+      Deallocator node_deallocator(p, this->node_alloc());
+      ::boost::container::construct_in_place(this->node_alloc(), container_detail::to_raw_pointer(p), it);
+      node_deallocator.release();
+      return (p);
+   }
+
+   void destroy_node(const NodePtr &nodep)
+   {
+      allocator_traits::destroy(this->node_alloc(), container_detail::to_raw_pointer(nodep));
+      this->deallocate_one(nodep);
+   }
+
+   void swap(node_alloc_holder &x)
+   {
+      this->icont().swap(x.icont());
+      container_detail::bool_ flag;
+      container_detail::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
+   }
+
+   template
+   FwdIterator allocate_many_and_construct
+      (FwdIterator beg, difference_type n, Inserter inserter)
+   {
+      if(n){
+         typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
+
+         //Try to allocate memory in a single block
+         multiallocation_chain mem(this->node_alloc().allocate_individual(n));
+         int constructed = 0;
+         Node *p = 0;
+         BOOST_TRY{
+               for(difference_type i = 0; i < n; ++i, ++beg, --constructed){
+               p = container_detail::to_raw_pointer(mem.front());
+               mem.pop_front();
+               //This can throw
+               constructed = 0;
+               boost::container::construct_in_place(this->node_alloc(), p, beg);
+               ++constructed;
+               //This can throw in some containers (predicate might throw)
+               inserter(*p);
+            }
+         }
+         BOOST_CATCH(...){
+            if(constructed){
+               allocator_traits::destroy(this->node_alloc(), container_detail::to_raw_pointer(p));
+            }
+            this->node_alloc().deallocate_individual(boost::move(mem));
+            BOOST_RETHROW
+         }
+         BOOST_CATCH_END
+      }
+      return beg;
+   }
+
+   void clear(allocator_v1)
+   {  this->icont().clear_and_dispose(Destroyer(this->node_alloc()));   }
+
+   void clear(allocator_v2)
+   {
+      typename NodeAlloc::multiallocation_chain chain;
+      allocator_destroyer_and_chain_builder builder(this->node_alloc(), chain);
+      this->icont().clear_and_dispose(builder);
+      //BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled::value == true));
+      if(!chain.empty())
+         this->node_alloc().deallocate_individual(boost::move(chain));
+   }
+
+   icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v1)
+   {  return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
+
+   icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v2)
+   {
+      allocator_multialloc_chain_node_deallocator chain_holder(this->node_alloc());
+      return this->icont().erase_and_dispose(first, last, chain_holder.get_chain_builder());
+   }
+
+   template
+   size_type erase_key(const Key& k, const Comparator &comp, allocator_v1)
+   {  return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
+
+   template
+   size_type erase_key(const Key& k, const Comparator &comp, allocator_v2)
+   {
+      allocator_multialloc_chain_node_deallocator chain_holder(this->node_alloc());
+      return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
+   }
+
+   protected:
+   struct cloner
+   {
+      cloner(node_alloc_holder &holder)
+         :  m_holder(holder)
+      {}
+
+      NodePtr operator()(const Node &other) const
+      {  return m_holder.create_node(other.get_data());  }
+
+      node_alloc_holder &m_holder;
+   };
+
+   struct members_holder
+      :  public NodeAlloc
+   {
+      private:
+      members_holder(const members_holder&);
+      members_holder & operator=(const members_holder&);
+
+      public:
+      members_holder()
+         : NodeAlloc(), m_icont()
+      {}
+
+      template
+      explicit members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc)
+         :  NodeAlloc(boost::forward(c2alloc))
+         , m_icont()
+      {}
+
+      template
+      members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const Pred &c)
+         :  NodeAlloc(boost::forward(c2alloc))
+         , m_icont(typename ICont::value_compare(c))
+      {}
+
+      explicit members_holder(const Pred &c)
+         : NodeAlloc()
+         , m_icont(typename ICont::value_compare(c))
+      {}
+
+      //The intrusive container
+      ICont m_icont;
+   };
+
+   ICont &non_const_icont() const
+   {  return const_cast(this->members_.m_icont);   }
+
+   ICont &icont()
+   {  return this->members_.m_icont;   }
+
+   const ICont &icont() const
+   {  return this->members_.m_icont;   }
+
+   NodeAlloc &node_alloc()
+   {  return static_cast(this->members_);   }
+
+   const NodeAlloc &node_alloc() const
+   {  return static_cast(this->members_);   }
+
+   members_holder members_;
+};
+
+}  //namespace container_detail {
+}  //namespace container {
+}  //namespace boost {
+
+#include 
+
+#endif // BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
diff --git a/src/third_party/boost/boost/container/detail/node_pool_impl.hpp b/src/third_party/boost/boost/container/detail/node_pool_impl.hpp
new file mode 100644
index 00000000000..9ee9e311c01
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/node_pool_impl.hpp
@@ -0,0 +1,367 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
+#define BOOST_CONTAINER_DETAIL_NODE_POOL_IMPL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include    //std::unary_function
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template
+class private_node_pool_impl
+{
+   //Non-copyable
+   private_node_pool_impl();
+   private_node_pool_impl(const private_node_pool_impl &);
+   private_node_pool_impl &operator=(const private_node_pool_impl &);
+
+   //A node object will hold node_t when it's not allocated
+   public:
+   typedef typename SegmentManagerBase::void_pointer              void_pointer;
+   typedef typename node_slist::slist_hook_t        slist_hook_t;
+   typedef typename node_slist::node_t              node_t;
+   typedef typename node_slist::node_slist_t        free_nodes_t;
+   typedef typename SegmentManagerBase::multiallocation_chain     multiallocation_chain;
+   typedef typename SegmentManagerBase::size_type                 size_type;
+
+   private:
+   typedef typename bi::make_slist
+      < node_t, bi::base_hook
+      , bi::linear
+      , bi::constant_time_size >::type      blockslist_t;
+   public:
+
+   //!Segment manager typedef
+   typedef SegmentManagerBase segment_manager_base_type;
+
+   //!Constructor from a segment manager. Never throws
+   private_node_pool_impl(segment_manager_base_type *segment_mngr_base, size_type node_size, size_type nodes_per_block)
+   :  m_nodes_per_block(nodes_per_block)
+   ,  m_real_node_size(lcm(node_size, size_type(alignment_of::value)))
+      //General purpose allocator
+   ,  mp_segment_mngr_base(segment_mngr_base)
+   ,  m_blocklist()
+   ,  m_freelist()
+      //Debug node count
+   ,  m_allocated(0)
+   {}
+
+   //!Destructor. Deallocates all allocated blocks. Never throws
+   ~private_node_pool_impl()
+   {  this->purge_blocks();  }
+
+   size_type get_real_num_node() const
+   {  return m_nodes_per_block; }
+
+   //!Returns the segment manager. Never throws
+   segment_manager_base_type* get_segment_manager_base()const
+   {  return container_detail::to_raw_pointer(mp_segment_mngr_base);  }
+
+   void *allocate_node()
+   {  return priv_alloc_node();  }
+   
+   //!Deallocates an array pointed by ptr. Never throws
+   void deallocate_node(void *ptr)
+   {  priv_dealloc_node(ptr); }
+
+   //!Allocates a singly linked list of n nodes ending in null pointer. 
+   multiallocation_chain allocate_nodes(const size_type n)
+   {
+      //Preallocate all needed blocks to fulfill the request
+      size_type cur_nodes = m_freelist.size();
+      if(cur_nodes < n){
+         priv_alloc_block(((n - cur_nodes) - 1)/m_nodes_per_block + 1);
+      }
+
+      //We just iterate the needed nodes to get the last we'll erase
+      typedef typename free_nodes_t::iterator free_iterator;
+      free_iterator before_last_new_it = m_freelist.before_begin();
+      for(size_type j = 0; j != n; ++j){
+         ++before_last_new_it;
+      }
+
+      //Cache the first node of the allocated range before erasing
+      free_iterator first_node(m_freelist.begin());
+      free_iterator last_node (before_last_new_it);
+
+      //Erase the range. Since we already have the distance, this is O(1)
+      m_freelist.erase_after( m_freelist.before_begin()
+                            , ++free_iterator(before_last_new_it)
+                            , n);
+
+      //Now take the last erased node and just splice it in the end
+      //of the intrusive list that will be traversed by the multialloc iterator.
+      multiallocation_chain chain;
+      chain.incorporate_after(chain.before_begin(), &*first_node, &*last_node, n);
+      m_allocated += n;
+      return boost::move(chain);
+   }
+
+   void deallocate_nodes(multiallocation_chain chain)
+   {
+      typedef typename multiallocation_chain::iterator iterator;
+      iterator it(chain.begin()), itend(chain.end());
+      while(it != itend){
+         void *pElem = &*it;
+         ++it;
+         priv_dealloc_node(pElem);
+      }
+   }
+
+   //!Deallocates all the free blocks of memory. Never throws
+   void deallocate_free_blocks()
+   {
+      typedef typename free_nodes_t::iterator nodelist_iterator;
+      typename blockslist_t::iterator bit(m_blocklist.before_begin()),
+                                      it(m_blocklist.begin()),
+                                      itend(m_blocklist.end());
+      free_nodes_t backup_list;
+      nodelist_iterator backup_list_last = backup_list.before_begin();
+
+      //Execute the algorithm and get an iterator to the last value
+      size_type blocksize = get_rounded_size
+         (m_real_node_size*m_nodes_per_block, (size_type) alignment_of::value);
+
+      while(it != itend){
+         //Collect all the nodes from the block pointed by it
+         //and push them in the list
+         free_nodes_t free_nodes;
+         nodelist_iterator last_it = free_nodes.before_begin();
+         const void *addr = get_block_from_hook(&*it, blocksize);
+
+         m_freelist.remove_and_dispose_if
+            (is_between(addr, blocksize), push_in_list(free_nodes, last_it));
+
+         //If the number of nodes is equal to m_nodes_per_block
+         //this means that the block can be deallocated
+         if(free_nodes.size() == m_nodes_per_block){
+            //Unlink the nodes
+            free_nodes.clear();
+            it = m_blocklist.erase_after(bit);
+            mp_segment_mngr_base->deallocate((void*)addr);
+         }
+         //Otherwise, insert them in the backup list, since the
+         //next "remove_if" does not need to check them again.
+         else{
+            //Assign the iterator to the last value if necessary
+            if(backup_list.empty() && !m_freelist.empty()){
+               backup_list_last = last_it;
+            }
+            //Transfer nodes. This is constant time.
+            backup_list.splice_after
+               ( backup_list.before_begin()
+               , free_nodes
+               , free_nodes.before_begin()
+               , last_it
+               , free_nodes.size());
+            bit = it;
+            ++it;
+         }
+      }
+      //We should have removed all the nodes from the free list
+      BOOST_ASSERT(m_freelist.empty());
+
+      //Now pass all the node to the free list again
+      m_freelist.splice_after
+         ( m_freelist.before_begin()
+         , backup_list
+         , backup_list.before_begin()
+         , backup_list_last
+         , backup_list.size());
+   }
+
+   size_type num_free_nodes()
+   {  return m_freelist.size();  }
+
+   //!Deallocates all used memory. Precondition: all nodes allocated from this pool should
+   //!already be deallocated. Otherwise, undefined behaviour. Never throws
+   void purge_blocks()
+   {
+      //check for memory leaks
+      BOOST_ASSERT(m_allocated==0);
+      size_type blocksize = get_rounded_size
+         (m_real_node_size*m_nodes_per_block, (size_type)alignment_of::value);
+      typename blockslist_t::iterator
+         it(m_blocklist.begin()), itend(m_blocklist.end()), aux;
+
+      //We iterate though the NodeBlock list to free the memory
+      while(!m_blocklist.empty()){
+         void *addr = get_block_from_hook(&m_blocklist.front(), blocksize);
+         m_blocklist.pop_front();
+         mp_segment_mngr_base->deallocate((void*)addr);
+      }
+      //Just clear free node list
+      m_freelist.clear();
+   }
+
+   void swap(private_node_pool_impl &other)
+   {
+      BOOST_ASSERT(m_nodes_per_block == other.m_nodes_per_block);
+      BOOST_ASSERT(m_real_node_size == other.m_real_node_size);
+      std::swap(mp_segment_mngr_base, other.mp_segment_mngr_base);
+      m_blocklist.swap(other.m_blocklist);
+      m_freelist.swap(other.m_freelist);
+      std::swap(m_allocated, other.m_allocated);
+   }
+
+   private:
+
+   struct push_in_list
+   {
+      push_in_list(free_nodes_t &l, typename free_nodes_t::iterator &it)
+         :  slist_(l), last_it_(it)
+      {}
+      
+      void operator()(typename free_nodes_t::pointer p) const
+      {
+         slist_.push_front(*p);
+         if(slist_.size() == 1){ //Cache last element
+            ++last_it_ = slist_.begin();
+         }
+      }
+
+      private:
+      free_nodes_t &slist_;
+      typename free_nodes_t::iterator &last_it_;
+   };
+
+   struct is_between
+      :  std::unary_function
+   {
+      is_between(const void *addr, std::size_t size)
+         :  beg_(static_cast(addr)), end_(beg_+size)
+      {}
+      
+      bool operator()(typename free_nodes_t::const_reference v) const
+      {
+         return (beg_ <= reinterpret_cast(&v) && 
+                 end_ >  reinterpret_cast(&v));
+      }
+      private:
+      const char *      beg_;
+      const char *      end_;
+   };
+
+   //!Allocates one node, using single segregated storage algorithm.
+   //!Never throws
+   node_t *priv_alloc_node()
+   {
+      //If there are no free nodes we allocate a new block
+      if (m_freelist.empty())
+         priv_alloc_block();
+      //We take the first free node
+      node_t *n = (node_t*)&m_freelist.front();
+      m_freelist.pop_front();
+      ++m_allocated;
+      return n;
+   }
+
+   //!Deallocates one node, using single segregated storage algorithm.
+   //!Never throws
+   void priv_dealloc_node(void *pElem)
+   {
+      //We put the node at the beginning of the free node list
+      node_t * to_deallocate = static_cast(pElem);
+      m_freelist.push_front(*to_deallocate);
+      BOOST_ASSERT(m_allocated>0);
+      --m_allocated;
+   }
+
+   //!Allocates several blocks of nodes. Can throw
+   void priv_alloc_block(size_type num_blocks = 1)
+   {
+      if(!num_blocks)
+         return;
+      size_type blocksize = 
+         get_rounded_size(m_real_node_size*m_nodes_per_block, (size_type)alignment_of::value);
+
+      try{
+         for(size_type i = 0; i != num_blocks; ++i){
+            //We allocate a new NodeBlock and put it as first
+            //element in the free Node list
+            char *pNode = reinterpret_cast
+               (mp_segment_mngr_base->allocate(blocksize + sizeof(node_t)));
+            char *pBlock = pNode;
+            m_blocklist.push_front(get_block_hook(pBlock, blocksize));
+
+            //We initialize all Nodes in Node Block to insert 
+            //them in the free Node list
+            for(size_type i = 0; i < m_nodes_per_block; ++i, pNode += m_real_node_size){
+               m_freelist.push_front(*new (pNode) node_t);
+            }
+         }
+      }
+      catch(...){
+         //to-do: if possible, an efficient way to deallocate allocated blocks
+         throw;
+      }
+   }
+
+   //!Deprecated, use deallocate_free_blocks
+   void deallocate_free_chunks()
+   {  this->deallocate_free_blocks(); }
+
+   //!Deprecated, use purge_blocks
+   void purge_chunks()
+   {  this->purge_blocks(); }
+
+   private:
+   //!Returns a reference to the block hook placed in the end of the block
+   static node_t & get_block_hook (void *block, size_type blocksize)
+   {  
+      return *reinterpret_cast(reinterpret_cast(block) + blocksize);  
+   }
+
+   //!Returns the starting address of the block reference to the block hook placed in the end of the block
+   void *get_block_from_hook (node_t *hook, size_type blocksize)
+   {  
+      return (reinterpret_cast(hook) - blocksize);
+   }
+
+   private:
+   typedef typename boost::intrusive::pointer_traits
+      ::template rebind_pointer::type   segment_mngr_base_ptr_t;
+
+   const size_type m_nodes_per_block;
+   const size_type m_real_node_size;
+   segment_mngr_base_ptr_t mp_segment_mngr_base;   //Segment manager
+   blockslist_t      m_blocklist;      //Intrusive container of blocks
+   free_nodes_t      m_freelist;       //Intrusive container of free nods
+   size_type       m_allocated;      //Used nodes for debugging
+};
+
+
+}  //namespace container_detail {
+}  //namespace container {
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
diff --git a/src/third_party/boost/boost/container/detail/pair.hpp b/src/third_party/boost/boost/container/detail/pair.hpp
new file mode 100644
index 00000000000..1aeff911374
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/pair.hpp
@@ -0,0 +1,320 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
+#define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+
+#include 
+#include 
+
+#include    //std::pair
+
+#include 
+#include 
+
+#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
+#include 
+#endif
+
+namespace boost {
+namespace container { 
+namespace container_detail {
+
+template 
+struct pair;
+
+template 
+struct is_pair
+{
+   static const bool value = false;
+};
+
+template 
+struct is_pair< pair >
+{
+   static const bool value = true;
+};
+
+template 
+struct is_pair< std::pair >
+{
+   static const bool value = true;
+};
+
+struct pair_nat;
+
+struct piecewise_construct_t { };
+static const piecewise_construct_t piecewise_construct = piecewise_construct_t();
+
+template 
+struct pair
+{
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(pair)
+
+   public:
+   typedef T1 first_type;
+   typedef T2 second_type;
+
+   T1 first;
+   T2 second;
+
+   //Default constructor
+   pair()
+      : first(), second()
+   {}
+/*
+   //pair from two values
+   pair(const T1 &t1, const T2 &t2)
+      : first(t1)
+      , second(t2)
+   {}
+
+
+   //pair from two values
+   pair(BOOST_RV_REF(T1) t1, BOOST_RV_REF(T2) t2)
+      : first(::boost::move(t1))
+      , second(::boost::move(t2))
+   {}
+*/
+   template
+   pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v)
+      : first(::boost::forward(u))
+      , second(::boost::forward(v))
+   {}
+
+   //pair copy assignment
+   pair(const pair& x)
+      : first(x.first), second(x.second)
+   {}
+
+   template 
+   pair(const pair &p)
+      : first(p.first), second(p.second)
+   {}
+
+   //pair move constructor
+   pair(BOOST_RV_REF(pair) p)
+      : first(::boost::move(p.first)), second(::boost::move(p.second))
+   {}
+
+   template 
+   pair(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
+      : first(::boost::move(p.first)), second(::boost::move(p.second))
+   {}
+
+   //std::pair copy constructor
+   pair(const std::pair& x)
+      : first(x.first), second(x.second)
+   {}
+
+   template 
+   pair(const std::pair& p)
+      : first(p.first), second(p.second)
+   {}
+
+   //std::pair move constructor
+   template 
+   pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+      : first(::boost::move(p.first)), second(::boost::move(p.second))
+   {}
+
+   pair(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+      : first(::boost::move(p.first)), second(::boost::move(p.second))
+   {}
+
+   //piecewise_construct missing
+/*
+   //Variadic versions
+   template
+   pair(BOOST_CONTAINER_PP_PARAM(U, u), typename container_detail::disable_if
+         < container_detail::is_pair< typename container_detail::remove_ref_const::type >, pair_nat>::type* = 0)
+      : first(::boost::forward(u))
+      , second()
+   {}
+
+   #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   template
+   pair(U &&u, V &&v)
+      : first(::boost::forward(u))
+      , second(::boost::forward(v), ::boost::forward(args)...)
+   {}
+
+   #else
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                            \
+   template                                        \
+   pair(BOOST_CONTAINER_PP_PARAM(U, u)                                                          \
+       ,BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                                  \
+      : first(::boost::forward(u))                             \
+      , second(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))                        \
+   {}                                                                                         \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+   #endif
+*/
+   //pair copy assignment
+   pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
+   {
+      first  = p.first;
+      second = p.second;
+      return *this;
+   }
+
+   template 
+   pair& operator=(const pair&p)
+   {
+      first  = p.first;
+      second = p.second;
+      return *this;
+   }
+
+   //pair move assignment
+   pair& operator=(BOOST_RV_REF(pair) p)
+   {
+      first  = ::boost::move(p.first);
+      second = ::boost::move(p.second);
+      return *this;
+   }
+
+   template 
+   pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(pair, D, S) p)
+   {
+      first  = ::boost::move(p.first);
+      second = ::boost::move(p.second);
+      return *this;
+   }
+
+   //std::pair copy assignment
+   pair& operator=(const std::pair &p)
+   {
+      first  = p.first;
+      second = p.second;
+      return *this;
+   }
+
+   template 
+   pair& operator=(const std::pair &p)
+   {
+      first  = ::boost::move(p.first);
+      second = ::boost::move(p.second);
+      return *this;
+   }
+
+   //std::pair move assignment
+   pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, T1, T2) p)
+   {
+      first  = ::boost::move(p.first);
+      second = ::boost::move(p.second);
+      return *this;
+   }
+
+   template 
+   pair& operator=(BOOST_RV_REF_2_TEMPL_ARGS(std::pair, D, S) p)
+   {
+      first  = ::boost::move(p.first);
+      second = ::boost::move(p.second);
+      return *this;
+   }
+
+   //swap
+   void swap(pair& p)
+   {
+      using std::swap;
+      swap(this->first, p.first);
+      swap(this->second, p.second);
+   }
+};
+
+template 
+inline bool operator==(const pair& x, const pair& y)
+{  return static_cast(x.first == y.first && x.second == y.second);  }
+
+template 
+inline bool operator< (const pair& x, const pair& y)
+{  return static_cast(x.first < y.first ||
+                         (!(y.first < x.first) && x.second < y.second)); }
+
+template 
+inline bool operator!=(const pair& x, const pair& y)
+{  return static_cast(!(x == y));  }
+
+template 
+inline bool operator> (const pair& x, const pair& y)
+{  return y < x;  }
+
+template 
+inline bool operator>=(const pair& x, const pair& y)
+{  return static_cast(!(x < y)); }
+
+template 
+inline bool operator<=(const pair& x, const pair& y)
+{  return static_cast(!(y < x)); }
+
+template 
+inline pair make_pair(T1 x, T2 y)
+{  return pair(x, y); }
+
+template 
+inline void swap(pair& x, pair& y)
+{
+   swap(x.first, y.first);
+   swap(x.second, y.second);
+}
+
+}  //namespace container_detail { 
+}  //namespace container { 
+
+
+//Without this specialization recursive flat_(multi)map instantiation fails
+//because is_enum needs to instantiate the recursive pair, leading to a compilation error).
+//This breaks the cycle clearly stating that pair is not an enum avoiding any instantiation.
+template
+struct is_enum;
+
+template
+struct is_enum< ::boost::container::container_detail::pair >
+{
+   static const bool value = false;
+};
+
+//This specialization is needed to avoid instantiation of pair in
+//is_class, and allow recursive maps.
+template 
+struct is_class< ::boost::container::container_detail::pair >
+   : public ::boost::true_type
+{};
+
+#ifdef BOOST_NO_RVALUE_REFERENCES
+
+template
+struct has_move_emulation_enabled< ::boost::container::container_detail::pair >
+   : ::boost::true_type
+{};
+
+#endif
+
+
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP
diff --git a/src/third_party/boost/boost/container/detail/pool_common.hpp b/src/third_party/boost/boost/container/detail/pool_common.hpp
new file mode 100644
index 00000000000..c66e2cd18cd
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/pool_common.hpp
@@ -0,0 +1,52 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
+#define BOOST_CONTAINER_DETAIL_NODE_POOL_COMMON_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+#include 
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template
+struct node_slist
+{
+   //This hook will be used to chain the individual nodes
+    typedef typename bi::make_slist_base_hook
+      , bi::link_mode >::type slist_hook_t;
+
+   //A node object will hold node_t when it's not allocated
+   typedef slist_hook_t node_t;
+
+   typedef typename bi::make_slist
+      , bi::base_hook >::type node_slist_t;
+};
+
+template
+struct is_stateless_segment_manager
+{
+   static const bool value = false;
+};
+
+}  //namespace container_detail {
+}  //namespace container {
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_ADAPTIVE_NODE_POOL_IMPL_HPP
diff --git a/src/third_party/boost/boost/container/detail/preprocessor.hpp b/src/third_party/boost/boost/container/detail/preprocessor.hpp
new file mode 100644
index 00000000000..9916fbac62b
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/preprocessor.hpp
@@ -0,0 +1,178 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
+#define BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+#include 
+#endif   //#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#include 
+
+#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+//#error "This file is not needed when perfect forwarding is available"
+#endif   //BOOST_CONTAINER_PERFECT_FORWARDING
+
+#include  
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS 10
+
+//Note:
+//We define template parameters as const references to
+//be able to bind temporaries. After that we will un-const them.
+//This cast is ugly but it is necessary until "perfect forwarding"
+//is achieved in C++0x. Meanwhile, if we want to be able to
+//bind rvalues with non-const references, we have to be ugly
+#ifndef BOOST_NO_RVALUE_REFERENCES
+   #define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
+   BOOST_PP_CAT(P, n) && BOOST_PP_CAT(p, n) \
+   //!
+#else
+   #define BOOST_CONTAINER_PP_PARAM_LIST(z, n, data) \
+   const BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n) \
+   //!
+#endif   //#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+   #define BOOST_CONTAINER_PP_PARAM(U, u) \
+   U && u \
+   //!
+#else
+   #define BOOST_CONTAINER_PP_PARAM(U, u) \
+   const U & u \
+   //!
+#endif   //#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+   #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+
+      #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
+      BOOST_PP_CAT(m_p, n) (boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ))           \
+      //!
+
+   #else    //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+
+      #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
+      BOOST_PP_CAT(m_p, n) (static_cast( BOOST_PP_CAT(p, n) ))           \
+      //!
+
+   #endif   //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+
+#else //BOOST_NO_RVALUE_REFERENCES
+
+   #define BOOST_CONTAINER_PP_PARAM_INIT(z, n, data) \
+   BOOST_PP_CAT(m_p, n) (const_cast(BOOST_PP_CAT(p, n))) \
+   //!
+#endif   //#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+   #if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+      #define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data)  \
+      BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n);            \
+      //!
+
+   #else //BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
+
+      #define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data)  \
+      BOOST_PP_CAT(P, n) && BOOST_PP_CAT(m_p, n);            \
+      //!
+
+   #endif //defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+#else //BOOST_NO_RVALUE_REFERENCES
+
+   #define BOOST_CONTAINER_PP_PARAM_DEFINE(z, n, data)  \
+   BOOST_PP_CAT(P, n) & BOOST_PP_CAT(m_p, n);             \
+   //!
+#endif   //#ifndef BOOST_NO_RVALUE_REFERENCES
+
+#if !defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+   #define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
+   ::boost::container::container_detail::stored_ref< BOOST_PP_CAT(P, n) >::forward( BOOST_PP_CAT(this->m_p, n) ) \
+   //!
+
+#else //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+   #define BOOST_CONTAINER_PP_MEMBER_FORWARD(z, n, data) \
+   boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(this->m_p, n) ) \
+   //!
+
+#endif   //!defined(BOOST_NO_RVALUE_REFERENCES) && defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+#define BOOST_CONTAINER_PP_PARAM_INC(z, n, data)   \
+  BOOST_PP_CAT(++this->m_p, n)                     \
+//!
+
+#define BOOST_CONTAINER_PP_IDENTITY(z, n, data) data
+
+
+#define BOOST_CONTAINER_PP_PARAM_FORWARD(z, n, data) \
+boost::forward< BOOST_PP_CAT(P, n) >( BOOST_PP_CAT(p, n) ) \
+//!
+
+#define BOOST_CONTAINER_PP_DECLVAL(z, n, data) \
+boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
+//!
+
+#define BOOST_CONTAINER_PP_MEMBER_IT_FORWARD(z, n, data) \
+BOOST_PP_CAT(*this->m_p, n) \
+//!
+
+#define BOOST_CONTAINER_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data)   \
+  BOOST_PP_CAT(class P, n) = void                                      \
+//!
+
+#define BOOST_CONTAINER_PP_STATIC_PARAM_REF_DECLARE(z, n, data) \
+   static BOOST_PP_CAT(P, n) & BOOST_PP_CAT(p, n); \
+//!
+
+#define BOOST_CONTAINER_PP_PARAM_PASS(z, n, data) \
+   BOOST_PP_CAT(p, n) \
+//!
+
+#define BOOST_CONTAINER_PP_FWD_TYPE(z, n, data) \
+   typename ::boost::move_detail::forward_type< BOOST_PP_CAT(P, n) >::type \
+//!
+
+#include 
+
+//#else
+
+//#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+//#error "This file is not needed when perfect forwarding is available"
+//#endif   //BOOST_CONTAINER_PERFECT_FORWARDING
+
+#endif //#ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
diff --git a/src/third_party/boost/boost/container/detail/stored_ref.hpp b/src/third_party/boost/boost/container/detail/stored_ref.hpp
new file mode 100644
index 00000000000..df0faa85a0c
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/stored_ref.hpp
@@ -0,0 +1,92 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_STORED_REF_HPP
+#define BOOST_CONTAINER_DETAIL_STORED_REF_HPP
+
+#include "config_begin.hpp"
+#include 
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+namespace boost{
+namespace container{
+namespace container_detail{
+
+template
+struct stored_ref
+{
+
+   static T && forward(T &t)
+   #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+   { return t; }
+   #else
+   { return boost::move(t); }
+   #endif
+};
+
+template
+struct stored_ref
+{
+   static const T && forward(const T &t)
+   #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+   { return t; }
+   #else
+   { return static_cast(t); }
+   #endif
+};
+
+template
+struct stored_ref
+{
+   static T && forward(T &t)
+   #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+   { return t; }
+   #else
+   { return boost::move(t); }
+   #endif
+};
+
+template
+struct stored_ref
+{
+   static const T && forward(const T &t)
+   #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+   { return t; }
+   #else
+   { return static_cast(t); }
+   #endif
+};
+
+template
+struct stored_ref
+{
+   static const T & forward(const T &t)
+   {  return t; }
+};
+
+template
+struct stored_ref
+{
+   static T & forward(T &t)
+   {  return t; }
+};
+
+}  //namespace container_detail{
+}  //namespace container{
+}  //namespace boost{
+
+#else
+#error "This header can be included only for compiler with rvalue references"
+#endif   //BOOST_NO_RVALUE_REFERENCES
+
+#include 
+
+#endif   //BOOST_CONTAINER_DETAIL_STORED_REF_HPP
diff --git a/src/third_party/boost/boost/container/detail/transform_iterator.hpp b/src/third_party/boost/boost/container/detail/transform_iterator.hpp
new file mode 100644
index 00000000000..17eca9ef619
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/transform_iterator.hpp
@@ -0,0 +1,176 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+// (C) Copyright Gennaro Prota 2003 - 2004.
+//
+// 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
+#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace container { 
+
+template 
+struct operator_arrow_proxy
+{
+   operator_arrow_proxy(const PseudoReference &px)
+      :  m_value(px)
+   {}
+
+   PseudoReference* operator->() const { return &m_value; }
+   // This function is needed for MWCW and BCC, which won't call operator->
+   // again automatically per 13.3.1.2 para 8
+//   operator T*() const { return &m_value; }
+   mutable PseudoReference m_value;
+};
+
+template 
+struct operator_arrow_proxy
+{
+   operator_arrow_proxy(T &px)
+      :  m_value(px)
+   {}
+
+   T* operator->() const { return const_cast(&m_value); }
+   // This function is needed for MWCW and BCC, which won't call operator->
+   // again automatically per 13.3.1.2 para 8
+//   operator T*() const { return &m_value; }
+   T &m_value;
+};
+
+template 
+class transform_iterator
+   : public UnaryFunction
+   , public std::iterator
+      < typename Iterator::iterator_category
+      , typename container_detail::remove_reference::type
+      , typename Iterator::difference_type
+      , operator_arrow_proxy
+      , typename UnaryFunction::result_type>
+{
+   public:
+   explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction())
+      :  UnaryFunction(f), m_it(it)
+   {}
+
+   explicit transform_iterator()
+      :  UnaryFunction(), m_it()
+   {}
+
+   //Constructors
+   transform_iterator& operator++() 
+   { increment();   return *this;   }
+
+   transform_iterator operator++(int)
+   {
+      transform_iterator result (*this);
+      increment();
+      return result;
+   }
+
+   friend bool operator== (const transform_iterator& i, const transform_iterator& i2)
+   { return i.equal(i2); }
+
+   friend bool operator!= (const transform_iterator& i, const transform_iterator& i2)
+   { return !(i == i2); }
+
+/*
+   friend bool operator> (const transform_iterator& i, const transform_iterator& i2)
+   { return i2 < i; }
+
+   friend bool operator<= (const transform_iterator& i, const transform_iterator& i2)
+   { return !(i > i2); }
+
+   friend bool operator>= (const transform_iterator& i, const transform_iterator& i2)
+   { return !(i < i2); }
+*/
+   friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2)
+   { return i2.distance_to(i); }
+
+   //Arithmetic
+   transform_iterator& operator+=(typename Iterator::difference_type off)
+   {  this->advance(off); return *this;   }
+
+   transform_iterator operator+(typename Iterator::difference_type off) const
+   {
+      transform_iterator other(*this);
+      other.advance(off);
+      return other;
+   }
+
+   friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right)
+   {  return right + off; }
+
+   transform_iterator& operator-=(typename Iterator::difference_type off)
+   {  this->advance(-off); return *this;   }
+
+   transform_iterator operator-(typename Iterator::difference_type off) const
+   {  return *this + (-off);  }
+
+   typename UnaryFunction::result_type operator*() const
+   { return dereference(); }
+
+   operator_arrow_proxy
+      operator->() const
+   { return operator_arrow_proxy(dereference());  }
+
+   Iterator & base()
+   {  return m_it;   }
+
+   const Iterator & base() const
+   {  return m_it;   }
+
+   private:
+   Iterator m_it;
+
+   void increment()
+   { ++m_it; }
+
+   void decrement()
+   { --m_it; }
+
+   bool equal(const transform_iterator &other) const
+   {  return m_it == other.m_it;   }
+
+   bool less(const transform_iterator &other) const
+   {  return other.m_it < m_it;   }
+
+   typename UnaryFunction::result_type dereference() const
+   { return UnaryFunction::operator()(*m_it); }
+
+   void advance(typename Iterator::difference_type n)
+   {  std::advance(m_it, n); }
+
+   typename Iterator::difference_type distance_to(const transform_iterator &other)const
+   {  return std::distance(other.m_it, m_it); }
+};
+
+template 
+transform_iterator
+make_transform_iterator(Iterator it, UnaryFunc fun)
+{
+   return transform_iterator(it, fun);
+}
+
+}  //namespace container { 
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
diff --git a/src/third_party/boost/boost/container/detail/tree.hpp b/src/third_party/boost/boost/container/detail/tree.hpp
new file mode 100644
index 00000000000..6cd91ed2a69
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/tree.hpp
@@ -0,0 +1,1154 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_TREE_HPP
+#define BOOST_CONTAINER_TREE_HPP
+
+#include "config_begin.hpp"
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
+#include 
+#endif
+
+#include    //std::pair
+#include 
+#include 
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template
+struct value_compare_impl
+   :  public KeyCompare
+{
+   typedef Value        value_type;
+   typedef KeyCompare   key_compare; 
+   typedef KeyOfValue   key_of_value;
+   typedef Key          key_type;
+
+   value_compare_impl(const key_compare &kcomp)
+      :  key_compare(kcomp)
+   {}
+
+   const key_compare &key_comp() const
+   {  return static_cast(*this);  }
+
+   key_compare &key_comp()
+   {  return static_cast(*this);  }
+
+   template
+   struct is_key
+   {
+      static const bool value = is_same::value;
+   };
+
+   template
+   typename enable_if_c::value, const key_type &>::type
+      key_forward(const T &key) const
+   {  return key; }
+
+   template
+   typename enable_if_c::value, const key_type &>::type
+      key_forward(const T &key) const
+   {  return KeyOfValue()(key);  }
+
+   template
+   bool operator()(const KeyType &key1, const KeyType2 &key2) const
+   {  return key_compare::operator()(this->key_forward(key1), this->key_forward(key2));  }
+};
+
+template
+struct rbtree_hook
+{
+   typedef typename container_detail::bi::make_set_base_hook
+      < container_detail::bi::void_pointer
+      , container_detail::bi::link_mode
+      , container_detail::bi::optimize_size
+      >::type  type;
+};
+
+template
+struct rbtree_type
+{
+   typedef T type;
+};
+
+template
+struct rbtree_type< std::pair >
+{
+   typedef pair type;
+};
+
+template 
+struct rbtree_node
+   :  public rbtree_hook::type
+{
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
+
+   public:
+   typedef typename rbtree_hook::type hook_type;
+
+   typedef T value_type;
+   typedef typename rbtree_type::type internal_type;
+
+   typedef rbtree_node node_type;
+
+   rbtree_node()
+      : m_data()
+   {}
+
+   rbtree_node(const rbtree_node &other)
+      : m_data(other.m_data)
+   {}
+
+   rbtree_node(BOOST_RV_REF(rbtree_node) other)
+      : m_data(boost::move(other.m_data))
+   {}
+
+   #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                           \
+   template                                \
+   rbtree_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))           \
+      : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))        \
+   {}                                                                        \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #else //#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   template
+   rbtree_node(Args &&...args)
+      : m_data(boost::forward(args)...)
+   {}
+   #endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   rbtree_node &operator=(const rbtree_node &other)
+   {  do_assign(other.m_data);   return *this;  }
+
+   rbtree_node &operator=(BOOST_RV_REF(rbtree_node) other)
+   {  do_move(other.m_data);   return *this;  }
+
+   T &get_data()
+   {
+      T* ptr = reinterpret_cast(&this->m_data);
+      return *ptr;
+   }
+
+   const T &get_data() const
+   {
+      const T* ptr = reinterpret_cast(&this->m_data);
+      return *ptr;
+   }
+
+   private:
+   internal_type m_data;
+
+   template
+   void do_assign(const std::pair &p)
+   {
+      const_cast(m_data.first) = p.first;
+      m_data.second  = p.second;
+   }
+
+   template
+   void do_assign(const pair &p)
+   {
+      const_cast(m_data.first) = p.first;
+      m_data.second  = p.second;
+   }
+
+   template
+   void do_assign(const V &v)
+   {  m_data = v; }
+
+   template
+   void do_move(std::pair &p)
+   {
+      const_cast(m_data.first) = boost::move(p.first);
+      m_data.second  = boost::move(p.second);
+   }
+
+   template
+   void do_move(pair &p)
+   {
+      const_cast(m_data.first) = boost::move(p.first);
+      m_data.second  = boost::move(p.second);
+   }
+
+   template
+   void do_move(V &v)
+   {  m_data = boost::move(v); }
+};
+
+}//namespace container_detail {
+
+namespace container_detail {
+
+template
+struct intrusive_rbtree_type
+{
+   typedef typename boost::container::
+      allocator_traits::value_type              value_type;
+   typedef typename boost::container::
+      allocator_traits::void_pointer            void_pointer;
+   typedef typename boost::container::
+      allocator_traits::size_type               size_type;
+   typedef typename container_detail::rbtree_node
+                         node_type;
+   typedef node_compare   node_compare_type;
+   typedef typename container_detail::bi::make_rbtree
+      
+      ,container_detail::bi::base_hook::type>
+      ,container_detail::bi::constant_time_size
+      ,container_detail::bi::size_type
+      >::type                                      container_type;
+   typedef container_type                          type ;
+};
+
+}  //namespace container_detail {
+
+namespace container_detail {
+
+template 
+class rbtree
+   : protected container_detail::node_alloc_holder
+      < A
+      , typename container_detail::intrusive_rbtree_type
+           
+         >::type
+      , KeyCompare
+      >
+{
+   typedef typename container_detail::intrusive_rbtree_type
+         < A, value_compare_impl
+            
+         >::type                                            Icont;
+   typedef container_detail::node_alloc_holder  
+                                      AllocHolder;
+   typedef typename AllocHolder::NodePtr                    NodePtr;
+   typedef rbtree < Key, Value, KeyOfValue
+                  , KeyCompare, A>                          ThisType;
+   typedef typename AllocHolder::NodeAlloc                  NodeAlloc;
+   typedef typename AllocHolder::ValAlloc                   ValAlloc;
+   typedef typename AllocHolder::Node                       Node;
+   typedef typename Icont::iterator                         iiterator;
+   typedef typename Icont::const_iterator                   iconst_iterator;
+   typedef container_detail::allocator_destroyer Destroyer;
+   typedef typename AllocHolder::allocator_v1               allocator_v1;
+   typedef typename AllocHolder::allocator_v2               allocator_v2;
+   typedef typename AllocHolder::alloc_version              alloc_version;
+
+   class RecyclingCloner;
+   friend class RecyclingCloner;
+
+   class RecyclingCloner
+   {
+      public:
+      RecyclingCloner(AllocHolder &holder, Icont &irbtree)
+         :  m_holder(holder), m_icont(irbtree)
+      {}
+
+      NodePtr operator()(const Node &other) const
+      {
+         if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
+            //First recycle a node (this can't throw)
+            try{
+               //This can throw
+               *p = other;
+               return p;
+            }
+            catch(...){
+               //If there is an exception destroy the whole source
+               m_holder.destroy_node(p);
+               while((p = m_icont.unlink_leftmost_without_rebalance())){
+                  m_holder.destroy_node(p);
+               }
+               throw;
+            }
+         }
+         else{
+            return m_holder.create_node(other);
+         }
+      }
+
+      AllocHolder &m_holder;
+      Icont &m_icont;
+   };
+
+   class RecyclingMoveCloner;
+   friend class RecyclingMoveCloner;
+
+   class RecyclingMoveCloner
+   {
+      public:
+      RecyclingMoveCloner(AllocHolder &holder, Icont &irbtree)
+         :  m_holder(holder), m_icont(irbtree)
+      {}
+
+      NodePtr operator()(const Node &other) const
+      {
+         if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
+            //First recycle a node (this can't throw)
+            try{
+               //This can throw
+               *p = boost::move(other);
+               return p;
+            }
+            catch(...){
+               //If there is an exception destroy the whole source
+               m_holder.destroy_node(p);
+               while((p = m_icont.unlink_leftmost_without_rebalance())){
+                  m_holder.destroy_node(p);
+               }
+               throw;
+            }
+         }
+         else{
+            return m_holder.create_node(other);
+         }
+      }
+
+      AllocHolder &m_holder;
+      Icont &m_icont;
+   };
+
+   BOOST_COPYABLE_AND_MOVABLE(rbtree)
+
+   public:
+
+   typedef Key                                        key_type;
+   typedef Value                                      value_type;
+   typedef A                                          allocator_type;
+   typedef KeyCompare                                 key_compare;
+   typedef value_compare_impl< Key, Value
+                        , KeyCompare, KeyOfValue>     value_compare;
+   typedef typename boost::container::
+      allocator_traits::pointer                    pointer;
+   typedef typename boost::container::
+      allocator_traits::const_pointer              const_pointer;
+   typedef typename boost::container::
+      allocator_traits::reference                  reference;
+   typedef typename boost::container::
+      allocator_traits::const_reference            const_reference;
+   typedef typename boost::container::
+      allocator_traits::size_type                  size_type;
+   typedef typename boost::container::
+      allocator_traits::difference_type            difference_type;
+   typedef difference_type                            rbtree_difference_type;
+   typedef pointer                                    rbtree_pointer;
+   typedef const_pointer                              rbtree_const_pointer;
+   typedef reference                                  rbtree_reference;
+   typedef const_reference                            rbtree_const_reference;
+   typedef NodeAlloc                                  stored_allocator_type;
+
+   private:
+
+   template
+   struct key_node_compare
+      :  private KeyValueCompare
+   {
+      key_node_compare(const KeyValueCompare &comp)
+         :  KeyValueCompare(comp)
+      {}
+
+      template
+      struct is_node
+      {
+         static const bool value = is_same::value;
+      };
+
+      template
+      typename enable_if_c::value, const value_type &>::type
+         key_forward(const T &node) const
+      {  return node.get_data();  }
+
+      template
+      typename enable_if_c::value, const T &>::type
+         key_forward(const T &key) const
+      {  return key; }
+
+      template
+      bool operator()(const KeyType &key1, const KeyType2 &key2) const
+      {  return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2));  }
+   };
+
+   typedef key_node_compare  KeyNodeCompare;
+
+   public:
+   //rbtree const_iterator
+   class const_iterator
+      : public std::iterator
+         < std::bidirectional_iterator_tag
+         , value_type            , rbtree_difference_type
+         , rbtree_const_pointer  , rbtree_const_reference>
+   {
+      protected:
+      typedef typename Icont::iterator  iiterator;
+      iiterator m_it;
+      explicit const_iterator(iiterator it)  : m_it(it){}
+      void prot_incr() { ++m_it; }
+      void prot_decr() { --m_it; }
+
+      private:
+      iiterator get()
+      {  return this->m_it;   }
+
+      public:
+      friend class rbtree ;
+      typedef rbtree_difference_type        difference_type;
+
+      //Constructors
+      const_iterator()
+         :  m_it()
+      {}
+
+      //Pointer like operators
+      const_reference operator*()  const 
+      { return  m_it->get_data();  }
+
+      const_pointer   operator->() const 
+      { return  const_pointer(&m_it->get_data()); }
+
+      //Increment / Decrement
+      const_iterator& operator++()       
+      { prot_incr();  return *this; }
+
+      const_iterator operator++(int)      
+      { iiterator tmp = m_it; ++*this; return const_iterator(tmp);  }
+
+      const_iterator& operator--()
+      {   prot_decr(); return *this;   }
+
+      const_iterator operator--(int)
+      {  iiterator tmp = m_it; --*this; return const_iterator(tmp); }
+
+      //Comparison operators
+      bool operator==   (const const_iterator& r)  const
+      {  return m_it == r.m_it;  }
+
+      bool operator!=   (const const_iterator& r)  const
+      {  return m_it != r.m_it;  }
+   };
+
+   //rbtree iterator
+   class iterator : public const_iterator
+   {
+      private:
+      explicit iterator(iiterator it)
+         :  const_iterator(it)
+      {}
+   
+      iiterator get()
+      {  return this->m_it;   }
+
+      public:
+      friend class rbtree ;
+      typedef rbtree_pointer       pointer;
+      typedef rbtree_reference     reference;
+
+      //Constructors
+      iterator(){}
+
+      //Pointer like operators
+      reference operator*()  const {  return  this->m_it->get_data();  }
+      pointer   operator->() const {  return  pointer(&this->m_it->get_data());  }
+
+      //Increment / Decrement
+      iterator& operator++()  
+         { this->prot_incr(); return *this;  }
+
+      iterator operator++(int)
+         { iiterator tmp = this->m_it; ++*this; return iterator(tmp); }
+      
+      iterator& operator--()
+         {  this->prot_decr(); return *this;  }
+
+      iterator operator--(int)
+         {  iterator tmp = *this; --*this; return tmp; }
+   };
+
+   typedef std::reverse_iterator        reverse_iterator;
+   typedef std::reverse_iterator  const_reverse_iterator;
+
+   rbtree()
+      : AllocHolder(key_compare())
+   {}
+
+   rbtree(const key_compare& comp, const allocator_type& a = allocator_type())
+      : AllocHolder(a, comp)
+   {}
+
+   template 
+   rbtree(InputIterator first, InputIterator last, const key_compare& comp,
+          const allocator_type& a, bool unique_insertion)
+      : AllocHolder(a, comp)
+   {
+      typedef typename std::iterator_traits::iterator_category ItCat;
+      priv_create_and_insert_nodes(first, last, unique_insertion, alloc_version(), ItCat());
+   }
+
+   template 
+   rbtree( ordered_range_t, InputIterator first, InputIterator last
+         , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type())
+      : AllocHolder(a, comp)
+   {
+      typedef typename std::iterator_traits::iterator_category ItCat;
+      priv_create_and_insert_ordered_nodes(first, last, alloc_version(), ItCat());
+   }
+
+   rbtree(const rbtree& x) 
+      :  AllocHolder(x, x.key_comp())
+   {
+      this->icont().clone_from
+         (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
+   }
+
+   rbtree(BOOST_RV_REF(rbtree) x) 
+      :  AllocHolder(boost::move(static_cast(x)), x.key_comp())
+   {}
+
+   ~rbtree()
+   {} //AllocHolder clears the tree
+
+   rbtree& operator=(BOOST_COPY_ASSIGN_REF(rbtree) x)
+   {
+      if (&x != this){
+         NodeAlloc &this_alloc     = this->get_stored_allocator();
+         const NodeAlloc &x_alloc  = x.get_stored_allocator();
+         container_detail::bool_::
+            propagate_on_container_copy_assignment::value> flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+         }
+         this->AllocHolder::copy_assign_alloc(x);
+         //Transfer all the nodes to a temporary tree
+         //If anything goes wrong, all the nodes will be destroyed
+         //automatically
+         Icont other_tree(boost::move(this->icont()));
+
+         //Now recreate the source tree reusing nodes stored by other_tree
+         this->icont().clone_from
+            (x.icont()
+            , RecyclingCloner(*this, other_tree)
+            , Destroyer(this->node_alloc()));
+
+         //If there are remaining nodes, destroy them
+         NodePtr p;
+         while((p = other_tree.unlink_leftmost_without_rebalance())){
+            AllocHolder::destroy_node(p);
+         }
+      }
+      return *this;
+   }
+
+   rbtree& operator=(BOOST_RV_REF(rbtree) x)
+   {
+      if (&x != this){
+         NodeAlloc &this_alloc = this->node_alloc();
+         NodeAlloc &x_alloc    = x.node_alloc();
+         //If allocators are equal we can just swap pointers
+         if(this_alloc == x_alloc){
+            //Destroy and swap pointers
+            this->clear();
+            this->icont() = boost::move(x.icont());
+            //Move allocator if needed
+            this->AllocHolder::move_assign_alloc(x);
+         }
+         //If unequal allocators, then do a one by one move
+         else{
+            //Transfer all the nodes to a temporary tree
+            //If anything goes wrong, all the nodes will be destroyed
+            //automatically
+            Icont other_tree(boost::move(this->icont()));
+
+            //Now recreate the source tree reusing nodes stored by other_tree
+            this->icont().clone_from
+               (x.icont()
+               , RecyclingMoveCloner(*this, other_tree)
+               , Destroyer(this->node_alloc()));
+
+            //If there are remaining nodes, destroy them
+            NodePtr p;
+            while((p = other_tree.unlink_leftmost_without_rebalance())){
+               AllocHolder::destroy_node(p);
+            }
+         }
+      }
+      return *this;
+   }
+
+   public:    
+   // accessors:
+   value_compare value_comp() const 
+   {  return this->icont().value_comp().value_comp(); }
+
+   key_compare key_comp() const 
+   {  return this->icont().value_comp().value_comp().key_comp(); }
+
+   allocator_type get_allocator() const 
+   {  return allocator_type(this->node_alloc()); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+   {  return this->node_alloc(); }
+
+   stored_allocator_type &get_stored_allocator()
+   {  return this->node_alloc(); }
+
+   iterator begin()
+   { return iterator(this->icont().begin()); }
+
+   const_iterator begin() const
+   {  return this->cbegin();  }
+
+   iterator end()
+   {  return iterator(this->icont().end());  }
+
+   const_iterator end() const
+   {  return this->cend();  }
+
+   reverse_iterator rbegin()
+   {  return reverse_iterator(end());  }
+
+   const_reverse_iterator rbegin() const
+   {  return this->crbegin();  }
+
+   reverse_iterator rend()
+   {  return reverse_iterator(begin());   }
+
+   const_reverse_iterator rend() const
+   {  return this->crend();   }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const 
+   { return const_iterator(this->non_const_icont().begin()); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const 
+   { return const_iterator(this->non_const_icont().end()); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin() const 
+   { return const_reverse_iterator(cend()); } 
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend() const 
+   { return const_reverse_iterator(cbegin()); }
+
+   bool empty() const 
+   {  return !this->size();  }
+
+   size_type size() const 
+   {  return this->icont().size();   }
+
+   size_type max_size() const 
+   {  return AllocHolder::max_size();  }
+
+   void swap(ThisType& x)
+   {  AllocHolder::swap(x);   }
+
+   public:
+
+   typedef typename Icont::insert_commit_data insert_commit_data;
+
+   // insert/erase
+   std::pair insert_unique_check
+      (const key_type& key, insert_commit_data &data)
+   {
+      std::pair ret = 
+         this->icont().insert_unique_check(key, KeyNodeCompare(value_comp()), data);
+      return std::pair(iterator(ret.first), ret.second);
+   }
+
+   std::pair insert_unique_check
+      (const_iterator hint, const key_type& key, insert_commit_data &data)
+   {
+      std::pair ret = 
+         this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
+      return std::pair(iterator(ret.first), ret.second);
+   }
+
+   iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
+   {
+      NodePtr tmp = AllocHolder::create_node(v);
+      iiterator it(this->icont().insert_unique_commit(*tmp, data));
+      return iterator(it);
+   }
+
+   template
+   iterator insert_unique_commit
+      (BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data)
+   {
+      NodePtr tmp = AllocHolder::create_node(boost::forward(mv));
+      iiterator it(this->icont().insert_unique_commit(*tmp, data));
+      return iterator(it);
+   }
+
+   std::pair insert_unique(const value_type& v)
+   {
+      insert_commit_data data;
+      std::pair ret =
+         this->insert_unique_check(KeyOfValue()(v), data);
+      if(!ret.second)
+         return ret;
+      return std::pair
+         (this->insert_unique_commit(v, data), true);
+   }
+
+   template
+   std::pair insert_unique(BOOST_FWD_REF(MovableConvertible) mv)
+   {
+      insert_commit_data data;
+      std::pair ret =
+         this->insert_unique_check(KeyOfValue()(mv), data);
+      if(!ret.second)
+         return ret;
+      return std::pair
+         (this->insert_unique_commit(boost::forward(mv), data), true);
+   }
+
+   private:
+   std::pair emplace_unique_impl(NodePtr p)
+   {
+      value_type &v = p->get_data();
+      insert_commit_data data;
+      std::pair ret =
+         this->insert_unique_check(KeyOfValue()(v), data);
+      if(!ret.second){
+         Destroyer(this->node_alloc())(p);
+         return ret;
+      }
+      return std::pair
+         ( iterator(iiterator(this->icont().insert_unique_commit(*p, data)))
+         , true );
+   }
+
+   iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
+   {
+      value_type &v = p->get_data();
+      insert_commit_data data;
+      std::pair ret =
+         this->insert_unique_check(hint, KeyOfValue()(v), data);
+      if(!ret.second){
+         Destroyer(this->node_alloc())(p);
+         return ret.first;
+      }
+      return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
+   }
+
+   public:
+
+   #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   template 
+   std::pair emplace_unique(Args&&... args)
+   {  return this->emplace_unique_impl(AllocHolder::create_node(boost::forward(args)...));   }
+
+   template 
+   iterator emplace_hint_unique(const_iterator hint, Args&&... args)
+   {  return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::forward(args)...));   }
+
+   template 
+   iterator emplace_equal(Args&&... args)
+   {
+      NodePtr p(AllocHolder::create_node(boost::forward(args)...));
+      return iterator(this->icont().insert_equal(this->icont().end(), *p));
+   }
+
+   template 
+   iterator emplace_hint_equal(const_iterator hint, Args&&... args)
+   {
+      NodePtr p(AllocHolder::create_node(boost::forward(args)...));
+      return iterator(this->icont().insert_equal(hint.get(), *p));
+   }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                                          \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)                   \
+   std::pair emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))             \
+   {                                                                                                        \
+      return this->emplace_unique_impl                                                                      \
+         (AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)));                 \
+   }                                                                                                        \
+                                                                                                            \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)                   \
+   iterator emplace_hint_unique(const_iterator hint                                                         \
+                       BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                         \
+   {                                                                                                        \
+      return this->emplace_unique_hint_impl                                                                 \
+         (hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)));           \
+   }                                                                                                        \
+                                                                                                            \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)                   \
+   iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                               \
+   {                                                                                                        \
+      NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)));           \
+      return iterator(this->icont().insert_equal(this->icont().end(), *p));                                 \
+   }                                                                                                        \
+                                                                                                            \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)                   \
+   iterator emplace_hint_equal(const_iterator hint                                                          \
+                       BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                         \
+   {                                                                                                        \
+      NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)));           \
+      return iterator(this->icont().insert_equal(hint.get(), *p));                                          \
+   }                                                                                                        \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   iterator insert_unique(const_iterator hint, const value_type& v)
+   {
+      insert_commit_data data;
+      std::pair ret =
+         this->insert_unique_check(hint, KeyOfValue()(v), data);
+      if(!ret.second)
+         return ret.first;
+      return this->insert_unique_commit(v, data);
+   }
+
+   template
+   iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
+   {
+      insert_commit_data data;
+      std::pair ret =
+         this->insert_unique_check(hint, KeyOfValue()(mv), data);
+      if(!ret.second)
+         return ret.first;
+      return this->insert_unique_commit(boost::forward(mv), data);
+   }
+
+   template 
+   void insert_unique(InputIterator first, InputIterator last)
+   {
+      if(this->empty()){
+         //Insert with end hint, to achieve linear
+         //complexity if [first, last) is ordered
+         const_iterator end(this->end());
+         for( ; first != last; ++first)
+            this->insert_unique(end, *first);
+      }
+      else{
+         for( ; first != last; ++first)
+            this->insert_unique(*first);
+      }
+   }
+
+   iterator insert_equal(const value_type& v)
+   {
+      NodePtr p(AllocHolder::create_node(v));
+      return iterator(this->icont().insert_equal(this->icont().end(), *p));
+   }
+
+   template
+   iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv)
+   {
+      NodePtr p(AllocHolder::create_node(boost::forward(mv)));
+      return iterator(this->icont().insert_equal(this->icont().end(), *p));
+   }
+
+   iterator insert_equal(const_iterator hint, const value_type& v)
+   {
+      NodePtr p(AllocHolder::create_node(v));
+      return iterator(this->icont().insert_equal(hint.get(), *p));
+   }
+
+   template
+   iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
+   {
+      NodePtr p(AllocHolder::create_node(boost::forward(mv)));
+      return iterator(this->icont().insert_equal(hint.get(), *p));
+   }
+
+   template 
+   void insert_equal(InputIterator first, InputIterator last)
+   {
+      //Insert with end hint, to achieve linear
+      //complexity if [first, last) is ordered
+      const_iterator end(this->cend());
+      for( ; first != last; ++first)
+         this->insert_equal(end, *first);
+   }
+
+   iterator erase(const_iterator position)
+   {  return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
+
+   size_type erase(const key_type& k)
+   {  return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
+
+   iterator erase(const_iterator first, const_iterator last)
+   {  return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
+
+   void clear() 
+   {  AllocHolder::clear(alloc_version());  }
+
+   // set operations:
+   iterator find(const key_type& k)
+   {  return iterator(this->icont().find(k, KeyNodeCompare(value_comp())));  }
+
+   const_iterator find(const key_type& k) const
+   {  return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp())));  }
+
+   size_type count(const key_type& k) const
+   {  return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); }
+
+   iterator lower_bound(const key_type& k)
+   {  return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp())));  }
+
+   const_iterator lower_bound(const key_type& k) const
+   {  return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp())));  }
+
+   iterator upper_bound(const key_type& k)
+   {  return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp())));   }
+
+   const_iterator upper_bound(const key_type& k) const
+   {  return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp())));  }
+
+   std::pair equal_range(const key_type& k)
+   {  
+      std::pair ret =
+         this->icont().equal_range(k, KeyNodeCompare(value_comp()));
+      return std::pair(iterator(ret.first), iterator(ret.second));
+   }
+
+   std::pair equal_range(const key_type& k) const
+   {  
+      std::pair ret =
+         this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp()));
+      return std::pair
+         (const_iterator(ret.first), const_iterator(ret.second));
+   }
+
+   private:
+   //Iterator range version
+   template
+   void priv_create_and_insert_nodes
+      (InpIterator beg, InpIterator end, bool unique, allocator_v1, std::input_iterator_tag)
+   {
+      if(unique){
+         for (; beg != end; ++beg){
+            this->insert_unique(*beg);
+         }
+      }
+      else{
+         for (; beg != end; ++beg){
+            this->insert_equal(*beg);
+         }
+      }
+   }
+
+   template
+   void priv_create_and_insert_nodes
+      (InpIterator beg, InpIterator end, bool unique, allocator_v2, std::input_iterator_tag)
+   {  //Just forward to the default one
+      priv_create_and_insert_nodes(beg, end, unique, allocator_v1(), std::input_iterator_tag());
+   }
+
+   class insertion_functor;
+   friend class insertion_functor;
+
+   class insertion_functor
+   {
+      Icont &icont_;
+
+      public:
+      insertion_functor(Icont &icont)
+         :  icont_(icont)
+      {}
+
+      void operator()(Node &n)
+      {  this->icont_.insert_equal(this->icont_.cend(), n); }
+   };
+
+
+   template
+   void priv_create_and_insert_nodes
+      (FwdIterator beg, FwdIterator end, bool unique, allocator_v2, std::forward_iterator_tag)
+   {
+      if(beg != end){
+         if(unique){
+            priv_create_and_insert_nodes(beg, end, unique, allocator_v2(), std::input_iterator_tag());
+         }
+         else{
+            //Optimized allocation and construction
+            this->allocate_many_and_construct
+               (beg, std::distance(beg, end), insertion_functor(this->icont()));
+         }
+      }
+   }
+
+   //Iterator range version
+   template
+   void priv_create_and_insert_ordered_nodes
+      (InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
+   {
+      const_iterator cend_n(this->cend());
+      for (; beg != end; ++beg){
+         this->insert_before(cend_n, *beg);
+      }
+   }
+
+   template
+   void priv_create_and_insert_ordered_nodes
+      (InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
+   {  //Just forward to the default one
+      priv_create_and_insert_ordered_nodes(beg, end, allocator_v1(), std::input_iterator_tag());
+   }
+
+   class back_insertion_functor;
+   friend class back_insertion_functor;
+
+   class back_insertion_functor
+   {
+      Icont &icont_;
+
+      public:
+      back_insertion_functor(Icont &icont)
+         :  icont_(icont)
+      {}
+
+      void operator()(Node &n)
+      {  this->icont_.push_back(n); }
+   };
+
+
+   template
+   void priv_create_and_insert_ordered_nodes
+      (FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+   {
+      if(beg != end){
+         //Optimized allocation and construction
+         this->allocate_many_and_construct
+            (beg, std::distance(beg, end), back_insertion_functor(this->icont()));
+      }
+   }
+};
+
+template 
+inline bool 
+operator==(const rbtree& x, 
+           const rbtree& y)
+{
+  return x.size() == y.size() &&
+         std::equal(x.begin(), x.end(), y.begin());
+}
+
+template 
+inline bool 
+operator<(const rbtree& x, 
+          const rbtree& y)
+{
+  return std::lexicographical_compare(x.begin(), x.end(), 
+                                      y.begin(), y.end());
+}
+
+template 
+inline bool 
+operator!=(const rbtree& x, 
+           const rbtree& y) {
+  return !(x == y);
+}
+
+template 
+inline bool 
+operator>(const rbtree& x, 
+          const rbtree& y) {
+  return y < x;
+}
+
+template 
+inline bool 
+operator<=(const rbtree& x, 
+           const rbtree& y) {
+  return !(y < x);
+}
+
+template 
+inline bool 
+operator>=(const rbtree& x, 
+           const rbtree& y) {
+  return !(x < y);
+}
+
+
+template 
+inline void 
+swap(rbtree& x, 
+     rbtree& y)
+{
+  x.swap(y);
+}
+
+} //namespace container_detail {
+} //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move
+    >
+{
+   static const bool value = has_trivial_destructor::value && has_trivial_destructor::value;
+};
+*/
+} //namespace boost  {
+
+#include 
+
+#endif //BOOST_CONTAINER_TREE_HPP
diff --git a/src/third_party/boost/boost/container/detail/type_traits.hpp b/src/third_party/boost/boost/container/detail/type_traits.hpp
new file mode 100644
index 00000000000..6a0b3ed58d4
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/type_traits.hpp
@@ -0,0 +1,203 @@
+//////////////////////////////////////////////////////////////////////////////
+// (C) Copyright John Maddock 2000.
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// 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/container for documentation.
+//
+// The alignment_of implementation comes from John Maddock's boost::alignment_of code
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
+#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+
+#include 
+
+namespace boost {
+namespace container { 
+namespace container_detail {
+
+struct nat{};
+
+//boost::alignment_of yields to 10K lines of preprocessed code, so we
+//need an alternative
+template  struct alignment_of;
+
+template 
+struct alignment_of_hack
+{
+    char c;
+    T t;
+    alignment_of_hack();
+};
+
+template 
+struct alignment_logic
+{
+    enum{   value = A < S ? A : S  };
+};
+
+template< typename T >
+struct alignment_of
+{
+   enum{ value = alignment_logic
+            < sizeof(alignment_of_hack) - sizeof(T)
+            , sizeof(T)>::value   };
+};
+
+//This is not standard, but should work with all compilers
+union max_align
+{
+   char        char_;
+   short       short_;
+   int         int_;
+   long        long_;
+   #ifdef BOOST_HAS_LONG_LONG
+   long long   long_long_;
+   #endif
+   float       float_;
+   double      double_;
+   long double long_double_;
+   void *      void_ptr_;
+};
+
+template
+struct remove_reference
+{
+   typedef T type;
+};
+
+template
+struct remove_reference
+{
+   typedef T type;
+};
+
+#ifndef BOOST_NO_RVALUE_REFERENCES
+
+template
+struct remove_reference
+{
+   typedef T type;
+};
+
+#else
+
+template
+struct remove_reference< ::boost::rv >
+{
+   typedef T type;
+};
+
+#endif
+
+template
+struct is_reference
+{
+   enum {  value = false   };
+};
+
+template
+struct is_reference
+{
+   enum {  value = true   };
+};
+
+template
+struct is_pointer
+{
+   enum {  value = false   };
+};
+
+template
+struct is_pointer
+{
+   enum {  value = true   };
+};
+
+template 
+struct add_reference
+{
+    typedef T& type;
+};
+
+template
+struct add_reference
+{
+    typedef T& type;
+};
+
+template<>
+struct add_reference
+{
+    typedef nat &type;
+};
+
+template<>
+struct add_reference
+{
+    typedef const nat &type;
+};
+
+template 
+struct add_const_reference
+{  typedef const T &type;   };
+
+template 
+struct add_const_reference
+{  typedef T& type;   };
+
+template 
+struct is_same
+{
+   typedef char yes_type;
+   struct no_type
+   {
+      char padding[8];
+   };
+
+   template 
+   static yes_type is_same_tester(V*, V*);
+   static no_type is_same_tester(...);
+
+   static T *t;
+   static U *u;
+
+   static const bool value = sizeof(yes_type) == sizeof(is_same_tester(t,u));
+};
+
+template
+struct remove_const
+{
+   typedef T type;
+};
+
+template
+struct remove_const< const T>
+{
+   typedef T type;
+};
+
+template
+struct remove_ref_const
+{
+   typedef typename remove_const< typename remove_reference::type >::type type;
+};
+
+} // namespace container_detail
+}  //namespace container { 
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
diff --git a/src/third_party/boost/boost/container/detail/utilities.hpp b/src/third_party/boost/boost/container/detail/utilities.hpp
new file mode 100644
index 00000000000..ee0fe993b25
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/utilities.hpp
@@ -0,0 +1,271 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
+#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
+
+#include "config_begin.hpp"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace container {
+namespace container_detail {
+
+template
+const T &max_value(const T &a, const T &b)
+{  return a > b ? a : b;   }
+
+template
+const T &min_value(const T &a, const T &b)
+{  return a < b ? a : b;   }
+
+template 
+SizeType
+   get_next_capacity(const SizeType max_size
+                    ,const SizeType capacity
+                    ,const SizeType n)
+{
+//   if (n > max_size - capacity)
+//      throw std::length_error("get_next_capacity");
+
+   const SizeType m3 = max_size/3;
+
+   if (capacity < m3)
+      return capacity + max_value(3*(capacity+1)/5, n);
+
+   if (capacity < m3*2)
+      return capacity + max_value((capacity+1)/2, n);
+
+   return max_size;
+}
+
+template 
+inline T* to_raw_pointer(T* p)
+{  return p; }
+
+template 
+inline typename Pointer::element_type*
+   to_raw_pointer(const Pointer &p)
+{  return boost::container::container_detail::to_raw_pointer(p.operator->());  }
+
+//!To avoid ADL problems with swap
+template 
+inline void do_swap(T& x, T& y)
+{
+   using std::swap;
+   swap(x, y);
+}
+
+template
+inline void swap_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
+   BOOST_CONTAINER_NOEXCEPT
+{}
+
+template
+inline void swap_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
+{  container_detail::do_swap(l, r);   }
+
+template
+inline void assign_alloc(AllocatorType &, const AllocatorType &, container_detail::false_type)
+   BOOST_CONTAINER_NOEXCEPT
+{}
+
+template
+inline void assign_alloc(AllocatorType &l, const AllocatorType &r, container_detail::true_type)
+{  l = r;   }
+
+template
+inline void move_alloc(AllocatorType &, AllocatorType &, container_detail::false_type)
+   BOOST_CONTAINER_NOEXCEPT
+{}
+
+template
+inline void move_alloc(AllocatorType &l, AllocatorType &r, container_detail::true_type)
+{  l = ::boost::move(r);   }
+
+//Rounds "orig_size" by excess to round_to bytes
+template
+inline SizeType get_rounded_size(SizeType orig_size, SizeType round_to)
+{
+   return ((orig_size-1)/round_to+1)*round_to;
+}
+
+template 
+struct ct_rounded_size
+{
+   enum { value = ((OrigSize-1)/RoundTo+1)*RoundTo };
+};
+/*
+template 
+struct __rw_is_enum
+{
+   struct _C_no { };
+   struct _C_yes { int _C_dummy [2]; };
+
+   struct _C_indirect {
+   // prevent classes with user-defined conversions from matching
+
+   // use double to prevent float->int gcc conversion warnings
+   _C_indirect (double);
+};
+
+// nested struct gets rid of bogus gcc errors
+struct _C_nest {
+   // supply first argument to prevent HP aCC warnings
+   static _C_no _C_is (int, ...);
+   static _C_yes _C_is (int, _C_indirect);
+
+   static _TypeT _C_make_T ();
+};
+
+enum {
+   _C_val = sizeof (_C_yes) == sizeof (_C_nest::_C_is (0, _C_nest::_C_make_T ()))
+   && !::boost::is_fundamental<_TypeT>::value
+};
+
+}; 
+*/
+
+template
+struct move_const_ref_type
+   : if_c
+//   < ::boost::is_fundamental::value || ::boost::is_pointer::value || ::boost::is_member_pointer::value || ::boost::is_enum::value
+   < !::boost::is_class::value
+   ,const T &
+   ,BOOST_CATCH_CONST_RLVALUE(T)
+   >
+{};
+
+}  //namespace container_detail {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_move_alloc
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! Effects:
+//!   \code
+//!   for (; first != last; ++result, ++first)
+//!      allocator_traits::construct(a, &*result, boost::move(*first));
+//!   \endcode
+//!
+//! Returns: result
+template
+    // F models ForwardIterator
+F uninitialized_move_alloc(A &a, I f, I l, F r)
+{
+   while (f != l) {
+      allocator_traits::construct(a, container_detail::to_raw_pointer(&*r), boost::move(*f));
+      ++f; ++r;
+   }
+   return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_copy_alloc
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! Effects:
+//!   \code
+//!   for (; first != last; ++result, ++first)
+//!      allocator_traits::construct(a, &*result, *first);
+//!   \endcode
+//!
+//! Returns: result
+template
+    // F models ForwardIterator
+F uninitialized_copy_alloc(A &a, I f, I l, F r)
+{
+   while (f != l) {
+      allocator_traits::construct(a, container_detail::to_raw_pointer(&*r), *f);
+      ++f; ++r;
+   }
+   return r;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_copy_alloc
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! Effects:
+//!   \code
+//!   for (; first != last; ++result, ++first)
+//!      allocator_traits::construct(a, &*result, *first);
+//!   \endcode
+//!
+//! Returns: result
+template
+    
+void uninitialized_fill_alloc(A &a, F f, F l, const T &t)
+{
+   while (f != l) {
+      allocator_traits::construct(a, container_detail::to_raw_pointer(&*f), t);
+      ++f;
+   }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            uninitialized_copy_or_move_alloc
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template
+   // F models ForwardIterator
+F uninitialized_copy_or_move_alloc
+   (A &a, I f, I l, F r
+   ,typename boost::container::container_detail::enable_if
+      < boost::move_detail::is_move_iterator >::type* = 0)
+{
+   return ::boost::container::uninitialized_move_alloc(a, f, l, r);
+}
+
+template
+   // F models ForwardIterator
+F uninitialized_copy_or_move_alloc
+   (A &a, I f, I l, F r
+   ,typename boost::container::container_detail::disable_if
+      < boost::move_detail::is_move_iterator >::type* = 0)
+{
+   return ::boost::container::uninitialized_copy_alloc(a, f, l, r);
+}
+
+}  //namespace container {
+}  //namespace boost {
+
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_UTILITIES_HPP
diff --git a/src/third_party/boost/boost/container/detail/value_init.hpp b/src/third_party/boost/boost/container/detail/value_init.hpp
new file mode 100644
index 00000000000..afbc9c1e34d
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/value_init.hpp
@@ -0,0 +1,45 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011.
+//
+// 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
+#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+
+namespace boost {
+namespace container { 
+namespace container_detail {
+
+template
+struct value_init
+{
+   value_init()
+      : m_t()
+   {}
+
+   operator T &() { return m_t; }
+
+   T m_t;
+};
+
+}  //namespace container_detail { 
+}  //namespace container { 
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
diff --git a/src/third_party/boost/boost/container/detail/variadic_templates_tools.hpp b/src/third_party/boost/boost/container/detail/variadic_templates_tools.hpp
new file mode 100644
index 00000000000..f21f972ab12
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/variadic_templates_tools.hpp
@@ -0,0 +1,153 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
+#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include "config_begin.hpp"
+#include 
+#include 
+#include    //std::size_t
+
+namespace boost {
+namespace container { 
+namespace container_detail {
+
+template
+class tuple;
+
+template<> class tuple<>
+{};
+
+template
+class tuple
+   : private tuple
+{
+   typedef tuple inherited;
+
+   public:
+   tuple() { }
+
+   // implicit copy-constructor is okay
+   // Construct tuple from separate arguments.
+   tuple(typename add_const_reference::type v,
+         typename add_const_reference::type... vtail)
+   : inherited(vtail...), m_head(v)
+   {}
+
+   // Construct tuple from another tuple.
+   template
+   tuple(const tuple& other)
+      : m_head(other.head()), inherited(other.tail())
+   {}
+
+   template
+   tuple& operator=(const tuple& other)
+   {
+      m_head = other.head();
+      tail() = other.tail();
+      return this;
+   }
+
+   typename add_reference::type head()             {  return m_head; }
+   typename add_reference::type head() const {  return m_head; }
+
+   inherited& tail()             { return *this; }
+   const inherited& tail() const { return *this; }
+
+   protected:
+   Head m_head;
+};
+
+
+template
+tuple tie_forward(Values&&... values)
+{ return tuple(values...); }
+
+template
+struct tuple_element;
+
+template
+struct tuple_element >
+{
+   typedef typename tuple_element >::type type;
+};
+
+template
+struct tuple_element<0, tuple >
+{
+   typedef Head type;
+};
+
+template
+class get_impl;
+
+template
+class get_impl >
+{
+   typedef typename tuple_element >::type   Element;
+   typedef get_impl >                       Next;
+
+   public:
+   typedef typename add_reference::type                  type;
+   typedef typename add_const_reference::type            const_type;
+   static type get(tuple& t)              { return Next::get(t.tail()); }
+   static const_type get(const tuple& t)  { return Next::get(t.tail()); }
+};
+
+template
+class get_impl<0, tuple >
+{
+   public:
+   typedef typename add_reference::type         type;
+   typedef typename add_const_reference::type   const_type;
+   static type       get(tuple& t)      { return t.head(); }
+   static const_type get(const tuple& t){ return t.head(); }
+};
+
+template
+typename get_impl >::type get(tuple& t)
+{  return get_impl >::get(t);  }
+
+template
+typename get_impl >::const_type get(const tuple& t)
+{  return get_impl >::get(t);  }
+
+////////////////////////////////////////////////////
+// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
+// be used to "unpack" into comma-separated values
+// in a function call.
+////////////////////////////////////////////////////
+
+template
+struct index_tuple{};
+
+template >
+struct build_number_seq;
+
+template 
+struct build_number_seq >
+   : build_number_seq >
+{};
+
+template
+struct build_number_seq<0, index_tuple >
+{  typedef index_tuple type;  };
+
+
+}}}   //namespace boost { namespace container { namespace container_detail {
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
diff --git a/src/third_party/boost/boost/container/detail/version_type.hpp b/src/third_party/boost/boost/container/detail/version_type.hpp
new file mode 100644
index 00000000000..46344faca05
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/version_type.hpp
@@ -0,0 +1,92 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+//       This code comes from N1953 document by Howard E. Hinnant
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
+#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
+
+#include "config_begin.hpp"
+
+#include 
+#include 
+
+namespace boost{
+namespace container {
+namespace container_detail {
+
+//using namespace boost;
+
+template 
+struct version_type
+    : public container_detail::integral_constant
+{
+    typedef T type;
+
+    version_type(const version_type&);
+};
+
+namespace impl{
+
+template , typename T::version>::value>
+struct extract_version
+{
+   static const unsigned value = 1;
+};
+
+template 
+struct extract_version
+{
+   static const unsigned value = T::version::value;
+};
+
+template 
+struct has_version
+{
+   private:
+   struct two {char _[2];};
+   template  static two test(...);
+   template  static char test(const typename U::version*);
+   public:
+   static const bool value = sizeof(test(0)) == 1;
+   void dummy(){}
+};
+
+template ::value>
+struct version
+{
+   static const unsigned value = 1;
+};
+
+template 
+struct version
+{
+   static const unsigned value = extract_version::value;
+};
+
+}  //namespace impl
+
+template 
+struct version
+   : public container_detail::integral_constant::value>
+{
+};
+
+}  //namespace container_detail {
+}  //namespace container {
+}  //namespace boost{
+
+#include "config_end.hpp"
+
+#endif   //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
diff --git a/src/third_party/boost/boost/container/detail/workaround.hpp b/src/third_party/boost/boost/container/detail/workaround.hpp
new file mode 100644
index 00000000000..45ab2f2c4da
--- /dev/null
+++ b/src/third_party/boost/boost/container/detail/workaround.hpp
@@ -0,0 +1,31 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
+#define BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
+
+#include 
+
+#if    !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)\
+    && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL)
+   #define BOOST_CONTAINER_PERFECT_FORWARDING
+#endif
+
+#if defined(BOOST_NO_NOEXCEPT)
+   #define BOOST_CONTAINER_NOEXCEPT
+   #define BOOST_CONTAINER_NOEXCEPT_IF(x)
+#else
+   #define BOOST_CONTAINER_NOEXCEPT    noexcept
+   #define BOOST_CONTAINER_NOEXCEPT_IF(x) noexcept(x)
+#endif
+
+#include 
+
+#endif   //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
diff --git a/src/third_party/boost/boost/container/flat_map.hpp b/src/third_party/boost/boost/container/flat_map.hpp
new file mode 100644
index 00000000000..2d4515b4a48
--- /dev/null
+++ b/src/third_party/boost/boost/container/flat_map.hpp
@@ -0,0 +1,1457 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_FLAT_MAP_HPP
+#define BOOST_CONTAINER_FLAT_MAP_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+// Forward declarations of operators == and <, needed for friend declarations.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >, class A = std::allocator >
+#else
+template 
+#endif
+class flat_map;
+
+template 
+inline bool operator==(const flat_map& x, 
+                       const flat_map& y);
+
+template 
+inline bool operator<(const flat_map& x, 
+                      const flat_map& y);
+
+namespace container_detail{
+
+template
+static D &force(const S &s)
+{  return *const_cast((reinterpret_cast(&s))); }
+
+template
+static D force_copy(S s)
+{
+   D *vp = reinterpret_cast(&s);
+   return D(*vp);
+}
+
+}  //namespace container_detail{
+
+
+/// @endcond
+
+//! A flat_map is a kind of associative container that supports unique keys (contains at
+//! most one of each key value) and provides for fast retrieval of values of another 
+//! type T based on the keys. The flat_map class supports random-access iterators.
+//! 
+//! A flat_map satisfies all of the requirements of a container and of a reversible 
+//! container and of an associative container. A flat_map also provides 
+//! most operations described for unique keys. For a 
+//! flat_map the key_type is Key and the value_type is std::pair
+//! (unlike std::map which value_type is std::pair<const Key, T>).
+//!
+//! Pred is the ordering function for Keys (e.g. std::less).
+//!
+//! A is the allocator to allocate the value_types
+//! (e.g. allocator< std::pair >).
+//! 
+//! flat_map is similar to std::map but it's implemented like an ordered vector.
+//! This means that inserting a new element into a flat_map invalidates
+//! previous iterators and references
+//!
+//! Erasing an element of a flat_map invalidates iterators and references 
+//! pointing to elements that come after (their keys are bigger) the erased element.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >, class A = std::allocator >
+#else
+template 
+#endif
+class flat_map 
+{
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(flat_map)
+   //This is the tree that we should store if pair was movable
+   typedef container_detail::flat_tree, 
+                           container_detail::select1st< std::pair >, 
+                           Pred, 
+                           A> tree_t;
+
+   //This is the real tree stored here. It's based on a movable pair
+   typedef container_detail::flat_tree, 
+                           container_detail::select1st >, 
+                           Pred, 
+                           typename allocator_traits::template portable_rebind_alloc
+                               >::type> impl_tree_t;
+   impl_tree_t m_flat_tree;  // flat tree representing flat_map
+
+   typedef typename impl_tree_t::value_type              impl_value_type;
+   typedef typename impl_tree_t::pointer                 impl_pointer;
+   typedef typename impl_tree_t::const_pointer           impl_const_pointer;
+   typedef typename impl_tree_t::reference               impl_reference;
+   typedef typename impl_tree_t::const_reference         impl_const_reference;
+   typedef typename impl_tree_t::value_compare           impl_value_compare;
+   typedef typename impl_tree_t::iterator                impl_iterator;
+   typedef typename impl_tree_t::const_iterator          impl_const_iterator;
+   typedef typename impl_tree_t::reverse_iterator        impl_reverse_iterator;
+   typedef typename impl_tree_t::const_reverse_iterator  impl_const_reverse_iterator;
+   typedef typename impl_tree_t::allocator_type          impl_allocator_type;
+   typedef allocator_traits                           allocator_traits_type;
+
+
+
+   /// @endcond
+
+   public:
+
+   // typedefs:
+   typedef Key                                              key_type;
+   typedef T                                                mapped_type;
+   typedef typename std::pair        value_type;
+   typedef typename allocator_traits_type::pointer          pointer;
+   typedef typename allocator_traits_type::const_pointer    const_pointer;
+   typedef typename allocator_traits_type::reference        reference;
+   typedef typename allocator_traits_type::const_reference  const_reference;
+   typedef typename impl_tree_t::size_type                  size_type;
+   typedef typename impl_tree_t::difference_type            difference_type;
+
+   typedef container_detail::flat_tree_value_compare
+      < Pred
+      , container_detail::select1st< std::pair >
+      , std::pair >                                 value_compare;
+   typedef Pred                                             key_compare;
+   typedef typename container_detail::
+      get_flat_tree_iterators::iterator            iterator;
+   typedef typename container_detail::
+      get_flat_tree_iterators::const_iterator      const_iterator;
+   typedef typename container_detail::
+      get_flat_tree_iterators
+         ::reverse_iterator                        reverse_iterator;
+   typedef typename container_detail::
+      get_flat_tree_iterators
+         ::const_reverse_iterator                  const_reverse_iterator;
+   typedef A                                                allocator_type;
+   typedef A                                                stored_allocator_type;
+
+   public:
+   //! Effects: Default constructs an empty flat_map.
+   //! 
+   //! Complexity: Constant.
+   flat_map() 
+      : m_flat_tree() {}
+
+   //! Effects: Constructs an empty flat_map using the specified
+   //! comparison object and allocator.
+   //! 
+   //! Complexity: Constant.
+   explicit flat_map(const Pred& comp, const allocator_type& a = allocator_type()) 
+      : m_flat_tree(comp, container_detail::force(a)) {}
+
+   //! Effects: Constructs an empty flat_map using the specified comparison object and 
+   //! allocator, and inserts elements from the range [first ,last ).
+   //! 
+   //! Complexity: Linear in N if the range [first ,last ) is already sorted using 
+   //! comp and otherwise N logN, where N is last - first.
+   template 
+   flat_map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
+         const allocator_type& a = allocator_type())
+      : m_flat_tree(comp, container_detail::force(a)) 
+      { m_flat_tree.insert_unique(first, last); }
+
+   //! Effects: Constructs an empty flat_map using the specified comparison object and 
+   //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! Requires: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //! 
+   //! Complexity: Linear in N.
+   template 
+   flat_map( ordered_unique_range_t, InputIterator first, InputIterator last
+           , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+      : m_flat_tree(ordered_range, first, last, comp, a) 
+   {}
+
+   //! Effects: Copy constructs a flat_map.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_map(const flat_map& x) 
+      : m_flat_tree(x.m_flat_tree) {}
+
+   //! Effects: Move constructs a flat_map.
+   //!   Constructs *this using x's resources.
+   //! 
+   //! Complexity: Construct.
+   //! 
+   //! Postcondition: x is emptied.
+   flat_map(BOOST_RV_REF(flat_map) x) 
+      : m_flat_tree(boost::move(x.m_flat_tree))
+   {}
+
+   //! Effects: Makes *this a copy of x.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_map& operator=(BOOST_COPY_ASSIGN_REF(flat_map) x)
+   {  m_flat_tree = x.m_flat_tree;   return *this;  }
+
+   //! Effects: Move constructs a flat_map.
+   //!   Constructs *this using x's resources.
+   //! 
+   //! Complexity: Construct.
+   //! 
+   //! Postcondition: x is emptied.
+   flat_map& operator=(BOOST_RV_REF(flat_map) mx)
+   {  m_flat_tree = boost::move(mx.m_flat_tree);   return *this;  }
+
+   //! Effects: Returns the comparison object out
+   //!   of which a was constructed.
+   //! 
+   //! Complexity: Constant.
+   key_compare key_comp() const 
+      { return container_detail::force(m_flat_tree.key_comp()); }
+
+   //! Effects: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //! 
+   //! Complexity: Constant.
+   value_compare value_comp() const 
+      { return value_compare(container_detail::force(m_flat_tree.key_comp())); }
+
+   //! Effects: Returns a copy of the Allocator that
+   //!   was passed to the object's constructor.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const 
+      { return container_detail::force(m_flat_tree.get_allocator()); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+      { return container_detail::force(m_flat_tree.get_stored_allocator()); }
+
+   stored_allocator_type &get_stored_allocator()
+      { return container_detail::force(m_flat_tree.get_stored_allocator()); }
+
+   //! Effects: Returns an iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin() 
+      { return container_detail::force_copy(m_flat_tree.begin()); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const 
+      { return container_detail::force(m_flat_tree.begin()); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const 
+      { return container_detail::force(m_flat_tree.cbegin()); }
+
+   //! Effects: Returns an iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end() 
+      { return container_detail::force_copy(m_flat_tree.end()); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const 
+      { return container_detail::force(m_flat_tree.end()); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const 
+      { return container_detail::force(m_flat_tree.cend()); }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin() 
+      { return container_detail::force(m_flat_tree.rbegin()); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const 
+      { return container_detail::force(m_flat_tree.rbegin()); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin() const 
+      { return container_detail::force(m_flat_tree.crbegin()); }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend() 
+      { return container_detail::force(m_flat_tree.rend()); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const 
+      { return container_detail::force(m_flat_tree.rend()); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend() const 
+      { return container_detail::force(m_flat_tree.crend()); }
+
+   //! Effects: Returns true if the container contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const 
+      { return m_flat_tree.empty(); }
+
+   //! Effects: Returns the number of the elements contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const 
+      { return m_flat_tree.size(); }
+
+   //! Effects: Returns the largest possible size of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const 
+      { return m_flat_tree.max_size(); }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Effects: If there is no key equivalent to x in the flat_map, inserts 
+   //!   value_type(x, T()) into the flat_map.
+   //! 
+   //! Returns: A reference to the mapped_type corresponding to x in *this.
+   //! 
+   //! Complexity: Logarithmic.
+   mapped_type &operator[](const key_type& k);
+
+   //! Effects: If there is no key equivalent to x in the flat_map, inserts 
+   //! value_type(move(x), T()) into the flat_map (the key is move-constructed)
+   //! 
+   //! Returns: A reference to the mapped_type corresponding to x in *this.
+   //! 
+   //! Complexity: Logarithmic.
+   mapped_type &operator[](key_type &&k) ;
+
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, priv_subscript)
+   #endif
+
+   //! Returns: A reference to the element whose key is equivalent to x.
+   //! Throws: An exception object of type out_of_range if no such element is present.
+   //! Complexity: logarithmic.
+   T& at(const key_type& k)
+   {
+      iterator i = this->find(k);
+      if(i == this->end()){
+         throw std::out_of_range("key not found");
+      }
+      return i->second;
+   }
+
+   //! Returns: A reference to the element whose key is equivalent to x.
+   //! Throws: An exception object of type out_of_range if no such element is present.
+   //! Complexity: logarithmic.
+   const T& at(const key_type& k) const
+   {
+      const_iterator i = this->find(k);
+      if(i == this->end()){
+         throw std::out_of_range("key not found");
+      }
+      return i->second;
+   }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(flat_map& x)
+   { m_flat_tree.swap(x.m_flat_tree); }
+
+   //! Effects: Inserts x if and only if there is no element in the container 
+   //!   with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   std::pair insert(const value_type& x) 
+      { return container_detail::force >(
+         m_flat_tree.insert_unique(container_detail::force(x))); }
+
+   //! Effects: Inserts a new value_type move constructed from the pair if and
+   //! only if there is no element in the container with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   std::pair insert(BOOST_RV_REF(value_type) x) 
+   {  return container_detail::force >(
+      m_flat_tree.insert_unique(boost::move(container_detail::force(x)))); }
+
+   //! Effects: Inserts a new value_type move constructed from the pair if and
+   //! only if there is no element in the container with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   std::pair insert(BOOST_RV_REF(impl_value_type) x) 
+   {
+      return container_detail::force >
+      (m_flat_tree.insert_unique(boost::move(x)));
+   }
+
+   //! Effects: Inserts a copy of x in the container if and only if there is 
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator position, const value_type& x)
+      { return container_detail::force_copy(
+         m_flat_tree.insert_unique(container_detail::force(position), container_detail::force(x))); }
+
+   //! Effects: Inserts an element move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
+      { return container_detail::force_copy
+         (m_flat_tree.insert_unique(container_detail::force(position), boost::move(container_detail::force(x)))); }
+
+   //! Effects: Inserts an element move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x)
+   {
+      return container_detail::force_copy(
+         m_flat_tree.insert_unique(container_detail::force(position), boost::move(x)));
+   }
+
+   //! Requires: first, last are not iterators into *this.
+   //!
+   //! Effects: inserts each element from the range [first,last) if and only 
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! Complexity: At most N log(size()+N) (N is the distance from first to last)
+   //!   search time plus N*size() insertion time.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   void insert(InputIterator first, InputIterator last) 
+   {  m_flat_tree.insert_unique(first, last);  }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object x of type T constructed with
+   //!   std::forward(args)... if and only if there is no element in the container 
+   //!   with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   std::pair emplace(Args&&... args)
+   {  return container_detail::force_copy< std::pair >(m_flat_tree.emplace_unique(boost::forward(args)...)); }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the container if and only if there is 
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   iterator emplace_hint(const_iterator hint, Args&&... args)
+   {  return container_detail::force_copy
+      (m_flat_tree.emplace_hint_unique(container_detail::force(hint), boost::forward(args)...)); }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                                 \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))            \
+   {  return container_detail::force_copy< std::pair >                             \
+         (m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); }    \
+                                                                                                   \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace_hint(const_iterator hint                                                       \
+                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              \
+   {  return container_detail::force_copy(m_flat_tree.emplace_hint_unique                \
+            (container_detail::force(hint)                                    \
+               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); }                 \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Erases the element pointed to by position.
+   //!
+   //! Returns: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists, 
+   //!   returns end().
+   //!
+   //! Complexity: Linear to the elements with keys bigger than position
+   //!
+   //! Note: Invalidates elements with keys
+   //!   not less than the erased element.
+   iterator erase(const_iterator position) 
+      { return container_detail::force_copy(m_flat_tree.erase(container_detail::force(position))); }
+
+   //! Effects: Erases all elements in the container with key equivalent to x.
+   //!
+   //! Returns: Returns the number of erased elements.
+   //!
+   //! Complexity: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   size_type erase(const key_type& x) 
+      { return m_flat_tree.erase(x); }
+
+   //! Effects: Erases all the elements in the range [first, last).
+   //!
+   //! Returns: Returns last.
+   //!
+   //! Complexity: size()*N where N is the distance from first to last.
+   //!
+   //! Complexity: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   iterator erase(const_iterator first, const_iterator last)
+      { return container_detail::force_copy
+         (m_flat_tree.erase(container_detail::force(first), container_detail::force(last))); }
+
+   //! Effects: erase(a.begin(),a.end()).
+   //!
+   //! Postcondition: size() == 0.
+   //!
+   //! Complexity: linear in size().
+   void clear() 
+      { m_flat_tree.clear(); }
+
+   //! Effects: Tries to deallocate the excess of memory created
+   //    with previous allocations. The size of the vector is unchanged
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to size().
+   void shrink_to_fit()
+      { m_flat_tree.shrink_to_fit(); }
+
+   //! Returns: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   iterator find(const key_type& x) 
+      { return container_detail::force_copy(m_flat_tree.find(x)); }
+
+   //! Returns: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.s
+   const_iterator find(const key_type& x) const 
+      { return container_detail::force(m_flat_tree.find(x)); }
+
+   //! Returns: The number of elements with key equivalent to x.
+   //!
+   //! Complexity: log(size())+count(k)
+   size_type count(const key_type& x) const 
+      {  return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1;  }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator lower_bound(const key_type& x) 
+      {  return container_detail::force_copy(m_flat_tree.lower_bound(x)); }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator lower_bound(const key_type& x) const 
+      {  return container_detail::force(m_flat_tree.lower_bound(x)); }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator upper_bound(const key_type& x) 
+      {  return container_detail::force_copy(m_flat_tree.upper_bound(x)); }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator upper_bound(const key_type& x) const 
+      {  return container_detail::force(m_flat_tree.upper_bound(x)); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair equal_range(const key_type& x) 
+      {  return container_detail::force >(m_flat_tree.equal_range(x)); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair equal_range(const key_type& x) const 
+      {  return container_detail::force >(m_flat_tree.equal_range(x)); }
+
+   //! Effects: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type capacity() const           
+      { return m_flat_tree.capacity(); }
+
+   //! Effects: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //! 
+   //! Throws: If memory allocation allocation throws or T's copy constructor throws.
+   //!
+   //! Note: If capacity() is less than "count", iterators and references to
+   //!   to values might be invalidated.
+   void reserve(size_type count)       
+      { m_flat_tree.reserve(count);   }
+
+   /// @cond
+   template 
+   friend bool operator== (const flat_map&,
+                           const flat_map&);
+   template 
+   friend bool operator< (const flat_map&,
+                           const flat_map&);
+
+   private:
+   mapped_type &priv_subscript(const key_type& k)
+   {
+      iterator i = lower_bound(k);
+      // i->first is greater than or equivalent to k.
+      if (i == end() || key_comp()(k, (*i).first)){
+         container_detail::value_init m;
+         i = insert(i, impl_value_type(k, ::boost::move(m.m_t)));
+      }
+      return (*i).second;
+   }
+   mapped_type &priv_subscript(BOOST_RV_REF(key_type) mk) 
+   {
+      key_type &k = mk;
+      iterator i = lower_bound(k);
+      // i->first is greater than or equivalent to k.
+      if (i == end() || key_comp()(k, (*i).first)){
+         container_detail::value_init m;
+         i = insert(i, impl_value_type(boost::move(k), ::boost::move(m.m_t)));
+      }
+      return (*i).second;
+   }
+   /// @endcond
+};
+
+template 
+inline bool operator==(const flat_map& x, 
+                       const flat_map& y) 
+   {  return x.m_flat_tree == y.m_flat_tree;  }
+
+template 
+inline bool operator<(const flat_map& x, 
+                      const flat_map& y) 
+   {  return x.m_flat_tree < y.m_flat_tree;   }
+
+template 
+inline bool operator!=(const flat_map& x, 
+                       const flat_map& y) 
+   {  return !(x == y); }
+
+template 
+inline bool operator>(const flat_map& x, 
+                      const flat_map& y) 
+   {  return y < x;  }
+
+template 
+inline bool operator<=(const flat_map& x, 
+                       const flat_map& y) 
+   {  return !(y < x);  }
+
+template 
+inline bool operator>=(const flat_map& x, 
+                       const flat_map& y) 
+   {  return !(x < y);  }
+
+template 
+inline void swap(flat_map& x, 
+                 flat_map& y) 
+   {  x.swap(y);  }
+
+/// @cond
+
+}  //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value && has_trivial_destructor::value;
+};
+*/
+namespace container {
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >, class A = std::allocator >
+#else
+template 
+#endif
+class flat_multimap;
+
+template 
+inline bool operator==(const flat_multimap& x, 
+                       const flat_multimap& y);
+
+template 
+inline bool operator<(const flat_multimap& x, 
+                      const flat_multimap& y);
+/// @endcond
+
+//! A flat_multimap is a kind of associative container that supports equivalent keys 
+//! (possibly containing multiple copies of the same key value) and provides for 
+//! fast retrieval of values of another type T based on the keys. The flat_multimap 
+//! class supports random-access iterators.
+//! 
+//! A flat_multimap satisfies all of the requirements of a container and of a reversible 
+//! container and of an associative container. For a 
+//! flat_multimap the key_type is Key and the value_type is std::pair
+//! (unlike std::multimap which value_type is std::pair<const Key, T>).
+//!
+//! Pred is the ordering function for Keys (e.g. std::less).
+//!
+//! A is the allocator to allocate the value_types
+//! (e.g. allocator< std::pair >).
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >, class A = std::allocator >
+#else
+template 
+#endif
+class flat_multimap 
+{
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(flat_multimap)
+   typedef container_detail::flat_tree, 
+                           container_detail::select1st< std::pair >, 
+                           Pred, 
+                           A> tree_t;
+   //This is the real tree stored here. It's based on a movable pair
+   typedef container_detail::flat_tree, 
+                           container_detail::select1st >, 
+                           Pred, 
+                           typename allocator_traits::template portable_rebind_alloc
+                               >::type> impl_tree_t;
+   impl_tree_t m_flat_tree;  // flat tree representing flat_map
+
+   typedef typename impl_tree_t::value_type              impl_value_type;
+   typedef typename impl_tree_t::pointer                 impl_pointer;
+   typedef typename impl_tree_t::const_pointer           impl_const_pointer;
+   typedef typename impl_tree_t::reference               impl_reference;
+   typedef typename impl_tree_t::const_reference         impl_const_reference;
+   typedef typename impl_tree_t::value_compare           impl_value_compare;
+   typedef typename impl_tree_t::iterator                impl_iterator;
+   typedef typename impl_tree_t::const_iterator          impl_const_iterator;
+   typedef typename impl_tree_t::reverse_iterator        impl_reverse_iterator;
+   typedef typename impl_tree_t::const_reverse_iterator  impl_const_reverse_iterator;
+   typedef typename impl_tree_t::allocator_type          impl_allocator_type;
+   typedef allocator_traits                           allocator_traits_type;
+
+   /// @endcond
+
+   public:
+
+   // typedefs:
+   typedef Key                                              key_type;
+   typedef T                                                mapped_type;
+   typedef Pred                                             key_compare;
+   typedef typename std::pair        value_type;
+   typedef typename allocator_traits_type::pointer          pointer;
+   typedef typename allocator_traits_type::const_pointer    const_pointer;
+   typedef typename allocator_traits_type::reference        reference;
+   typedef typename allocator_traits_type::const_reference  const_reference;
+   typedef typename impl_tree_t::size_type                  size_type;
+   typedef typename impl_tree_t::difference_type            difference_type;
+   typedef container_detail::flat_tree_value_compare
+      < Pred
+      , container_detail::select1st< std::pair >
+      , std::pair >                                 value_compare;
+
+   typedef typename container_detail::
+      get_flat_tree_iterators::iterator            iterator;
+   typedef typename container_detail::
+      get_flat_tree_iterators::const_iterator      const_iterator;
+   typedef typename container_detail::
+      get_flat_tree_iterators
+         ::reverse_iterator                        reverse_iterator;
+   typedef typename container_detail::
+      get_flat_tree_iterators
+         ::const_reverse_iterator                  const_reverse_iterator;
+   typedef A                                                allocator_type;
+   //Non-standard extension
+   typedef A                                                stored_allocator_type;
+
+   //! Effects: Default constructs an empty flat_map.
+   //! 
+   //! Complexity: Constant.
+   flat_multimap() 
+      : m_flat_tree() {}
+
+   //! Effects: Constructs an empty flat_multimap using the specified comparison
+   //!   object and allocator.
+   //! 
+   //! Complexity: Constant.
+   explicit flat_multimap(const Pred& comp,
+                          const allocator_type& a = allocator_type())
+      : m_flat_tree(comp, container_detail::force(a)) { }
+
+   //! Effects: Constructs an empty flat_multimap using the specified comparison object
+   //!   and allocator, and inserts elements from the range [first ,last ).
+   //! 
+   //! Complexity: Linear in N if the range [first ,last ) is already sorted using 
+   //! comp and otherwise N logN, where N is last - first.
+   template 
+   flat_multimap(InputIterator first, InputIterator last,
+            const Pred& comp        = Pred(),
+            const allocator_type& a = allocator_type())
+      : m_flat_tree(comp, container_detail::force(a)) 
+      { m_flat_tree.insert_equal(first, last); }
+
+   //! Effects: Constructs an empty flat_multimap using the specified comparison object and 
+   //! allocator, and inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! Requires: [first ,last) must be ordered according to the predicate.
+   //! 
+   //! Complexity: Linear in N.
+   template 
+   flat_multimap(ordered_range_t, InputIterator first, InputIterator last,
+            const Pred& comp        = Pred(),
+            const allocator_type& a = allocator_type())
+      : m_flat_tree(ordered_range, first, last, comp, a) 
+   {}
+
+   //! Effects: Copy constructs a flat_multimap.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_multimap(const flat_multimap& x) 
+      : m_flat_tree(x.m_flat_tree) { }
+
+   //! Effects: Move constructs a flat_multimap. Constructs *this using x's resources.
+   //! 
+   //! Complexity: Construct.
+   //! 
+   //! Postcondition: x is emptied.
+   flat_multimap(BOOST_RV_REF(flat_multimap) x) 
+      : m_flat_tree(boost::move(x.m_flat_tree))
+   { }
+
+   //! Effects: Makes *this a copy of x.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_multimap& operator=(BOOST_COPY_ASSIGN_REF(flat_multimap) x) 
+      {  m_flat_tree = x.m_flat_tree;   return *this;  }
+
+   //! Effects: this->swap(x.get()).
+   //! 
+   //! Complexity: Constant.
+   flat_multimap& operator=(BOOST_RV_REF(flat_multimap) mx) 
+      {  m_flat_tree = boost::move(mx.m_flat_tree);   return *this;  }
+
+   //! Effects: Returns the comparison object out
+   //!   of which a was constructed.
+   //! 
+   //! Complexity: Constant.
+   key_compare key_comp() const 
+      { return container_detail::force(m_flat_tree.key_comp()); }
+
+   //! Effects: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //! 
+   //! Complexity: Constant.
+   value_compare value_comp() const 
+      { return value_compare(container_detail::force(m_flat_tree.key_comp())); }
+
+   //! Effects: Returns a copy of the Allocator that
+   //!   was passed to the object's constructor.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const 
+      { return container_detail::force(m_flat_tree.get_allocator()); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+      { return container_detail::force(m_flat_tree.get_stored_allocator()); }
+
+   stored_allocator_type &get_stored_allocator()
+      { return container_detail::force(m_flat_tree.get_stored_allocator()); }
+
+   //! Effects: Returns an iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin() 
+      { return container_detail::force_copy(m_flat_tree.begin()); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const 
+      { return container_detail::force(m_flat_tree.begin()); }
+
+   //! Effects: Returns an iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end() 
+      { return container_detail::force_copy(m_flat_tree.end()); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const 
+      { return container_detail::force(m_flat_tree.end()); }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin() 
+      { return container_detail::force(m_flat_tree.rbegin()); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const 
+      { return container_detail::force(m_flat_tree.rbegin()); }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend() 
+      { return container_detail::force(m_flat_tree.rend()); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const 
+      { return container_detail::force(m_flat_tree.rend()); }
+
+   //! Effects: Returns true if the container contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const 
+      { return m_flat_tree.empty(); }
+
+   //! Effects: Returns the number of the elements contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const 
+      { return m_flat_tree.size(); }
+
+   //! Effects: Returns the largest possible size of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const 
+      { return m_flat_tree.max_size(); }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(flat_multimap& x)
+   { m_flat_tree.swap(x.m_flat_tree); }
+
+   //! Effects: Inserts x and returns the iterator pointing to the
+   //!   newly inserted element. 
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const value_type& x) 
+      { return container_detail::force_copy(m_flat_tree.insert_equal(container_detail::force(x))); }
+
+   //! Effects: Inserts a new value move-constructed from x and returns 
+   //!   the iterator pointing to the newly inserted element. 
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(BOOST_RV_REF(value_type) x) 
+   { return container_detail::force_copy(m_flat_tree.insert_equal(boost::move(x))); }
+
+   //! Effects: Inserts a new value move-constructed from x and returns 
+   //!   the iterator pointing to the newly inserted element. 
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(BOOST_RV_REF(impl_value_type) x) 
+      { return container_detail::force_copy(m_flat_tree.insert_equal(boost::move(x))); }
+
+   //! Effects: Inserts a copy of x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant time if the value
+   //!   is to be inserted before p) plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator position, const value_type& x) 
+      { return container_detail::force_copy
+         (m_flat_tree.insert_equal(container_detail::force(position), container_detail::force(x))); }
+
+   //! Effects: Inserts a value move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant time if the value
+   //!   is to be inserted before p) plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) 
+   {
+      return container_detail::force_copy
+         (m_flat_tree.insert_equal(container_detail::force(position)
+                                  , boost::move(x)));
+   }
+
+   //! Effects: Inserts a value move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant time if the value
+   //!   is to be inserted before p) plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator position, BOOST_RV_REF(impl_value_type) x) 
+   {
+      return container_detail::force_copy(
+         m_flat_tree.insert_equal(container_detail::force(position), boost::move(x)));
+   }
+
+   //! Requires: first, last are not iterators into *this.
+   //!
+   //! Effects: inserts each element from the range [first,last) .
+   //!
+   //! Complexity: At most N log(size()+N) (N is the distance from first to last)
+   //!   search time plus N*size() insertion time.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   void insert(InputIterator first, InputIterator last) 
+      {  m_flat_tree.insert_equal(first, last); }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... and returns the iterator pointing to the
+   //!   newly inserted element. 
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   iterator emplace(Args&&... args)
+   {  return container_detail::force_copy(m_flat_tree.emplace_equal(boost::forward(args)...)); }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant time if the value
+   //!   is to be inserted before p) plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   iterator emplace_hint(const_iterator hint, Args&&... args)
+   {
+      return container_detail::force_copy(m_flat_tree.emplace_hint_equal
+         (container_detail::force(hint), boost::forward(args)...));
+   }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                                 \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                            \
+   {  return container_detail::force_copy(m_flat_tree.emplace_equal                      \
+               (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); }                         \
+                                                                                                   \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace_hint(const_iterator hint                                                       \
+                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              \
+   {  return container_detail::force_copy(m_flat_tree.emplace_hint_equal                 \
+            (container_detail::force(hint)                                    \
+               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); }                 \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Erases the element pointed to by position.
+   //!
+   //! Returns: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists, 
+   //!   returns end().
+   //!
+   //! Complexity: Linear to the elements with keys bigger than position
+   //!
+   //! Note: Invalidates elements with keys
+   //!   not less than the erased element.
+   iterator erase(const_iterator position) 
+      { return container_detail::force_copy(m_flat_tree.erase(container_detail::force(position))); }
+
+   //! Effects: Erases all elements in the container with key equivalent to x.
+   //!
+   //! Returns: Returns the number of erased elements.
+   //!
+   //! Complexity: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   size_type erase(const key_type& x) 
+      { return m_flat_tree.erase(x); }
+
+   //! Effects: Erases all the elements in the range [first, last).
+   //!
+   //! Returns: Returns last.
+   //!
+   //! Complexity: size()*N where N is the distance from first to last.
+   //!
+   //! Complexity: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   iterator erase(const_iterator first, const_iterator last)
+      { return container_detail::force_copy
+         (m_flat_tree.erase(container_detail::force(first), container_detail::force(last))); }
+
+   //! Effects: erase(a.begin(),a.end()).
+   //!
+   //! Postcondition: size() == 0.
+   //!
+   //! Complexity: linear in size().
+   void clear() 
+      { m_flat_tree.clear(); }
+
+   //! Effects: Tries to deallocate the excess of memory created
+   //    with previous allocations. The size of the vector is unchanged
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to size().
+   void shrink_to_fit()
+      { m_flat_tree.shrink_to_fit(); }
+
+   //! Returns: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   iterator find(const key_type& x)
+      { return container_detail::force_copy(m_flat_tree.find(x)); }
+
+   //! Returns: An const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   const_iterator find(const key_type& x) const 
+      { return container_detail::force(m_flat_tree.find(x)); }
+
+   //! Returns: The number of elements with key equivalent to x.
+   //!
+   //! Complexity: log(size())+count(k)
+   size_type count(const key_type& x) const 
+      { return m_flat_tree.count(x); }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator lower_bound(const key_type& x) 
+      {return container_detail::force_copy(m_flat_tree.lower_bound(x)); }
+
+   //! Returns: A const iterator pointing to the first element with key
+   //!   not less than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator lower_bound(const key_type& x) const 
+      {  return container_detail::force(m_flat_tree.lower_bound(x));  }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator upper_bound(const key_type& x) 
+      {return container_detail::force_copy(m_flat_tree.upper_bound(x)); }
+
+   //! Returns: A const iterator pointing to the first element with key
+   //!   not less than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator upper_bound(const key_type& x) const 
+      {  return container_detail::force(m_flat_tree.upper_bound(x)); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair equal_range(const key_type& x) 
+      {  return container_detail::force_copy >(m_flat_tree.equal_range(x));   }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair 
+      equal_range(const key_type& x) const 
+      {  return container_detail::force_copy >(m_flat_tree.equal_range(x));   }
+
+   //! Effects: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type capacity() const           
+      { return m_flat_tree.capacity(); }
+
+   //! Effects: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //! 
+   //! Throws: If memory allocation allocation throws or T's copy constructor throws.
+   //!
+   //! Note: If capacity() is less than "count", iterators and references to
+   //!   to values might be invalidated.
+   void reserve(size_type count)       
+      { m_flat_tree.reserve(count);   }
+
+   /// @cond
+   template 
+   friend bool operator== (const flat_multimap& x,
+                           const flat_multimap& y);
+
+   template 
+   friend bool operator< (const flat_multimap& x,
+                          const flat_multimap& y);
+   /// @endcond
+};
+
+template 
+inline bool operator==(const flat_multimap& x, 
+                       const flat_multimap& y) 
+   {  return x.m_flat_tree == y.m_flat_tree;  }
+
+template 
+inline bool operator<(const flat_multimap& x, 
+                      const flat_multimap& y) 
+   {  return x.m_flat_tree < y.m_flat_tree;   }
+
+template 
+inline bool operator!=(const flat_multimap& x, 
+                       const flat_multimap& y) 
+   {  return !(x == y);  }
+
+template 
+inline bool operator>(const flat_multimap& x, 
+                      const flat_multimap& y) 
+   {  return y < x;  }
+
+template 
+inline bool operator<=(const flat_multimap& x, 
+                       const flat_multimap& y) 
+   {  return !(y < x);  }
+
+template 
+inline bool operator>=(const flat_multimap& x, 
+                       const flat_multimap& y) 
+   {  return !(x < y);  }
+
+template 
+inline void swap(flat_multimap& x, flat_multimap& y) 
+   {  x.swap(y);  }
+
+}}
+
+/// @cond
+
+namespace boost {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move< boost::container::flat_multimap >
+{
+   static const bool value = has_trivial_destructor::value && has_trivial_destructor::value;
+};
+*/
+}  //namespace boost { 
+
+/// @endcond
+
+#include 
+
+#endif /* BOOST_CONTAINER_FLAT_MAP_HPP */
diff --git a/src/third_party/boost/boost/container/flat_set.hpp b/src/third_party/boost/boost/container/flat_set.hpp
new file mode 100644
index 00000000000..f36730972e3
--- /dev/null
+++ b/src/third_party/boost/boost/container/flat_set.hpp
@@ -0,0 +1,1265 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_FLAT_SET_HPP
+#define BOOST_CONTAINER_FLAT_SET_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+// Forward declarations of operators < and ==, needed for friend declaration.
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template , class A = std::allocator >
+#else
+template 
+#endif
+class flat_set;
+
+template 
+inline bool operator==(const flat_set& x, 
+                       const flat_set& y);
+
+template 
+inline bool operator<(const flat_set& x, 
+                      const flat_set& y);
+/// @endcond
+
+//! flat_set is a Sorted Associative Container that stores objects of type Key. 
+//! flat_set is a Simple Associative Container, meaning that its value type, 
+//! as well as its key type, is Key. It is also a Unique Associative Container, 
+//! meaning that no two elements are the same. 
+//! 
+//! flat_set is similar to std::set but it's implemented like an ordered vector.
+//! This means that inserting a new element into a flat_set invalidates
+//! previous iterators and references
+//!
+//! Erasing an element of a flat_set invalidates iterators and references 
+//! pointing to elements that come after (their keys are bigger) the erased element.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template , class A = std::allocator >
+#else
+template 
+#endif
+class flat_set 
+{
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(flat_set)
+   typedef container_detail::flat_tree, Pred, A> tree_t;
+   tree_t m_flat_tree;  // flat tree representing flat_set
+   typedef typename container_detail::
+      move_const_ref_type::type insert_const_ref_type;
+   /// @endcond
+
+   public:
+
+   // typedefs:
+   typedef typename tree_t::key_type               key_type;
+   typedef typename tree_t::value_type             value_type;
+   typedef typename tree_t::pointer                pointer;
+   typedef typename tree_t::const_pointer          const_pointer;
+   typedef typename tree_t::reference              reference;
+   typedef typename tree_t::const_reference        const_reference;
+   typedef typename tree_t::key_compare            key_compare;
+   typedef typename tree_t::value_compare          value_compare;
+   typedef typename tree_t::iterator               iterator;
+   typedef typename tree_t::const_iterator         const_iterator;
+   typedef typename tree_t::reverse_iterator       reverse_iterator;
+   typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+   typedef typename tree_t::size_type              size_type;
+   typedef typename tree_t::difference_type        difference_type;
+   typedef typename tree_t::allocator_type         allocator_type;
+   typedef typename tree_t::stored_allocator_type  stored_allocator_type;
+
+   //! Effects: Defatuls constructs an empty flat_map.
+   //! 
+   //! Complexity: Constant.
+   explicit flat_set()
+      : m_flat_tree()
+   {}
+
+   //! Effects: Constructs an empty flat_map using the specified
+   //! comparison object and allocator.
+   //! 
+   //! Complexity: Constant.
+   explicit flat_set(const Pred& comp,
+                     const allocator_type& a = allocator_type())
+      : m_flat_tree(comp, a)
+   {}
+
+   //! Effects: Constructs an empty map using the specified comparison object and 
+   //! allocator, and inserts elements from the range [first ,last ).
+   //! 
+   //! Complexity: Linear in N if the range [first ,last ) is already sorted using 
+   //! comp and otherwise N logN, where N is last - first.
+   template 
+   flat_set(InputIterator first, InputIterator last, 
+            const Pred& comp = Pred(),
+            const allocator_type& a = allocator_type())
+      : m_flat_tree(comp, a) 
+      { m_flat_tree.insert_unique(first, last); }
+
+   //! Effects: Constructs an empty flat_set using the specified comparison object and 
+   //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! Requires: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //! 
+   //! Complexity: Linear in N.
+   template 
+   flat_set(ordered_unique_range_t, InputIterator first, InputIterator last, 
+            const Pred& comp = Pred(),
+            const allocator_type& a = allocator_type())
+      : m_flat_tree(ordered_range, first, last, comp, a) 
+   {}
+
+   //! Effects: Copy constructs a map.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_set(const flat_set& x) 
+      : m_flat_tree(x.m_flat_tree) {}
+
+   //! Effects: Move constructs a map. Constructs *this using x's resources.
+   //! 
+   //! Complexity: Construct.
+   //! 
+   //! Postcondition: x is emptied.
+   flat_set(BOOST_RV_REF(flat_set) mx) 
+      : m_flat_tree(boost::move(mx.m_flat_tree))
+   {}
+
+   //! Effects: Makes *this a copy of x.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
+      {  m_flat_tree = x.m_flat_tree;   return *this;  }
+
+   //! Effects: Makes *this a copy of x.
+   //! 
+   //! Complexity: Linear in x.size().
+   flat_set& operator=(BOOST_RV_REF(flat_set) mx)
+   {  m_flat_tree = boost::move(mx.m_flat_tree);   return *this;  }
+
+   //! Effects: Returns the comparison object out
+   //!   of which a was constructed.
+   //! 
+   //! Complexity: Constant.
+   key_compare key_comp() const 
+      { return m_flat_tree.key_comp(); }
+
+   //! Effects: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //! 
+   //! Complexity: Constant.
+   value_compare value_comp() const 
+      { return m_flat_tree.key_comp(); }
+
+   //! Effects: Returns a copy of the Allocator that
+   //!   was passed to the object's constructor.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const 
+      { return m_flat_tree.get_allocator(); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+   {  return m_flat_tree.get_stored_allocator(); }
+
+   stored_allocator_type &get_stored_allocator()
+   {  return m_flat_tree.get_stored_allocator(); }
+
+   //! Effects: Returns an iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin() 
+      { return m_flat_tree.begin(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const 
+      { return m_flat_tree.begin(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const 
+      { return m_flat_tree.cbegin(); }
+
+   //! Effects: Returns an iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end() 
+      { return m_flat_tree.end(); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const 
+      { return m_flat_tree.end(); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const 
+      { return m_flat_tree.cend(); }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin() 
+      { return m_flat_tree.rbegin(); } 
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const 
+      { return m_flat_tree.rbegin(); } 
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin() const 
+      { return m_flat_tree.crbegin(); } 
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend()
+      { return m_flat_tree.rend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const 
+      { return m_flat_tree.rend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend() const 
+      { return m_flat_tree.crend(); }
+
+   //! Effects: Returns true if the container contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const 
+      { return m_flat_tree.empty(); }
+
+   //! Effects: Returns the number of the elements contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const 
+      { return m_flat_tree.size(); }
+
+   //! Effects: Returns the largest possible size of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const 
+      { return m_flat_tree.max_size(); }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(flat_set& x)
+   { m_flat_tree.swap(x.m_flat_tree); }
+
+   //! Effects: Inserts x if and only if there is no element in the container 
+   //!   with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   std::pair insert(insert_const_ref_type x) 
+   {  return priv_insert(x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   std::pair insert(T &x)
+   { return this->insert(const_cast(x)); }
+
+   template
+   std::pair insert(const U &u, typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return priv_insert(u); }
+   #endif
+
+   //! Effects: Inserts a new value_type move constructed from the pair if and
+   //! only if there is no element in the container with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   std::pair insert(BOOST_RV_REF(value_type) x) 
+   {  return m_flat_tree.insert_unique(boost::move(x));  }
+
+   //! Effects: Inserts a copy of x in the container if and only if there is 
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator p, insert_const_ref_type x) 
+   {  return priv_insert(p, x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   iterator insert(const_iterator position, T &x)
+   { return this->insert(position, const_cast(x)); }
+
+   template
+   iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return priv_insert(position, u); }
+   #endif
+
+   //! Effects: Inserts an element move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) 
+   {  return m_flat_tree.insert_unique(position, boost::move(x)); }
+
+   //! Requires: first, last are not iterators into *this.
+   //!
+   //! Effects: inserts each element from the range [first,last) if and only 
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! Complexity: At most N log(size()+N) (N is the distance from first to last)
+   //!   search time plus N*size() insertion time.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   void insert(InputIterator first, InputIterator last) 
+      {  m_flat_tree.insert_unique(first, last);  }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object x of type T constructed with
+   //!   std::forward(args)... if and only if there is no element in the container 
+   //!   with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   std::pair emplace(Args&&... args)
+   {  return m_flat_tree.emplace_unique(boost::forward(args)...); }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the container if and only if there is 
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   iterator emplace_hint(const_iterator hint, Args&&... args)
+   {  return m_flat_tree.emplace_hint_unique(hint, boost::forward(args)...); }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                                 \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))            \
+   {  return m_flat_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }  \
+                                                                                                   \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace_hint(const_iterator hint                                                       \
+                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              \
+   {  return m_flat_tree.emplace_hint_unique                                                       \
+            (hint BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }               \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Erases the element pointed to by position.
+   //!
+   //! Returns: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists, 
+   //!   returns end().
+   //!
+   //! Complexity: Linear to the elements with keys bigger than position
+   //!
+   //! Note: Invalidates elements with keys
+   //!   not less than the erased element.
+   iterator erase(const_iterator position) 
+      {  return m_flat_tree.erase(position); }
+
+   //! Effects: Erases all elements in the container with key equivalent to x.
+   //!
+   //! Returns: Returns the number of erased elements.
+   //!
+   //! Complexity: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   size_type erase(const key_type& x) 
+      {  return m_flat_tree.erase(x); }
+
+   //! Effects: Erases all the elements in the range [first, last).
+   //!
+   //! Returns: Returns last.
+   //!
+   //! Complexity: size()*N where N is the distance from first to last.
+   //!
+   //! Complexity: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   iterator erase(const_iterator first, const_iterator last) 
+      {  return m_flat_tree.erase(first, last);  }
+
+   //! Effects: erase(a.begin(),a.end()).
+   //!
+   //! Postcondition: size() == 0.
+   //!
+   //! Complexity: linear in size().
+   void clear() 
+      { m_flat_tree.clear(); }
+
+   //! Effects: Tries to deallocate the excess of memory created
+   //    with previous allocations. The size of the vector is unchanged
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to size().
+   void shrink_to_fit()
+      { m_flat_tree.shrink_to_fit(); }
+
+   //! Returns: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   iterator find(const key_type& x) 
+      { return m_flat_tree.find(x); }
+
+   //! Returns: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.s
+   const_iterator find(const key_type& x) const 
+      { return m_flat_tree.find(x); }
+
+   //! Returns: The number of elements with key equivalent to x.
+   //!
+   //! Complexity: log(size())+count(k)
+   size_type count(const key_type& x) const 
+      {  return m_flat_tree.find(x) == m_flat_tree.end() ? 0 : 1;  }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator lower_bound(const key_type& x) 
+      {  return m_flat_tree.lower_bound(x); }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator lower_bound(const key_type& x) const 
+      {  return m_flat_tree.lower_bound(x); }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator upper_bound(const key_type& x)
+      {  return m_flat_tree.upper_bound(x);    }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator upper_bound(const key_type& x) const 
+      {  return m_flat_tree.upper_bound(x);    }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair 
+      equal_range(const key_type& x) const 
+      {  return m_flat_tree.equal_range(x); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair 
+      equal_range(const key_type& x) 
+      {  return m_flat_tree.equal_range(x); }
+
+   //! Effects: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type capacity() const           
+      { return m_flat_tree.capacity(); }
+
+   //! Effects: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //! 
+   //! Throws: If memory allocation allocation throws or T's copy constructor throws.
+   //!
+   //! Note: If capacity() is less than "count", iterators and references to
+   //!   to values might be invalidated.
+   void reserve(size_type count)       
+      { m_flat_tree.reserve(count);   }
+
+   /// @cond
+   template 
+   friend bool operator== (const flat_set&, const flat_set&);
+
+   template 
+   friend bool operator< (const flat_set&, const flat_set&);
+
+   private:
+   std::pair priv_insert(const T &x) 
+   {  return m_flat_tree.insert_unique(x);  }
+
+   iterator priv_insert(const_iterator p, const T &x) 
+   {  return m_flat_tree.insert_unique(p, x); }
+   /// @endcond
+};
+
+template 
+inline bool operator==(const flat_set& x, 
+                       const flat_set& y) 
+   {  return x.m_flat_tree == y.m_flat_tree;  }
+
+template 
+inline bool operator<(const flat_set& x, 
+                      const flat_set& y) 
+   {  return x.m_flat_tree < y.m_flat_tree;   }
+
+template 
+inline bool operator!=(const flat_set& x, 
+                       const flat_set& y) 
+   {  return !(x == y);   }
+
+template 
+inline bool operator>(const flat_set& x, 
+                      const flat_set& y) 
+   {  return y < x; }
+
+template 
+inline bool operator<=(const flat_set& x, 
+                       const flat_set& y) 
+   {  return !(y < x); }
+
+template 
+inline bool operator>=(const flat_set& x, 
+                       const flat_set& y) 
+   {  return !(x < y);  }
+
+template 
+inline void swap(flat_set& x, flat_set& y) 
+   {  x.swap(y);  }
+
+/// @cond
+
+}  //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value &&has_trivial_destructor::value;
+};
+*/
+namespace container {
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template , class A = std::allocator >
+#else
+template 
+#endif
+class flat_multiset;
+
+template 
+inline bool operator==(const flat_multiset& x, 
+                       const flat_multiset& y);
+
+template 
+inline bool operator<(const flat_multiset& x, 
+                      const flat_multiset& y);
+/// @endcond
+
+//! flat_multiset is a Sorted Associative Container that stores objects of type Key. 
+//! flat_multiset is a Simple Associative Container, meaning that its value type, 
+//! as well as its key type, is Key.
+//! flat_Multiset can store multiple copies of the same key value.
+//! 
+//! flat_multiset is similar to std::multiset but it's implemented like an ordered vector.
+//! This means that inserting a new element into a flat_multiset invalidates
+//! previous iterators and references
+//!
+//! Erasing an element of a flat_multiset invalidates iterators and references 
+//! pointing to elements that come after (their keys are equal or bigger) the erased element.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template , class A = std::allocator >
+#else
+template 
+#endif
+class flat_multiset 
+{
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(flat_multiset)
+   typedef container_detail::flat_tree, Pred, A> tree_t;
+   tree_t m_flat_tree;  // flat tree representing flat_multiset
+   typedef typename container_detail::
+      move_const_ref_type::type insert_const_ref_type;
+   /// @endcond
+
+   public:
+   // typedefs:
+   typedef typename tree_t::key_type               key_type;
+   typedef typename tree_t::value_type             value_type;
+   typedef typename tree_t::pointer                pointer;
+   typedef typename tree_t::const_pointer          const_pointer;
+   typedef typename tree_t::reference              reference;
+   typedef typename tree_t::const_reference        const_reference;
+   typedef typename tree_t::key_compare            key_compare;
+   typedef typename tree_t::value_compare          value_compare;
+   typedef typename tree_t::iterator               iterator;
+   typedef typename tree_t::const_iterator         const_iterator;
+   typedef typename tree_t::reverse_iterator       reverse_iterator;
+   typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+   typedef typename tree_t::size_type              size_type;
+   typedef typename tree_t::difference_type        difference_type;
+   typedef typename tree_t::allocator_type         allocator_type;
+   typedef typename tree_t::stored_allocator_type  stored_allocator_type;
+
+   //! Effects: Defatuls constructs an empty flat_map.
+   //! 
+   //! Complexity: Constant.
+   explicit flat_multiset()
+      : m_flat_tree()
+   {}
+
+   explicit flat_multiset(const Pred& comp,
+                          const allocator_type& a = allocator_type())
+      : m_flat_tree(comp, a) {}
+
+   template 
+   flat_multiset(InputIterator first, InputIterator last,
+                 const Pred& comp        = Pred(),
+                 const allocator_type& a = allocator_type())
+      : m_flat_tree(comp, a) 
+      { m_flat_tree.insert_equal(first, last); }
+
+   //! Effects: Constructs an empty flat_multiset using the specified comparison object and 
+   //! allocator, and inserts elements from the ordered range [first ,last ). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! Requires: [first ,last) must be ordered according to the predicate.
+   //! 
+   //! Complexity: Linear in N.
+   template 
+   flat_multiset(ordered_range_t, InputIterator first, InputIterator last,
+                 const Pred& comp        = Pred(),
+                 const allocator_type& a = allocator_type())
+      : m_flat_tree(ordered_range, first, last, comp, a) 
+   {}
+
+   flat_multiset(const flat_multiset& x) 
+      : m_flat_tree(x.m_flat_tree) {}
+
+   flat_multiset(BOOST_RV_REF(flat_multiset) x) 
+      : m_flat_tree(boost::move(x.m_flat_tree))
+   {}
+
+   flat_multiset& operator=(BOOST_COPY_ASSIGN_REF(flat_multiset) x) 
+      {  m_flat_tree = x.m_flat_tree;   return *this;  }
+
+   flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx) 
+   {  m_flat_tree = boost::move(mx.m_flat_tree);   return *this;  }
+
+   //! Effects: Returns the comparison object out
+   //!   of which a was constructed.
+   //! 
+   //! Complexity: Constant.
+   key_compare key_comp() const 
+      { return m_flat_tree.key_comp(); }
+
+   //! Effects: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //! 
+   //! Complexity: Constant.
+   value_compare value_comp() const 
+      { return m_flat_tree.key_comp(); }
+
+   //! Effects: Returns a copy of the Allocator that
+   //!   was passed to the object's constructor.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const 
+   { return m_flat_tree.get_allocator(); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+   { return m_flat_tree.get_stored_allocator(); }
+
+   stored_allocator_type &get_stored_allocator()
+   { return m_flat_tree.get_stored_allocator(); }
+
+   //! Effects: Returns an iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin() 
+      { return m_flat_tree.begin(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const 
+      { return m_flat_tree.begin(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const 
+      { return m_flat_tree.cbegin(); }
+
+   //! Effects: Returns an iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end() 
+      { return m_flat_tree.end(); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const 
+      { return m_flat_tree.end(); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const 
+      { return m_flat_tree.cend(); }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin() 
+      { return m_flat_tree.rbegin(); } 
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const 
+      { return m_flat_tree.rbegin(); } 
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin() const 
+      { return m_flat_tree.crbegin(); } 
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend()
+      { return m_flat_tree.rend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const 
+      { return m_flat_tree.rend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend() const 
+      { return m_flat_tree.crend(); }
+
+   //! Effects: Returns true if the container contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const 
+      { return m_flat_tree.empty(); }
+
+   //! Effects: Returns the number of the elements contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const 
+      { return m_flat_tree.size(); }
+
+   //! Effects: Returns the largest possible size of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const 
+      { return m_flat_tree.max_size(); }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(flat_multiset& x)
+   { m_flat_tree.swap(x.m_flat_tree); }
+
+   //! Effects: Inserts x and returns the iterator pointing to the
+   //!   newly inserted element. 
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(insert_const_ref_type x) 
+   {  return priv_insert(x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   iterator insert(T &x)
+   { return this->insert(const_cast(x)); }
+
+   template
+   iterator insert(const U &u, typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return priv_insert(u); }
+   #endif
+
+   //! Effects: Inserts a new value_type move constructed from x
+   //!   and returns the iterator pointing to the newly inserted element. 
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(BOOST_RV_REF(value_type) x) 
+   {  return m_flat_tree.insert_equal(boost::move(x));   }
+
+   //! Effects: Inserts a copy of x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator p, insert_const_ref_type x) 
+   {  return priv_insert(p, x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   iterator insert(const_iterator position, T &x)
+   { return this->insert(position, const_cast(x)); }
+
+   template
+   iterator insert( const_iterator position, const U &u
+                  , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return priv_insert(position, u); }
+   #endif
+
+   //! Effects: Inserts a new value move constructed  from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   iterator insert(const_iterator position, BOOST_RV_REF(value_type) x) 
+   {  return m_flat_tree.insert_equal(position, boost::move(x));  }
+
+   //! Requires: first, last are not iterators into *this.
+   //!
+   //! Effects: inserts each element from the range [first,last) .
+   //!
+   //! Complexity: At most N log(size()+N) (N is the distance from first to last)
+   //!   search time plus N*size() insertion time.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   void insert(InputIterator first, InputIterator last) 
+      {  m_flat_tree.insert_equal(first, last);  }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... and returns the iterator pointing to the
+   //!   newly inserted element. 
+   //!
+   //! Complexity: Logarithmic search time plus linear insertion
+   //!   to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   iterator emplace(Args&&... args)
+   {  return m_flat_tree.emplace_equal(boost::forward(args)...); }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic search time (constant if x is inserted
+   //!   right before p) plus insertion linear to the elements with bigger keys than x.
+   //!
+   //! Note: If an element is inserted it might invalidate elements.
+   template 
+   iterator emplace_hint(const_iterator hint, Args&&... args)
+   {  return m_flat_tree.emplace_hint_equal(hint, boost::forward(args)...); }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                                 \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                            \
+   {  return m_flat_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }   \
+                                                                                                   \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace_hint(const_iterator hint                                                       \
+                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              \
+   {  return m_flat_tree.emplace_hint_equal                                                        \
+            (hint BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }               \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Erases the element pointed to by position.
+   //!
+   //! Returns: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists, 
+   //!   returns end().
+   //!
+   //! Complexity: Linear to the elements with keys bigger than position
+   //!
+   //! Note: Invalidates elements with keys
+   //!   not less than the erased element.
+   iterator erase(const_iterator position) 
+      {  return m_flat_tree.erase(position); }
+
+   //! Effects: Erases all elements in the container with key equivalent to x.
+   //!
+   //! Returns: Returns the number of erased elements.
+   //!
+   //! Complexity: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   size_type erase(const key_type& x) 
+      {  return m_flat_tree.erase(x); }
+
+   //! Effects: Erases all the elements in the range [first, last).
+   //!
+   //! Returns: Returns last.
+   //!
+   //! Complexity: size()*N where N is the distance from first to last.
+   //!
+   //! Complexity: Logarithmic search time plus erasure time
+   //!   linear to the elements with bigger keys.
+   iterator erase(const_iterator first, const_iterator last) 
+      {  return m_flat_tree.erase(first, last);  }
+
+   //! Effects: erase(a.begin(),a.end()).
+   //!
+   //! Postcondition: size() == 0.
+   //!
+   //! Complexity: linear in size().
+   void clear() 
+      { m_flat_tree.clear(); }
+
+   //! Effects: Tries to deallocate the excess of memory created
+   //    with previous allocations. The size of the vector is unchanged
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to size().
+   void shrink_to_fit()
+      { m_flat_tree.shrink_to_fit(); }
+
+   //! Returns: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   iterator find(const key_type& x) 
+      { return m_flat_tree.find(x); }
+
+   //! Returns: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.s
+   const_iterator find(const key_type& x) const 
+      { return m_flat_tree.find(x); }
+
+   //! Returns: The number of elements with key equivalent to x.
+   //!
+   //! Complexity: log(size())+count(k)
+   size_type count(const key_type& x) const 
+      { return m_flat_tree.count(x); }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator lower_bound(const key_type& x) 
+      {  return m_flat_tree.lower_bound(x); }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator lower_bound(const key_type& x) const 
+      {  return m_flat_tree.lower_bound(x); }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator upper_bound(const key_type& x)
+      {  return m_flat_tree.upper_bound(x);    }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator upper_bound(const key_type& x) const 
+      {  return m_flat_tree.upper_bound(x);    }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair 
+      equal_range(const key_type& x) const 
+      {  return m_flat_tree.equal_range(x); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair 
+      equal_range(const key_type& x) 
+      {  return m_flat_tree.equal_range(x); }
+
+   //! Effects: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type capacity() const           
+      { return m_flat_tree.capacity(); }
+
+   //! Effects: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //! 
+   //! Throws: If memory allocation allocation throws or T's copy constructor throws.
+   //!
+   //! Note: If capacity() is less than "count", iterators and references to
+   //!   to values might be invalidated.
+   void reserve(size_type count)       
+      { m_flat_tree.reserve(count);   }
+
+   /// @cond
+   template 
+   friend bool operator== (const flat_multiset&,
+                           const flat_multiset&);
+   template 
+   friend bool operator< (const flat_multiset&,
+                          const flat_multiset&);
+   private:
+   iterator priv_insert(const T &x) 
+   {  return m_flat_tree.insert_equal(x);  }
+
+   iterator priv_insert(const_iterator p, const T &x) 
+   {  return m_flat_tree.insert_equal(p, x); }
+   /// @endcond
+};
+
+template 
+inline bool operator==(const flat_multiset& x, 
+                       const flat_multiset& y) 
+   {  return x.m_flat_tree == y.m_flat_tree;  }
+
+template 
+inline bool operator<(const flat_multiset& x, 
+                      const flat_multiset& y) 
+   {  return x.m_flat_tree < y.m_flat_tree;   }
+
+template 
+inline bool operator!=(const flat_multiset& x, 
+                       const flat_multiset& y) 
+   {  return !(x == y);  }
+
+template 
+inline bool operator>(const flat_multiset& x, 
+                      const flat_multiset& y) 
+   {  return y < x;  }
+
+template 
+inline bool operator<=(const flat_multiset& x, 
+                       const flat_multiset& y) 
+   {  return !(y < x);  }
+
+template 
+inline bool operator>=(const flat_multiset& x, 
+                       const flat_multiset& y) 
+{  return !(x < y);  }
+
+template 
+inline void swap(flat_multiset& x, flat_multiset& y) 
+   {  x.swap(y);  }
+
+/// @cond
+
+}  //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value && has_trivial_destructor::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+}}
+
+#include 
+
+#endif /* BOOST_CONTAINER_FLAT_SET_HPP */
diff --git a/src/third_party/boost/boost/container/list.hpp b/src/third_party/boost/boost/container/list.hpp
new file mode 100644
index 00000000000..6df999bb513
--- /dev/null
+++ b/src/third_party/boost/boost/container/list.hpp
@@ -0,0 +1,1371 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+
+#ifndef BOOST_CONTAINER_LIST_HPP_
+#define BOOST_CONTAINER_LIST_HPP_
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+#else
+//Preprocessor library to emulate perfect forwarding
+#include  
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+namespace container_detail {
+
+template
+struct list_hook
+{
+   typedef typename container_detail::bi::make_list_base_hook
+      , container_detail::bi::link_mode >::type type;
+};
+
+template 
+struct list_node
+   :  public list_hook::type
+{
+
+   list_node()
+      : m_data()
+   {}
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   template
+   list_node(Args &&...args)
+      : m_data(boost::forward(args)...)
+   {}
+
+   #else //#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                           \
+   template                                                \
+   list_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                          \
+      : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))                     \
+   {}                                                                                        \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif//#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   T m_data;
+};
+
+template
+struct intrusive_list_type
+{
+   typedef boost::container::allocator_traits   allocator_traits_type;
+   typedef typename allocator_traits_type::value_type value_type;
+   typedef typename boost::intrusive::pointer_traits
+      ::template
+         rebind_pointer::type
+            void_pointer;
+   typedef typename container_detail::list_node
+                      node_type;
+   typedef typename container_detail::bi::make_list
+      < node_type
+      , container_detail::bi::base_hook::type>
+      , container_detail::bi::constant_time_size
+      , container_detail::bi::size_type
+         
+      >::type                                   container_type;
+   typedef container_type                       type ;
+};
+
+}  //namespace container_detail {
+/// @endcond
+
+//! A list is a doubly linked list. That is, it is a Sequence that supports both
+//! forward and backward traversal, and (amortized) constant time insertion and 
+//! removal of elements at the beginning or the end, or in the middle. Lists have 
+//! the important property that insertion and splicing do not invalidate iterators 
+//! to list elements, and that even removal invalidates only the iterators that point 
+//! to the elements that are removed. The ordering of iterators may be changed 
+//! (that is, list::iterator might have a different predecessor or successor 
+//! after a list operation than it did before), but the iterators themselves will 
+//! not be invalidated or made to point to different elements unless that invalidation 
+//! or mutation is explicit.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >
+#else
+template 
+#endif
+class list 
+   : protected container_detail::node_alloc_holder
+      ::type>
+{
+   /// @cond
+   typedef typename 
+      container_detail::intrusive_list_type::type Icont;
+   typedef list                                 ThisType;
+   typedef container_detail::node_alloc_holder        AllocHolder;
+   typedef typename AllocHolder::NodePtr              NodePtr;
+   typedef typename AllocHolder::NodeAlloc            NodeAlloc;
+   typedef typename AllocHolder::ValAlloc             ValAlloc;
+   typedef typename AllocHolder::Node                 Node;
+   typedef container_detail::allocator_destroyer     Destroyer;
+   typedef typename AllocHolder::allocator_v1         allocator_v1;
+   typedef typename AllocHolder::allocator_v2         allocator_v2;
+   typedef typename AllocHolder::alloc_version        alloc_version;
+   typedef boost::container::allocator_traits      allocator_traits_type;
+
+   class equal_to_value
+   {
+      typedef typename AllocHolder::value_type value_type;
+      const value_type &t_;
+
+      public:
+      equal_to_value(const value_type &t)
+         :  t_(t)
+      {}
+
+      bool operator()(const value_type &t)const
+      {  return t_ == t;   }
+   };
+
+   template
+   struct ValueCompareToNodeCompare
+      :  Pred
+   {
+      ValueCompareToNodeCompare(Pred pred)
+         :  Pred(pred)
+      {}
+
+      bool operator()(const Node &a, const Node &b) const
+      {  return static_cast(*this)(a.m_data, b.m_data);  }
+
+      bool operator()(const Node &a) const
+      {  return static_cast(*this)(a.m_data);  }
+   };
+   /// @endcond
+
+   public:
+   //! The type of object, T, stored in the list
+   typedef T                                                value_type;
+   //! Pointer to T
+   typedef typename allocator_traits_type::pointer          pointer;
+   //! Const pointer to T
+   typedef typename allocator_traits_type::const_pointer    const_pointer;
+   //! Reference to T
+   typedef typename allocator_traits_type::reference        reference;
+   //! Const reference to T
+   typedef typename allocator_traits_type::const_reference  const_reference;
+   //! An unsigned integral type
+   typedef typename allocator_traits_type::size_type        size_type;
+   //! A signed integral type
+   typedef typename allocator_traits_type::difference_type  difference_type;
+   //! The allocator type
+   typedef A                                                allocator_type;
+   //! Non-standard extension: the stored allocator type
+   typedef NodeAlloc                                        stored_allocator_type;
+
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(list)
+   typedef difference_type                         list_difference_type;
+   typedef pointer                                 list_pointer;
+   typedef const_pointer                           list_const_pointer;
+   typedef reference                               list_reference;
+   typedef const_reference                         list_const_reference;
+   /// @endcond
+
+   public:
+   //! Const iterator used to iterate through a list. 
+   class const_iterator
+      /// @cond
+      : public std::iterator
+   {
+
+      protected:
+      typename Icont::iterator m_it;
+      explicit const_iterator(typename Icont::iterator it)  : m_it(it){}
+      void prot_incr() { ++m_it; }
+      void prot_decr() { --m_it; }
+
+      private:
+      typename Icont::iterator get()
+      {  return this->m_it;   }
+
+      public:
+      friend class list;
+      typedef list_difference_type        difference_type;
+
+      //Constructors
+      const_iterator()
+         :  m_it()
+      {}
+
+      //Pointer like operators
+      const_reference operator*()  const 
+      { return  m_it->m_data;  }
+
+      const_pointer   operator->() const 
+      { return  const_pointer(&m_it->m_data); }
+
+      //Increment / Decrement
+      const_iterator& operator++()       
+      { prot_incr();  return *this; }
+
+      const_iterator operator++(int)      
+      { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp);  }
+
+      const_iterator& operator--()
+      {   prot_decr(); return *this;   }
+
+      const_iterator operator--(int)
+      {  typename Icont::iterator tmp = m_it; --*this; return const_iterator(tmp); }
+
+      //Comparison operators
+      bool operator==   (const const_iterator& r)  const
+      {  return m_it == r.m_it;  }
+
+      bool operator!=   (const const_iterator& r)  const
+      {  return m_it != r.m_it;  }
+   }
+   /// @endcond
+   ;
+
+   //! Iterator used to iterate through a list
+   class iterator
+   /// @cond
+      : public const_iterator
+   {
+
+      private:
+      explicit iterator(typename Icont::iterator it)
+         :  const_iterator(it)
+      {}
+   
+      typename Icont::iterator get()
+      {  return this->m_it;   }
+
+      public:
+      friend class list;
+      typedef list_pointer       pointer;
+      typedef list_reference     reference;
+
+      //Constructors
+      iterator(){}
+
+      //Pointer like operators
+      reference operator*()  const {  return  this->m_it->m_data;  }
+      pointer   operator->() const {  return  pointer(&this->m_it->m_data);  }
+
+      //Increment / Decrement
+      iterator& operator++()  
+         { this->prot_incr(); return *this;  }
+
+      iterator operator++(int)
+         { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
+      
+      iterator& operator--()
+         {  this->prot_decr(); return *this;  }
+
+      iterator operator--(int)
+         {  iterator tmp = *this; --*this; return tmp; }
+   };
+   /// @endcond
+
+   //! Iterator used to iterate backwards through a list. 
+   typedef std::reverse_iterator        reverse_iterator;
+   //! Const iterator used to iterate backwards through a list. 
+   typedef std::reverse_iterator  const_reverse_iterator;
+
+   //! Effects: Default constructs a list.
+   //! 
+   //! Throws: If allocator_type's default constructor throws.
+   //! 
+   //! Complexity: Constant.
+   list() 
+      : AllocHolder()
+   {}
+
+   //! Effects: Constructs a list taking the allocator as parameter.
+   //! 
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   explicit list(const allocator_type &a)
+      : AllocHolder(a)
+   {}
+
+   //! Effects: Constructs a list that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's default or copy constructor throws.
+   //! 
+   //! Complexity: Linear to n.
+   explicit list(size_type n)
+      : AllocHolder(A())
+   {  this->resize(n);  }
+
+   //! Effects: Constructs a list that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's default or copy constructor throws.
+   //! 
+   //! Complexity: Linear to n.
+   list(size_type n, const T& value, const A& a = A())
+      : AllocHolder(a)
+   {  this->insert(this->cbegin(), n, value);  }
+
+   //! Effects: Copy constructs a list.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Throws: If allocator_type's default constructor or copy constructor throws.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   list(const list& x) 
+      : AllocHolder(x)
+   {  this->insert(this->cbegin(), x.begin(), x.end());   }
+
+   //! Effects: Move constructor. Moves mx's resources to *this.
+   //!
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   list(BOOST_RV_REF(list) x)
+      : AllocHolder(boost::move(static_cast(x)))
+   {}
+
+   //! Effects: Constructs a list that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the list.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's constructor taking an dereferenced InIt throws.
+   //!
+   //! Complexity: Linear to the range [first, last).
+   template 
+   list(InpIt first, InpIt last, const A &a = A())
+      : AllocHolder(a)
+   {  this->insert(this->cbegin(), first, last);  }
+
+   //! Effects: Destroys the list. All stored values are destroyed
+   //!   and used memory is deallocated.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements.
+   ~list()
+   {} //AllocHolder clears the list
+
+   //! Effects: Returns a copy of the internal allocator.
+   //! 
+   //! Throws: If allocator's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const
+   {  return allocator_type(this->node_alloc()); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+   {  return this->node_alloc(); }
+
+   stored_allocator_type &get_stored_allocator()
+   {  return this->node_alloc(); }
+
+   //! Effects: Erases all the elements of the list.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements in the list.
+   void clear()
+   {  AllocHolder::clear(alloc_version());  }
+
+   //! Effects: Returns an iterator to the first element contained in the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin()
+   { return iterator(this->icont().begin()); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const
+   {  return this->cbegin();   }
+
+   //! Effects: Returns an iterator to the end of the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end()
+   {  return iterator(this->icont().end());  }
+
+   //! Effects: Returns a const_iterator to the end of the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const
+   {  return this->cend();  }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed list. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin()
+   {  return reverse_iterator(end());  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed list. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const
+   {  return this->crbegin();  }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed list. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend()
+   {  return reverse_iterator(begin());   }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed list. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const
+   {  return this->crend();   }
+
+   //! Effects: Returns a const_iterator to the first element contained in the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const
+   {  return const_iterator(this->non_const_icont().begin());   }
+
+   //! Effects: Returns a const_iterator to the end of the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const
+   {  return const_iterator(this->non_const_icont().end());  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed list. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin() const
+   {  return const_reverse_iterator(this->cend());  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed list. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend() const
+   {  return const_reverse_iterator(this->cbegin());   }
+
+   //! Effects: Returns true if the list contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const 
+   {  return !this->size();  }
+
+   //! Effects: Returns the number of the elements contained in the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const 
+   {   return this->icont().size();   }
+
+   //! Effects: Returns the largest possible size of the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const 
+   {  return AllocHolder::max_size();  }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Effects: Inserts a copy of x at the beginning of the list.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_front(const T &x);
+
+   //! Effects: Constructs a new element in the beginning of the list
+   //!   and moves the resources of mx to this new element.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_front(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_front, T, void, priv_push_front)
+   #endif
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Effects: Inserts a copy of x at the end of the list.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_back(const T &x);
+
+   //! Effects: Constructs a new element in the end of the list
+   //!   and moves the resources of mx to this new element.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_back(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+   #endif
+
+   //! Effects: Removes the first element from the list.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Amortized constant time.
+   void pop_front()              
+   {  this->erase(this->cbegin());      }
+
+   //! Effects: Removes the last element from the list.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Amortized constant time.
+   void pop_back()               
+   {  const_iterator tmp = this->cend(); this->erase(--tmp);  }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a reference to the first element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference front()             
+   { return *this->begin(); }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a const reference to the first element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference front() const 
+   { return *this->begin(); }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a reference to the first element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference back()              
+   { return *(--this->end()); }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a const reference to the first element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference back()  const 
+   { return *(--this->end()); }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type new_size, const T& x)
+   {
+      const_iterator iend = this->cend();
+      size_type len = this->size();
+      
+      if(len > new_size){
+         size_type to_erase = len - new_size;
+         while(to_erase--){
+            --iend;
+         }
+         this->erase(iend, this->cend());
+      }
+      else{
+         this->priv_create_and_insert_nodes(iend, new_size - len, x);
+      }
+   }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are default constructed.
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type new_size)
+   {
+      const_iterator iend = this->end();
+      size_type len = this->size();
+      
+      if(len > new_size){
+         size_type to_erase = len - new_size;
+         const_iterator ifirst;
+         if(to_erase < len/2u){
+            ifirst = iend;
+            while(to_erase--){
+               --ifirst;
+            }
+         }
+         else{
+            ifirst = this->begin();
+            size_type to_skip = len - to_erase;
+            while(to_skip--){
+               ++ifirst;
+            }
+         }
+         this->erase(ifirst, iend);
+      }
+      else{
+         this->priv_create_and_insert_nodes(this->cend(), new_size - len);
+      }
+   }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(ThisType& x)
+   {  AllocHolder::swap(x);   }
+
+   //! Effects: Makes *this contain the same elements as x.
+   //!
+   //! Postcondition: this->size() == x.size(). *this contains a copy 
+   //! of each of x's elements. 
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the number of elements in x.
+   ThisType& operator=(BOOST_COPY_ASSIGN_REF(ThisType) x)
+   {
+      if (&x != this){
+         NodeAlloc &this_alloc     = this->node_alloc();
+         const NodeAlloc &x_alloc  = x.node_alloc();
+         container_detail::bool_ flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+         }
+         this->AllocHolder::copy_assign_alloc(x);
+         this->assign(x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! Effects: Move assignment. All mx's values are transferred to *this.
+   //!
+   //! Postcondition: x.empty(). *this contains a the elements x had
+   //!   before the function.
+   //!
+   //! Throws: If allocator_type's copy constructor throws.
+   //!
+   //! Complexity: Constant.
+   ThisType& operator=(BOOST_RV_REF(ThisType) x)
+   {
+      if (&x != this){
+         NodeAlloc &this_alloc = this->node_alloc();
+         NodeAlloc &x_alloc    = x.node_alloc();
+         //If allocators are equal we can just swap pointers
+         if(this_alloc == x_alloc){
+            //Destroy and swap pointers
+            this->clear();
+            this->icont() = boost::move(x.icont());
+            //Move allocator if needed
+            this->AllocHolder::move_assign_alloc(x);
+         }
+         //If unequal allocators, then do a one by one move
+         else{
+            typedef typename std::iterator_traits::iterator_category ItCat;
+            this->assign( boost::make_move_iterator(x.begin())
+                        , boost::make_move_iterator(x.end()));
+         }
+      }
+      return *this;
+   }
+
+   //! Requires: p must be a valid iterator of *this.
+   //!
+   //! Effects: Inserts n copies of x before p.
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to n.
+   void insert(const_iterator p, size_type n, const T& x)
+   { this->priv_create_and_insert_nodes(p, n, x); }
+
+   //! Requires: p must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a copy of the [first, last) range before p.
+   //!
+   //! Throws: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws.
+   //!
+   //! Complexity: Linear to std::distance [first, last).
+   template 
+   void insert(const_iterator p, InpIt first, InpIt last) 
+   {
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_insert_dispatch(p, first, last, Result());
+   }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a copy of x before position.
+   //!
+   //! Throws: If memory allocation throws or x's copy constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   iterator insert(const_iterator position, const T &x);
+
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a new element before position with mx's resources.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: Amortized constant time.
+   iterator insert(const_iterator position, T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
+   #endif
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the end of the list.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! Complexity: Constant
+   template 
+   void emplace_back(Args&&... args)
+   {
+      this->emplace(this->cend(), boost::forward(args)...);
+   }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the beginning of the list.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! Complexity: Constant
+   template 
+   void emplace_front(Args&&... args)
+   {
+      this->emplace(this->cbegin(), boost::forward(args)...);
+   }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... before p.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! Complexity: Constant
+   template 
+   iterator emplace(const_iterator p, Args&&... args)
+   {
+      NodePtr pnode(AllocHolder::create_node(boost::forward(args)...));
+      return iterator(this->icont().insert(p.get(), *pnode));
+   }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                              \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)       \
+   void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                        \
+   {                                                                                            \
+      this->emplace(this->cend()                                                                \
+                    BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));            \
+   }                                                                                            \
+                                                                                                \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)       \
+   void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                       \
+   {                                                                                            \
+      this->emplace(this->cbegin()                                                              \
+                    BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));            \
+   }                                                                                            \
+                                                                                                \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)       \
+   iterator emplace(const_iterator p                                                            \
+                    BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                \
+   {                                                                                            \
+      NodePtr pnode (AllocHolder::create_node                                                   \
+         (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)));                              \
+      return iterator(this->icont().insert(p.get(), *pnode));                                   \
+   }                                                                                            \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Requires: p must be a valid iterator of *this.
+   //!
+   //! Effects: Erases the element at p p.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Amortized constant time.
+   iterator erase(const_iterator p) 
+   {  return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
+
+   //! Requires: first and last must be valid iterator to elements in *this.
+   //!
+   //! Effects: Erases the elements pointed by [first, last).
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the distance between first and last.
+   iterator erase(const_iterator first, const_iterator last)
+   {  return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
+
+   //! Effects: Assigns the n copies of val to *this.
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to n.
+   void assign(size_type n, const T& val) 
+   {  this->priv_fill_assign(n, val);  }
+
+   //! Effects: Assigns the the range [first, last) to *this.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's constructor from dereferencing InpIt throws.
+   //!
+   //! Complexity: Linear to n.
+   template 
+   void assign(InpIt first, InpIt last) 
+   {
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_assign_dispatch(first, last, Result());
+   }
+
+   //! Requires: p must point to an element contained
+   //!   by the list. x != *this
+   //!
+   //! Effects: Transfers all the elements of list x to this list, before the
+   //!   the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //!
+   //! Complexity: Constant.
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of
+   //!    this list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, ThisType& x) BOOST_CONTAINER_NOEXCEPT
+   {
+      BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
+      this->icont().splice(p.get(), x.icont());
+   }
+
+   //! Requires: p must point to an element contained
+   //!   by this list. i must point to an element contained in list x.
+   //! 
+   //! Effects: Transfers the value pointed by i, from list x to this list, 
+   //!   before the the element pointed by p. No destructors or copy constructors are called.
+   //!   If p == i or p == ++i, this function is a null operation. 
+   //! 
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, ThisType &x, const_iterator i) BOOST_CONTAINER_NOEXCEPT
+   {
+      BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
+      this->icont().splice(p.get(), x.icont(), i.get());
+   }
+
+   //! Requires: p must point to an element contained
+   //!   by this list. first and last must point to elements contained in list x.
+   //! 
+   //! Effects: Transfers the range pointed by first and last from list x to this list, 
+   //!   before the the element pointed by p. No destructors or copy constructors are called.
+   //! 
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //! 
+   //! Complexity: Linear to the number of elements transferred.
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
+   {
+      BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
+      this->icont().splice(p.get(), x.icont(), first.get(), last.get());
+   }
+
+   //! Requires: p must point to an element contained
+   //!   by this list. first and last must point to elements contained in list x.
+   //!   n == std::distance(first, last)
+   //! 
+   //! Effects: Transfers the range pointed by first and last from list x to this list, 
+   //!   before the the element pointed by p. No destructors or copy constructors are called.
+   //! 
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, ThisType &x, const_iterator first, const_iterator last, size_type n) BOOST_CONTAINER_NOEXCEPT
+   {
+      BOOST_ASSERT((NodeAlloc&)*this == (NodeAlloc&)x);
+      this->icont().splice(p.get(), x.icont(), first.get(), last.get(), n);
+   }
+
+   //! Effects: Reverses the order of elements in the list. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: This function is linear time.
+   //! 
+   //! Note: Iterators and references are not invalidated
+   void reverse()
+   {  this->icont().reverse(); }    
+
+   //! Effects: Removes all the elements that compare equal to value.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear time. It performs exactly size() comparisons for equality.
+   //! 
+   //! Note: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   void remove(const T& value)
+   {  remove_if(equal_to_value(value));  }
+
+   //! Effects: Removes all the elements for which a specified
+   //!   predicate is satisfied.
+   //! 
+   //! Throws: If pred throws.
+   //! 
+   //! Complexity: Linear time. It performs exactly size() calls to the predicate.
+   //! 
+   //! Note: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   template 
+   void remove_if(Pred pred)
+   {
+      typedef ValueCompareToNodeCompare Predicate;
+      this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
+   }
+
+   //! Effects: Removes adjacent duplicate elements or adjacent 
+   //!   elements that are equal from the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear time (size()-1 comparisons calls to pred()).
+   //! 
+   //! Note: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   void unique()
+   {  this->unique(value_equal());  }
+
+   //! Effects: Removes adjacent duplicate elements or adjacent 
+   //!   elements that satisfy some binary predicate from the list.
+   //! 
+   //! Throws: If pred throws.
+   //! 
+   //! Complexity: Linear time (size()-1 comparisons equality comparisons).
+   //! 
+   //! Note: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   template 
+   void unique(BinaryPredicate binary_pred)
+   {
+      typedef ValueCompareToNodeCompare Predicate;
+      this->icont().unique_and_dispose(Predicate(binary_pred), Destroyer(this->node_alloc()));
+   }
+
+   //! Requires: The lists x and *this must be distinct. 
+   //!
+   //! Effects: This function removes all of x's elements and inserts them
+   //!   in order into *this according to std::less. The merge is stable; 
+   //!   that is, if an element from *this is equivalent to one from x, then the element 
+   //!   from *this will precede the one from x. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   void merge(list& x)
+   {  this->merge(x, value_less());  }
+
+   //! Requires: p must be a comparison function that induces a strict weak
+   //!   ordering and both *this and x must be sorted according to that ordering
+   //!   The lists x and *this must be distinct. 
+   //! 
+   //! Effects: This function removes all of x's elements and inserts them
+   //!   in order into *this. The merge is stable; that is, if an element from *this is 
+   //!   equivalent to one from x, then the element from *this will precede the one from x. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   //! 
+   //! Note: Iterators and references to *this are not invalidated.
+   template 
+   void merge(list &x, StrictWeakOrdering comp)
+   {
+      if((NodeAlloc&)*this == (NodeAlloc&)x){
+         this->icont().merge(x.icont(),
+            ValueCompareToNodeCompare(comp));
+      }
+      else{
+         throw std::runtime_error("list::merge called with unequal allocators");
+      }
+   }
+
+   //! Effects: This function sorts the list *this according to std::less. 
+   //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Notes: Iterators and references are not invalidated.
+   //!   
+   //! Complexity: The number of comparisons is approximately N log N, where N
+   //!   is the list's size.
+   void sort()
+   {  this->sort(value_less());  }
+
+   //! Effects: This function sorts the list *this according to std::less. 
+   //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
+   //! 
+   //! Throws: Nothing.
+   //!
+   //! Notes: Iterators and references are not invalidated.
+   //! 
+   //! Complexity: The number of comparisons is approximately N log N, where N
+   //!   is the list's size.
+   template 
+   void sort(StrictWeakOrdering comp)
+   {
+      // nothing if the list has length 0 or 1.
+      if (this->size() < 2)
+         return;
+      this->icont().sort(ValueCompareToNodeCompare(comp));
+   }
+
+   /// @cond
+   private:
+
+   iterator priv_insert(const_iterator p, const T &x) 
+   {
+      NodePtr tmp = AllocHolder::create_node(x);
+      return iterator(this->icont().insert(p.get(), *tmp));
+   }
+
+   iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x) 
+   {
+      NodePtr tmp = AllocHolder::create_node(boost::move(x));
+      return iterator(this->icont().insert(p.get(), *tmp));
+   }
+
+   void priv_push_back (const T &x)   
+   {  this->insert(this->cend(), x);    }
+
+   void priv_push_back (BOOST_RV_REF(T) x)
+   {  this->insert(this->cend(), boost::move(x));    }
+
+   void priv_push_front (const T &x)   
+   {  this->insert(this->cbegin(), x);  }
+
+   void priv_push_front (BOOST_RV_REF(T) x)
+   {  this->insert(this->cbegin(), boost::move(x));  }
+
+   //Iterator range version
+   template
+   void priv_create_and_insert_nodes
+      (const_iterator pos, InpIterator beg, InpIterator end)
+   {
+      typedef typename std::iterator_traits::iterator_category ItCat;
+      priv_create_and_insert_nodes(pos, beg, end, alloc_version(), ItCat());
+   }
+
+   template
+   void priv_create_and_insert_nodes
+      (const_iterator pos, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
+   {
+      for (; beg != end; ++beg){
+         this->icont().insert(pos.get(), *this->create_node_from_it(beg));
+      }
+   }
+
+   template
+   void priv_create_and_insert_nodes
+      (const_iterator pos, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
+   {  //Just forward to the default one
+      priv_create_and_insert_nodes(pos, beg, end, allocator_v1(), std::input_iterator_tag());
+   }
+
+   class insertion_functor;
+   friend class insertion_functor;
+
+   class insertion_functor
+   {
+      Icont &icont_;
+      typename Icont::const_iterator pos_;
+
+      public:
+      insertion_functor(Icont &icont, typename Icont::const_iterator pos)
+         :  icont_(icont), pos_(pos)
+      {}
+
+      void operator()(Node &n)
+      {  this->icont_.insert(pos_, n); }
+   };
+
+
+   template
+   void priv_create_and_insert_nodes
+      (const_iterator pos, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+   {
+      if(beg != end){
+         //Optimized allocation and construction
+         this->allocate_many_and_construct
+            (beg, std::distance(beg, end), insertion_functor(this->icont(), pos.get()));
+      }
+   }
+
+   //Default constructed version
+   void priv_create_and_insert_nodes(const_iterator pos, size_type n)
+   {
+      typedef default_construct_iterator default_iterator;
+      this->priv_create_and_insert_nodes(pos, default_iterator(n), default_iterator());
+   }
+
+   //Copy constructed version
+   void priv_create_and_insert_nodes(const_iterator pos, size_type n, const T& x)
+   {
+      typedef constant_iterator cvalue_iterator;
+      this->priv_create_and_insert_nodes(pos, cvalue_iterator(x, n), cvalue_iterator());
+   }
+
+   //Dispatch to detect iterator range or integer overloads
+   template 
+   void priv_insert_dispatch(const_iterator p,
+                             InputIter first, InputIter last,
+                             container_detail::false_)
+   {  this->priv_create_and_insert_nodes(p, first, last);   }
+
+   template
+   void priv_insert_dispatch(const_iterator p, Integer n, Integer x, container_detail::true_) 
+   {  this->insert(p, (size_type)n, x);  }
+
+   void priv_fill_assign(size_type n, const T& val) 
+   {
+      iterator i = this->begin(), iend = this->end();
+
+      for ( ; i != iend && n > 0; ++i, --n)
+         *i = val;
+      if (n > 0){
+         this->priv_create_and_insert_nodes(this->cend(), n, val);
+      }
+      else{
+         this->erase(i, cend());
+      }
+   }
+
+   template 
+   void priv_assign_dispatch(Integer n, Integer val, container_detail::true_)
+   {  this->priv_fill_assign((size_type) n, (T) val); }
+
+   template 
+   void priv_assign_dispatch(InputIter first2, InputIter last2, container_detail::false_)
+   {
+      iterator first1   = this->begin();
+      iterator last1    = this->end();
+      for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
+         *first1 = *first2;
+      if (first2 == last2)
+         this->erase(first1, last1);
+      else{
+         this->priv_create_and_insert_nodes(last1, first2, last2);
+      }
+   }
+
+   //Functors for member algorithm defaults
+   struct value_less
+   {
+      bool operator()(const value_type &a, const value_type &b) const
+         {  return a < b;  }
+   };
+
+   struct value_equal
+   {
+      bool operator()(const value_type &a, const value_type &b) const
+         {  return a == b;  }
+   };
+   /// @endcond
+
+};
+
+template 
+inline bool operator==(const list& x, const list& y)
+{
+   if(x.size() != y.size()){
+      return false;
+   }
+   typedef typename list::const_iterator const_iterator;
+   const_iterator end1 = x.end();
+
+   const_iterator i1 = x.begin();
+   const_iterator i2 = y.begin();
+   while (i1 != end1 && *i1 == *i2) {
+      ++i1;
+      ++i2;
+   }
+   return i1 == end1;
+}
+
+template 
+inline bool operator<(const list& x,
+                      const list& y)
+{
+  return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template 
+inline bool operator!=(const list& x, const list& y) 
+{
+  return !(x == y);
+}
+
+template 
+inline bool operator>(const list& x, const list& y) 
+{
+  return y < x;
+}
+
+template 
+inline bool operator<=(const list& x, const list& y) 
+{
+  return !(y < x);
+}
+
+template 
+inline bool operator>=(const list& x, const list& y) 
+{
+  return !(x < y);
+}
+
+template 
+inline void swap(list& x, list& y)
+{
+  x.swap(y);
+}
+
+/// @cond
+
+}  //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+}}
+
+#include 
+
+#endif // BOOST_CONTAINER_LIST_HPP_
diff --git a/src/third_party/boost/boost/container/map.hpp b/src/third_party/boost/boost/container/map.hpp
new file mode 100644
index 00000000000..8f7ecd42b37
--- /dev/null
+++ b/src/third_party/boost/boost/container/map.hpp
@@ -0,0 +1,1317 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_MAP_HPP
+#define BOOST_CONTAINER_MAP_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+// Forward declarations of operators == and <, needed for friend declarations.
+template 
+inline bool operator==(const map& x, 
+                       const map& y);
+
+template 
+inline bool operator<(const map& x, 
+                      const map& y);
+/// @endcond
+
+//! A map is a kind of associative container that supports unique keys (contains at 
+//! most one of each key value) and provides for fast retrieval of values of another 
+//! type T based on the keys. The map class supports bidirectional iterators.
+//! 
+//! A map satisfies all of the requirements of a container and of a reversible 
+//! container and of an associative container. For a 
+//! map the key_type is Key and the value_type is std::pair.
+//!
+//! Pred is the ordering function for Keys (e.g. std::less).
+//!
+//! A is the allocator to allocate the value_types
+//! (e.g. allocator< std::pair > ).
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >, class A = std::allocator >
+#else
+template 
+#endif
+class map 
+{
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(map)
+   typedef container_detail::rbtree, 
+                           container_detail::select1st< std::pair >, 
+                           Pred, 
+                           A> tree_t;
+   tree_t m_tree;  // red-black tree representing map
+
+   /// @endcond
+
+   public:
+
+   // typedefs:
+   typedef typename tree_t::key_type               key_type;
+   typedef typename tree_t::value_type             value_type;
+   typedef typename tree_t::pointer                pointer;
+   typedef typename tree_t::const_pointer          const_pointer;
+   typedef typename tree_t::reference              reference;
+   typedef typename tree_t::const_reference        const_reference;
+   typedef T                                       mapped_type;
+   typedef Pred                                    key_compare;
+   typedef typename tree_t::iterator               iterator;
+   typedef typename tree_t::const_iterator         const_iterator;
+   typedef typename tree_t::reverse_iterator       reverse_iterator;
+   typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+   typedef typename tree_t::size_type              size_type;
+   typedef typename tree_t::difference_type        difference_type;
+   typedef typename tree_t::allocator_type         allocator_type;
+   typedef typename tree_t::stored_allocator_type  stored_allocator_type;
+   typedef std::pair        nonconst_value_type;
+   typedef container_detail::pair
+                            nonconst_impl_value_type;
+
+   /// @cond
+   class value_compare_impl
+      :  public Pred,
+         public std::binary_function 
+   {
+      friend class map;
+    protected :
+      value_compare_impl(const Pred &c) : Pred(c) {}
+    public:
+      bool operator()(const value_type& x, const value_type& y) const {
+         return Pred::operator()(x.first, y.first);
+      }
+   };
+   /// @endcond
+   typedef value_compare_impl             value_compare;
+
+   //! Effects: Default constructs an empty map.
+   //! 
+   //! Complexity: Constant.
+   map()
+      : m_tree()
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
+   }
+
+   //! Effects: Constructs an empty map using the specified comparison object 
+   //! and allocator.
+   //! 
+   //! Complexity: Constant.
+   explicit map(const Pred& comp,
+                const allocator_type& a = allocator_type())
+      : m_tree(comp, a)
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
+   }
+
+   //! Effects: Constructs an empty map using the specified comparison object and 
+   //! allocator, and inserts elements from the range [first ,last ).
+   //! 
+   //! Complexity: Linear in N if the range [first ,last ) is already sorted using 
+   //! comp and otherwise N logN, where N is last - first.
+   template 
+   map(InputIterator first, InputIterator last, const Pred& comp = Pred(),
+         const allocator_type& a = allocator_type())
+      : m_tree(first, last, comp, a, true) 
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+   }
+
+   //! Effects: Constructs an empty map using the specified comparison object and 
+   //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! Requires: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //! 
+   //! Complexity: Linear in N.
+   template 
+   map( ordered_unique_range_t, InputIterator first, InputIterator last
+      , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+      : m_tree(ordered_range, first, last, comp, a) 
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+   }
+
+   //! Effects: Copy constructs a map.
+   //! 
+   //! Complexity: Linear in x.size().
+   map(const map& x) 
+      : m_tree(x.m_tree)
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+   }
+
+   //! Effects: Move constructs a map. Constructs *this using x's resources.
+   //! 
+   //! Complexity: Construct.
+   //! 
+   //! Postcondition: x is emptied.
+   map(BOOST_RV_REF(map) x) 
+      : m_tree(boost::move(x.m_tree))
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+   }
+
+   //! Effects: Makes *this a copy of x.
+   //! 
+   //! Complexity: Linear in x.size().
+   map& operator=(BOOST_COPY_ASSIGN_REF(map) x)
+   {  m_tree = x.m_tree;   return *this;  }
+
+   //! Effects: this->swap(x.get()).
+   //! 
+   //! Complexity: Constant.
+   map& operator=(BOOST_RV_REF(map) x)
+   {  m_tree = boost::move(x.m_tree);   return *this;  }
+
+   //! Effects: Returns the comparison object out
+   //!   of which a was constructed.
+   //! 
+   //! Complexity: Constant.
+   key_compare key_comp() const 
+   { return m_tree.key_comp(); }
+
+   //! Effects: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //! 
+   //! Complexity: Constant.
+   value_compare value_comp() const 
+   { return value_compare(m_tree.key_comp()); }
+
+   //! Effects: Returns a copy of the Allocator that
+   //!   was passed to the object's constructor.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const 
+   { return m_tree.get_allocator(); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+   { return m_tree.get_stored_allocator(); }
+
+   stored_allocator_type &get_stored_allocator()
+   { return m_tree.get_stored_allocator(); }
+
+   //! Effects: Returns an iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin() 
+   { return m_tree.begin(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const 
+   { return m_tree.begin(); }
+
+   //! Effects: Returns an iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end() 
+   { return m_tree.end(); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const 
+   { return m_tree.end(); }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin() 
+   { return m_tree.rbegin(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const 
+   { return m_tree.rbegin(); }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend() 
+   { return m_tree.rend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const 
+   { return m_tree.rend(); }
+
+   //! Effects: Returns true if the container contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const 
+   { return m_tree.empty(); }
+
+   //! Effects: Returns the number of the elements contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const 
+   { return m_tree.size(); }
+
+   //! Effects: Returns the largest possible size of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const 
+   { return m_tree.max_size(); }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Effects: If there is no key equivalent to x in the map, inserts 
+   //! value_type(x, T()) into the map.
+   //! 
+   //! Returns: A reference to the mapped_type corresponding to x in *this.
+   //! 
+   //! Complexity: Logarithmic.
+   mapped_type& operator[](const key_type &k);
+
+   //! Effects: If there is no key equivalent to x in the map, inserts 
+   //! value_type(boost::move(x), T()) into the map (the key is move-constructed)
+   //! 
+   //! Returns: A reference to the mapped_type corresponding to x in *this.
+   //! 
+   //! Complexity: Logarithmic.
+   mapped_type& operator[](key_type &&k);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, priv_subscript)
+   #endif
+
+   //! Returns: A reference to the element whose key is equivalent to x.
+   //! Throws: An exception object of type out_of_range if no such element is present.
+   //! Complexity: logarithmic.
+   T& at(const key_type& k)
+   {
+      iterator i = this->find(k);
+      if(i == this->end()){
+         throw std::out_of_range("key not found");
+      }
+      return i->second;
+   }
+
+   //! Returns: A reference to the element whose key is equivalent to x.
+   //! Throws: An exception object of type out_of_range if no such element is present.
+   //! Complexity: logarithmic.
+   const T& at(const key_type& k) const
+   {
+      const_iterator i = this->find(k);
+      if(i == this->end()){
+         throw std::out_of_range("key not found");
+      }
+      return i->second;
+   }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(map& x)
+   { m_tree.swap(x.m_tree); }
+
+   //! Effects: Inserts x if and only if there is no element in the container 
+   //!   with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   std::pair insert(const value_type& x) 
+   { return m_tree.insert_unique(x); }
+
+   //! Effects: Inserts a new value_type created from the pair if and only if 
+   //! there is no element in the container  with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   std::pair insert(const nonconst_value_type& x) 
+   { return m_tree.insert_unique(x); }
+
+   //! Effects: Inserts a new value_type move constructed from the pair if and
+   //! only if there is no element in the container with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   std::pair insert(BOOST_RV_REF(nonconst_value_type) x) 
+   { return m_tree.insert_unique(boost::move(x)); }
+
+   //! Effects: Inserts a new value_type move constructed from the pair if and
+   //! only if there is no element in the container with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   std::pair insert(BOOST_RV_REF(nonconst_impl_value_type) x) 
+   { return m_tree.insert_unique(boost::move(x)); }
+
+   //! Effects: Move constructs a new value from x if and only if there is 
+   //!   no element in the container with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   std::pair insert(BOOST_RV_REF(value_type) x) 
+   { return m_tree.insert_unique(boost::move(x)); }
+
+   //! Effects: Inserts a copy of x in the container if and only if there is 
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(iterator position, const value_type& x)
+   { return m_tree.insert_unique(position, x); }
+
+   //! Effects: Move constructs a new value from x if and only if there is 
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(iterator position, BOOST_RV_REF(nonconst_value_type) x)
+   { return m_tree.insert_unique(position, boost::move(x)); }
+
+   //! Effects: Move constructs a new value from x if and only if there is 
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(iterator position, BOOST_RV_REF(nonconst_impl_value_type) x)
+   { return m_tree.insert_unique(position, boost::move(x)); }
+
+   //! Effects: Inserts a copy of x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   iterator insert(iterator position, const nonconst_value_type& x)
+   { return m_tree.insert_unique(position, x); }
+
+   //! Effects: Inserts an element move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   iterator insert(iterator position, BOOST_RV_REF(value_type) x)
+   { return m_tree.insert_unique(position, boost::move(x)); }
+
+   //! Requires: first, last are not iterators into *this.
+   //!
+   //! Effects: inserts each element from the range [first,last) if and only 
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! Complexity: At most N log(size()+N) (N is the distance from first to last)
+   template 
+   void insert(InputIterator first, InputIterator last) 
+   {  m_tree.insert_unique(first, last);  }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object x of type T constructed with
+   //!   std::forward(args)... in the container if and only if there is 
+   //!   no element in the container with an equivalent key.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   template 
+   std::pair emplace(Args&&... args)
+   {  return m_tree.emplace_unique(boost::forward(args)...); }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the container if and only if there is 
+   //!   no element in the container with an equivalent key.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   template 
+   iterator emplace_hint(const_iterator hint, Args&&... args)
+   {  return m_tree.emplace_hint_unique(hint, boost::forward(args)...); }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                                 \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))            \
+   {  return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }       \
+                                                                                                   \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace_hint(const_iterator hint                                                       \
+                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              \
+   {  return m_tree.emplace_hint_unique(hint                                                       \
+                               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));}   \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Erases the element pointed to by position.
+   //!
+   //! Returns: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists, 
+   //!   returns end().
+   //!
+   //! Complexity: Amortized constant time
+   iterator erase(const_iterator position) 
+   { return m_tree.erase(position); }
+
+   //! Effects: Erases all elements in the container with key equivalent to x.
+   //!
+   //! Returns: Returns the number of erased elements.
+   //!
+   //! Complexity: log(size()) + count(k)
+   size_type erase(const key_type& x) 
+   { return m_tree.erase(x); }
+
+   //! Effects: Erases all the elements in the range [first, last).
+   //!
+   //! Returns: Returns last.
+   //!
+   //! Complexity: log(size())+N where N is the distance from first to last.
+   iterator erase(const_iterator first, const_iterator last)
+   { return m_tree.erase(first, last); }
+
+   //! Effects: erase(a.begin(),a.end()).
+   //!
+   //! Postcondition: size() == 0.
+   //!
+   //! Complexity: linear in size().
+   void clear() 
+   { m_tree.clear(); }
+
+   //! Returns: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   iterator find(const key_type& x) 
+   { return m_tree.find(x); }
+
+   //! Returns: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   const_iterator find(const key_type& x) const 
+   { return m_tree.find(x); }
+
+   //! Returns: The number of elements with key equivalent to x.
+   //!
+   //! Complexity: log(size())+count(k)
+   size_type count(const key_type& x) const 
+   {  return m_tree.find(x) == m_tree.end() ? 0 : 1;  }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator lower_bound(const key_type& x) 
+   {  return m_tree.lower_bound(x); }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator lower_bound(const key_type& x) const 
+   {  return m_tree.lower_bound(x); }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator upper_bound(const key_type& x) 
+   {  return m_tree.upper_bound(x); }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator upper_bound(const key_type& x) const 
+   {  return m_tree.upper_bound(x); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair equal_range(const key_type& x) 
+   {  return m_tree.equal_range(x); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair equal_range(const key_type& x) const 
+   {  return m_tree.equal_range(x); }
+
+   /// @cond
+   template 
+   friend bool operator== (const map&,
+                           const map&);
+   template 
+   friend bool operator< (const map&,
+                          const map&);
+   private:
+   mapped_type& priv_subscript(const key_type &k)
+   {
+      //we can optimize this
+      iterator i = lower_bound(k);
+      // i->first is greater than or equivalent to k.
+      if (i == end() || key_comp()(k, (*i).first)){
+         container_detail::value_init m;
+         nonconst_impl_value_type val(k, boost::move(m.m_t));
+         i = insert(i, boost::move(val));
+      }
+      return (*i).second;
+   }
+
+   mapped_type& priv_subscript(BOOST_RV_REF(key_type) mk) 
+   {
+      key_type &k = mk;
+      //we can optimize this
+      iterator i = lower_bound(k);
+      // i->first is greater than or equivalent to k.
+      if (i == end() || key_comp()(k, (*i).first)){
+         container_detail::value_init m;
+         nonconst_impl_value_type val(boost::move(k), boost::move(m.m_t));
+         i = insert(i, boost::move(val));
+      }
+      return (*i).second;
+   }
+
+   /// @endcond
+};
+
+template 
+inline bool operator==(const map& x, 
+                       const map& y) 
+   {  return x.m_tree == y.m_tree;  }
+
+template 
+inline bool operator<(const map& x, 
+                      const map& y) 
+   {  return x.m_tree < y.m_tree;   }
+
+template 
+inline bool operator!=(const map& x, 
+                       const map& y) 
+   {  return !(x == y); }
+
+template 
+inline bool operator>(const map& x, 
+                      const map& y) 
+   {  return y < x;  }
+
+template 
+inline bool operator<=(const map& x, 
+                       const map& y) 
+   {  return !(y < x);  }
+
+template 
+inline bool operator>=(const map& x, 
+                       const map& y) 
+   {  return !(x < y);  }
+
+template 
+inline void swap(map& x, map& y) 
+   {  x.swap(y);  }
+
+/// @cond
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+
+template 
+inline bool operator==(const multimap& x, 
+                       const multimap& y);
+
+template 
+inline bool operator<(const multimap& x, 
+                      const multimap& y);
+
+}  //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value && has_trivial_destructor::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+//! A multimap is a kind of associative container that supports equivalent keys 
+//! (possibly containing multiple copies of the same key value) and provides for 
+//! fast retrieval of values of another type T based on the keys. The multimap class
+//! supports bidirectional iterators.
+//! 
+//! A multimap satisfies all of the requirements of a container and of a reversible 
+//! container and of an associative container. For a 
+//! map the key_type is Key and the value_type is std::pair. 
+//!
+//! Pred is the ordering function for Keys (e.g. std::less).
+//!
+//! A is the allocator to allocate the value_types
+//!(e.g. allocator< std::pair<const Key, T> >).
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >, class A = std::allocator >
+#else
+template 
+#endif
+class multimap 
+{
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(multimap)
+   typedef container_detail::rbtree, 
+                           container_detail::select1st< std::pair >, 
+                           Pred, 
+                           A> tree_t;
+   tree_t m_tree;  // red-black tree representing map
+   typedef typename container_detail::
+      move_const_ref_type::type insert_key_const_ref_type;
+   /// @endcond
+
+   public:
+
+   // typedefs:
+   typedef typename tree_t::key_type               key_type;
+   typedef typename tree_t::value_type             value_type;
+   typedef typename tree_t::pointer                pointer;
+   typedef typename tree_t::const_pointer          const_pointer;
+   typedef typename tree_t::reference              reference;
+   typedef typename tree_t::const_reference        const_reference;
+   typedef T                                       mapped_type;
+   typedef Pred                                    key_compare;
+   typedef typename tree_t::iterator               iterator;
+   typedef typename tree_t::const_iterator         const_iterator;
+   typedef typename tree_t::reverse_iterator       reverse_iterator;
+   typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+   typedef typename tree_t::size_type              size_type;
+   typedef typename tree_t::difference_type        difference_type;
+   typedef typename tree_t::allocator_type         allocator_type;
+   typedef typename tree_t::stored_allocator_type  stored_allocator_type;
+   typedef std::pair        nonconst_value_type;
+   typedef container_detail::pair
+                            nonconst_impl_value_type;
+
+   /// @cond
+   class value_compare_impl
+      :  public Pred,
+         public std::binary_function 
+   {
+      friend class multimap;
+    protected :
+      value_compare_impl(const Pred &c) : Pred(c) {}
+    public:
+      bool operator()(const value_type& x, const value_type& y) const {
+         return Pred::operator()(x.first, y.first);
+      }
+   };
+   /// @endcond
+   typedef value_compare_impl                      value_compare;
+
+   //! Effects: Default constructs an empty multimap.
+   //! 
+   //! Complexity: Constant.
+   multimap()
+      : m_tree()
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename A::value_type>::value));
+   }
+
+   //! Effects: Constructs an empty multimap using the specified comparison
+   //!   object and allocator.
+   //! 
+   //! Complexity: Constant.
+   explicit multimap(const Pred& comp, const allocator_type& a = allocator_type())
+      : m_tree(comp, a)
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+   }
+
+   //! Effects: Constructs an empty multimap using the specified comparison object
+   //!   and allocator, and inserts elements from the range [first ,last ).
+   //! 
+   //! Complexity: Linear in N if the range [first ,last ) is already sorted using 
+   //! comp and otherwise N logN, where N is last - first.
+   template 
+   multimap(InputIterator first, InputIterator last,
+            const Pred& comp = Pred(),
+            const allocator_type& a = allocator_type())
+      : m_tree(first, last, comp, a, false) 
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+   }
+
+   //! Effects: Constructs an empty multimap using the specified comparison object and 
+   //! allocator, and inserts elements from the ordered range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! Requires: [first ,last) must be ordered according to the predicate.
+   //! 
+   //! Complexity: Linear in N.
+   template 
+   multimap(ordered_range_t ordered_range, InputIterator first, InputIterator last, const Pred& comp = Pred(),
+         const allocator_type& a = allocator_type())
+      : m_tree(ordered_range, first, last, comp, a) 
+   {}
+
+
+   //! Effects: Copy constructs a multimap.
+   //! 
+   //! Complexity: Linear in x.size().
+   multimap(const multimap& x) 
+      : m_tree(x.m_tree)
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+   }
+
+   //! Effects: Move constructs a multimap. Constructs *this using x's resources.
+   //! 
+   //! Complexity: Construct.
+   //! 
+   //! Postcondition: x is emptied.
+   multimap(BOOST_RV_REF(multimap) x) 
+      : m_tree(boost::move(x.m_tree))
+   {
+      //Allocator type must be std::pair
+      BOOST_STATIC_ASSERT((container_detail::is_same, typename     A::value_type>::value));
+   }
+
+   //! Effects: Makes *this a copy of x.
+   //! 
+   //! Complexity: Linear in x.size().
+   multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x) 
+   {  m_tree = x.m_tree;   return *this;  }
+
+   //! Effects: this->swap(x.get()).
+   //! 
+   //! Complexity: Constant.
+   multimap& operator=(BOOST_RV_REF(multimap) x) 
+   {  m_tree = boost::move(x.m_tree);   return *this;  }
+
+   //! Effects: Returns the comparison object out
+   //!   of which a was constructed.
+   //! 
+   //! Complexity: Constant.
+   key_compare key_comp() const 
+   { return m_tree.key_comp(); }
+
+   //! Effects: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //! 
+   //! Complexity: Constant.
+   value_compare value_comp() const 
+   { return value_compare(m_tree.key_comp()); }
+
+   //! Effects: Returns a copy of the Allocator that
+   //!   was passed to the object's constructor.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const 
+   { return m_tree.get_allocator(); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+   { return m_tree.get_stored_allocator(); }
+
+   stored_allocator_type &get_stored_allocator()
+   { return m_tree.get_stored_allocator(); }
+
+   //! Effects: Returns an iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin() 
+   { return m_tree.begin(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const 
+   { return m_tree.begin(); }
+
+   //! Effects: Returns an iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end() 
+   { return m_tree.end(); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const 
+   { return m_tree.end(); }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin() 
+   { return m_tree.rbegin(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const 
+   { return m_tree.rbegin(); }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend() 
+   { return m_tree.rend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const 
+   { return m_tree.rend(); }
+
+   //! Effects: Returns true if the container contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const 
+   { return m_tree.empty(); }
+
+   //! Effects: Returns the number of the elements contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const 
+   { return m_tree.size(); }
+
+   //! Effects: Returns the largest possible size of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const 
+   { return m_tree.max_size(); }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(multimap& x)
+   { m_tree.swap(x.m_tree); }
+
+   //! Effects: Inserts x and returns the iterator pointing to the
+   //!   newly inserted element. 
+   //!
+   //! Complexity: Logarithmic.
+   iterator insert(const value_type& x) 
+   { return m_tree.insert_equal(x); }
+
+   //! Effects: Inserts a new value constructed from x and returns 
+   //!   the iterator pointing to the newly inserted element. 
+   //!
+   //! Complexity: Logarithmic.
+   iterator insert(const nonconst_value_type& x) 
+   { return m_tree.insert_equal(x); }
+
+   //! Effects: Inserts a new value move-constructed from x and returns 
+   //!   the iterator pointing to the newly inserted element. 
+   //!
+   //! Complexity: Logarithmic.
+   iterator insert(BOOST_RV_REF(nonconst_value_type) x) 
+   { return m_tree.insert_equal(boost::move(x)); }
+
+   //! Effects: Inserts a new value move-constructed from x and returns 
+   //!   the iterator pointing to the newly inserted element. 
+   //!
+   //! Complexity: Logarithmic.
+   iterator insert(BOOST_RV_REF(nonconst_impl_value_type) x) 
+   { return m_tree.insert_equal(boost::move(x)); }
+
+   //! Effects: Inserts a copy of x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(iterator position, const value_type& x)
+   { return m_tree.insert_equal(position, x); }
+
+   //! Effects: Inserts a new value constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(iterator position, const nonconst_value_type& x)
+   { return m_tree.insert_equal(position, x); }
+
+   //! Effects: Inserts a new value move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(iterator position, BOOST_RV_REF(nonconst_value_type) x)
+   { return m_tree.insert_equal(position, boost::move(x)); }
+
+   //! Effects: Inserts a new value move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(iterator position, BOOST_RV_REF(nonconst_impl_value_type) x)
+   { return m_tree.insert_equal(position, boost::move(x)); }
+
+   //! Requires: first, last are not iterators into *this.
+   //!
+   //! Effects: inserts each element from the range [first,last) .
+   //!
+   //! Complexity: At most N log(size()+N) (N is the distance from first to last)
+   template 
+   void insert(InputIterator first, InputIterator last) 
+   {  m_tree.insert_equal(first, last); }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   template 
+   iterator emplace(Args&&... args)
+   {  return m_tree.emplace_equal(boost::forward(args)...); }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   template 
+   iterator emplace_hint(const_iterator hint, Args&&... args)
+   {  return m_tree.emplace_hint_equal(hint, boost::forward(args)...); }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                                 \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                            \
+   {  return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }        \
+                                                                                                   \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace_hint(const_iterator hint                                                       \
+                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              \
+   {  return m_tree.emplace_hint_equal(hint                                                        \
+                               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));}   \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Erases the element pointed to by position.
+   //!
+   //! Returns: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists, 
+   //!   returns end().
+   //!
+   //! Complexity: Amortized constant time
+   iterator erase(const_iterator position) 
+   { return m_tree.erase(position); }
+
+   //! Effects: Erases all elements in the container with key equivalent to x.
+   //!
+   //! Returns: Returns the number of erased elements.
+   //!
+   //! Complexity: log(size()) + count(k)
+   size_type erase(const key_type& x) 
+   { return m_tree.erase(x); }
+
+   //! Effects: Erases all the elements in the range [first, last).
+   //!
+   //! Returns: Returns last.
+   //!
+   //! Complexity: log(size())+N where N is the distance from first to last.
+   iterator erase(const_iterator first, const_iterator last)
+   { return m_tree.erase(first, last); }
+
+   //! Effects: erase(a.begin(),a.end()).
+   //!
+   //! Postcondition: size() == 0.
+   //!
+   //! Complexity: linear in size().
+   void clear() 
+   { m_tree.clear(); }
+
+   //! Returns: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   iterator find(const key_type& x) 
+   { return m_tree.find(x); }
+
+   //! Returns: A const iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   const_iterator find(const key_type& x) const 
+   { return m_tree.find(x); }
+
+   //! Returns: The number of elements with key equivalent to x.
+   //!
+   //! Complexity: log(size())+count(k)
+   size_type count(const key_type& x) const 
+   { return m_tree.count(x); }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator lower_bound(const key_type& x) 
+   {return m_tree.lower_bound(x); }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator lower_bound(const key_type& x) const 
+   {  return m_tree.lower_bound(x);  }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator upper_bound(const key_type& x) 
+   {  return m_tree.upper_bound(x); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair equal_range(const key_type& x) 
+   {  return m_tree.equal_range(x);   }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator upper_bound(const key_type& x) const 
+   {  return m_tree.upper_bound(x); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair 
+      equal_range(const key_type& x) const 
+   {  return m_tree.equal_range(x);   }
+
+   /// @cond
+   template 
+   friend bool operator== (const multimap& x,
+                           const multimap& y);
+
+   template 
+   friend bool operator< (const multimap& x,
+                          const multimap& y);
+   /// @endcond
+};
+
+template 
+inline bool operator==(const multimap& x, 
+                       const multimap& y) 
+{  return x.m_tree == y.m_tree;  }
+
+template 
+inline bool operator<(const multimap& x, 
+                      const multimap& y) 
+{  return x.m_tree < y.m_tree;   }
+
+template 
+inline bool operator!=(const multimap& x, 
+                       const multimap& y) 
+{  return !(x == y);  }
+
+template 
+inline bool operator>(const multimap& x, 
+                      const multimap& y) 
+{  return y < x;  }
+
+template 
+inline bool operator<=(const multimap& x, 
+                       const multimap& y) 
+{  return !(y < x);  }
+
+template 
+inline bool operator>=(const multimap& x, 
+                       const multimap& y) 
+{  return !(x < y);  }
+
+template 
+inline void swap(multimap& x, multimap& y) 
+{  x.swap(y);  }
+
+/// @cond
+
+}  //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value && has_trivial_destructor::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+}}
+
+#include 
+
+#endif /* BOOST_CONTAINER_MAP_HPP */
+
diff --git a/src/third_party/boost/boost/container/set.hpp b/src/third_party/boost/boost/container/set.hpp
new file mode 100644
index 00000000000..b25e7013fc7
--- /dev/null
+++ b/src/third_party/boost/boost/container/set.hpp
@@ -0,0 +1,1176 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_SET_HPP
+#define BOOST_CONTAINER_SET_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
+#include 
+#endif
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+// Forward declarations of operators < and ==, needed for friend declaration.
+template 
+inline bool operator==(const set& x, 
+                       const set& y);
+
+template 
+inline bool operator<(const set& x, 
+                      const set& y);
+/// @endcond
+
+//! A set is a kind of associative container that supports unique keys (contains at 
+//! most one of each key value) and provides for fast retrieval of the keys themselves. 
+//! Class set supports bidirectional iterators. 
+//! 
+//! A set satisfies all of the requirements of a container and of a reversible container 
+//! , and of an associative container. A set also provides most operations described in 
+//! for unique keys.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template , class A = std::allocator >
+#else
+template 
+#endif
+class set 
+{
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(set)
+   typedef container_detail::rbtree, Pred, A> tree_t;
+   tree_t m_tree;  // red-black tree representing set
+   typedef typename container_detail::
+      move_const_ref_type::type insert_const_ref_type;
+   /// @endcond
+
+   public:
+
+   // typedefs:
+   typedef typename tree_t::key_type               key_type;
+   typedef typename tree_t::value_type             value_type;
+   typedef typename tree_t::pointer                pointer;
+   typedef typename tree_t::const_pointer          const_pointer;
+   typedef typename tree_t::reference              reference;
+   typedef typename tree_t::const_reference        const_reference;
+   typedef Pred                                    key_compare;
+   typedef Pred                                    value_compare;
+   typedef typename tree_t::iterator               iterator;
+   typedef typename tree_t::const_iterator         const_iterator;
+   typedef typename tree_t::reverse_iterator       reverse_iterator;
+   typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+   typedef typename tree_t::size_type              size_type;
+   typedef typename tree_t::difference_type        difference_type;
+   typedef typename tree_t::allocator_type         allocator_type;
+   typedef typename tree_t::stored_allocator_type  stored_allocator_type;
+
+   //! Effects: Default constructs an empty set.
+   //! 
+   //! Complexity: Constant.
+   set()
+      : m_tree()
+   {}
+
+   //! Effects: Constructs an empty set using the specified comparison object 
+   //! and allocator.
+   //! 
+   //! Complexity: Constant.
+   explicit set(const Pred& comp,
+                const allocator_type& a = allocator_type())
+      : m_tree(comp, a)
+   {}
+
+   //! Effects: Constructs an empty set using the specified comparison object and 
+   //! allocator, and inserts elements from the range [first ,last ).
+   //! 
+   //! Complexity: Linear in N if the range [first ,last ) is already sorted using 
+   //! comp and otherwise N logN, where N is last - first.
+   template 
+   set(InputIterator first, InputIterator last, const Pred& comp = Pred(),
+         const allocator_type& a = allocator_type())
+      : m_tree(first, last, comp, a, true) 
+   {}
+
+   //! Effects: Constructs an empty set using the specified comparison object and 
+   //! allocator, and inserts elements from the ordered unique range [first ,last). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! Requires: [first ,last) must be ordered according to the predicate and must be
+   //! unique values.
+   //! 
+   //! Complexity: Linear in N.
+   template 
+   set( ordered_unique_range_t, InputIterator first, InputIterator last
+      , const Pred& comp = Pred(), const allocator_type& a = allocator_type())
+      : m_tree(ordered_range, first, last, comp, a) 
+   {}
+
+   //! Effects: Copy constructs a set.
+   //! 
+   //! Complexity: Linear in x.size().
+   set(const set& x) 
+      : m_tree(x.m_tree)
+   {}
+
+   //! Effects: Move constructs a set. Constructs *this using x's resources.
+   //! 
+   //! Complexity: Construct.
+   //! 
+   //! Postcondition: x is emptied.
+   set(BOOST_RV_REF(set) x) 
+      : m_tree(boost::move(x.m_tree))
+   {}
+
+   //! Effects: Makes *this a copy of x.
+   //! 
+   //! Complexity: Linear in x.size().
+   set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
+   {  m_tree = x.m_tree;   return *this;  }
+
+   //! Effects: this->swap(x.get()).
+   //! 
+   //! Complexity: Constant.
+   set& operator=(BOOST_RV_REF(set) x)
+   {  m_tree = boost::move(x.m_tree);   return *this;  }
+
+   //! Effects: Returns the comparison object out
+   //!   of which a was constructed.
+   //! 
+   //! Complexity: Constant.
+   key_compare key_comp() const 
+   { return m_tree.key_comp(); }
+
+   //! Effects: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //! 
+   //! Complexity: Constant.
+   value_compare value_comp() const 
+   { return m_tree.key_comp(); }
+
+   //! Effects: Returns a copy of the Allocator that
+   //!   was passed to the object's constructor.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const 
+   { return m_tree.get_allocator(); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+   { return m_tree.get_stored_allocator(); }
+
+   stored_allocator_type &get_stored_allocator()
+   { return m_tree.get_stored_allocator(); }
+
+   //! Effects: Returns an iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant
+   iterator begin() 
+   { return m_tree.begin(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const 
+   { return m_tree.begin(); }
+
+   //! Effects: Returns an iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end() 
+   { return m_tree.end(); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const 
+   { return m_tree.end(); }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin() 
+   { return m_tree.rbegin(); } 
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const 
+   { return m_tree.rbegin(); } 
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend() 
+   { return m_tree.rend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const 
+   { return m_tree.rend(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const 
+   { return m_tree.cbegin(); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const 
+   { return m_tree.cend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin() const 
+   { return m_tree.crbegin(); } 
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend() const 
+   { return m_tree.crend(); }
+
+   //! Effects: Returns true if the container contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const 
+   { return m_tree.empty(); }
+
+   //! Effects: Returns the number of the elements contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const 
+   { return m_tree.size(); }
+
+   //! Effects: Returns the largest possible size of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const 
+   { return m_tree.max_size(); }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(set& x)
+   { m_tree.swap(x.m_tree); }
+
+   //! Effects: Inserts x if and only if there is no element in the container 
+   //!   with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   std::pair insert(insert_const_ref_type x) 
+   {  return priv_insert(x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   std::pair insert(T &x)
+   { return this->insert(const_cast(x)); }
+
+   template
+   std::pair insert(const U &u
+      , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return priv_insert(u); }
+   #endif
+
+   //! Effects: Move constructs a new value from x if and only if there is 
+   //!   no element in the container with key equivalent to the key of x.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   std::pair insert(BOOST_RV_REF(value_type) x) 
+   {  return m_tree.insert_unique(boost::move(x));  }
+
+   //! Effects: Inserts a copy of x in the container if and only if there is 
+   //!   no element in the container with key equivalent to the key of x.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(const_iterator p, insert_const_ref_type x) 
+   {  return priv_insert(p, x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   iterator insert(const_iterator position, T &x)
+   { return this->insert(position, const_cast(x)); }
+
+   template
+   iterator insert( const_iterator position, const U &u
+                  , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return priv_insert(position, u); }
+   #endif
+
+   //! Effects: Inserts an element move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) 
+   {  return m_tree.insert_unique(p, boost::move(x)); }
+
+   //! Requires: first, last are not iterators into *this.
+   //!
+   //! Effects: inserts each element from the range [first,last) if and only 
+   //!   if there is no element with key equivalent to the key of that element.
+   //!
+   //! Complexity: At most N log(size()+N) (N is the distance from first to last)
+   template 
+   void insert(InputIterator first, InputIterator last) 
+   {  m_tree.insert_unique(first, last);  }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects:  Inserts an object x of type T constructed with
+   //!   std::forward(args)... if and only if there is 
+   //!   no element in the container with equivalent value.
+   //!   and returns the iterator pointing to the
+   //!   newly inserted element.
+   //!
+   //! Returns: The bool component of the returned pair is true if and only 
+   //!   if the insertion takes place, and the iterator component of the pair
+   //!   points to the element with key equivalent to the key of x.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! Complexity: Logarithmic.
+   template 
+   std::pair emplace(Args&&... args)
+   {  return m_tree.emplace_unique(boost::forward(args)...); }
+
+   //! Effects:  Inserts an object of type T constructed with
+   //!   std::forward(args)... if and only if there is 
+   //!   no element in the container with equivalent value.
+   //!   p is a hint pointing to where the insert
+   //!   should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent to the key of x.
+   //!
+   //! Complexity: Logarithmic.
+   template 
+   iterator emplace_hint(const_iterator hint, Args&&... args)
+   {  return m_tree.emplace_hint_unique(hint, boost::forward(args)...); }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                                 \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   std::pair emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))            \
+   {  return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }       \
+                                                                                                   \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace_hint(const_iterator hint                                                       \
+                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              \
+   {  return m_tree.emplace_hint_unique(hint                                                       \
+                               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));}   \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Erases the element pointed to by p.
+   //!
+   //! Returns: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists, 
+   //!   returns end().
+   //!
+   //! Complexity: Amortized constant time
+   iterator erase(const_iterator p) 
+   {  return m_tree.erase(p); }
+
+   //! Effects: Erases all elements in the container with key equivalent to x.
+   //!
+   //! Returns: Returns the number of erased elements.
+   //!
+   //! Complexity: log(size()) + count(k)
+   size_type erase(const key_type& x) 
+   {  return m_tree.erase(x); }
+
+   //! Effects: Erases all the elements in the range [first, last).
+   //!
+   //! Returns: Returns last.
+   //!
+   //! Complexity: log(size())+N where N is the distance from first to last.
+   iterator erase(const_iterator first, const_iterator last) 
+   {  return m_tree.erase(first, last);  }
+
+   //! Effects: erase(a.begin(),a.end()).
+   //!
+   //! Postcondition: size() == 0.
+   //!
+   //! Complexity: linear in size().
+   void clear() 
+   { m_tree.clear(); }
+
+   //! Returns: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   iterator find(const key_type& x) 
+   { return m_tree.find(x); }
+
+   //! Returns: A const_iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   const_iterator find(const key_type& x) const 
+   { return m_tree.find(x); }
+
+   //! Returns: The number of elements with key equivalent to x.
+   //!
+   //! Complexity: log(size())+count(k)
+   size_type count(const key_type& x) const 
+   {  return m_tree.find(x) == m_tree.end() ? 0 : 1;  }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator lower_bound(const key_type& x) 
+   {  return m_tree.lower_bound(x); }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator lower_bound(const key_type& x) const 
+   {  return m_tree.lower_bound(x); }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator upper_bound(const key_type& x)
+   {  return m_tree.upper_bound(x);    }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator upper_bound(const key_type& x) const 
+   {  return m_tree.upper_bound(x);    }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair 
+      equal_range(const key_type& x) 
+   {  return m_tree.equal_range(x); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair 
+      equal_range(const key_type& x) const 
+   {  return m_tree.equal_range(x); }
+
+   /// @cond
+   template 
+   friend bool operator== (const set&, const set&);
+
+   template 
+   friend bool operator< (const set&, const set&);
+
+   private:
+   std::pair priv_insert(const T &x) 
+   {  return m_tree.insert_unique(x);  }
+
+   iterator priv_insert(const_iterator p, const T &x) 
+   {  return m_tree.insert_unique(p, x); }
+
+   /// @endcond
+};
+
+template 
+inline bool operator==(const set& x, 
+                       const set& y) 
+{  return x.m_tree == y.m_tree;  }
+
+template 
+inline bool operator<(const set& x, 
+                      const set& y) 
+{  return x.m_tree < y.m_tree;   }
+
+template 
+inline bool operator!=(const set& x, 
+                       const set& y) 
+{  return !(x == y);   }
+
+template 
+inline bool operator>(const set& x, 
+                      const set& y) 
+{  return y < x; }
+
+template 
+inline bool operator<=(const set& x, 
+                       const set& y) 
+{  return !(y < x); }
+
+template 
+inline bool operator>=(const set& x, 
+                       const set& y) 
+{  return !(x < y);  }
+
+template 
+inline void swap(set& x, set& y) 
+{  x.swap(y);  }
+
+/// @cond
+
+}  //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value && has_trivial_destructor::value;
+};
+*/
+namespace container {
+
+// Forward declaration of operators < and ==, needed for friend declaration.
+
+template 
+inline bool operator==(const multiset& x, 
+                       const multiset& y);
+
+template 
+inline bool operator<(const multiset& x, 
+                      const multiset& y);
+/// @endcond
+
+//! A multiset is a kind of associative container that supports equivalent keys 
+//! (possibly contains multiple copies of the same key value) and provides for 
+//! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators.
+//! 
+//! A multiset satisfies all of the requirements of a container and of a reversible 
+//! container, and of an associative container). multiset also provides most operations 
+//! described for duplicate keys.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template , class A = std::allocator >
+#else
+template 
+#endif
+class multiset 
+{
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(multiset)
+   typedef container_detail::rbtree, Pred, A> tree_t;
+   tree_t m_tree;  // red-black tree representing multiset
+   typedef typename container_detail::
+      move_const_ref_type::type insert_const_ref_type;
+   /// @endcond
+
+   public:
+
+   // typedefs:
+   typedef typename tree_t::key_type               key_type;
+   typedef typename tree_t::value_type             value_type;
+   typedef typename tree_t::pointer                pointer;
+   typedef typename tree_t::const_pointer          const_pointer;
+   typedef typename tree_t::reference              reference;
+   typedef typename tree_t::const_reference        const_reference;
+   typedef Pred                                    key_compare;
+   typedef Pred                                    value_compare;
+   typedef typename tree_t::iterator               iterator;
+   typedef typename tree_t::const_iterator         const_iterator;
+   typedef typename tree_t::reverse_iterator       reverse_iterator;
+   typedef typename tree_t::const_reverse_iterator const_reverse_iterator;
+   typedef typename tree_t::size_type              size_type;
+   typedef typename tree_t::difference_type        difference_type;
+   typedef typename tree_t::allocator_type         allocator_type;
+   typedef typename tree_t::stored_allocator_type  stored_allocator_type;
+
+   //! Effects: Constructs an empty multiset using the specified comparison
+   //!   object and allocator.
+   //! 
+   //! Complexity: Constant.
+   multiset()
+      : m_tree()
+   {}
+
+   //! Effects: Constructs an empty multiset using the specified comparison
+   //!   object and allocator.
+   //! 
+   //! Complexity: Constant.
+   explicit multiset(const Pred& comp,
+                     const allocator_type& a = allocator_type())
+      : m_tree(comp, a)
+   {}
+
+   //! Effects: Constructs an empty multiset using the specified comparison object
+   //!   and allocator, and inserts elements from the range [first ,last ).
+   //! 
+   //! Complexity: Linear in N if the range [first ,last ) is already sorted using 
+   //! comp and otherwise N logN, where N is last - first.
+   template 
+   multiset(InputIterator first, InputIterator last,
+            const Pred& comp = Pred(),
+            const allocator_type& a = allocator_type())
+      : m_tree(first, last, comp, a, false) 
+   {}
+
+   //! Effects: Constructs an empty multiset using the specified comparison object and 
+   //! allocator, and inserts elements from the ordered range [first ,last ). This function
+   //! is more efficient than the normal range creation for ordered ranges.
+   //!
+   //! Requires: [first ,last) must be ordered according to the predicate.
+   //! 
+   //! Complexity: Linear in N.
+   template 
+   multiset( ordered_range_t ordered_range, InputIterator first, InputIterator last
+           , const Pred& comp = Pred()
+           , const allocator_type& a = allocator_type())
+      : m_tree(ordered_range, first, last, comp, a) 
+   {}
+
+   //! Effects: Copy constructs a multiset.
+   //! 
+   //! Complexity: Linear in x.size().
+   multiset(const multiset& x) 
+      : m_tree(x.m_tree)
+   {}
+
+   //! Effects: Move constructs a multiset. Constructs *this using x's resources.
+   //! 
+   //! Complexity: Construct.
+   //! 
+   //! Postcondition: x is emptied.
+   multiset(BOOST_RV_REF(multiset) x) 
+      : m_tree(boost::move(x.m_tree))
+   {}
+
+   //! Effects: Makes *this a copy of x.
+   //! 
+   //! Complexity: Linear in x.size().
+   multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x) 
+   {  m_tree = x.m_tree;   return *this;  }
+
+   //! Effects: this->swap(x.get()).
+   //! 
+   //! Complexity: Constant.
+   multiset& operator=(BOOST_RV_REF(multiset) x) 
+   {  m_tree = boost::move(x.m_tree);   return *this;  }
+
+   //! Effects: Returns the comparison object out
+   //!   of which a was constructed.
+   //! 
+   //! Complexity: Constant.
+   key_compare key_comp() const 
+   { return m_tree.key_comp(); }
+
+   //! Effects: Returns an object of value_compare constructed out
+   //!   of the comparison object.
+   //! 
+   //! Complexity: Constant.
+   value_compare value_comp() const 
+   { return m_tree.key_comp(); }
+
+   //! Effects: Returns a copy of the Allocator that
+   //!   was passed to the object's constructor.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const 
+   { return m_tree.get_allocator(); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+   { return m_tree.get_stored_allocator(); }
+
+   stored_allocator_type &get_stored_allocator()
+   { return m_tree.get_stored_allocator(); }
+
+   //! Effects: Returns an iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin() 
+   { return m_tree.begin(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const 
+   { return m_tree.begin(); }
+
+   //! Effects: Returns an iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end() 
+   { return m_tree.end(); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const 
+   { return m_tree.end(); }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin() 
+   { return m_tree.rbegin(); } 
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const 
+   { return m_tree.rbegin(); } 
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend() 
+   { return m_tree.rend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const 
+   { return m_tree.rend(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const 
+   { return m_tree.cbegin(); }
+
+   //! Effects: Returns a const_iterator to the end of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const 
+   { return m_tree.cend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin() const 
+   { return m_tree.crbegin(); } 
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed container. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend() const 
+   { return m_tree.crend(); }
+
+   //! Effects: Returns true if the container contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const 
+   { return m_tree.empty(); }
+
+   //! Effects: Returns the number of the elements contained in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const 
+   { return m_tree.size(); }
+
+   //! Effects: Returns the largest possible size of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const 
+   { return m_tree.max_size(); }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(multiset& x)
+   { m_tree.swap(x.m_tree); }
+
+   //! Effects: Inserts x and returns the iterator pointing to the
+   //!   newly inserted element. 
+   //!
+   //! Complexity: Logarithmic.
+   iterator insert(insert_const_ref_type x) 
+   {  return priv_insert(x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   iterator insert(T &x)
+   { return this->insert(const_cast(x)); }
+
+   template
+   iterator insert(const U &u
+      , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return priv_insert(u); }
+   #endif
+
+   //! Effects: Inserts a copy of x in the container.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(BOOST_RV_REF(value_type) x) 
+   {  return m_tree.insert_equal(boost::move(x));  }
+
+   //! Effects: Inserts a copy of x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(const_iterator p, insert_const_ref_type x) 
+   {  return priv_insert(p, x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   iterator insert(const_iterator position, T &x)
+   { return this->insert(position, const_cast(x)); }
+
+   template
+   iterator insert( const_iterator position, const U &u
+                  , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return priv_insert(position, u); }
+   #endif
+
+   //! Effects: Inserts a value move constructed from x in the container.
+   //!   p is a hint pointing to where the insert should start to search.
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) 
+   {  return m_tree.insert_equal(p, boost::move(x));  }
+
+   //! Requires: first, last are not iterators into *this.
+   //!
+   //! Effects: inserts each element from the range [first,last) .
+   //!
+   //! Complexity: At most N log(size()+N) (N is the distance from first to last)
+   template 
+   void insert(InputIterator first, InputIterator last) 
+   {  m_tree.insert_equal(first, last);  }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... and returns the iterator pointing to the
+   //!   newly inserted element. 
+   //!
+   //! Complexity: Logarithmic.
+   template 
+   iterator emplace(Args&&... args)
+   {  return m_tree.emplace_equal(boost::forward(args)...); }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)...
+   //!
+   //! Returns: An iterator pointing to the element with key equivalent
+   //!   to the key of x.
+   //!
+   //! Complexity: Logarithmic in general, but amortized constant if t
+   //!   is inserted right before p.
+   template 
+   iterator emplace_hint(const_iterator hint, Args&&... args)
+   {  return m_tree.emplace_hint_equal(hint, boost::forward(args)...); }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                                 \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                            \
+   {  return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }        \
+                                                                                                   \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          \
+   iterator emplace_hint(const_iterator hint                                                       \
+                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              \
+   {  return m_tree.emplace_hint_equal(hint                                                        \
+                               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));}   \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Erases the element pointed to by p.
+   //!
+   //! Returns: Returns an iterator pointing to the element immediately
+   //!   following q prior to the element being erased. If no such element exists, 
+   //!   returns end().
+   //!
+   //! Complexity: Amortized constant time
+   iterator erase(const_iterator p) 
+   {  return m_tree.erase(p); }
+
+   //! Effects: Erases all elements in the container with key equivalent to x.
+   //!
+   //! Returns: Returns the number of erased elements.
+   //!
+   //! Complexity: log(size()) + count(k)
+   size_type erase(const key_type& x) 
+   {  return m_tree.erase(x); }
+
+   //! Effects: Erases all the elements in the range [first, last).
+   //!
+   //! Returns: Returns last.
+   //!
+   //! Complexity: log(size())+N where N is the distance from first to last.
+   iterator erase(const_iterator first, const_iterator last)
+   {  return m_tree.erase(first, last); }
+
+   //! Effects: erase(a.begin(),a.end()).
+   //!
+   //! Postcondition: size() == 0.
+   //!
+   //! Complexity: linear in size().
+   void clear() 
+   { m_tree.clear(); }
+
+   //! Returns: An iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   iterator find(const key_type& x) 
+   { return m_tree.find(x); }
+
+   //! Returns: A const iterator pointing to an element with the key
+   //!   equivalent to x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic.
+   const_iterator find(const key_type& x) const 
+   { return m_tree.find(x); }
+
+   //! Returns: The number of elements with key equivalent to x.
+   //!
+   //! Complexity: log(size())+count(k)
+   size_type count(const key_type& x) const 
+   {  return m_tree.count(x);  }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator lower_bound(const key_type& x) 
+   {  return m_tree.lower_bound(x); }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than k, or a.end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator lower_bound(const key_type& x) const 
+   {  return m_tree.lower_bound(x); }
+
+   //! Returns: An iterator pointing to the first element with key not less
+   //!   than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   iterator upper_bound(const key_type& x)
+   {  return m_tree.upper_bound(x);    }
+
+   //! Returns: A const iterator pointing to the first element with key not
+   //!   less than x, or end() if such an element is not found.
+   //!
+   //! Complexity: Logarithmic
+   const_iterator upper_bound(const key_type& x) const 
+   {  return m_tree.upper_bound(x);    }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair 
+      equal_range(const key_type& x) 
+   {  return m_tree.equal_range(x); }
+
+   //! Effects: Equivalent to std::make_pair(this->lower_bound(k), this->upper_bound(k)).
+   //!
+   //! Complexity: Logarithmic
+   std::pair 
+      equal_range(const key_type& x) const 
+   {  return m_tree.equal_range(x); }
+
+   /// @cond
+   template 
+   friend bool operator== (const multiset&,
+                           const multiset&);
+   template 
+   friend bool operator< (const multiset&,
+                          const multiset&);
+   private:
+   iterator priv_insert(const T &x) 
+   {  return m_tree.insert_equal(x);  }
+
+   iterator priv_insert(const_iterator p, const T &x) 
+   {  return m_tree.insert_equal(p, x); }
+
+   /// @endcond
+};
+
+template 
+inline bool operator==(const multiset& x, 
+                       const multiset& y) 
+{  return x.m_tree == y.m_tree;  }
+
+template 
+inline bool operator<(const multiset& x, 
+                      const multiset& y) 
+{  return x.m_tree < y.m_tree;   }
+
+template 
+inline bool operator!=(const multiset& x, 
+                       const multiset& y) 
+{  return !(x == y);  }
+
+template 
+inline bool operator>(const multiset& x, 
+                      const multiset& y) 
+{  return y < x;  }
+
+template 
+inline bool operator<=(const multiset& x, 
+                       const multiset& y) 
+{  return !(y < x);  }
+
+template 
+inline bool operator>=(const multiset& x, 
+                       const multiset& y) 
+{  return !(x < y);  }
+
+template 
+inline void swap(multiset& x, multiset& y) 
+{  x.swap(y);  }
+
+/// @cond
+
+}  //namespace container {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value && has_trivial_destructor::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+}}
+
+#include 
+
+#endif /* BOOST_CONTAINER_SET_HPP */
+
diff --git a/src/third_party/boost/boost/container/slist.hpp b/src/third_party/boost/boost/container/slist.hpp
new file mode 100644
index 00000000000..1cdcdf1046a
--- /dev/null
+++ b/src/third_party/boost/boost/container/slist.hpp
@@ -0,0 +1,1549 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2004-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_SLIST_HPP
+#define BOOST_CONTAINER_SLIST_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+#if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+//Preprocessor library to emulate perfect forwarding
+#else
+#include  
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+
+namespace container_detail {
+
+template
+struct slist_hook
+{
+   typedef typename container_detail::bi::make_slist_base_hook
+      , container_detail::bi::link_mode >::type type;
+};
+
+template 
+struct slist_node
+   :  public slist_hook::type
+{
+
+   slist_node()
+      : m_data()
+   {}
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   template
+   slist_node(Args &&...args)
+      : m_data(boost::forward(args)...)
+   {}
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                      \
+   template                           \
+   slist_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))       \
+      : m_data(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))   \
+   {}                                                                   \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif//#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   T m_data;
+};
+
+template
+struct intrusive_slist_type
+{
+   typedef boost::container::allocator_traits      allocator_traits_type;
+   typedef typename allocator_traits_type::value_type value_type;
+   typedef typename boost::intrusive::pointer_traits
+      ::template
+         rebind_pointer::type
+            void_pointer;
+   typedef typename container_detail::slist_node
+                      node_type;
+
+   typedef typename container_detail::bi::make_slist
+      ::type>
+      ,container_detail::bi::constant_time_size
+      , container_detail::bi::size_type
+         
+      >::type                                   container_type;
+   typedef container_type                       type ;
+};
+
+}  //namespace container_detail {
+
+/// @endcond
+
+//! An slist is a singly linked list: a list where each element is linked to the next 
+//! element, but not to the previous element. That is, it is a Sequence that 
+//! supports forward but not backward traversal, and (amortized) constant time 
+//! insertion and removal of elements. Slists, like lists, have the important 
+//! property that insertion and splicing do not invalidate iterators to list elements, 
+//! and that even removal invalidates only the iterators that point to the elements 
+//! that are removed. The ordering of iterators may be changed (that is, 
+//! slist::iterator might have a different predecessor or successor after a list 
+//! operation than it did before), but the iterators themselves will not be invalidated 
+//! or made to point to different elements unless that invalidation or mutation is explicit.
+//!
+//! The main difference between slist and list is that list's iterators are bidirectional 
+//! iterators, while slist's iterators are forward iterators. This means that slist is 
+//! less versatile than list; frequently, however, bidirectional iterators are 
+//! unnecessary. You should usually use slist unless you actually need the extra 
+//! functionality of list, because singly linked lists are smaller and faster than double 
+//! linked lists. 
+//! 
+//! Important performance note: like every other Sequence, slist defines the member 
+//! functions insert and erase. Using these member functions carelessly, however, can 
+//! result in disastrously slow programs. The problem is that insert's first argument is 
+//! an iterator p, and that it inserts the new element(s) before p. This means that 
+//! insert must find the iterator just before p; this is a constant-time operation 
+//! for list, since list has bidirectional iterators, but for slist it must find that 
+//! iterator by traversing the list from the beginning up to p. In other words: 
+//! insert and erase are slow operations anywhere but near the beginning of the slist.
+//! 
+//! Slist provides the member functions insert_after and erase_after, which are constant 
+//! time operations: you should always use insert_after and erase_after whenever 
+//! possible. If you find that insert_after and erase_after aren't adequate for your 
+//! needs, and that you often need to use insert and erase in the middle of the list, 
+//! then you should probably use list instead of slist.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >
+#else
+template 
+#endif
+class slist 
+   : protected container_detail::node_alloc_holder
+      ::type>
+{
+   /// @cond
+   typedef typename container_detail::
+      move_const_ref_type::type                    insert_const_ref_type;
+   typedef typename 
+      container_detail::intrusive_slist_type::type           Icont;
+   typedef container_detail::node_alloc_holder        AllocHolder;
+   typedef typename AllocHolder::NodePtr              NodePtr;
+   typedef slist                                ThisType;
+   typedef typename AllocHolder::NodeAlloc            NodeAlloc;
+   typedef typename AllocHolder::ValAlloc             ValAlloc;
+   typedef typename AllocHolder::Node                 Node;
+   typedef container_detail::allocator_destroyer     Destroyer;
+   typedef typename AllocHolder::allocator_v1         allocator_v1;
+   typedef typename AllocHolder::allocator_v2         allocator_v2;
+   typedef typename AllocHolder::alloc_version        alloc_version;
+   typedef boost::container::allocator_traits      allocator_traits_type;
+
+   class equal_to_value
+   {
+      typedef typename AllocHolder::value_type value_type;
+      const value_type &t_;
+
+      public:
+      equal_to_value(const value_type &t)
+         :  t_(t)
+      {}
+
+      bool operator()(const value_type &t)const
+      {  return t_ == t;   }
+   };
+
+   template
+   struct ValueCompareToNodeCompare
+      :  Pred
+   {
+      ValueCompareToNodeCompare(Pred pred)
+         :  Pred(pred)
+      {}
+
+      bool operator()(const Node &a, const Node &b) const
+      {  return static_cast(*this)(a.m_data, b.m_data);  }
+
+      bool operator()(const Node &a) const
+      {  return static_cast(*this)(a.m_data);  }
+   };
+   /// @endcond
+   public:
+   //! The type of object, T, stored in the list
+   typedef T                                                value_type;
+   //! Pointer to T
+   typedef typename allocator_traits_type::pointer          pointer;
+   //! Const pointer to T
+   typedef typename allocator_traits_type::const_pointer    const_pointer;
+   //! Reference to T
+   typedef typename allocator_traits_type::reference        reference;
+   //! Const reference to T
+   typedef typename allocator_traits_type::const_reference  const_reference;
+   //! An unsigned integral type
+   typedef typename allocator_traits_type::size_type        size_type;
+   //! A signed integral type
+   typedef typename allocator_traits_type::difference_type  difference_type;
+   //! The allocator type
+   typedef A                                                allocator_type;
+   //! Non-standard extension: the stored allocator type
+   typedef NodeAlloc                                        stored_allocator_type;
+
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(slist)
+   typedef difference_type                         list_difference_type;
+   typedef pointer                                 list_pointer;
+   typedef const_pointer                           list_const_pointer;
+   typedef reference                               list_reference;
+   typedef const_reference                         list_const_reference;
+   /// @endcond
+
+   public:
+
+   //! Const iterator used to iterate through a list. 
+   class const_iterator
+      /// @cond
+      : public std::iterator
+   {
+
+      protected:
+      typename Icont::iterator m_it;
+      explicit const_iterator(typename Icont::iterator it)  : m_it(it){}
+      void prot_incr(){ ++m_it; }
+
+      private:
+      typename Icont::iterator get()
+      {  return this->m_it;   }
+
+      public:
+      friend class slist;
+      typedef list_difference_type        difference_type;
+
+      //Constructors
+      const_iterator()
+         :  m_it()
+      {}
+
+      //Pointer like operators
+      const_reference operator*() const 
+      { return m_it->m_data;  }
+
+      const_pointer   operator->() const 
+      { return  const_pointer(&m_it->m_data); }
+
+      //Increment / Decrement
+      const_iterator& operator++()       
+      { prot_incr();  return *this; }
+
+      const_iterator operator++(int)      
+      { typename Icont::iterator tmp = m_it; ++*this; return const_iterator(tmp);  }
+
+      //Comparison operators
+      bool operator==   (const const_iterator& r)  const
+      {  return m_it == r.m_it;  }
+
+      bool operator!=   (const const_iterator& r)  const
+      {  return m_it != r.m_it;  }
+   }
+      /// @endcond
+   ;
+
+   //! Iterator used to iterate through a list
+   class iterator
+      /// @cond
+   : public const_iterator
+   {
+
+      private:
+      explicit iterator(typename Icont::iterator it)
+         :  const_iterator(it)
+      {}
+   
+      typename Icont::iterator get()
+      {  return this->m_it;   }
+
+      public:
+      friend class slist;
+      typedef list_pointer       pointer;
+      typedef list_reference     reference;
+
+      //Constructors
+      iterator(){}
+
+      //Pointer like operators
+      reference operator*()  const {  return  this->m_it->m_data;  }
+      pointer   operator->() const {  return  pointer(&this->m_it->m_data);  }
+
+      //Increment / Decrement
+      iterator& operator++()  
+         { this->prot_incr(); return *this;  }
+
+      iterator operator++(int)
+         { typename Icont::iterator tmp = this->m_it; ++*this; return iterator(tmp); }
+   }
+      /// @endcond
+   ;
+
+   public:
+   //! Effects: Constructs a list taking the allocator as parameter.
+   //! 
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   slist()
+      :  AllocHolder()
+   {}
+
+   //! Effects: Constructs a list taking the allocator as parameter.
+   //! 
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   explicit slist(const allocator_type& a)
+      :  AllocHolder(a)
+   {}
+
+   explicit slist(size_type n)
+      :  AllocHolder(allocator_type())
+   { this->resize(n); }
+
+   //! Effects: Constructs a list that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's default or copy constructor throws.
+   //! 
+   //! Complexity: Linear to n.
+   explicit slist(size_type n, const value_type& x, const allocator_type& a = allocator_type())
+      :  AllocHolder(a)
+   { this->priv_create_and_insert_nodes(this->before_begin(), n, x); }
+
+   //! Effects: Constructs a list that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the list.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's constructor taking an dereferenced InIt throws.
+   //!
+   //! Complexity: Linear to the range [first, last).
+   template 
+   slist(InpIt first, InpIt last,
+         const allocator_type& a =  allocator_type()) 
+      : AllocHolder(a)
+   { this->insert_after(this->before_begin(), first, last); }
+
+   //! Effects: Copy constructs a list.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Throws: If allocator_type's default constructor or copy constructor throws.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   slist(const slist& x) 
+      : AllocHolder(x)
+   { this->insert_after(this->before_begin(), x.begin(), x.end()); }
+
+   //! Effects: Move constructor. Moves mx's resources to *this.
+   //!
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   slist(BOOST_RV_REF(slist) x)
+      : AllocHolder(boost::move(static_cast(x)))
+   {}
+
+   //! Effects: Makes *this contain the same elements as x.
+   //!
+   //! Postcondition: this->size() == x.size(). *this contains a copy 
+   //! of each of x's elements. 
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the number of elements in x.
+   slist& operator= (BOOST_COPY_ASSIGN_REF(slist) x)
+   {
+      if (&x != this){
+         NodeAlloc &this_alloc     = this->node_alloc();
+         const NodeAlloc &x_alloc  = x.node_alloc();
+         container_detail::bool_ flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+         }
+         this->AllocHolder::copy_assign_alloc(x);
+         this->assign(x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! Effects: Makes *this contain the same elements as x.
+   //!
+   //! Postcondition: this->size() == x.size(). *this contains a copy 
+   //! of each of x's elements. 
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the number of elements in x.
+   slist& operator= (BOOST_RV_REF(slist) x)
+   {
+      if (&x != this){
+         NodeAlloc &this_alloc = this->node_alloc();
+         NodeAlloc &x_alloc    = x.node_alloc();
+         //If allocators a re equal we can just swap pointers
+         if(this_alloc == x_alloc){
+            //Destroy and swap pointers
+            this->clear();
+            this->icont() = boost::move(x.icont());
+            //Move allocator if needed
+            this->AllocHolder::move_assign_alloc(x);
+         }
+         //If unequal allocators, then do a one by one move
+         else{
+            typedef typename std::iterator_traits::iterator_category ItCat;
+            this->assign( boost::make_move_iterator(x.begin())
+                        , boost::make_move_iterator(x.end()));
+         }
+      }
+      return *this;
+   }
+
+   //! Effects: Destroys the list. All stored values are destroyed
+   //!   and used memory is deallocated.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements.
+   ~slist() 
+   {} //AllocHolder clears the slist
+
+   //! Effects: Returns a copy of the internal allocator.
+   //! 
+   //! Throws: If allocator's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const
+   {  return allocator_type(this->node_alloc()); }
+
+   const stored_allocator_type &get_stored_allocator() const 
+   {  return this->node_alloc(); }
+
+   stored_allocator_type &get_stored_allocator()
+   {  return this->node_alloc(); }
+
+   public:
+
+   //! Effects: Assigns the n copies of val to *this.
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to n.
+   void assign(size_type n, const T& val)
+   { this->priv_fill_assign(n, val); }
+
+   //! Effects: Assigns the range [first, last) to *this.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's constructor from dereferencing InpIt throws.
+   //!
+   //! Complexity: Linear to n.
+   template 
+   void assign(InpIt first, InpIt last) 
+   {
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_assign_dispatch(first, last, Result());
+   }
+
+   //! Effects: Returns an iterator to the first element contained in the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin() 
+   { return iterator(this->icont().begin()); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const 
+   {  return this->cbegin();   }
+
+   //! Effects: Returns an iterator to the end of the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end()
+   { return iterator(this->icont().end()); }
+
+   //! Effects: Returns a const_iterator to the end of the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const
+   {  return this->cend();   }
+
+   //! Effects: Returns a non-dereferenceable iterator that,
+   //! when incremented, yields begin().  This iterator may be used
+   //! as the argument toinsert_after, erase_after, etc.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator before_begin() 
+   {  return iterator(end());  }
+
+   //! Effects: Returns a non-dereferenceable const_iterator 
+   //! that, when incremented, yields begin().  This iterator may be used
+   //! as the argument toinsert_after, erase_after, etc.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator before_begin() const
+   {  return this->cbefore_begin();  }
+
+   //! Effects: Returns a const_iterator to the first element contained in the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const 
+   {  return const_iterator(this->non_const_icont().begin());   }
+
+   //! Effects: Returns a const_iterator to the end of the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const
+   {  return const_iterator(this->non_const_icont().end());   }
+
+   //! Effects: Returns a non-dereferenceable const_iterator 
+   //! that, when incremented, yields begin().  This iterator may be used
+   //! as the argument toinsert_after, erase_after, etc.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbefore_begin() const
+   {  return const_iterator(end());  }
+
+   //! Effects: Returns the number of the elements contained in the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const 
+   {  return this->icont().size(); }
+
+   //! Effects: Returns the largest possible size of the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const 
+   {  return AllocHolder::max_size();  }
+
+   //! Effects: Returns true if the list contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const 
+   {  return !this->size();   }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements on *this and x.
+   void swap(slist& x)
+   {  AllocHolder::swap(x);   }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a reference to the first element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference front() 
+   {  return *this->begin();  }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a const reference to the first element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference front() const 
+   {  return *this->begin();  }
+
+   //! Effects: Inserts a copy of t in the beginning of the list.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_front(insert_const_ref_type x)
+   {  return priv_push_front(x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   void push_front(T &x) { push_front(const_cast(x)); }
+
+   template
+   void push_front(const U &u
+      , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return priv_push_front(u); }
+   #endif
+
+   //! Effects: Constructs a new element in the beginning of the list
+   //!   and moves the resources of t to this new element.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_front(BOOST_RV_REF(T) x)
+   {  this->icont().push_front(*this->create_node(boost::move(x)));  }
+
+   //! Effects: Removes the first element from the list.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Amortized constant time.
+   void pop_front()
+   {  this->icont().pop_front_and_dispose(Destroyer(this->node_alloc()));      }
+
+   //! Returns: The iterator to the element before i in the sequence. 
+   //!   Returns the end-iterator, if either i is the begin-iterator or the 
+   //!   sequence is empty. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear to the number of elements before i. 
+   iterator previous(iterator p) 
+   {  return iterator(this->icont().previous(p.get())); }
+
+   //! Returns: The const_iterator to the element before i in the sequence. 
+   //!   Returns the end-const_iterator, if either i is the begin-const_iterator or 
+   //!   the sequence is empty. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear to the number of elements before i. 
+   const_iterator previous(const_iterator p) 
+   {  return const_iterator(this->icont().previous(p.get())); }
+
+   //! Requires: p must be a valid iterator of *this.
+   //!
+   //! Effects: Inserts a copy of the value after the p pointed
+   //!    by prev_p.
+   //!
+   //! Returns: An iterator to the inserted element.
+   //! 
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //! 
+   //! Complexity: Amortized constant time.
+   //!
+   //! Note: Does not affect the validity of iterators and references of
+   //!   previous values.
+   iterator insert_after(const_iterator prev_pos, insert_const_ref_type x) 
+   {  return this->priv_insert_after(prev_pos, x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   iterator insert_after(const_iterator position, T &x)
+   { return this->insert_after(position, const_cast(x)); }
+
+   template
+   iterator insert_after( const_iterator position, const U &u
+                        , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return this->priv_insert_after(position, u); }
+   #endif
+
+   //! Requires: prev_pos must be a valid iterator of *this.
+   //!
+   //! Effects: Inserts a move constructed copy object from the value after the
+   //!    p pointed by prev_pos.
+   //!
+   //! Returns: An iterator to the inserted element.
+   //! 
+   //! Throws: If memory allocation throws.
+   //! 
+   //! Complexity: Amortized constant time.
+   //!
+   //! Note: Does not affect the validity of iterators and references of
+   //!   previous values.
+   iterator insert_after(const_iterator prev_pos, BOOST_RV_REF(value_type) x) 
+   {  return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(boost::move(x)))); }
+
+   //! Requires: prev_pos must be a valid iterator of *this.
+   //!
+   //! Effects: Inserts n copies of x after prev_pos.
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to n.
+   //!
+   //! Note: Does not affect the validity of iterators and references of
+   //!   previous values.
+   void insert_after(const_iterator prev_pos, size_type n, const value_type& x)
+   {  this->priv_create_and_insert_nodes(prev_pos, n, x); }
+
+   //! Requires: prev_pos must be a valid iterator of *this.
+   //! 
+   //! Effects: Inserts the range pointed by [first, last) 
+   //!   after the p prev_pos.
+   //! 
+   //! Throws: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws.
+   //! 
+   //! Complexity: Linear to the number of elements inserted.
+   //! 
+   //! Note: Does not affect the validity of iterators and references of
+   //!   previous values.
+   template 
+   void insert_after(const_iterator prev_pos, InIter first, InIter last) 
+   {
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_insert_after_range_dispatch(prev_pos, first, last, Result());
+   }
+
+   //! Requires: p must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a copy of x before p.
+   //!
+   //! Throws: If memory allocation throws or x's copy constructor throws.
+   //!
+   //! Complexity: Linear to the elements before p.
+   iterator insert(const_iterator position, insert_const_ref_type x) 
+   {  return this->priv_insert(position, x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   iterator insert(const_iterator position, T &x)
+   { return this->insert(position, const_cast(x)); }
+
+   template
+   iterator insert( const_iterator position, const U &u
+                  , typename container_detail::enable_if_c::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return this->priv_insert(position, u); }
+   #endif
+
+   //! Requires: p must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a new element before p with mx's resources.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: Linear to the elements before p.
+   iterator insert(const_iterator p, BOOST_RV_REF(value_type) x) 
+   {  return this->insert_after(previous(p), boost::move(x)); }
+
+   //! Requires: p must be a valid iterator of *this.
+   //!
+   //! Effects: Inserts n copies of x before p.
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to n plus linear to the elements before p.
+   void insert(const_iterator p, size_type n, const value_type& x) 
+   {  return this->insert_after(previous(p), n, x); }
+      
+   //! Requires: p must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a copy of the [first, last) range before p.
+   //!
+   //! Throws: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws.
+   //!
+   //! Complexity: Linear to std::distance [first, last) plus
+   //!    linear to the elements before p.
+   template 
+   void insert(const_iterator p, InIter first, InIter last) 
+   {  return this->insert_after(previous(p), first, last); }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the front of the list
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   template 
+   void emplace_front(Args&&... args)
+   {  this->emplace_after(this->cbefore_begin(), boost::forward(args)...); }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... before p
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! Complexity: Linear to the elements before p
+   template 
+   iterator emplace(const_iterator p, Args&&... args)
+   {  return this->emplace_after(this->previous(p), boost::forward(args)...);  }
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... after prev
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's in-place constructor throws.
+   //!
+   //! Complexity: Constant
+   template 
+   iterator emplace_after(const_iterator prev, Args&&... args)
+   {
+      NodePtr pnode(AllocHolder::create_node(boost::forward(args)...));
+      return iterator(this->icont().insert_after(prev.get(), *pnode));
+   }
+
+   #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                           \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)    \
+   void emplace_front(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                    \
+   {                                                                                         \
+      this->emplace(this->cbegin()                                                           \
+          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));                   \
+   }                                                                                         \
+                                                                                             \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)    \
+   iterator emplace (const_iterator p                                                        \
+                 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                \
+   {                                                                                         \
+      return this->emplace_after                                                             \
+         (this->previous(p)                                                                  \
+          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));                   \
+   }                                                                                         \
+                                                                                             \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)    \
+   iterator emplace_after(const_iterator prev                                                \
+                 BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                \
+   {                                                                                         \
+      NodePtr pnode (AllocHolder::create_node                                                \
+         (BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)));                           \
+      return iterator(this->icont().insert_after(prev.get(), *pnode));                       \
+   }                                                                                         \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Erases the element after the element pointed by prev_pos
+   //!    of the list.
+   //!
+   //! Returns: the first element remaining beyond the removed elements,
+   //!   or end() if no such element exists.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Does not invalidate iterators or references to non erased elements.
+   iterator erase_after(const_iterator prev_pos)
+   {
+      return iterator(this->icont().erase_after_and_dispose(prev_pos.get(), Destroyer(this->node_alloc())));
+   }
+
+   //! Effects: Erases the range (before_first, last) from
+   //!   the list. 
+   //!
+   //! Returns: the first element remaining beyond the removed elements,
+   //!   or end() if no such element exists.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear to the number of erased elements.
+   //! 
+   //! Note: Does not invalidate iterators or references to non erased elements.
+   iterator erase_after(const_iterator before_first, const_iterator last) 
+   {
+      return iterator(this->icont().erase_after_and_dispose(before_first.get(), last.get(), Destroyer(this->node_alloc())));
+   }
+
+   //! Requires: p must be a valid iterator of *this.
+   //!
+   //! Effects: Erases the element at p p.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements before p.
+   iterator erase(const_iterator p) 
+   {  return iterator(this->erase_after(previous(p))); }
+
+   //! Requires: first and last must be valid iterator to elements in *this.
+   //!
+   //! Effects: Erases the elements pointed by [first, last).
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the distance between first and last plus
+   //!   linear to the elements before first.
+   iterator erase(const_iterator first, const_iterator last)
+   {  return iterator(this->erase_after(previous(first), last)); }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type new_size, const T& x)
+   {
+      typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
+      while (++(cur_next = cur) != end_n && new_size > 0){
+         --new_size;
+         cur = cur_next;
+      }
+      if (cur_next != end_n) 
+         this->erase_after(const_iterator(cur), const_iterator(end_n));
+      else
+         this->insert_after(const_iterator(cur), new_size, x);
+   }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are default constructed.
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type new_size)
+   {
+      typename Icont::iterator end_n(this->icont().end()), cur(this->icont().before_begin()), cur_next;
+      size_type len = this->size();
+      size_type left = new_size;
+      
+      while (++(cur_next = cur) != end_n && left > 0){
+         --left;
+         cur = cur_next;
+      }
+      if (cur_next != end_n){
+         this->erase_after(const_iterator(cur), const_iterator(end_n));
+      }
+      else{
+         this->priv_create_and_insert_nodes(const_iterator(cur), new_size - len);
+      }
+   }
+
+   //! Effects: Erases all the elements of the list.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements in the list.
+   void clear() 
+   {  this->icont().clear_and_dispose(Destroyer(this->node_alloc()));  }
+
+   //! Requires: p must point to an element contained
+   //!   by the list. x != *this
+   //!
+   //! Effects: Transfers all the elements of list x to this list, after the
+   //!   the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //!
+   //! Complexity: Linear to the elements in x.
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of
+   //!    this list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_pos, slist& x)
+   {
+      if((NodeAlloc&)*this == (NodeAlloc&)x){
+         this->icont().splice_after(prev_pos.get(), x.icont());
+      }
+      else{
+         throw std::runtime_error("slist::splice called with unequal allocators");
+      }
+   }
+
+   //! Requires: prev_pos must be a valid iterator of this.
+   //!   i must point to an element contained in list x.
+   //! 
+   //! Effects: Transfers the value pointed by i, from list x to this list, 
+   //!   after the element pointed by prev_pos.
+   //!   If prev_pos == prev or prev_pos == ++prev, this function is a null operation. 
+   //! 
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_pos, slist& x, const_iterator prev)
+   {
+      if((NodeAlloc&)*this == (NodeAlloc&)x){
+         this->icont().splice_after(prev_pos.get(), x.icont(), prev.get());
+      }
+      else{
+         throw std::runtime_error("slist::splice called with unequal allocators");
+      }
+   }
+
+   //! Requires: prev_pos must be a valid iterator of this.
+   //!   before_first and before_last must be valid iterators of x.
+   //!   prev_pos must not be contained in [before_first, before_last) range.
+   //! 
+   //! Effects: Transfers the range [before_first + 1, before_last + 1)
+   //!   from list x to this list, after the element pointed by prev_pos.
+   //! 
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //! 
+   //! Complexity: Linear to the number of transferred elements.
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_pos,      slist& x, 
+      const_iterator before_first,  const_iterator before_last)
+   {
+      if((NodeAlloc&)*this == (NodeAlloc&)x){
+         this->icont().splice_after
+            (prev_pos.get(), x.icont(), before_first.get(), before_last.get());
+      }
+      else{
+         throw std::runtime_error("slist::splice called with unequal allocators");
+      }
+   }
+
+   //! Requires: prev_pos must be a valid iterator of this.
+   //!   before_first and before_last must be valid iterators of x.
+   //!   prev_pos must not be contained in [before_first, before_last) range.
+   //!   n == std::distance(before_first, before_last)
+   //! 
+   //! Effects: Transfers the range [before_first + 1, before_last + 1)
+   //!   from list x to this list, after the element pointed by prev_pos.
+   //! 
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice_after(const_iterator prev_pos,      slist& x, 
+                     const_iterator before_first,  const_iterator before_last,
+                     size_type n)
+   {
+      if((NodeAlloc&)*this == (NodeAlloc&)x){
+         this->icont().splice_after
+            (prev_pos.get(), x.icont(), before_first.get(), before_last.get(), n);
+      }
+      else{
+         throw std::runtime_error("slist::splice called with unequal allocators");
+      }
+   }
+
+   //! Requires: p must point to an element contained
+   //!   by the list. x != *this
+   //!
+   //! Effects: Transfers all the elements of list x to this list, before the
+   //!   the element pointed by p. No destructors or copy constructors are called.
+   //!
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //!
+   //! Complexity: Linear in distance(begin(), p), and linear in x.size().
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of
+   //!    this list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, ThisType& x) 
+   {  this->splice_after(this->previous(p), x);  }
+
+   //! Requires: p must point to an element contained
+   //!   by this list. i must point to an element contained in list x.
+   //! 
+   //! Effects: Transfers the value pointed by i, from list x to this list, 
+   //!   before the the element pointed by p. No destructors or copy constructors are called.
+   //!   If p == i or p == ++i, this function is a null operation. 
+   //! 
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //! 
+   //! Complexity: Linear in distance(begin(), p), and in distance(x.begin(), i).
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, slist& x, const_iterator i)
+   {  this->splice_after(previous(p), x, i);  }
+
+   //! Requires: p must point to an element contained
+   //!   by this list. first and last must point to elements contained in list x.
+   //! 
+   //! Effects: Transfers the range pointed by first and last from list x to this list, 
+   //!   before the the element pointed by p. No destructors or copy constructors are called.
+   //! 
+   //! Throws: std::runtime_error if this' allocator and x's allocator
+   //!   are not equal.
+   //! 
+   //! Complexity: Linear in distance(begin(), p), in distance(x.begin(), first),
+   //!   and in distance(first, last).
+   //! 
+   //! Note: Iterators of values obtained from list x now point to elements of this
+   //!   list. Iterators of this list and all the references are not invalidated.
+   void splice(const_iterator p, slist& x, const_iterator first, const_iterator last)
+   {  this->splice_after(previous(p), x, previous(first), previous(last));  }
+
+   //! Effects: Reverses the order of elements in the list. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: This function is linear time.
+   //! 
+   //! Note: Iterators and references are not invalidated
+   void reverse() 
+   {  this->icont().reverse();  }
+
+   //! Effects: Removes all the elements that compare equal to value.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear time. It performs exactly size() comparisons for equality.
+   //! 
+   //! Note: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   void remove(const T& value)
+   {  remove_if(equal_to_value(value));  }
+
+   //! Effects: Removes all the elements for which a specified
+   //!   predicate is satisfied.
+   //! 
+   //! Throws: If pred throws.
+   //! 
+   //! Complexity: Linear time. It performs exactly size() calls to the predicate.
+   //! 
+   //! Note: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   template  
+   void remove_if(Pred pred)
+   {
+      typedef ValueCompareToNodeCompare Predicate;
+      this->icont().remove_and_dispose_if(Predicate(pred), Destroyer(this->node_alloc()));
+   }
+
+   //! Effects: Removes adjacent duplicate elements or adjacent 
+   //!   elements that are equal from the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear time (size()-1 comparisons calls to pred()).
+   //! 
+   //! Note: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   void unique()
+   {  this->unique(value_equal());  }
+
+   //! Effects: Removes adjacent duplicate elements or adjacent 
+   //!   elements that satisfy some binary predicate from the list.
+   //! 
+   //! Throws: If pred throws.
+   //! 
+   //! Complexity: Linear time (size()-1 comparisons equality comparisons).
+   //! 
+   //! Note: The relative order of elements that are not removed is unchanged,
+   //!   and iterators to elements that are not removed remain valid.
+   template  
+   void unique(Pred pred)
+   {
+      typedef ValueCompareToNodeCompare Predicate;
+      this->icont().unique_and_dispose(Predicate(pred), Destroyer(this->node_alloc()));
+   }
+
+   //! Requires: The lists x and *this must be distinct. 
+   //!
+   //! Effects: This function removes all of x's elements and inserts them
+   //!   in order into *this according to std::less. The merge is stable; 
+   //!   that is, if an element from *this is equivalent to one from x, then the element 
+   //!   from *this will precede the one from x. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   void merge(slist & x)
+   {  this->merge(x, value_less()); }
+
+   //! Requires: p must be a comparison function that induces a strict weak
+   //!   ordering and both *this and x must be sorted according to that ordering
+   //!   The lists x and *this must be distinct. 
+   //! 
+   //! Effects: This function removes all of x's elements and inserts them
+   //!   in order into *this. The merge is stable; that is, if an element from *this is 
+   //!   equivalent to one from x, then the element from *this will precede the one from x. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: This function is linear time: it performs at most
+   //!   size() + x.size() - 1 comparisons.
+   //! 
+   //! Note: Iterators and references to *this are not invalidated.
+   template 
+   void merge(slist& x, StrictWeakOrdering comp)
+   {
+      if((NodeAlloc&)*this == (NodeAlloc&)x){
+         this->icont().merge(x.icont(),
+            ValueCompareToNodeCompare(comp));
+      }
+      else{
+         throw std::runtime_error("list::merge called with unequal allocators");
+      }
+   }
+
+   //! Effects: This function sorts the list *this according to std::less. 
+   //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
+   //! 
+   //! Throws: Nothing.
+   //!
+   //! Notes: Iterators and references are not invalidated.
+   //! 
+   //! Complexity: The number of comparisons is approximately N log N, where N
+   //!   is the list's size.
+   void sort()
+   {  this->sort(value_less());  }
+
+   //! Effects: This function sorts the list *this according to std::less. 
+   //!   The sort is stable, that is, the relative order of equivalent elements is preserved.
+   //! 
+   //! Throws: Nothing.
+   //!
+   //! Notes: Iterators and references are not invalidated.
+   //! 
+   //! Complexity: The number of comparisons is approximately N log N, where N
+   //!   is the list's size.
+   template  
+   void sort(StrictWeakOrdering comp)
+   {
+      // nothing if the slist has length 0 or 1.
+      if (this->size() < 2)
+         return;
+      this->icont().sort(ValueCompareToNodeCompare(comp));
+   }
+
+   /// @cond
+   private:
+   iterator priv_insert(const_iterator p, const value_type& x) 
+   {  return this->insert_after(previous(p), x); }
+
+   iterator priv_insert_after(const_iterator prev_pos, const value_type& x) 
+   {  return iterator(this->icont().insert_after(prev_pos.get(), *this->create_node(x))); }
+
+   void priv_push_front(const value_type &x)
+   {  this->icont().push_front(*this->create_node(x));  }
+
+   //Iterator range version
+   template
+   void priv_create_and_insert_nodes
+      (const_iterator prev, InpIterator beg, InpIterator end)
+   {
+      typedef typename std::iterator_traits::iterator_category ItCat;
+      priv_create_and_insert_nodes(prev, beg, end, alloc_version(), ItCat());
+   }
+
+   template
+   void priv_create_and_insert_nodes
+      (const_iterator prev, InpIterator beg, InpIterator end, allocator_v1, std::input_iterator_tag)
+   {
+      for (; beg != end; ++beg){
+         this->icont().insert_after(prev.get(), *this->create_node_from_it(beg));
+         ++prev;
+      }
+   }
+
+   template
+   void priv_create_and_insert_nodes
+      (const_iterator prev, InpIterator beg, InpIterator end, allocator_v2, std::input_iterator_tag)
+   {  //Just forward to the default one
+      priv_create_and_insert_nodes(prev, beg, end, allocator_v1(), std::input_iterator_tag());
+   }
+
+   class insertion_functor;
+   friend class insertion_functor;
+
+   class insertion_functor
+   {
+      Icont &icont_;
+      typename Icont::const_iterator prev_;
+
+      public:
+      insertion_functor(Icont &icont, typename Icont::const_iterator prev)
+         :  icont_(icont), prev_(prev)
+      {}
+
+      void operator()(Node &n)
+      {  prev_ = this->icont_.insert_after(prev_, n); }
+   };
+
+   template
+   void priv_create_and_insert_nodes
+      (const_iterator prev, FwdIterator beg, FwdIterator end, allocator_v2, std::forward_iterator_tag)
+   {
+      //Optimized allocation and construction
+      this->allocate_many_and_construct
+         (beg, std::distance(beg, end), insertion_functor(this->icont(), prev.get()));
+   }
+
+   //Default constructed version
+   void priv_create_and_insert_nodes(const_iterator prev, size_type n)
+   {
+      typedef default_construct_iterator default_iterator;
+      this->priv_create_and_insert_nodes(prev, default_iterator(n), default_iterator());
+   }
+
+   //Copy constructed version
+   void priv_create_and_insert_nodes(const_iterator prev, size_type n, const T& x)
+   {
+      typedef constant_iterator cvalue_iterator;
+      this->priv_create_and_insert_nodes(prev, cvalue_iterator(x, n), cvalue_iterator());
+   }
+
+   //Dispatch to detect iterator range or integer overloads
+   template 
+   void priv_insert_dispatch(const_iterator prev,
+                             InputIter first, InputIter last,
+                             container_detail::false_)
+   {  this->priv_create_and_insert_nodes(prev, first, last);   }
+
+   template
+   void priv_insert_dispatch(const_iterator prev, Integer n, Integer x, container_detail::true_) 
+   {  this->priv_create_and_insert_nodes(prev, (size_type)n, x);  }
+
+   void priv_fill_assign(size_type n, const T& val) 
+   {
+      iterator end_n(this->end());
+      iterator prev(this->before_begin());
+      iterator node(this->begin());
+      for ( ; node != end_n && n > 0 ; --n){
+         *node = val;
+         prev = node;
+         ++node;
+      }
+      if (n > 0)
+         this->priv_create_and_insert_nodes(prev, n, val);
+      else
+         this->erase_after(prev, end_n);
+   }
+
+   template 
+   void priv_assign_dispatch(Int n, Int val, container_detail::true_)
+   {  this->priv_fill_assign((size_type) n, (T)val); }
+
+   template 
+   void priv_assign_dispatch(InpIt first, InpIt last, container_detail::false_)
+   {
+      iterator end_n(this->end());
+      iterator prev(this->before_begin());
+      iterator node(this->begin());
+      while (node != end_n && first != last){
+         *node = *first;
+         prev = node;
+         ++node;
+         ++first;
+      }
+      if (first != last)
+         this->priv_create_and_insert_nodes(prev, first, last);
+      else
+         this->erase_after(prev, end_n);
+   }
+
+   template 
+   void priv_insert_after_range_dispatch(const_iterator prev_pos, Int n, Int x, container_detail::true_) 
+   {  this->priv_create_and_insert_nodes(prev_pos, (size_type)n, x);  }
+
+   template 
+   void priv_insert_after_range_dispatch(const_iterator prev_pos, InIter first, InIter last, container_detail::false_) 
+   {  this->priv_create_and_insert_nodes(prev_pos, first, last); }
+
+   //Functors for member algorithm defaults
+   struct value_less
+   {
+      bool operator()(const value_type &a, const value_type &b) const
+         {  return a < b;  }
+   };
+
+   struct value_equal
+   {
+      bool operator()(const value_type &a, const value_type &b) const
+         {  return a == b;  }
+   };
+
+   struct value_equal_to_this
+   {
+      explicit value_equal_to_this(const value_type &ref)
+         : m_ref(ref){}
+
+      bool operator()(const value_type &val) const
+         {  return m_ref == val;  }
+
+      const value_type &m_ref;
+   };
+   /// @endcond
+};
+
+template 
+inline bool 
+operator==(const slist& x, const slist& y)
+{
+   if(x.size() != y.size()){
+      return false;
+   }
+   typedef typename slist::const_iterator const_iterator;
+   const_iterator end1 = x.end();
+
+   const_iterator i1 = x.begin();
+   const_iterator i2 = y.begin();
+   while (i1 != end1 && *i1 == *i2){
+      ++i1;
+      ++i2;
+   }
+   return i1 == end1;
+}
+
+template 
+inline bool
+operator<(const slist& sL1, const slist& sL2)
+{
+   return std::lexicographical_compare
+      (sL1.begin(), sL1.end(), sL2.begin(), sL2.end());
+}
+
+template 
+inline bool 
+operator!=(const slist& sL1, const slist& sL2) 
+   {  return !(sL1 == sL2);   }
+
+template 
+inline bool 
+operator>(const slist& sL1, const slist& sL2) 
+   {  return sL2 < sL1; }
+
+template 
+inline bool 
+operator<=(const slist& sL1, const slist& sL2)
+   {  return !(sL2 < sL1); }
+
+template 
+inline bool 
+operator>=(const slist& sL1, const slist& sL2)
+   {  return !(sL1 < sL2); }
+
+template 
+inline void swap(slist& x, slist& y) 
+   {  x.swap(y);  }
+
+}}
+
+/// @cond
+
+namespace boost {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value;
+};
+*/
+namespace container {
+
+/// @endcond
+
+}} //namespace boost{  namespace container {
+
+// Specialization of insert_iterator so that insertions will be constant
+// time rather than linear time.
+
+///@cond
+
+//Ummm, I don't like to define things in namespace std, but 
+//there is no other way
+namespace std {
+
+template 
+class insert_iterator > 
+{
+ protected:
+   typedef boost::container::slist Container;
+   Container* container;
+   typename Container::iterator iter;
+   public:
+   typedef Container           container_type;
+   typedef output_iterator_tag iterator_category;
+   typedef void                value_type;
+   typedef void                difference_type;
+   typedef void                pointer;
+   typedef void                reference;
+
+   insert_iterator(Container& x, 
+                   typename Container::iterator i, 
+                   bool is_previous = false) 
+      : container(&x), iter(is_previous ? i : x.previous(i)){ }
+
+   insert_iterator& 
+      operator=(const typename Container::value_type& value) 
+   { 
+      iter = container->insert_after(iter, value);
+      return *this;
+   }
+   insert_iterator& operator*(){ return *this; }
+   insert_iterator& operator++(){ return *this; }
+   insert_iterator& operator++(int){ return *this; }
+};
+
+}  //namespace std;
+
+///@endcond
+
+#include 
+
+#endif /* BOOST_CONTAINER_SLIST_HPP */
diff --git a/src/third_party/boost/boost/container/stable_vector.hpp b/src/third_party/boost/boost/container/stable_vector.hpp
new file mode 100644
index 00000000000..851b5f26e8c
--- /dev/null
+++ b/src/third_party/boost/boost/container/stable_vector.hpp
@@ -0,0 +1,1818 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+// Stable vector.
+//
+// Copyright 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)
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP
+#define BOOST_CONTAINER_STABLE_VECTOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+///@cond
+
+#include 
+
+//#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING
+
+#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+#include 
+#endif
+
+///@endcond
+
+namespace boost {
+namespace container {
+
+///@cond
+
+namespace stable_vector_detail{
+
+template
+struct smart_ptr_type
+{
+   typedef typename SmartPtr::value_type value_type;
+   typedef value_type *pointer;
+   static pointer get (const SmartPtr &smartptr)
+   {  return smartptr.get();}
+};
+
+template
+struct smart_ptr_type
+{
+   typedef T value_type;
+   typedef value_type *pointer;
+   static pointer get (pointer ptr)
+   {  return ptr;}
+};
+
+template
+inline typename smart_ptr_type::pointer to_raw_pointer(const Ptr &ptr)
+{  return smart_ptr_type::get(ptr);   }
+
+template 
+class clear_on_destroy
+{
+   public:
+   clear_on_destroy(C &c)
+      :  c_(c), do_clear_(true)
+   {}
+
+   void release()
+   {  do_clear_ = false; }
+
+   ~clear_on_destroy()
+   {
+      if(do_clear_){
+         c_.clear();
+         c_.clear_pool();  
+      }
+   }
+
+   private:
+   clear_on_destroy(const clear_on_destroy &);
+   clear_on_destroy &operator=(const clear_on_destroy &);
+   C &c_;
+   bool do_clear_;
+};
+
+template
+struct node_type_base
+{/*
+   node_type_base(VoidPtr p)
+      : up(p)
+   {}*/
+   node_type_base()
+   {}
+   void set_pointer(VoidPtr p)
+   {  up = p; }
+
+   VoidPtr up;
+};
+
+template
+struct node_type
+   : public node_type_base
+{
+   node_type()
+      : value()
+   {}
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   template
+   node_type(Args &&...args)
+      : value(boost::forward(args)...)
+   {}
+
+   #else //BOOST_CONTAINER_PERFECT_FORWARDING
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                           \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)    \
+   node_type(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                             \
+      : value(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))                         \
+   {}                                                                                        \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif//BOOST_CONTAINER_PERFECT_FORWARDING
+   
+   void set_pointer(VoidPointer p)
+   {  node_type_base::set_pointer(p); }
+
+   T value;
+};
+
+template
+class iterator
+   : public std::iterator< std::random_access_iterator_tag
+                         , T
+                         , typename boost::intrusive::
+                              pointer_traits::difference_type
+                         , Pointer
+                         , Reference>
+{
+   typedef typename boost::intrusive::
+      pointer_traits::template
+         rebind_pointer::type                void_ptr;
+   typedef typename boost::intrusive::
+      pointer_traits::template
+         rebind_pointer::type          const_void_ptr;
+   typedef node_type                  node_type_t;
+   typedef typename boost::intrusive::
+      pointer_traits::template
+         rebind_pointer::type         node_type_ptr_t;
+   typedef typename boost::intrusive::
+      pointer_traits::template
+         rebind_pointer::type   const_node_type_ptr_t;
+   typedef typename boost::intrusive::
+      pointer_traits::template
+         rebind_pointer::type            void_ptr_ptr;
+
+   friend class iterator::template rebind_pointer::type>;
+
+   public:
+   typedef std::random_access_iterator_tag      iterator_category;
+   typedef T                                    value_type;
+   typedef typename boost::intrusive::
+      pointer_traits::difference_type  difference_type;
+   typedef Pointer                              pointer;
+   typedef Reference                            reference;
+
+   iterator()
+   {}
+
+   explicit iterator(node_type_ptr_t pn)
+      : pn(pn)
+   {}
+
+   iterator(const iterator::template rebind_pointer::type>& x)
+      : pn(x.pn)
+   {}
+   
+   private:
+   static node_type_ptr_t node_ptr_cast(const void_ptr &p)
+   {
+      return node_type_ptr_t(static_cast(stable_vector_detail::to_raw_pointer(p)));
+   }
+
+   static const_node_type_ptr_t node_ptr_cast(const const_void_ptr &p)
+   {
+      return const_node_type_ptr_t(static_cast(stable_vector_detail::to_raw_pointer(p)));
+   }
+
+   static void_ptr_ptr void_ptr_ptr_cast(const void_ptr &p)
+   {
+      return void_ptr_ptr(static_cast(stable_vector_detail::to_raw_pointer(p)));
+   }
+
+   reference dereference() const
+   {  return pn->value; }
+   bool equal(const iterator& x) const
+   {  return pn==x.pn;  }
+   void increment()
+   {  pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+1)); }
+   void decrement()
+   {  pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)-1)); }
+   void advance(difference_type n)
+   {  pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+n)); }
+   difference_type distance_to(const iterator& x)const
+   {  return void_ptr_ptr_cast(x.pn->up) - void_ptr_ptr_cast(pn->up);   }
+
+   public:
+   //Pointer like operators
+   reference operator*()  const {  return  this->dereference();  }
+   pointer   operator->() const {  return  pointer(&this->dereference());  }
+
+   //Increment / Decrement
+   iterator& operator++()  
+   {  this->increment(); return *this;  }
+
+   iterator operator++(int)
+   {  iterator tmp(*this);  ++*this; return iterator(tmp); }
+
+   iterator& operator--()
+   {  this->decrement(); return *this;  }
+
+   iterator operator--(int)
+   {  iterator tmp(*this);  --*this; return iterator(tmp);  }
+
+   reference operator[](difference_type off) const
+   {
+      iterator tmp(*this);
+      tmp += off;
+      return *tmp;
+   }
+
+   iterator& operator+=(difference_type off)
+   {
+      pn = node_ptr_cast(*(void_ptr_ptr_cast(pn->up)+off));
+      return *this;
+   }
+
+   friend iterator operator+(const iterator &left, difference_type off)
+   {
+      iterator tmp(left);
+      tmp += off;
+      return tmp;
+   }
+
+   friend iterator operator+(difference_type off, const iterator& right)
+   {
+      iterator tmp(right);
+      tmp += off;
+      return tmp;
+   }
+
+   iterator& operator-=(difference_type off)
+   {  *this += -off; return *this;   }
+
+   friend iterator operator-(const iterator &left, difference_type off)
+   {
+      iterator tmp(left);
+      tmp -= off;
+      return tmp;
+   }
+
+   friend difference_type operator-(const iterator& left, const iterator& right)
+   {
+      return void_ptr_ptr_cast(left.pn->up) - void_ptr_ptr_cast(right.pn->up);
+   }
+
+   //Comparison operators
+   friend bool operator==   (const iterator& l, const iterator& r)
+   {  return l.pn == r.pn;  }
+
+   friend bool operator!=   (const iterator& l, const iterator& r)
+   {  return l.pn != r.pn;  }
+
+   friend bool operator<    (const iterator& l, const iterator& r)
+   {  return void_ptr_ptr_cast(l.pn->up) < void_ptr_ptr_cast(r.pn->up);  }
+
+   friend bool operator<=   (const iterator& l, const iterator& r)
+   {  return void_ptr_ptr_cast(l.pn->up) <= void_ptr_ptr_cast(r.pn->up);  }
+
+   friend bool operator>    (const iterator& l, const iterator& r)
+   {  return void_ptr_ptr_cast(l.pn->up) > void_ptr_ptr_cast(r.pn->up);  }
+
+   friend bool operator>=   (const iterator& l, const iterator& r)
+   {  return void_ptr_ptr_cast(l.pn->up) >= void_ptr_ptr_cast(r.pn->up);  }
+
+   node_type_ptr_t pn;
+};
+
+template
+struct select_multiallocation_chain
+{
+   typedef typename A::multiallocation_chain type;
+};
+
+template
+struct select_multiallocation_chain
+{
+   typedef typename boost::intrusive::pointer_traits
+      ::pointer>::
+         template rebind_pointer::type                void_ptr;
+   typedef container_detail::basic_multiallocation_chain
+                                                  multialloc_cached_counted;
+   typedef boost::container::container_detail::
+      transform_multiallocation_chain
+         < multialloc_cached_counted
+         , typename allocator_traits::value_type>        type;
+};
+
+} //namespace stable_vector_detail
+
+#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+
+#define STABLE_VECTOR_CHECK_INVARIANT \
+invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \
+BOOST_JOIN(check_invariant_,__LINE__).touch();
+#else
+
+#define STABLE_VECTOR_CHECK_INVARIANT
+
+#endif   //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+
+#endif   //#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+/// @endcond
+
+//!Originally developed by Joaquin M. Lopez Munoz, stable_vector is std::vector
+//!drop-in replacement implemented as a node container, offering iterator and reference
+//!stability.
+//!
+//!More details taken the author's blog: ( Introducing stable_vector)
+//!
+//!We present stable_vector, a fully STL-compliant stable container that provides
+//!most of the features of std::vector except element contiguity. 
+//!
+//!General properties: stable_vector satisfies all the requirements of a container,
+//!a reversible container and a sequence and provides all the optional operations
+//!present in std::vector. Like std::vector,  iterators are random access.
+//!stable_vector does not provide element contiguity; in exchange for this absence,
+//!the container is stable, i.e. references and iterators to an element of a stable_vector
+//!remain valid as long as the element is not erased, and an iterator that has been
+//!assigned the return value of end() always remain valid until the destruction of
+//!the associated  stable_vector.
+//!
+//!Operation complexity: The big-O complexities of stable_vector operations match
+//!exactly those of std::vector. In general, insertion/deletion is constant time at
+//!the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector
+//!does not internally perform any value_type destruction, copy or assignment
+//!operations other than those exactly corresponding to the insertion of new
+//!elements or deletion of stored elements, which can sometimes compensate in terms
+//!of performance for the extra burden of doing more pointer manipulation and an
+//!additional allocation per element.
+//!
+//!Exception safety: As stable_vector does not internally copy elements around, some
+//!operations provide stronger exception safety guarantees than in std::vector:
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >
+#else
+template 
+#endif
+class stable_vector
+{
+   ///@cond
+   typedef allocator_traits                        allocator_traits_type;
+   typedef typename container_detail::
+      move_const_ref_type::type                    insert_const_ref_type;
+   typedef typename boost::intrusive::pointer_traits
+      ::
+         template rebind_pointer::type          void_ptr;
+   typedef typename boost::intrusive::pointer_traits
+      ::template
+         rebind_pointer::type             const_void_ptr;
+   typedef typename boost::intrusive::pointer_traits
+      ::template
+         rebind_pointer::type               void_ptr_ptr;
+   typedef typename boost::intrusive::pointer_traits
+      ::template
+         rebind_pointer::type         const_void_ptr_ptr;
+   typedef stable_vector_detail::node_type
+                                         node_type_t;
+   typedef typename boost::intrusive::pointer_traits
+      ::template
+         rebind_pointer::type            node_type_ptr_t;
+   typedef stable_vector_detail::node_type_base
+                                            node_type_base_t;
+   typedef typename boost::intrusive::pointer_traits
+      ::template
+         rebind_pointer::type       node_type_base_ptr_t;
+   typedef ::boost::container::vector::type>                         impl_type;
+   typedef typename impl_type::iterator               impl_iterator;
+   typedef typename impl_type::const_iterator         const_impl_iterator;
+
+   typedef ::boost::container::container_detail::
+      integral_constant                  allocator_v1;
+   typedef ::boost::container::container_detail::
+      integral_constant                  allocator_v2;
+   typedef ::boost::container::container_detail::integral_constant 
+      ::value>                              alloc_version;
+   typedef typename allocator_traits_type::
+      template portable_rebind_alloc
+         ::type                          node_allocator_type;
+
+   node_type_ptr_t allocate_one()
+   {  return this->allocate_one(alloc_version());   }
+
+   template
+   node_type_ptr_t allocate_one(AllocatorVersion,
+      typename boost::container::container_detail::enable_if_c
+         
+            ::value>::type * = 0)
+   {  return node_alloc().allocate(1);   }
+
+   template
+   node_type_ptr_t allocate_one(AllocatorVersion,
+      typename boost::container::container_detail::enable_if_c
+         
+            ::value>::type * = 0)
+   {  return node_alloc().allocate_one();   }
+
+   void deallocate_one(node_type_ptr_t p)
+   {  return this->deallocate_one(p, alloc_version());   }
+
+   template
+   void deallocate_one(node_type_ptr_t p, AllocatorVersion,
+      typename boost::container::container_detail::enable_if_c
+         
+            ::value>::type * = 0)
+   {  node_alloc().deallocate(p, 1);   }
+
+   template
+   void deallocate_one(node_type_ptr_t p, AllocatorVersion,
+      typename boost::container::container_detail::enable_if_c
+         
+            ::value>::type * = 0)
+   {  node_alloc().deallocate_one(p);   }
+
+   friend class stable_vector_detail::clear_on_destroy;
+   ///@endcond
+   public:
+
+
+   // types:
+
+   typedef typename allocator_traits_type::reference              reference;
+   typedef typename allocator_traits_type::const_reference        const_reference;
+   typedef typename allocator_traits_type::pointer                pointer;
+   typedef typename allocator_traits_type::const_pointer          const_pointer;
+   typedef stable_vector_detail::iterator
+                                       iterator;
+   typedef stable_vector_detail::iterator
+                           const_iterator;
+   typedef typename impl_type::size_type              size_type;
+   typedef typename iterator::difference_type         difference_type;
+   typedef T                                          value_type;
+   typedef A                                          allocator_type;
+   typedef std::reverse_iterator            reverse_iterator;
+   typedef std::reverse_iterator      const_reverse_iterator;
+   typedef node_allocator_type                        stored_allocator_type;
+
+   ///@cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(stable_vector)
+   static const size_type ExtraPointers = 3;
+   //This container stores metadata at the end of the void_ptr vector with additional 3 pointers:
+   //    back() is impl.back() - ExtraPointers;
+   //    end node index is impl.end()[-3]
+   //    Node cache first is impl.end()[-2];
+   //    Node cache last is  *impl.back();
+
+   typedef typename stable_vector_detail::
+      select_multiallocation_chain
+      < node_allocator_type
+      , alloc_version::value
+      >::type                                         multiallocation_chain;
+   ///@endcond
+   public:
+
+   //! Effects: Default constructs a stable_vector.
+   //! 
+   //! Throws: If allocator_type's default constructor throws.
+   //! 
+   //! Complexity: Constant.
+   stable_vector()
+      : internal_data(), impl()
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+   }
+
+   //! Effects: Constructs a stable_vector taking the allocator as parameter.
+   //! 
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   explicit stable_vector(const A& al)
+      : internal_data(al),impl(al)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+   }
+
+   //! Effects: Constructs a stable_vector that will use a copy of allocator a
+   //!   and inserts n default contructed values.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's default or copy constructor throws.
+   //! 
+   //! Complexity: Linear to n.
+   explicit stable_vector(size_type n)
+      : internal_data(A()),impl(A())
+   {
+      stable_vector_detail::clear_on_destroy cod(*this);
+      this->resize(n);
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! Effects: Constructs a stable_vector that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's default or copy constructor throws.
+   //! 
+   //! Complexity: Linear to n.
+   stable_vector(size_type n, const T& t, const A& al=A())
+      : internal_data(al),impl(al)
+   {
+      stable_vector_detail::clear_on_destroy cod(*this);
+      this->insert(this->cbegin(), n, t);
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! Effects: Constructs a stable_vector that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the stable_vector.
+   //!
+   //! Throws: If allocator_type's default constructor or copy constructor
+   //!   throws or T's constructor taking an dereferenced InIt throws.
+   //!
+   //! Complexity: Linear to the range [first, last).
+   template 
+   stable_vector(InputIterator first,InputIterator last,const A& al=A())
+      : internal_data(al),impl(al)
+   {
+      stable_vector_detail::clear_on_destroy cod(*this);
+      this->insert(this->cbegin(), first, last);
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! Effects: Copy constructs a stable_vector.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   stable_vector(const stable_vector& x)
+      : internal_data(allocator_traits::
+         select_on_container_copy_construction(x.node_alloc()))
+      , impl(allocator_traits::
+         select_on_container_copy_construction(x.impl.get_stored_allocator()))
+   {
+      stable_vector_detail::clear_on_destroy cod(*this);
+      this->insert(this->cbegin(), x.begin(), x.end());
+      STABLE_VECTOR_CHECK_INVARIANT;
+      cod.release();
+   }
+
+   //! Effects: Move constructor. Moves mx's resources to *this.
+   //!
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   stable_vector(BOOST_RV_REF(stable_vector) x)
+      : internal_data(boost::move(x.node_alloc())), impl(boost::move(x.impl))
+   {
+      this->priv_swap_members(x);
+   }
+
+   //! Effects: Destroys the stable_vector. All stored values are destroyed
+   //!   and used memory is deallocated.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements.
+   ~stable_vector()
+   {
+      this->clear();
+      clear_pool();  
+   }
+
+   //! Effects: Makes *this contain the same elements as x.
+   //!
+   //! Postcondition: this->size() == x.size(). *this contains a copy 
+   //! of each of x's elements. 
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the number of elements in x.
+   stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      if (&x != this){
+         node_allocator_type &this_alloc     = this->node_alloc();
+         const node_allocator_type &x_alloc  = x.node_alloc();
+         container_detail::bool_ flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+            this->shrink_to_fit();
+         }
+         container_detail::assign_alloc(this->node_alloc(), x.node_alloc(), flag);
+         container_detail::assign_alloc(this->impl.get_stored_allocator(), x.impl.get_stored_allocator(), flag);
+         this->assign(x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! Effects: Move assignment. All mx's values are transferred to *this.
+   //!
+   //! Postcondition: x.empty(). *this contains a the elements x had
+   //!   before the function.
+   //!
+   //! Throws: If allocator_type's copy constructor throws.
+   //!
+   //! Complexity: Linear.
+   stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
+   {
+      if (&x != this){
+         node_allocator_type &this_alloc = this->node_alloc();
+         node_allocator_type &x_alloc    = x.node_alloc();
+         //If allocators are equal we can just swap pointers
+         if(this_alloc == x_alloc){
+            //Destroy objects but retain memory
+            this->clear();
+            this->impl = boost::move(x.impl);
+            this->priv_swap_members(x);
+            //Move allocator if needed
+            container_detail::bool_ flag;
+            container_detail::move_alloc(this->node_alloc(), x.node_alloc(), flag);
+         }
+         //If unequal allocators, then do a one by one move
+         else{
+            typedef typename std::iterator_traits::iterator_category ItCat;
+            this->assign( boost::make_move_iterator(x.begin())
+                        , boost::make_move_iterator(x.end()));
+         }
+      }
+      return *this;
+   }
+
+   //! Effects: Assigns the the range [first, last) to *this.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's constructor from dereferencing InpIt throws.
+   //!
+   //! Complexity: Linear to n.
+   template
+   void assign(InputIterator first,InputIterator last)
+   {
+      assign_dispatch(first, last, boost::is_integral());
+   }
+
+
+   //! Effects: Assigns the n copies of val to *this.
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to n.
+   void assign(size_type n,const T& t)
+   {
+      typedef constant_iterator cvalue_iterator;
+      return assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
+   }
+
+   //! Effects: Returns a copy of the internal allocator.
+   //! 
+   //! Throws: If allocator's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator()const  {return node_alloc();}
+
+   //! Effects: Returns a reference to the internal allocator.
+   //! 
+   //! Throws: Nothing
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+   {  return node_alloc(); }
+
+   //! Effects: Returns a reference to the internal allocator.
+   //! 
+   //! Throws: Nothing
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+   {  return node_alloc(); }
+
+
+   //! Effects: Returns an iterator to the first element contained in the stable_vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator  begin()
+   {   return (impl.empty()) ? end(): iterator(node_ptr_cast(impl.front())) ;   }
+
+   //! Effects: Returns a const_iterator to the first element contained in the stable_vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator  begin()const
+   {   return (impl.empty()) ? cend() : const_iterator(node_ptr_cast(impl.front())) ;   }
+
+   //! Effects: Returns an iterator to the end of the stable_vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator        end()                {return iterator(get_end_node());}
+
+   //! Effects: Returns a const_iterator to the end of the stable_vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator  end()const           {return const_iterator(get_end_node());}
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed stable_vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator       rbegin()      {return reverse_iterator(this->end());}
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed stable_vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin()const {return const_reverse_iterator(this->end());}
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed stable_vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator       rend()        {return reverse_iterator(this->begin());}
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed stable_vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend()const   {return const_reverse_iterator(this->begin());}
+
+   //! Effects: Returns a const_iterator to the first element contained in the stable_vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator         cbegin()const {return this->begin();}
+
+   //! Effects: Returns a const_iterator to the end of the stable_vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator         cend()const   {return this->end();}
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed stable_vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin()const{return this->rbegin();}
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed stable_vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend()const  {return this->rend();}
+
+   //! Effects: Returns the number of the elements contained in the stable_vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const
+   {  return impl.empty() ? 0 : (impl.size() - ExtraPointers);   }
+
+   //! Effects: Returns the largest possible size of the stable_vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const
+   {  return impl.max_size() - ExtraPointers;  }
+
+   //! Effects: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type capacity() const
+   {
+      if(!impl.capacity()){
+         return 0;
+      }
+      else{
+         const size_type num_nodes = this->impl.size() + this->internal_data.pool_size;
+         const size_type num_buck  = this->impl.capacity();
+         return (num_nodes < num_buck) ? num_nodes : num_buck;
+      }
+   }
+
+   //! Effects: Returns true if the stable_vector contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const
+   {  return impl.empty() || impl.size() == ExtraPointers;  }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type n, const T& t)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      if(n > size())
+         this->insert(this->cend(), n - this->size(), t);
+      else if(n < this->size())
+         this->erase(this->cbegin() + n, this->cend());
+   }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are default constructed.
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type n)
+   {
+      typedef default_construct_iterator default_iterator;
+      STABLE_VECTOR_CHECK_INVARIANT;
+      if(n > size())
+         this->insert(this->cend(), default_iterator(n - this->size()), default_iterator());
+      else if(n < this->size())
+         this->erase(this->cbegin() + n, this->cend());
+   }
+
+   //! Effects: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //! 
+   //! Throws: If memory allocation allocation throws.
+   void reserve(size_type n)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      if(n > this->max_size())
+         throw std::bad_alloc();
+
+      size_type size = this->size();   
+      size_type old_capacity = this->capacity();
+      if(n > old_capacity){
+         this->initialize_end_node(n);
+         const void * old_ptr = &impl[0];
+         impl.reserve(n + ExtraPointers);
+         bool realloced = &impl[0] != old_ptr;
+         //Fix the pointers for the newly allocated buffer
+         if(realloced){
+            this->align_nodes(impl.begin(), impl.begin()+size+1);
+         }
+         //Now fill pool if data is not enough
+         if((n - size) > this->internal_data.pool_size){
+            this->add_to_pool((n - size) - this->internal_data.pool_size);
+         }
+      }
+   }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference operator[](size_type n){return value(impl[n]);}
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a const reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference operator[](size_type n)const{return value(impl[n]);}
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: std::range_error if n >= size()
+   //! 
+   //! Complexity: Constant.
+   reference at(size_type n)
+   {
+      if(n>=size())
+         throw std::out_of_range("invalid subscript at stable_vector::at");
+      return operator[](n);
+   }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a const reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: std::range_error if n >= size()
+   //! 
+   //! Complexity: Constant.
+   const_reference at(size_type n)const
+   {
+      if(n>=size())
+         throw std::out_of_range("invalid subscript at stable_vector::at");
+      return operator[](n);
+   }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a reference to the first
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference front()
+   {  return value(impl.front());   }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a const reference to the first
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference front()const
+   {  return value(impl.front());   }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a reference to the last
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference back()
+   {  return value(*(&impl.back() - ExtraPointers)); }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a const reference to the last
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference back()const
+   {  return value(*(&impl.back() - ExtraPointers)); }
+
+   //! Effects: Inserts a copy of x at the end of the stable_vector.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's copy constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_back(insert_const_ref_type x) 
+   {  return priv_push_back(x);  }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   void push_back(T &x) { push_back(const_cast(x)); }
+
+   template
+   void push_back(const U &u, typename container_detail::enable_if_c
+                  ::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   { return priv_push_back(u); }
+   #endif
+
+   //! Effects: Constructs a new element in the end of the stable_vector
+   //!   and moves the resources of mx to this new element.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_back(BOOST_RV_REF(T) t) 
+   {  this->insert(end(), boost::move(t));  }
+
+   //! Effects: Removes the last element from the stable_vector.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant time.
+   void pop_back()
+   {  this->erase(this->end()-1);   }
+
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a copy of x before position.
+   //!
+   //! Throws: If memory allocation throws or x's copy constructor throws.
+   //!
+   //! Complexity: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator position, insert_const_ref_type x) 
+   {  return this->priv_insert(position, x); }
+
+   #if defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   iterator insert(const_iterator position, T &x) { return this->insert(position, const_cast(x)); }
+
+   template
+   iterator insert(const_iterator position, const U &u, typename container_detail::enable_if_c
+                  ::value && !::boost::has_move_emulation_enabled::value >::type* =0)
+   {  return this->priv_insert(position, u); }
+   #endif
+
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a new element before position with mx's resources.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator position, BOOST_RV_REF(T) x) 
+   {
+      typedef repeat_iterator           repeat_it;
+      typedef boost::move_iterator repeat_move_it;
+      //Just call more general insert(pos, size, value) and return iterator
+      size_type pos_n = position - cbegin();
+      this->insert(position
+         ,repeat_move_it(repeat_it(x, 1))
+         ,repeat_move_it(repeat_it()));
+      return iterator(this->begin() + pos_n);
+   }
+
+   //! Requires: pos must be a valid iterator of *this.
+   //!
+   //! Effects: Insert n copies of x before pos.
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to n.
+   void insert(const_iterator position, size_type n, const T& t)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      this->insert_not_iter(position, n, t);
+   }
+
+   //! Requires: pos must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a copy of the [first, last) range before pos.
+   //!
+   //! Throws: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to std::distance [first, last).
+   template 
+   void insert(const_iterator position,InputIterator first, InputIterator last)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      this->insert_iter(position,first,last,
+                        boost::mpl::not_ >());
+   }
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the end of the stable_vector.
+   //!
+   //! Throws: If memory allocation throws or the in-place constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   template
+   void emplace_back(Args &&...args)
+   {
+      typedef emplace_functor         EmplaceFunctor;
+      typedef emplace_iterator EmplaceIterator;
+      EmplaceFunctor &&ef = EmplaceFunctor(boost::forward(args)...);
+      this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator());
+   }
+
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... before position
+   //!
+   //! Throws: If memory allocation throws or the in-place constructor throws.
+   //!
+   //! Complexity: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   template
+   iterator emplace(const_iterator position, Args && ...args)
+   {
+      //Just call more general insert(pos, size, value) and return iterator
+      size_type pos_n = position - cbegin();
+      typedef emplace_functor         EmplaceFunctor;
+      typedef emplace_iterator EmplaceIterator;
+      EmplaceFunctor &&ef = EmplaceFunctor(boost::forward(args)...);
+      this->insert(position, EmplaceIterator(ef), EmplaceIterator());
+      return iterator(this->begin() + pos_n);
+   }
+
+   #else
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                              \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)       \
+   void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                        \
+   {                                                                                            \
+      typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                               \
+         BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >)               \
+            EmplaceFunctor;                                                                     \
+      typedef emplace_iterator  EmplaceIterator;  \
+      EmplaceFunctor ef BOOST_PP_LPAREN_IF(n)                                                   \
+                        BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)                   \
+                        BOOST_PP_RPAREN_IF(n);                                                  \
+      this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator());                      \
+   }                                                                                            \
+                                                                                                \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)       \
+   iterator emplace(const_iterator pos                                                          \
+           BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                         \
+   {                                                                                            \
+      typedef BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                               \
+         BOOST_PP_EXPR_IF(n, <) BOOST_PP_ENUM_PARAMS(n, P) BOOST_PP_EXPR_IF(n, >)               \
+            EmplaceFunctor;                                                                     \
+      typedef emplace_iterator  EmplaceIterator;  \
+      EmplaceFunctor ef BOOST_PP_LPAREN_IF(n)                                                   \
+                        BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)                   \
+                        BOOST_PP_RPAREN_IF(n);                                                  \
+      size_type pos_n = pos - this->cbegin();                                                   \
+      this->insert(pos, EmplaceIterator(ef), EmplaceIterator());                                \
+      return iterator(this->begin() + pos_n);                                                   \
+   }                                                                                            \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+
+   //! Effects: Erases the element at position pos.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the elements between pos and the 
+   //!   last element. Constant if pos is the last element.
+   iterator erase(const_iterator position)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      difference_type d = position - this->cbegin();
+      impl_iterator   it = impl.begin() + d;
+      this->delete_node(*it);
+      it = impl.erase(it);
+      this->align_nodes(it, get_last_align());
+      return this->begin()+d;
+   }
+
+   //! Effects: Erases the elements pointed by [first, last).
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the distance between first and last
+   //!   plus linear to the elements between pos and the last element.
+   iterator erase(const_iterator first, const_iterator last)
+   {   return priv_erase(first, last, alloc_version());  }
+
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(stable_vector & x)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      container_detail::bool_ flag;
+      container_detail::swap_alloc(this->node_alloc(), x.node_alloc(), flag);
+      //vector's allocator is swapped here
+      this->impl.swap(x.impl);
+      this->priv_swap_members(x);
+   }
+
+   //! Effects: Erases all the elements of the stable_vector.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements in the stable_vector.
+   void clear()
+   {   this->erase(this->cbegin(),this->cend()); }
+
+   //! Effects: Tries to deallocate the excess of memory created
+   //!   with previous allocations. The size of the stable_vector is unchanged
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: Linear to size().
+   void shrink_to_fit()
+   {
+      if(this->capacity()){
+         //First empty allocated node pool
+         this->clear_pool();
+         //If empty completely destroy the index, let's recover default-constructed state
+         if(this->empty()){
+            this->impl.clear();
+            this->impl.shrink_to_fit();
+            this->internal_data.set_end_pointer_to_default_constructed();
+         }
+         //Otherwise, try to shrink-to-fit the index and readjust pointers if necessary
+         else{
+            const size_type size = this->size();
+            const void* old_ptr = &impl[0];
+            this->impl.shrink_to_fit();
+            bool realloced = &impl[0] != old_ptr;
+            //Fix the pointers for the newly allocated buffer
+            if(realloced){
+               this->align_nodes(impl.begin(), impl.begin()+size+1);
+            }
+         }
+      }
+   }
+
+   /// @cond
+
+   iterator priv_insert(const_iterator position, const value_type &t)
+   {
+      typedef constant_iterator cvalue_iterator;
+      return this->insert_iter(position, cvalue_iterator(t, 1), cvalue_iterator(), std::forward_iterator_tag());
+   }
+
+   void priv_push_back(const value_type &t)
+   {  this->insert(end(), t);  }
+
+   template
+   void clear_pool(AllocatorVersion,
+      typename boost::container::container_detail::enable_if_c
+         
+            ::value>::type * = 0)
+   {
+      if(!impl.empty() && impl.back()){
+         void_ptr &pool_first_ref = impl.end()[-2];
+         void_ptr &pool_last_ref = impl.back();
+
+         multiallocation_chain holder;
+         holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, this->internal_data.pool_size);
+         while(!holder.empty()){
+            node_type_ptr_t n = holder.front();
+            holder.pop_front();
+            this->deallocate_one(n);
+         }
+         pool_first_ref = pool_last_ref = 0;
+         this->internal_data.pool_size = 0;
+      }
+   }
+
+   template
+   void clear_pool(AllocatorVersion,
+      typename boost::container::container_detail::enable_if_c
+         
+            ::value>::type * = 0)
+   {
+      if(!impl.empty() && impl.back()){
+         void_ptr &pool_first_ref = impl.end()[-2];
+         void_ptr &pool_last_ref = impl.back();
+         multiallocation_chain holder;
+         holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
+         node_alloc().deallocate_individual(boost::move(holder));
+         pool_first_ref = pool_last_ref = 0;
+         this->internal_data.pool_size = 0;
+      }
+   }
+
+   void clear_pool()
+   {
+      this->clear_pool(alloc_version());
+   }
+
+   void add_to_pool(size_type n)
+   {
+      this->add_to_pool(n, alloc_version());
+   }
+
+   template
+   void add_to_pool(size_type n, AllocatorVersion,
+      typename boost::container::container_detail::enable_if_c
+         
+            ::value>::type * = 0)
+   {
+      size_type remaining = n;
+      while(remaining--){
+         this->put_in_pool(this->allocate_one());
+      }
+   }
+
+   template
+   void add_to_pool(size_type n, AllocatorVersion,
+      typename boost::container::container_detail::enable_if_c
+         
+            ::value>::type * = 0)
+   {
+      void_ptr &pool_first_ref = impl.end()[-2];
+      void_ptr &pool_last_ref = impl.back();
+      multiallocation_chain holder;
+      holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
+      //BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled::value == true));
+      multiallocation_chain m (node_alloc().allocate_individual(n));
+      holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n);
+      this->internal_data.pool_size += n;
+      std::pair data(holder.extract_data());
+      pool_first_ref = data.first;
+      pool_last_ref = data.second;
+   }
+
+   void put_in_pool(node_type_ptr_t p)
+   {
+      void_ptr &pool_first_ref = impl.end()[-2];
+      void_ptr &pool_last_ref = impl.back();
+      multiallocation_chain holder;
+      holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
+      holder.push_front(p);
+      ++this->internal_data.pool_size;
+      std::pair ret(holder.extract_data());
+      pool_first_ref = ret.first;
+      pool_last_ref = ret.second;
+   }
+
+   node_type_ptr_t get_from_pool()
+   {
+      if(!impl.back()){
+         return node_type_ptr_t(0);
+      }
+      else{
+         void_ptr &pool_first_ref = impl.end()[-2];
+         void_ptr &pool_last_ref = impl.back();
+         multiallocation_chain holder;
+         holder.incorporate_after(holder.before_begin(), pool_first_ref, pool_last_ref, internal_data.pool_size);
+         node_type_ptr_t ret = holder.front();
+         holder.pop_front();
+         --this->internal_data.pool_size;
+         if(!internal_data.pool_size){
+            pool_first_ref = pool_last_ref = void_ptr(0);
+         }
+         else{
+            std::pair data(holder.extract_data());
+            pool_first_ref = data.first;
+            pool_last_ref = data.second;
+         }
+         return ret;
+      }
+   }
+
+   void insert_iter_prolog(size_type n, difference_type d)
+   {
+      initialize_end_node(n);
+      const void* old_ptr = &impl[0];
+      //size_type old_capacity = capacity();
+      //size_type old_size = size();
+      impl.insert(impl.begin()+d, n, 0);
+      bool realloced = &impl[0] != old_ptr;
+      //Fix the pointers for the newly allocated buffer
+      if(realloced){
+         align_nodes(impl.begin(), impl.begin()+d);
+      }
+   }
+
+   template
+   void assign_dispatch(InputIterator first, InputIterator last, boost::mpl::false_)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      iterator first1   = this->begin();
+      iterator last1    = this->end();
+      for ( ; first1 != last1 && first != last; ++first1, ++first)
+         *first1 = *first;
+      if (first == last){
+         this->erase(first1, last1);
+      }
+      else{
+         this->insert(last1, first, last);
+      }
+   }
+
+   template
+   void assign_dispatch(Integer n, Integer t, boost::mpl::true_)
+   {
+      typedef constant_iterator cvalue_iterator;
+      this->assign_dispatch(cvalue_iterator(t, n), cvalue_iterator(), boost::mpl::false_());
+   }
+
+   iterator priv_erase(const_iterator first, const_iterator last, allocator_v1)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      difference_type d1 = first - this->cbegin(), d2 = last - this->cbegin();
+      if(d1 != d2){
+         impl_iterator it1(impl.begin() + d1), it2(impl.begin() + d2);
+         for(impl_iterator it = it1; it != it2; ++it)
+            this->delete_node(*it);
+         impl_iterator e = impl.erase(it1, it2);
+         this->align_nodes(e, get_last_align());
+      }
+      return iterator(this->begin() + d1);
+   }
+
+   impl_iterator get_last_align()
+   {
+      return impl.end() - (ExtraPointers - 1);
+   }
+
+   const_impl_iterator get_last_align() const
+   {
+      return impl.cend() - (ExtraPointers - 1);
+   }
+
+   template
+   iterator priv_erase(const_iterator first, const_iterator last, AllocatorVersion,
+      typename boost::container::container_detail::enable_if_c
+         
+            ::value>::type * = 0)
+   {
+      STABLE_VECTOR_CHECK_INVARIANT;
+      return priv_erase(first, last, allocator_v1());
+   }
+
+   static node_type_ptr_t node_ptr_cast(const void_ptr &p)
+   {
+      return node_type_ptr_t(static_cast(stable_vector_detail::to_raw_pointer(p)));
+   }
+
+   static node_type_base_ptr_t node_base_ptr_cast(const void_ptr &p)
+   {
+      return node_type_base_ptr_t(static_cast(stable_vector_detail::to_raw_pointer(p)));
+   }
+
+   static value_type& value(const void_ptr &p)
+   {
+      return node_ptr_cast(p)->value;
+   }
+
+   void initialize_end_node(size_type impl_capacity = 0)
+   {
+      if(impl.empty()){
+         impl.reserve(impl_capacity + ExtraPointers);
+         impl.resize (ExtraPointers, void_ptr(0));
+         impl[0] = &this->internal_data.end_node;
+         this->internal_data.end_node.up = &impl[0];
+      }
+   }
+
+   void readjust_end_node()
+   {
+      if(!this->impl.empty()){
+         void_ptr &end_node_ref = *(this->get_last_align()-1);
+         end_node_ref = this->get_end_node();
+         this->internal_data.end_node.up = &end_node_ref;
+      }
+      else{
+         this->internal_data.end_node.up = void_ptr(&this->internal_data.end_node.up);
+      }
+   }
+
+   node_type_ptr_t get_end_node() const
+   {
+      const node_type_base_t* cp = &this->internal_data.end_node;
+      node_type_base_t* p = const_cast(cp);
+      return node_ptr_cast(p);
+   }
+
+   template
+   void_ptr new_node(const void_ptr &up, Iter it)
+   {
+      node_type_ptr_t p = this->allocate_one();
+      try{
+         boost::container::construct_in_place(this->node_alloc(), &*p, it);
+         p->set_pointer(up);
+      }
+      catch(...){
+         this->deallocate_one(p);
+         throw;
+      }
+      return p;
+   }
+
+   void delete_node(const void_ptr &p)
+   {
+      node_type_ptr_t n(node_ptr_cast(p));
+      allocator_traits::
+         destroy(this->node_alloc(), container_detail::to_raw_pointer(n));
+      this->put_in_pool(n);
+   }
+
+   static void align_nodes(impl_iterator first, impl_iterator last)
+   {
+      while(first!=last){
+         node_ptr_cast(*first)->up = void_ptr(&*first);
+         ++first;
+      }
+   }
+
+   void insert_not_iter(const_iterator position, size_type n, const T& t)
+   {
+      typedef constant_iterator cvalue_iterator;
+      this->insert_iter(position, cvalue_iterator(t, n), cvalue_iterator(), std::forward_iterator_tag());
+   }
+
+   template 
+   void insert_iter(const_iterator position,InputIterator first,InputIterator last, boost::mpl::true_)
+   {
+      typedef typename std::iterator_traits::iterator_category category;
+      this->insert_iter(position, first, last, category());
+   }
+
+   template 
+   void insert_iter(const_iterator position,InputIterator first,InputIterator last,std::input_iterator_tag)
+   {
+      for(; first!=last; ++first){
+         this->insert(position, *first);
+      }    
+   }
+
+   template 
+   iterator insert_iter(const_iterator position, InputIterator first, InputIterator last, std::forward_iterator_tag)
+   {
+      size_type       n = (size_type)std::distance(first,last);
+      difference_type d = position-this->cbegin();
+      if(n){
+         this->insert_iter_prolog(n, d);
+         const impl_iterator it(impl.begin() + d);
+         this->insert_iter_fwd(it, first, last, n);
+         //Fix the pointers for the newly allocated buffer
+         this->align_nodes(it + n, get_last_align());
+      }
+      return this->begin() + d;
+   }
+
+   template 
+   void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v1)
+   {
+      size_type i=0;
+      try{
+         while(first!=last){
+            it[i] = this->new_node(void_ptr_ptr(&it[i]), first);
+            ++first;
+            ++i;
+         }
+      }
+      catch(...){
+         impl_iterator e = impl.erase(it + i, it + n);
+         this->align_nodes(e, get_last_align());
+         throw;
+      }
+   }
+
+   template 
+   void insert_iter_fwd_alloc(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n, allocator_v2)
+   {
+      multiallocation_chain mem(node_alloc().allocate_individual(n));
+
+      size_type i = 0;
+      node_type_ptr_t p = 0;
+      try{
+         while(first != last){
+            p = mem.front();
+            mem.pop_front();
+            //This can throw
+            boost::container::construct_in_place(this->node_alloc(), &*p, first);
+            p->set_pointer(void_ptr_ptr(&it[i]));
+            ++first;
+            it[i] = p;
+            ++i;
+         }
+      }
+      catch(...){
+         node_alloc().deallocate_one(p);
+         node_alloc().deallocate_many(boost::move(mem));
+         impl_iterator e = impl.erase(it+i, it+n);
+         this->align_nodes(e, get_last_align());
+         throw;
+      }
+   }
+
+   template 
+   void insert_iter_fwd(const impl_iterator it, FwdIterator first, FwdIterator last, difference_type n)
+   {
+      size_type i = 0;
+      node_type_ptr_t p = 0;
+      try{
+         while(first != last){
+            p = this->get_from_pool();
+            if(!p){
+               insert_iter_fwd_alloc(it+i, first, last, n-i, alloc_version());
+               break;
+            }
+            //This can throw
+            boost::container::construct_in_place(this->node_alloc(), &*p, first);
+            p->set_pointer(void_ptr_ptr(&it[i]));
+            ++first;
+            it[i]=p;
+            ++i;
+         }
+      }
+      catch(...){
+         put_in_pool(p);
+         impl_iterator e = impl.erase(it+i, it+n);
+         this->align_nodes(e, get_last_align());
+         throw;
+      }
+   }
+
+   template 
+   void insert_iter(const_iterator position, InputIterator first, InputIterator last, boost::mpl::false_)
+   {
+      this->insert_not_iter(position, first, last);
+   }
+
+   #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING)
+   bool invariant()const
+   {
+      if(impl.empty())
+         return !capacity() && !size();
+      if(get_end_node() != *(impl.end() - ExtraPointers)){
+         return false;
+      }
+      for(const_impl_iterator it = impl.begin(), it_end = get_last_align(); it != it_end; ++it){
+         if(const_void_ptr(node_ptr_cast(*it)->up) != 
+               const_void_ptr(const_void_ptr_ptr(&*it)))
+            return false;
+      }
+      size_type n = capacity()-size();
+      const void_ptr &pool_head = impl.back();
+      size_type num_pool = 0;
+      node_type_ptr_t p = node_ptr_cast(pool_head);
+      while(p){
+         ++num_pool;
+         p = node_ptr_cast(p->up);
+      }
+      return n >= num_pool;
+   }
+
+   class invariant_checker
+   {
+      invariant_checker(const invariant_checker &);
+      invariant_checker & operator=(const invariant_checker &);
+      const stable_vector* p;
+
+      public:
+      invariant_checker(const stable_vector& v):p(&v){}
+      ~invariant_checker(){BOOST_ASSERT(p->invariant());}
+      void touch(){}
+   };
+   #endif
+
+   class ebo_holder
+      : public node_allocator_type
+   {
+      private:
+      BOOST_MOVABLE_BUT_NOT_COPYABLE(ebo_holder)
+      public:
+/*
+      explicit ebo_holder(BOOST_RV_REF(ebo_holder) x)
+         : node_allocator_type(boost::move(static_cast(x)))
+         , pool_size(0)
+         , end_node()
+      {}
+*/
+      template
+      explicit ebo_holder(BOOST_FWD_REF(AllocatorRLValue) a)
+         : node_allocator_type(boost::forward(a))
+         , pool_size(0)
+         , end_node()
+      {
+         this->set_end_pointer_to_default_constructed();
+      }
+
+      ebo_holder()
+         : node_allocator_type()
+         , pool_size(0)
+         , end_node()
+      {
+         this->set_end_pointer_to_default_constructed();
+      }
+
+      void set_end_pointer_to_default_constructed()
+      {
+         end_node.set_pointer(void_ptr(&end_node.up));
+      }
+
+      size_type pool_size;
+      node_type_base_t end_node;
+   } internal_data;
+
+   void priv_swap_members(stable_vector &x)
+   {
+      container_detail::do_swap(this->internal_data.pool_size, x.internal_data.pool_size);
+      this->readjust_end_node();
+      x.readjust_end_node();
+   }
+
+   node_allocator_type &node_alloc()              { return internal_data;  }
+   const node_allocator_type &node_alloc() const  { return internal_data;  }
+
+   impl_type                           impl;
+   /// @endcond
+};
+
+template 
+bool operator==(const stable_vector& x,const stable_vector& y)
+{
+   return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin());
+}
+
+template 
+bool operator< (const stable_vector& x,const stable_vector& y)
+{
+   return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
+}
+
+template 
+bool operator!=(const stable_vector& x,const stable_vector& y)
+{
+   return !(x==y);
+}
+
+template 
+bool operator> (const stable_vector& x,const stable_vector& y)
+{
+   return y
+bool operator>=(const stable_vector& x,const stable_vector& y)
+{
+   return !(x
+bool operator<=(const stable_vector& x,const stable_vector& y)
+{
+   return !(x>y);
+}
+
+// specialized algorithms:
+
+template 
+void swap(stable_vector& x,stable_vector& y)
+{
+   x.swap(y);
+}
+
+/// @cond
+
+#undef STABLE_VECTOR_CHECK_INVARIANT
+
+/// @endcond
+
+}}
+
+#include 
+
+#endif   //BOOST_CONTAINER_STABLE_VECTOR_HPP
diff --git a/src/third_party/boost/boost/container/string.hpp b/src/third_party/boost/boost/container/string.hpp
new file mode 100644
index 00000000000..3a9c55a3c4c
--- /dev/null
+++ b/src/third_party/boost/boost/container/string.hpp
@@ -0,0 +1,2895 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 1996,1997
+// Silicon Graphics Computer Systems, Inc.
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation.  Silicon Graphics makes no
+// representations about the suitability of this software for any
+// purpose.  It is provided "as is" without express or implied warranty.
+//
+//
+// Copyright (c) 1994
+// Hewlett-Packard Company
+//
+// Permission to use, copy, modify, distribute and sell this software
+// and its documentation for any purpose is hereby granted without fee,
+// provided that the above copyright notice appear in all copies and
+// that both that copyright notice and this permission notice appear
+// in supporting documentation.  Hewlett-Packard Company makes no
+// representations about the suitability of this software for any
+// purpose.  It is provided "as is" without express or implied warranty.
+
+#ifndef BOOST_CONTAINER_STRING_HPP
+#define BOOST_CONTAINER_STRING_HPP
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include       
+#include   
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+namespace boost {
+namespace container {
+#else
+namespace boost {
+namespace container {
+#endif
+
+/// @cond
+namespace container_detail {
+// ------------------------------------------------------------
+// Class basic_string_base.  
+
+// basic_string_base is a helper class that makes it it easier to write
+// an exception-safe version of basic_string.  The constructor allocates,
+// but does not initialize, a block of memory.  The destructor
+// deallocates, but does not destroy elements within, a block of
+// memory.  The destructor assumes that the memory either is the internal buffer, 
+// or else points to a block of memory that was allocated using _String_base's 
+// allocator and whose size is this->m_storage.
+template 
+class basic_string_base
+{
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_string_base)
+
+   typedef allocator_traits allocator_traits_type;
+ public:
+   typedef A allocator_type;
+   //! The stored allocator type
+   typedef allocator_type                          stored_allocator_type;
+   typedef typename allocator_traits_type::pointer     pointer;
+   typedef typename allocator_traits_type::value_type  value_type;
+   typedef typename allocator_traits_type::size_type   size_type;
+
+   basic_string_base()
+      : members_()
+   {  init(); }
+
+   basic_string_base(const allocator_type& a)
+      : members_(a)
+   {  init(); }
+
+   basic_string_base(const allocator_type& a, size_type n)
+      : members_(a)
+   {  
+      this->init(); 
+      this->allocate_initial_block(n);
+   }
+
+   basic_string_base(BOOST_RV_REF(basic_string_base) b)
+      :  members_(boost::move(b.alloc()))
+   {  
+      this->init();
+      this->swap_data(b); 
+   }
+
+   ~basic_string_base() 
+   {  
+      if(!this->is_short()){
+         this->deallocate_block(); 
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , static_cast(static_cast(&this->members_.m_repr.r))
+            );
+      }
+   }
+
+   private:
+
+   //This is the structure controlling a long string 
+   struct long_t
+   {
+      size_type      is_short  : 1;
+      size_type      length    : (sizeof(size_type)*CHAR_BIT - 1);
+      size_type      storage;
+      pointer        start;
+
+      long_t()
+      {}
+
+      long_t(const long_t &other)
+      {
+         this->is_short = other.is_short;
+         length   = other.length;
+         storage  = other.storage;
+         start    = other.start;
+      }
+
+      long_t &operator =(const long_t &other)
+      {
+         this->is_short = other.is_short;
+         length   = other.length;
+         storage  = other.storage;
+         start    = other.start;
+         return *this;
+      }
+   };
+
+   //This type is the first part of the structure controlling a short string
+   //The "data" member stores
+   struct short_header
+   {
+      unsigned char  is_short  : 1;
+      unsigned char  length    : (CHAR_BIT - 1);
+   };
+
+   //This type has the same alignment and size as long_t but it's POD
+   //so, unlike long_t, it can be placed in a union
+   
+   typedef typename boost::aligned_storage< sizeof(long_t), 
+       container_detail::alignment_of::value>::type   long_raw_t;
+
+   protected:
+   static const size_type  MinInternalBufferChars = 8;
+   static const size_type  AlignmentOfValueType =
+      alignment_of::value;
+   static const size_type  ShortDataOffset =
+      container_detail::ct_rounded_size::value;
+   static const size_type  ZeroCostInternalBufferChars =
+      (sizeof(long_t) - ShortDataOffset)/sizeof(value_type);
+   static const size_type  UnalignedFinalInternalBufferChars = 
+      (ZeroCostInternalBufferChars > MinInternalBufferChars) ?
+                ZeroCostInternalBufferChars : MinInternalBufferChars;
+
+   struct short_t
+   {
+      short_header   h; 
+      value_type     data[UnalignedFinalInternalBufferChars];
+   };
+
+   union repr_t
+   {
+      long_raw_t  r;
+      short_t     s;
+
+      short_t &short_repr() const
+      {  return *const_cast(&s);  }
+
+      long_t &long_repr() const
+      {  return *const_cast(reinterpret_cast(&r));  }
+   };
+
+   struct members_holder
+      :  public A
+   {
+      members_holder()
+         : A()
+      {}
+
+      template
+      explicit members_holder(BOOST_FWD_REF(AllocatorConvertible) a)
+         :  A(boost::forward(a))
+      {}
+
+      repr_t m_repr;
+   } members_;
+
+   const A &alloc() const
+   {  return members_;  }
+
+   A &alloc()
+   {  return members_;  }
+
+   static const size_type InternalBufferChars = (sizeof(repr_t) - ShortDataOffset)/sizeof(value_type);
+
+   private:
+
+   static const size_type MinAllocation = InternalBufferChars*2;
+
+   protected:
+   bool is_short() const
+   {  return static_cast(this->members_.m_repr.s.h.is_short != 0);  }
+
+   void is_short(bool yes)
+   {  
+      if(yes && !this->is_short()){
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , static_cast(static_cast(&this->members_.m_repr.r))
+            );
+      }
+      else{
+         allocator_traits_type::construct
+            ( this->alloc()
+            , static_cast(static_cast(&this->members_.m_repr.r))
+            );
+      }
+      this->members_.m_repr.s.h.is_short = yes;
+   }
+
+   private:
+   void init()
+   {
+      this->members_.m_repr.s.h.is_short = 1;
+      this->members_.m_repr.s.h.length   = 0;
+   }
+
+   protected:
+
+   typedef container_detail::integral_constant      allocator_v1;
+   typedef container_detail::integral_constant      allocator_v2;
+   typedef container_detail::integral_constant::value> alloc_version;
+
+   std::pair
+      allocation_command(allocation_type command,
+                         size_type limit_size, 
+                         size_type preferred_size,
+                         size_type &received_size, pointer reuse = 0)
+   {
+      if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
+         reuse = pointer(0);
+         command &= ~(expand_fwd | expand_bwd);
+      }
+      return this->allocation_command
+         (command, limit_size, preferred_size, received_size, reuse, alloc_version());
+   }
+
+   std::pair
+      allocation_command(allocation_type command,
+                         size_type limit_size, 
+                         size_type preferred_size,
+                         size_type &received_size,
+                         const pointer &reuse,
+                         allocator_v1)
+   {
+      (void)limit_size;
+      (void)reuse;
+      if(!(command & allocate_new))
+         return std::pair(pointer(0), false);
+      received_size = preferred_size;
+      return std::make_pair(this->alloc().allocate(received_size), false);
+   }
+
+   std::pair
+      allocation_command(allocation_type command,
+                         size_type limit_size, 
+                         size_type preferred_size,
+                         size_type &received_size,
+                         pointer reuse,
+                         allocator_v2)
+   {
+      return this->alloc().allocation_command(command, limit_size, preferred_size, 
+                                              received_size, reuse);
+   }
+
+   size_type next_capacity(size_type additional_objects) const
+   {  return get_next_capacity(allocator_traits_type::max_size(this->alloc()), this->priv_storage(), additional_objects);  }
+
+   void deallocate(pointer p, size_type n) 
+   {  
+      if (p && (n > InternalBufferChars))
+         this->alloc().deallocate(p, n);
+   }
+
+   void construct(pointer p, const value_type &value = value_type())
+   {
+      allocator_traits_type::construct
+         ( this->alloc()
+         , container_detail::to_raw_pointer(p)
+         , value
+         );
+   }
+
+   void destroy(pointer p, size_type n)
+   {
+      for(; n--; ++p){
+         allocator_traits_type::destroy
+            ( this->alloc()
+            , container_detail::to_raw_pointer(p)
+            );
+      }
+   }
+
+   void destroy(pointer p)
+   {
+      allocator_traits_type::destroy
+         ( this->alloc()
+         , container_detail::to_raw_pointer(p)
+         );
+   }
+
+   void allocate_initial_block(size_type n)
+   {
+      if (n <= this->max_size()) {
+         if(n > InternalBufferChars){
+            size_type new_cap = this->next_capacity(n);
+            pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first;
+            this->is_short(false);
+            this->priv_long_addr(p);
+            this->priv_size(0);
+            this->priv_storage(new_cap);
+         }
+      }
+      else
+         throw_length_error();
+   }
+
+   void deallocate_block() 
+   {  this->deallocate(this->priv_addr(), this->priv_storage());  }
+      
+   size_type max_size() const
+   {  return allocator_traits_type::max_size(this->alloc()) - 1; }
+
+   // Helper functions for exception handling.
+   void throw_length_error() const
+   {  throw(std::length_error("basic_string"));  }
+
+   void throw_out_of_range() const
+   {  throw(std::out_of_range("basic_string"));  }
+
+   protected:
+   size_type priv_capacity() const
+   { return this->priv_storage() - 1; }
+
+   pointer priv_short_addr() const
+   {  return pointer(&this->members_.m_repr.short_repr().data[0]);  }
+
+   pointer priv_long_addr() const
+   {  return this->members_.m_repr.long_repr().start;  }
+
+   pointer priv_addr() const
+   {  return this->is_short() ? pointer(&this->members_.m_repr.short_repr().data[0]) : this->members_.m_repr.long_repr().start;  }
+
+   void priv_long_addr(pointer addr)
+   {  this->members_.m_repr.long_repr().start = addr;  }
+
+   size_type priv_storage() const
+   {  return this->is_short() ? priv_short_storage() : priv_long_storage();  }
+
+   size_type priv_short_storage() const
+   {  return InternalBufferChars;  }
+
+   size_type priv_long_storage() const
+   {  return this->members_.m_repr.long_repr().storage;  }
+
+   void priv_storage(size_type storage)
+   {  
+      if(!this->is_short())
+         this->priv_long_storage(storage);
+   }
+
+   void priv_long_storage(size_type storage)
+   {  
+      this->members_.m_repr.long_repr().storage = storage;
+   }
+
+   size_type priv_size() const
+   {  return this->is_short() ? priv_short_size() : priv_long_size();  }
+
+   size_type priv_short_size() const
+   {  return this->members_.m_repr.short_repr().h.length;  }
+
+   size_type priv_long_size() const
+   {  return this->members_.m_repr.long_repr().length;  }
+
+   void priv_size(size_type sz)
+   {  
+      if(this->is_short())
+         this->priv_short_size(sz);
+      else
+         this->priv_long_size(sz);
+   }
+
+   void priv_short_size(size_type sz)
+   {  
+      this->members_.m_repr.s.h.length = (unsigned char)sz;
+   }
+
+   void priv_long_size(size_type sz)
+   {  
+      this->members_.m_repr.long_repr().length = static_cast(sz);
+   }
+
+   void swap_data(basic_string_base& other)
+   {
+      if(this->is_short()){
+         if(other.is_short()){
+            container_detail::do_swap(this->members_.m_repr, other.members_.m_repr);
+         }
+         else{
+            repr_t copied(this->members_.m_repr);
+            this->members_.m_repr.long_repr() = other.members_.m_repr.long_repr();
+            other.members_.m_repr = copied;
+         }
+      }
+      else{
+         if(other.is_short()){
+            repr_t copied(other.members_.m_repr);
+            other.members_.m_repr.long_repr() = this->members_.m_repr.long_repr();
+            this->members_.m_repr = copied;
+         }
+         else{
+            container_detail::do_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
+         }
+      }
+   }
+};
+
+}  //namespace container_detail {
+
+/// @endcond
+
+//! The basic_string class represents a Sequence of characters. It contains all the 
+//! usual operations of a Sequence, and, additionally, it contains standard string 
+//! operations such as search and concatenation.
+//!
+//! The basic_string class is parameterized by character type, and by that type's 
+//! Character Traits.
+//! 
+//! This class has performance characteristics very much like vector<>, meaning, 
+//! for example, that it does not perform reference-count or copy-on-write, and that
+//! concatenation of two strings is an O(N) operation. 
+//! 
+//! Some of basic_string's member functions use an unusual method of specifying positions 
+//! and ranges. In addition to the conventional method using iterators, many of 
+//! basic_string's member functions use a single value pos of type size_type to represent a 
+//! position (in which case the position is begin() + pos, and many of basic_string's 
+//! member functions use two values, pos and n, to represent a range. In that case pos is 
+//! the beginning of the range and n is its size. That is, the range is 
+//! [begin() + pos, begin() + pos + n). 
+//! 
+//! Note that the C++ standard does not specify the complexity of basic_string operations. 
+//! In this implementation, basic_string has performance characteristics very similar to 
+//! those of vector: access to a single character is O(1), while copy and concatenation 
+//! are O(N).
+//! 
+//! In this implementation, begin(), 
+//! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators.
+//! In this implementation, iterators are only invalidated by member functions that
+//! explicitly change the string's contents. 
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template , class A = std::allocator >
+#else
+template 
+#endif
+class basic_string
+   :  private container_detail::basic_string_base 
+{
+   /// @cond
+   private:
+   typedef allocator_traits allocator_traits_type;
+   BOOST_COPYABLE_AND_MOVABLE(basic_string)
+   typedef container_detail::basic_string_base base_t;
+   static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
+
+   protected:
+   // A helper class to use a char_traits as a function object.
+
+   template 
+   struct Eq_traits
+      : public std::binary_function
+   {
+      bool operator()(const typename Tr::char_type& x,
+                      const typename Tr::char_type& y) const
+         { return Tr::eq(x, y); }
+   };
+
+   template 
+   struct Not_within_traits
+      : public std::unary_function
+   {
+      typedef const typename Tr::char_type* Pointer;
+      const Pointer m_first;
+      const Pointer m_last;
+
+      Not_within_traits(Pointer f, Pointer l) 
+         : m_first(f), m_last(l) {}
+
+      bool operator()(const typename Tr::char_type& x) const 
+      {
+         return std::find_if(m_first, m_last, 
+                        std::bind1st(Eq_traits(), x)) == m_last;
+      }
+   };
+   /// @endcond
+
+   public:
+
+   //! The allocator type
+   typedef A                                       allocator_type;
+   //! The stored allocator type
+   typedef allocator_type                          stored_allocator_type;
+   //! The type of object, CharT, stored in the string
+   typedef CharT                                   value_type;
+   //! The second template parameter Traits
+   typedef Traits                                  traits_type;
+   //! Pointer to CharT
+   typedef typename allocator_traits_type::pointer pointer;
+   //! Const pointer to CharT 
+   typedef typename allocator_traits_type::const_pointer               const_pointer;
+   //! Reference to CharT 
+   typedef typename allocator_traits_type::reference                   reference;
+   //! Const reference to CharT 
+   typedef typename allocator_traits_type::const_reference             const_reference;
+   //! An unsigned integral type
+   typedef typename allocator_traits_type::size_type                   size_type;
+   //! A signed integral type
+   typedef typename allocator_traits_type::difference_type             difference_type;
+   //! Iterator used to iterate through a string. It's a Random Access Iterator
+   typedef pointer                                 iterator;
+   //! Const iterator used to iterate through a string. It's a Random Access Iterator
+   typedef const_pointer                           const_iterator;
+   //! Iterator used to iterate backwards through a string
+   typedef std::reverse_iterator       reverse_iterator;
+   //! Const iterator used to iterate backwards through a string
+   typedef std::reverse_iterator const_reverse_iterator;
+   //! The largest possible value of type size_type. That is, size_type(-1). 
+   static const size_type npos;
+
+   /// @cond
+   private:
+   typedef constant_iterator cvalue_iterator;
+   typedef typename base_t::allocator_v1  allocator_v1;
+   typedef typename base_t::allocator_v2  allocator_v2;
+   typedef typename base_t::alloc_version  alloc_version;
+   /// @endcond
+
+   public:                         // Constructor, destructor, assignment.
+   /// @cond
+   struct reserve_t {};
+
+   basic_string(reserve_t, size_type n,
+                const allocator_type& a = allocator_type())
+      //Select allocator as in copy constructor as reserve_t-based constructors
+      //are two step copies optimized for capacity
+      : base_t( allocator_traits_type::select_on_container_copy_construction(a)
+              , n + 1)
+   { this->priv_terminate_string(); }
+
+   /// @endcond
+
+   //! Effects: Default constructs a basic_string.
+   //! 
+   //! Throws: If allocator_type's default constructor throws.
+   basic_string()
+      : base_t()
+   { this->priv_terminate_string(); }
+
+
+   //! Effects: Constructs a basic_string taking the allocator as parameter.
+   //! 
+   //! Throws: If allocator_type's copy constructor throws.
+   explicit basic_string(const allocator_type& a)
+      : base_t(a)
+   { this->priv_terminate_string(); }
+
+   //! Effects: Copy constructs a basic_string.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Throws: If allocator_type's default constructor or copy constructor throws.
+   basic_string(const basic_string& s) 
+      :  base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
+   { this->priv_range_initialize(s.begin(), s.end()); }
+
+   //! Effects: Move constructor. Moves mx's resources to *this.
+   //!
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   basic_string(BOOST_RV_REF(basic_string) s) 
+      : base_t(boost::move((base_t&)s))
+   {}
+
+   //! Effects: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by a specific number of characters of the s string. 
+   basic_string(const basic_string& s, size_type pos, size_type n = npos,
+               const allocator_type& a = allocator_type()) 
+      : base_t(a) 
+   {
+      if (pos > s.size())
+         this->throw_out_of_range();
+      else
+         this->priv_range_initialize
+            (s.begin() + pos, s.begin() + pos + container_detail::min_value(n, s.size() - pos));
+   }
+
+   //! Effects: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by a specific number of characters of the s c-string.
+   basic_string(const CharT* s, size_type n,
+               const allocator_type& a = allocator_type()) 
+      : base_t(a) 
+   { this->priv_range_initialize(s, s + n); }
+
+   //! Effects: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by the null-terminated s c-string.
+   basic_string(const CharT* s,
+                const allocator_type& a = allocator_type())
+      : base_t(a) 
+   { this->priv_range_initialize(s, s + Traits::length(s)); }
+
+   //! Effects: Constructs a basic_string taking the allocator as parameter,
+   //!   and is initialized by n copies of c.
+   basic_string(size_type n, CharT c,
+                const allocator_type& a = allocator_type())
+      : base_t(a)
+   {  
+      this->priv_range_initialize(cvalue_iterator(c, n),
+                                  cvalue_iterator());
+   }
+
+   //! Effects: Constructs a basic_string taking the allocator as parameter,
+   //!   and a range of iterators.
+   template 
+   basic_string(InputIterator f, InputIterator l,
+               const allocator_type& a = allocator_type())
+      : base_t(a)
+   {
+      //Dispatch depending on integer/iterator
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_initialize_dispatch(f, l, Result());
+   }
+
+   //! Effects: Destroys the basic_string. All used memory is deallocated.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   ~basic_string() 
+   {}
+      
+   //! Effects: Copy constructs a string.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   basic_string& operator=(BOOST_COPY_ASSIGN_REF(basic_string) x)
+   {
+      if (&x != this){
+         allocator_type &this_alloc     = this->alloc();
+         const allocator_type &x_alloc  = x.alloc();
+         container_detail::bool_ flag;
+         if(flag && this_alloc != x_alloc){
+            if(!this->is_short()){
+               this->deallocate_block();
+               this->is_short(true);
+               Traits::assign(*this->priv_addr(), this->priv_null());
+               this->priv_size(0);
+            }
+         }
+         container_detail::assign_alloc(this->alloc(), x.alloc(), flag);
+         this->assign(x.begin(), x.end());
+      }
+      return *this;
+   }
+
+   //! Effects: Move constructor. Moves mx's resources to *this.
+   //!
+   //! Throws: If allocator_type's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   basic_string& operator=(BOOST_RV_REF(basic_string) x)
+   {
+      if (&x != this){
+         allocator_type &this_alloc = this->alloc();
+         allocator_type &x_alloc    = x.alloc();
+         //If allocators are equal we can just swap pointers
+         if(this_alloc == x_alloc){
+            //Destroy objects but retain memory in case x reuses it in the future
+            this->clear();
+            this->swap_data(x);
+            //Move allocator if needed
+            container_detail::bool_ flag;
+            container_detail::move_alloc(this_alloc, x_alloc, flag);
+         }
+         //If unequal allocators, then do a one by one move
+         else{
+            this->assign( x.begin(), x.end());
+         }
+      }
+      return *this;
+   }
+
+   //! Effects: Assignment from a null-terminated c-string.
+   basic_string& operator=(const CharT* s) 
+   { return this->assign(s, s + Traits::length(s)); }
+
+   //! Effects: Assignment from character.
+   basic_string& operator=(CharT c)
+   { return this->assign(static_cast(1), c); }
+
+   //! Effects: Returns an iterator to the first element contained in the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin()
+   { return this->priv_addr(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const
+   { return this->priv_addr(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const
+   { return this->priv_addr(); }
+
+   //! Effects: Returns an iterator to the end of the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end()
+   { return this->priv_addr() + this->priv_size(); }
+
+   //! Effects: Returns a const_iterator to the end of the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const 
+   { return this->priv_addr() + this->priv_size(); }  
+
+   //! Effects: Returns a const_iterator to the end of the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const 
+   { return this->priv_addr() + this->priv_size(); }  
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin()             
+   { return reverse_iterator(this->priv_addr() + this->priv_size()); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const 
+   { return this->crbegin(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin() const 
+   { return const_reverse_iterator(this->priv_addr() + this->priv_size()); }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend()               
+   { return reverse_iterator(this->priv_addr()); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend()   const 
+   { return this->crend(); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend()   const 
+   { return const_reverse_iterator(this->priv_addr()); }
+
+   //! Effects: Returns a copy of the internal allocator.
+   //! 
+   //! Throws: If allocator's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const 
+   { return this->alloc(); }
+
+   //! Effects: Returns a reference to the internal allocator.
+   //! 
+   //! Throws: Nothing
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+   {  return this->alloc(); }
+
+   //! Effects: Returns a reference to the internal allocator.
+   //! 
+   //! Throws: Nothing
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+   {  return this->alloc(); }
+
+   //! Effects: Returns the number of the elements contained in the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const    
+   { return this->priv_size(); }
+
+   //! Effects: Returns the number of the elements contained in the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type length() const
+   { return this->size(); }
+
+   //! Effects: Returns the largest possible size of the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const
+   { return base_t::max_size(); }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! Throws: If memory allocation throws
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type n, CharT c)
+   {
+      if (n <= size())
+         this->erase(this->begin() + n, this->end());
+      else
+         this->append(n - this->size(), c);
+   }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are default constructed.
+   //!
+   //! Throws: If memory allocation throws
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type n)
+   { resize(n, this->priv_null()); }
+
+   //! Effects: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //! 
+   //! Throws: If memory allocation allocation throws
+   void reserve(size_type res_arg)
+   {
+      if (res_arg > this->max_size())
+         this->throw_length_error();
+
+      if (this->capacity() < res_arg){
+         size_type n = container_detail::max_value(res_arg, this->size()) + 1;
+         size_type new_cap = this->next_capacity(n);
+         pointer new_start = this->allocation_command
+            (allocate_new, n, new_cap, new_cap).first;
+         size_type new_length = 0;
+
+         new_length += priv_uninitialized_copy
+            (this->priv_addr(), this->priv_addr() + this->priv_size(), new_start);
+         this->priv_construct_null(new_start + new_length);
+         this->deallocate_block();
+         this->is_short(false);
+         this->priv_long_addr(new_start);
+         this->priv_size(new_length);
+         this->priv_storage(new_cap);
+      }
+   }
+
+   //! Effects: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type capacity() const
+   { return this->priv_capacity(); }
+
+   //! Effects: Erases all the elements of the vector.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements in the vector.
+   void clear()
+   {
+      if (!empty()) {
+         Traits::assign(*this->priv_addr(), this->priv_null());
+         this->priv_size(0);
+      }
+   }
+
+   //! Effects: Tries to deallocate the excess of memory created
+   //!   with previous allocations. The size of the string is unchanged
+   //!
+   //! Throws: Nothing
+   //!
+   //! Complexity: Linear to size().
+   void shrink_to_fit()
+   {
+      //Check if shrinking is possible
+      if(this->priv_storage() > InternalBufferChars){
+         //Check if we should pass from dynamically allocated buffer
+         //to the internal storage
+         if(this->priv_size() < (InternalBufferChars)){
+            //Dynamically allocated buffer attributes
+            pointer   long_addr    = this->priv_long_addr();
+            size_type long_storage = this->priv_long_storage();
+            size_type long_size    = this->priv_long_size();
+            //Shrink from allocated buffer to the internal one, including trailing null
+            Traits::copy( container_detail::to_raw_pointer(this->priv_short_addr())
+                        , container_detail::to_raw_pointer(long_addr)
+                        , long_size+1);
+            this->is_short(true);
+            this->alloc().deallocate(long_addr, long_storage);
+         }
+         else{
+            //Shrinking in dynamic buffer
+            this->priv_shrink_to_fit_dynamic_buffer(alloc_version());
+         }
+      }
+   }
+
+   //! Effects: Returns true if the vector contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const
+   { return !this->priv_size(); }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference operator[](size_type n)
+      { return *(this->priv_addr() + n); }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a const reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference operator[](size_type n) const
+      { return *(this->priv_addr() + n); }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: std::range_error if n >= size()
+   //! 
+   //! Complexity: Constant.
+   reference at(size_type n) {
+      if (n >= size())
+      this->throw_out_of_range();
+      return *(this->priv_addr() + n);
+   }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a const reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: std::range_error if n >= size()
+   //! 
+   //! Complexity: Constant.
+   const_reference at(size_type n) const {
+      if (n >= size())
+         this->throw_out_of_range();
+      return *(this->priv_addr() + n);
+   }
+
+   //! Effects: Calls append(str.data, str.size()).
+   //!
+   //! Returns: *this
+   basic_string& operator+=(const basic_string& s)
+   {  return this->append(s); }
+
+   //! Effects: Calls append(s).
+   //!
+   //! Returns: *this
+   basic_string& operator+=(const CharT* s)
+   {  return this->append(s); }
+
+   //! Effects: Calls append(1, c).
+   //!
+   //! Returns: *this
+   basic_string& operator+=(CharT c)
+   {  this->push_back(c); return *this;   }
+
+   //! Effects: Calls append(str.data(), str.size()).
+   //!
+   //! Returns: *this
+   basic_string& append(const basic_string& s) 
+   {  return this->append(s.begin(), s.end());  }
+
+   //! Requires: pos <= str.size()
+   //!
+   //! Effects: Determines the effective length rlen of the string to append 
+   //! as the smaller of n and str.size() - pos and calls append(str.data() + pos, rlen).
+   //!
+   //! Throws: If memory allocation throws and out_of_range if pos > str.size()
+   //!
+   //! Returns: *this
+   basic_string& append(const basic_string& s, size_type pos, size_type n)
+   {
+      if (pos > s.size())
+      this->throw_out_of_range();
+      return this->append(s.begin() + pos,
+                          s.begin() + pos + container_detail::min_value(n, s.size() - pos));
+   }
+
+   //! Requires: s points to an array of at least n elements of CharT.
+   //!
+   //! Effects: The function replaces the string controlled by *this with
+   //!   a string of length size() + n whose irst size() elements are a copy of the
+   //!   original string controlled by *this and whose remaining
+   //!   elements are a copy of the initial n elements of s.
+   //!
+   //! Throws: If memory allocation throws length_error if size() + n > max_size().
+   //!
+   //! Returns: *this
+   basic_string& append(const CharT* s, size_type n) 
+   {  return this->append(s, s + n);  }
+
+   //! Requires: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Effects: Calls append(s, traits::length(s)).
+   //!
+   //! Returns: *this
+   basic_string& append(const CharT* s) 
+   {  return this->append(s, s + Traits::length(s));  }
+
+   //! Effects: Equivalent to append(basic_string(n, c)).
+   //!
+   //! Returns: *this
+   basic_string& append(size_type n, CharT c)
+   {  return this->append(cvalue_iterator(c, n), cvalue_iterator()); }
+
+   //! Requires: [first,last) is a valid range.
+   //!
+   //! Effects: Equivalent to append(basic_string(first, last)).
+   //!
+   //! Returns: *this
+   template 
+   basic_string& append(InputIter first, InputIter last)
+   {  this->insert(this->end(), first, last);   return *this;  }
+
+   //! Effects: Equivalent to append(static_cast(1), c).
+   void push_back(CharT c)
+   {
+      if (this->priv_size() < this->capacity()){
+         this->priv_construct_null(this->priv_addr() + (this->priv_size() + 1));
+         Traits::assign(this->priv_addr()[this->priv_size()], c);
+         this->priv_size(this->priv_size()+1);
+      }
+      else{
+         //No enough memory, insert a new object at the end
+         this->append((size_type)1, c);
+      }
+   }
+
+   //! Effects: Equivalent to assign(str, 0, npos).
+   //!
+   //! Returns: *this
+   basic_string& assign(const basic_string& s) 
+   {  return this->operator=(s); }
+
+   //! Effects: The function replaces the string controlled by *this
+   //!    with a string of length str.size() whose elements are a copy of the string 
+   //!   controlled by str. Leaves str in a valid but unspecified state.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: *this
+   basic_string& assign(BOOST_RV_REF(basic_string) ms) 
+   {  return this->swap_data(ms), *this;  }
+
+   //! Requires: pos <= str.size()
+   //!
+   //! Effects: Determines the effective length rlen of the string to assign as
+   //!   the smaller of n and str.size() - pos and calls assign(str.data() + pos rlen).
+   //!
+   //! Throws: If memory allocation throws or out_of_range if pos > str.size().
+   //!
+   //! Returns: *this
+   basic_string& assign(const basic_string& s, 
+                        size_type pos, size_type n) {
+      if (pos > s.size())
+      this->throw_out_of_range();
+      return this->assign(s.begin() + pos, 
+                          s.begin() + pos + container_detail::min_value(n, s.size() - pos));
+   }
+
+   //! Requires: s points to an array of at least n elements of CharT.
+   //!
+   //! Effects: Replaces the string controlled by *this with a string of
+   //! length n whose elements are a copy of those pointed to by s.
+   //!
+   //! Throws: If memory allocation throws or length_error if n > max_size().
+   //!    
+   //! Returns: *this
+   basic_string& assign(const CharT* s, size_type n)
+   {  return this->assign(s, s + n);   }
+
+   //! Requires: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Effects: Calls assign(s, traits::length(s)).
+   //!
+   //! Returns: *this
+   basic_string& assign(const CharT* s)
+   { return this->assign(s, s + Traits::length(s)); }
+
+   //! Effects: Equivalent to assign(basic_string(n, c)).
+   //!
+   //! Returns: *this
+   basic_string& assign(size_type n, CharT c)
+   {  return this->assign(cvalue_iterator(c, n), cvalue_iterator()); }
+
+   //! Effects: Equivalent to assign(basic_string(first, last)).
+   //!
+   //! Returns: *this
+   template 
+   basic_string& assign(InputIter first, InputIter last) 
+   {
+      //Dispatch depending on integer/iterator
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      return this->priv_assign_dispatch(first, last, Result());
+   }
+
+   //! Requires: pos <= size().
+   //!
+   //! Effects: Calls insert(pos, str.data(), str.size()).
+   //!
+   //! Throws: If memory allocation throws or out_of_range if pos > size().
+   //!
+   //! Returns: *this
+   basic_string& insert(size_type pos, const basic_string& s) 
+   {
+      if (pos > size())
+         this->throw_out_of_range();
+      if (this->size() > this->max_size() - s.size())
+         this->throw_length_error();
+      this->insert(this->priv_addr() + pos, s.begin(), s.end());
+      return *this;
+   }
+
+   //! Requires: pos1 <= size() and pos2 <= str.size()
+   //!
+   //! Effects: Determines the effective length rlen of the string to insert as
+   //!   the smaller of n and str.size() - pos2 and calls insert(pos1, str.data() + pos2, rlen).
+   //!
+   //! Throws: If memory allocation throws or out_of_range if pos1 > size() or pos2 > str.size().
+   //!
+   //! Returns: *this
+   basic_string& insert(size_type pos1, const basic_string& s,
+                        size_type pos2, size_type n) 
+   {
+      if (pos1 > this->size() || pos2 > s.size())
+         this->throw_out_of_range();
+      size_type len = container_detail::min_value(n, s.size() - pos2);
+      if (this->size() > this->max_size() - len)
+         this->throw_length_error();
+      const CharT *beg_ptr = container_detail::to_raw_pointer(s.begin()) + pos2;
+      const CharT *end_ptr = beg_ptr + len;
+      this->insert(this->priv_addr() + pos1, beg_ptr, end_ptr);
+      return *this;
+   }
+
+   //! Requires: s points to an array of at least n elements of CharT and pos <= size().
+   //!
+   //! Effects: Replaces the string controlled by *this with a string of length size() + n
+   //!   whose first pos elements are a copy of the initial elements of the original string
+   //!   controlled by *this and whose next n elements are a copy of the elements in s and whose
+   //!   remaining elements are a copy of the remaining elements of the original string controlled by *this.
+   //!
+   //! Throws: If memory allocation throws, out_of_range if pos > size() or
+   //!   length_error if size() + n > max_size().
+   //!
+   //! Returns: *this
+   basic_string& insert(size_type pos, const CharT* s, size_type n) 
+   {
+      if (pos > this->size())
+         this->throw_out_of_range();
+      if (this->size() > this->max_size() - n)
+         this->throw_length_error();
+      this->insert(this->priv_addr() + pos, s, s + n);
+      return *this;
+   }
+
+   //! Requires: pos <= size() and s points to an array of at least traits::length(s) + 1 elements of CharT
+   //!
+   //! Effects: Calls insert(pos, s, traits::length(s)).
+   //!
+   //! Throws: If memory allocation throws, out_of_range if pos > size()
+   //!   length_error if size() > max_size() - Traits::length(s)
+   //!
+   //! Returns: *this
+   basic_string& insert(size_type pos, const CharT* s) 
+   {
+      if (pos > size())
+         this->throw_out_of_range();
+      size_type len = Traits::length(s);
+      if (this->size() > this->max_size() - len)
+         this->throw_length_error();
+      this->insert(this->priv_addr() + pos, s, s + len);
+      return *this;
+   }
+
+   //! Effects: Equivalent to insert(pos, basic_string(n, c)).
+   //!
+   //! Throws: If memory allocation throws, out_of_range if pos > size()
+   //!   length_error if size() > max_size() - n
+   //!
+   //! Returns: *this
+   basic_string& insert(size_type pos, size_type n, CharT c) 
+   {
+      if (pos > this->size())
+         this->throw_out_of_range();
+      if (this->size() > this->max_size() - n)
+         this->throw_length_error();
+      this->insert(const_iterator(this->priv_addr() + pos), n, c);
+      return *this;
+   }
+
+   //! Requires: p is a valid iterator on *this.
+   //!
+   //! Effects: inserts a copy of c before the character referred to by p.
+   //!
+   //! Returns: An iterator which refers to the copy of the inserted character.
+   iterator insert(const_iterator p, CharT c) 
+   {
+      size_type new_offset = p - this->priv_addr() + 1;
+      this->insert(p, cvalue_iterator(c, 1), cvalue_iterator());
+      return this->priv_addr() + new_offset;
+   }
+
+
+   //! Requires: p is a valid iterator on *this.
+   //!
+   //! Effects: Inserts n copies of c before the character referred to by p.
+   //!
+   //! Returns: An iterator which refers to the copy of the first
+   //!   inserted character, or p if n == 0.
+   void insert(const_iterator p, size_type n, CharT c)
+   {
+      this->insert(p, cvalue_iterator(c, n), cvalue_iterator());
+   }
+
+   //! Requires: p is a valid iterator on *this. [first,last) is a valid range.
+   //!
+   //! Effects: Equivalent to insert(p - begin(), basic_string(first, last)).
+   //!
+   //! Returns: An iterator which refers to the copy of the first
+   //!   inserted character, or p if first == last.
+   template 
+   void insert(const_iterator p, InputIter first, InputIter last) 
+   {
+      //Dispatch depending on integer/iterator
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_insert_dispatch(p, first, last, Result());
+   }
+
+   //! Requires: pos <= size()
+   //!
+   //! Effects: Determines the effective length xlen of the string to be removed as the smaller of n and size() - pos.
+   //!   The function then replaces the string controlled by *this with a string of length size() - xlen
+   //!   whose first pos elements are a copy of the initial elements of the original string controlled by *this,
+   //!   and whose remaining elements are a copy of the elements of the original string controlled by *this
+   //!   beginning at position pos + xlen.
+   //!
+   //! Throws: out_of_range if pos > size().
+   //!
+   //! Returns: *this
+   basic_string& erase(size_type pos = 0, size_type n = npos) 
+   {
+      if (pos > size())
+         this->throw_out_of_range();
+      erase(this->priv_addr() + pos, this->priv_addr() + pos + container_detail::min_value(n, size() - pos));
+      return *this;
+   }  
+
+   //! Effects: Removes the character referred to by p.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: An iterator which points to the element immediately following p prior to the element being
+   //!    erased. If no such element exists, end() is returned.
+   iterator erase(const_iterator p) 
+   {
+      // The move includes the terminating null.
+      CharT *ptr = const_cast(container_detail::to_raw_pointer(p));
+      Traits::move(ptr,
+                   container_detail::to_raw_pointer(p + 1), 
+                   this->priv_size() - (p - this->priv_addr()));
+      this->priv_size(this->priv_size()-1);
+      return iterator(ptr);
+   }
+
+   //! Requires: first and last are valid iterators on *this, defining a range [first,last).
+   //!
+   //! Effects: Removes the characters in the range [first,last).
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: An iterator which points to the element pointed to by last prior to
+   //!   the other elements being erased. If no such element exists, end() is returned.
+   iterator erase(const_iterator first, const_iterator last)
+   {
+      CharT * f = const_cast(container_detail::to_raw_pointer(first));
+      if (first != last) { // The move includes the terminating null.
+         size_type num_erased = last - first;
+         Traits::move(f,
+                      container_detail::to_raw_pointer(last), 
+                      (this->priv_size() + 1)-(last - this->priv_addr()));
+         size_type new_length = this->priv_size() - num_erased;
+         this->priv_size(new_length);
+      }
+      return iterator(f);
+   }
+
+   //! Requires: !empty()
+   //!
+   //! Throws: Nothing
+   //!
+   //! Effects: Equivalent to erase(size() - 1, 1).
+   void pop_back()
+   {
+      Traits::assign(this->priv_addr()[this->priv_size()-1], this->priv_null());
+      this->priv_size(this->priv_size()-1);;
+   }
+
+   //! Requires: pos1 <= size().
+   //!
+   //! Effects: Calls replace(pos1, n1, str.data(), str.size()).
+   //!
+   //! Throws: if memory allocation throws or out_of_range if pos1 > size().
+   //!
+   //! Returns: *this
+   basic_string& replace(size_type pos1, size_type n1, const basic_string& str) 
+   {
+      if (pos1 > size())
+         this->throw_out_of_range();
+      const size_type len = container_detail::min_value(n1, size() - pos1);
+      if (this->size() - len >= this->max_size() - str.size())
+         this->throw_length_error();
+      return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len, 
+                           str.begin(), str.end());
+   }
+
+   //! Requires: pos1 <= size() and pos2 <= str.size().
+   //!
+   //! Effects: Determines the effective length rlen of the string to be
+   //!   inserted as the smaller of n2 and str.size() - pos2 and calls
+   //!   replace(pos1, n1, str.data() + pos2, rlen).
+   //!
+   //! Throws: if memory allocation throws, out_of_range if pos1 > size() or pos2 > str.size().
+   //!
+   //! Returns: *this
+   basic_string& replace(size_type pos1, size_type n1,
+                         const basic_string& str, size_type pos2, size_type n2) 
+   {
+      if (pos1 > size() || pos2 > str.size())
+         this->throw_out_of_range();
+      const size_type len1 = container_detail::min_value(n1, size() - pos1);
+      const size_type len2 = container_detail::min_value(n2, str.size() - pos2);
+      if (this->size() - len1 >= this->max_size() - len2)
+         this->throw_length_error();
+      return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len1,
+                     str.priv_addr() + pos2, str.priv_addr() + pos2 + len2);
+   }
+
+   //! Requires: pos1 <= size() and s points to an array of at least n2 elements of CharT.
+   //!
+   //! Effects: Determines the effective length xlen of the string to be removed as the 
+   //!   smaller of n1 and size() - pos1. If size() - xlen >= max_size() - n2 throws length_error. 
+   //!   Otherwise, the function replaces the string controlled by *this with a string of 
+   //!   length size() - xlen + n2 whose first pos1 elements are a copy of the initial elements 
+   //!   of the original string controlled by *this, whose next n2 elements are a copy of the 
+   //!   initial n2 elements of s, and whose remaining elements are a copy of the elements of 
+   //!   the original string controlled by *this beginning at position pos + xlen.
+   //!
+   //! Throws: if memory allocation throws, out_of_range if pos1 > size() or length_error 
+   //!   if the length of the  resulting string would exceed max_size()
+   //!
+   //! Returns: *this
+   basic_string& replace(size_type pos1, size_type n1,
+                        const CharT* s, size_type n2) 
+   {
+      if (pos1 > size())
+         this->throw_out_of_range();
+      const size_type len = container_detail::min_value(n1, size() - pos1);
+      if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
+         this->throw_length_error();
+      return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len,
+                     s, s + n2);
+   }
+
+   //! Requires: pos1 <= size() and s points to an array of at least n2 elements of CharT.
+   //!
+   //! Effects: Determines the effective length xlen of the string to be removed as the smaller
+   //! of n1 and size() - pos1. If size() - xlen >= max_size() - n2 throws length_error. Otherwise,
+   //! the function replaces the string controlled by *this with a string of length size() - xlen + n2
+   //! whose first pos1 elements are a copy of the initial elements of the original string controlled
+   //! by *this, whose next n2 elements are a copy of the initial n2 elements of s, and whose
+   //! remaining elements are a copy of the elements of the original string controlled by *this
+   //! beginning at position pos + xlen.
+   //!
+   //! Throws: if memory allocation throws, out_of_range if pos1 > size() or length_error 
+   //!   if the length of the resulting string would exceed max_size()
+   //!
+   //! Returns: *this
+   basic_string& replace(size_type pos, size_type n1, const CharT* s) 
+   {
+      if (pos > size())
+         this->throw_out_of_range();
+      const size_type len = container_detail::min_value(n1, size() - pos);
+      const size_type n2 = Traits::length(s);
+      if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
+         this->throw_length_error();
+      return this->replace(this->priv_addr() + pos, this->priv_addr() + pos + len,
+                     s, s + Traits::length(s));
+   }
+
+   //! Requires: pos1 <= size().
+   //!
+   //! Effects: Equivalent to replace(pos1, n1, basic_string(n2, c)).
+   //!
+   //! Throws: if memory allocation throws, out_of_range if pos1 > size() or length_error 
+   //!   if the length of the  resulting string would exceed max_size()
+   //!
+   //! Returns: *this
+   basic_string& replace(size_type pos1, size_type n1, size_type n2, CharT c) 
+   {
+      if (pos1 > size())
+         this->throw_out_of_range();
+      const size_type len = container_detail::min_value(n1, size() - pos1);
+      if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
+         this->throw_length_error();
+      return this->replace(this->priv_addr() + pos1, this->priv_addr() + pos1 + len, n2, c);
+   }
+
+   //! Requires: [begin(),i1) and [i1,i2) are valid ranges.
+   //!
+   //! Effects: Calls replace(i1 - begin(), i2 - i1, str).
+   //!
+   //! Throws: if memory allocation throws
+   //!
+   //! Returns: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str) 
+   { return this->replace(i1, i2, str.begin(), str.end()); }
+
+   //! Requires: [begin(),i1) and [i1,i2) are valid ranges and 
+   //!   s points to an array of at least n elements
+   //!
+   //! Effects: Calls replace(i1 - begin(), i2 - i1, s, n).
+   //!
+   //! Throws: if memory allocation throws
+   //!
+   //! Returns: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s, size_type n) 
+   { return this->replace(i1, i2, s, s + n); }
+
+   //! Requires: [begin(),i1) and [i1,i2) are valid ranges and s points to an
+   //!   array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Effects: Calls replace(i1 - begin(), i2 - i1, s, traits::length(s)).
+   //!
+   //! Throws: if memory allocation throws
+   //!
+   //! Returns: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, const CharT* s) 
+   {  return this->replace(i1, i2, s, s + Traits::length(s));   }
+
+   //! Requires: [begin(),i1) and [i1,i2) are valid ranges.
+   //!
+   //! Effects: Calls replace(i1 - begin(), i2 - i1, basic_string(n, c)).
+   //!
+   //! Throws: if memory allocation throws
+   //!
+   //! Returns: *this
+   basic_string& replace(const_iterator i1, const_iterator i2, size_type n, CharT c)
+   {
+      const size_type len = static_cast(i2 - i1);
+      if (len >= n) {
+         Traits::assign(const_cast(container_detail::to_raw_pointer(i1)), n, c);
+         erase(i1 + n, i2);
+      }
+      else {
+         Traits::assign(const_cast(container_detail::to_raw_pointer(i1)), len, c);
+         insert(i2, n - len, c);
+      }
+      return *this;
+   }
+
+   //! Requires: [begin(),i1), [i1,i2) and [j1,j2) are valid ranges.
+   //!
+   //! Effects: Calls replace(i1 - begin(), i2 - i1, basic_string(j1, j2)).
+   //!
+   //! Throws: if memory allocation throws
+   //!
+   //! Returns: *this
+   template 
+   basic_string& replace(const_iterator i1, const_iterator i2, InputIter j1, InputIter j2) 
+   {
+      //Dispatch depending on integer/iterator
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      return this->priv_replace_dispatch(i1, i2, j1, j2,  Result());
+   }
+
+   //! Requires: pos <= size()
+   //!
+   //! Effects: Determines the effective length rlen of the string to copy as the
+   //!   smaller of n and size() - pos. s shall designate an array of at least rlen elements.
+   //!   The function then replaces the string designated by s with a string of length rlen 
+   //!   whose elements are a copy of the string controlled by *this beginning at position pos.
+   //!   The function does not append a null object to the string designated by s.
+   //!
+   //! Throws: if memory allocation throws, out_of_range if pos > size().
+   //!
+   //! Returns: rlen
+   size_type copy(CharT* s, size_type n, size_type pos = 0) const 
+   {
+      if (pos > size())
+         this->throw_out_of_range();
+      const size_type len = container_detail::min_value(n, size() - pos);
+      Traits::copy(s, container_detail::to_raw_pointer(this->priv_addr() + pos), len);
+      return len;
+   }
+
+   //! Effects: *this contains the same sequence of characters that was in s, 
+   //!   s contains the same sequence of characters that was in *this.
+   //!
+   //! Throws: Nothing
+   void swap(basic_string& x)
+   {
+      this->base_t::swap_data(x);
+      container_detail::bool_ flag;
+      container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
+   }
+
+   //! Requires: The program shall not alter any of the values stored in the character array.
+   //!
+   //! Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
+   //!
+   //! Complexity: constant time.
+   const CharT* c_str() const 
+   {  return container_detail::to_raw_pointer(this->priv_addr()); }
+
+   //! Requires: The program shall not alter any of the values stored in the character array.
+   //!
+   //! Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
+   //!
+   //! Complexity: constant time.
+   const CharT* data()  const 
+   {  return container_detail::to_raw_pointer(this->priv_addr()); }
+
+   //! Effects: Determines the lowest position xpos, if possible, such that both 
+   //!   of the following conditions obtain: 19 pos <= xpos and xpos + str.size() <= size();
+   //!   2) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find(const basic_string& s, size_type pos = 0) const 
+   { return find(s.c_str(), pos, s.size()); }
+
+   //! Requires: s points to an array of at least n elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find(basic_string(s,n),pos).
+   size_type find(const CharT* s, size_type pos, size_type n) const
+   {
+      if (pos + n > size())
+         return npos;
+      else {
+         pointer finish = this->priv_addr() + this->priv_size();
+         const const_iterator result =
+            std::search(container_detail::to_raw_pointer(this->priv_addr() + pos), 
+                   container_detail::to_raw_pointer(finish),
+                   s, s + n, Eq_traits());
+         return result != finish ? result - begin() : npos;
+      }
+   }
+
+   //! Requires: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find(basic_string(s), pos).
+   size_type find(const CharT* s, size_type pos = 0) const 
+   { return find(s, pos, Traits::length(s)); }
+
+   //! Throws: Nothing
+   //!
+   //! Returns: find(basic_string(1,c), pos).
+   size_type find(CharT c, size_type pos = 0) const
+   {
+      if (pos >= size())
+         return npos;
+      else {
+         pointer finish = this->priv_addr() + this->priv_size();
+         const const_iterator result =
+            std::find_if(this->priv_addr() + pos, finish,
+                  std::bind2nd(Eq_traits(), c));
+         return result != finish ? result - begin() : npos;
+      }
+   }
+
+   //! Effects: Determines the highest position xpos, if possible, such 
+   //!   that both of the following conditions obtain:
+   //!   a) xpos <= pos and xpos + str.size() <= size();
+   //!   b) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type rfind(const basic_string& str, size_type pos = npos) const 
+      { return rfind(str.c_str(), pos, str.size()); }
+
+   //! Requires: s points to an array of at least n elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: rfind(basic_string(s, n), pos).
+   size_type rfind(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type len = size();
+
+      if (n > len)
+         return npos;
+      else if (n == 0)
+         return container_detail::min_value(len, pos);
+      else {
+         const const_iterator last = begin() + container_detail::min_value(len - n, pos) + n;
+         const const_iterator result = find_end(begin(), last,
+                                                s, s + n,
+                                                Eq_traits());
+         return result != last ? result - begin() : npos;
+      }
+   }
+
+   //! Requires: pos <= size() and s points to an array of at least 
+   //!   traits::length(s) + 1 elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: rfind(basic_string(s), pos).
+   size_type rfind(const CharT* s, size_type pos = npos) const 
+      { return rfind(s, pos, Traits::length(s)); }
+
+   //! Throws: Nothing
+   //!
+   //! Returns: rfind(basic_string(1,c),pos).
+   size_type rfind(CharT c, size_type pos = npos) const
+   {
+      const size_type len = size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const const_iterator last = begin() + container_detail::min_value(len - 1, pos) + 1;
+         const_reverse_iterator rresult =
+            std::find_if(const_reverse_iterator(last), rend(),
+                  std::bind2nd(Eq_traits(), c));
+         return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+      }
+   }
+
+   //! Effects: Determines the lowest position xpos, if possible, such that both of the
+   //!   following conditions obtain: a) pos <= xpos and xpos < size();
+   //!   b) traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_first_of(const basic_string& s, size_type pos = 0) const 
+      { return find_first_of(s.c_str(), pos, s.size()); }
+
+   //! Requires: s points to an array of at least n elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find_first_of(basic_string(s, n), pos).
+   size_type find_first_of(const CharT* s, size_type pos, size_type n) const
+   {
+      if (pos >= size())
+         return npos;
+      else {
+         pointer finish = this->priv_addr() + this->priv_size();
+         const_iterator result = std::find_first_of(this->priv_addr() + pos, finish,
+                                                    s, s + n,
+                                                    Eq_traits());
+         return result != finish ? result - begin() : npos;
+      }
+   }
+
+   //! Requires: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find_first_of(basic_string(s), pos).
+   size_type find_first_of(const CharT* s, size_type pos = 0) const 
+      { return find_first_of(s, pos, Traits::length(s)); }
+
+   //! Requires: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find_first_of(basic_string(1,c), pos).
+   size_type find_first_of(CharT c, size_type pos = 0) const 
+    { return find(c, pos); }
+
+   //! Effects: Determines the highest position xpos, if possible, such that both of 
+   //!   the following conditions obtain: a) xpos <= pos and xpos < size(); b)
+   //!   traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_last_of(const basic_string& str, size_type pos = npos) const
+      { return find_last_of(str.c_str(), pos, str.size()); }
+
+   //! Requires: s points to an array of at least n elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find_last_of(basic_string(s, n), pos).
+   size_type find_last_of(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type len = size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const const_iterator last = this->priv_addr() + container_detail::min_value(len - 1, pos) + 1;
+         const const_reverse_iterator rresult =
+            std::find_first_of(const_reverse_iterator(last), rend(),
+                               s, s + n,
+                               Eq_traits());
+         return rresult != rend() ? (rresult.base() - 1) - this->priv_addr() : npos;
+      }
+   }
+
+   //! Requires: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find_last_of(basic_string(1,c),pos).
+   size_type find_last_of(const CharT* s, size_type pos = npos) const 
+      { return find_last_of(s, pos, Traits::length(s)); }
+
+   //! Throws: Nothing
+   //!
+   //! Returns: find_last_of(basic_string(s), pos).
+   size_type find_last_of(CharT c, size_type pos = npos) const 
+      {  return rfind(c, pos);   }
+
+   //! Effects: Determines the lowest position xpos, if possible, such that 
+   //!   both of the following conditions obtain:
+   //!   a) pos <= xpos and xpos < size(); b) traits::eq(at(xpos), str.at(I)) for no
+   //!   element I of the string controlled by str.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_first_not_of(const basic_string& str, size_type pos = 0) const 
+      { return find_first_not_of(str.c_str(), pos, str.size()); }
+
+   //! Requires: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find_first_not_of(basic_string(s, n), pos).
+   size_type find_first_not_of(const CharT* s, size_type pos, size_type n) const
+   {
+      if (pos > size())
+         return npos;
+      else {
+         pointer finish = this->priv_addr() + this->priv_size();
+         const_iterator result = std::find_if(this->priv_addr() + pos, finish,
+                                    Not_within_traits(s, s + n));
+         return result != finish ? result - this->priv_addr() : npos;
+      }
+   }
+
+   //! Requires: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find_first_not_of(basic_string(s), pos).
+   size_type find_first_not_of(const CharT* s, size_type pos = 0) const 
+      { return find_first_not_of(s, pos, Traits::length(s)); }
+
+   //! Throws: Nothing
+   //!
+   //! Returns: find_first_not_of(basic_string(1, c), pos).
+   size_type find_first_not_of(CharT c, size_type pos = 0) const
+   {
+      if (pos > size())
+         return npos;
+      else {
+         pointer finish = this->priv_addr() + this->priv_size();
+         const_iterator result
+            = std::find_if(this->priv_addr() + pos, finish,
+                     std::not1(std::bind2nd(Eq_traits(), c)));
+         return result != finish ? result - begin() : npos;
+      }
+   }
+
+   //! Effects: Determines the highest position xpos, if possible, such that
+   //!   both of the following conditions obtain: a) xpos <= pos and xpos < size(); 
+   //!   b) traits::eq(at(xpos), str.at(I)) for no element I of the string controlled by str.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
+   size_type find_last_not_of(const basic_string& str, size_type pos = npos) const
+      { return find_last_not_of(str.c_str(), pos, str.size()); }
+
+   //! Requires: s points to an array of at least n elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find_last_not_of(basic_string(s, n), pos).
+   size_type find_last_not_of(const CharT* s, size_type pos, size_type n) const
+   {
+      const size_type len = size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const const_iterator last = begin() + container_detail::min_value(len - 1, pos) + 1;
+         const const_reverse_iterator rresult =
+            std::find_if(const_reverse_iterator(last), rend(),
+                    Not_within_traits(s, s + n));
+         return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+      }
+   }
+
+   //! Requires: s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: find_last_not_of(basic_string(s), pos).
+   size_type find_last_not_of(const CharT* s, size_type pos = npos) const
+      { return find_last_not_of(s, pos, Traits::length(s)); }
+
+   //! Throws: Nothing
+   //!
+   //! Returns: find_last_not_of(basic_string(1, c), pos).
+   size_type find_last_not_of(CharT c, size_type pos = npos) const
+   {
+      const size_type len = size();
+
+      if (len < 1)
+         return npos;
+      else {
+         const const_iterator last = begin() + container_detail::min_value(len - 1, pos) + 1;
+         const_reverse_iterator rresult =
+            std::find_if(const_reverse_iterator(last), rend(),
+                  std::not1(std::bind2nd(Eq_traits(), c)));
+         return rresult != rend() ? (rresult.base() - 1) - begin() : npos;
+      }
+   }
+
+   //! Requires: Requires: pos <= size()
+   //!
+   //! Effects: Determines the effective length rlen of the string to copy as
+   //!   the smaller of n and size() - pos.
+   //!
+   //! Throws: If memory allocation throws or out_of_range if pos > size().
+   //!
+   //! Returns: basic_string(data()+pos,rlen).
+   basic_string substr(size_type pos = 0, size_type n = npos) const 
+   {
+      if (pos > size())
+         this->throw_out_of_range();
+      return basic_string(this->priv_addr() + pos, 
+                          this->priv_addr() + pos + container_detail::min_value(n, size() - pos), this->alloc());
+   }
+
+   //! Effects: Determines the effective length rlen of the string to copy as
+   //!   the smaller of size() and str.size(). The function then compares the two strings by
+   //!   calling traits::compare(data(), str.data(), rlen).
+   //!
+   //! Throws: Nothing
+   //!
+   //! Returns: The nonzero result if the result of the comparison is nonzero.
+   //!   Otherwise, returns a value < 0 if size() < str.size(), a 0 value if size() == str.size(),
+   //!   and value > 0 if size() > str.size()
+   int compare(const basic_string& str) const 
+   { return s_compare(this->priv_addr(), this->priv_addr() + this->priv_size(), str.priv_addr(), str.priv_addr() + str.priv_size()); }
+
+   //! Requires: pos1 <= size()
+   //!
+   //! Effects: Determines the effective length rlen of the string to copy as
+   //!   the smaller of
+   //!
+   //! Throws: out_of_range if pos1 > size()
+   //!
+   //! Returns:basic_string(*this,pos1,n1).compare(str).
+   int compare(size_type pos1, size_type n1, const basic_string& str) const 
+   {
+      if (pos1 > size())
+         this->throw_out_of_range();
+      return s_compare(this->priv_addr() + pos1, 
+                        this->priv_addr() + pos1 + container_detail::min_value(n1, size() - pos1),
+                        str.priv_addr(), str.priv_addr() + str.priv_size());
+   }
+
+   //! Requires: pos1 <= size() and pos2 <= str.size() 
+   //!
+   //! Effects: Determines the effective length rlen of the string to copy as
+   //!   the smaller of
+   //!
+   //! Throws: out_of_range if pos1 > size() or pos2 > str.size()
+   //!
+   //! Returns: basic_string(*this, pos1, n1).compare(basic_string(str, pos2, n2)).
+   int compare(size_type pos1, size_type n1, 
+               const basic_string& str, size_type pos2, size_type n2) const {
+      if (pos1 > size() || pos2 > str.size())
+         this->throw_out_of_range();
+      return s_compare(this->priv_addr() + pos1, 
+                        this->priv_addr() + pos1 + container_detail::min_value(n1, size() - pos1),
+                        str.priv_addr() + pos2, 
+                        str.priv_addr() + pos2 + container_detail::min_value(n2, size() - pos2));
+   }
+
+   //! Throws: Nothing
+   //!
+   //! Returns: compare(basic_string(s)).
+   int compare(const CharT* s) const 
+   {  return s_compare(this->priv_addr(), this->priv_addr() + this->priv_size(), s, s + Traits::length(s));   }
+
+
+   //! Requires: pos1 > size() and s points to an array of at least n2 elements of CharT.
+   //!
+   //! Throws: out_of_range if pos1 > size()
+   //!
+   //! Returns: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
+   int compare(size_type pos1, size_type n1,
+               const CharT* s, size_type n2) const 
+   {
+      if (pos1 > size())
+         this->throw_out_of_range();
+      return s_compare(this->priv_addr() + pos1, 
+                        this->priv_addr() + pos1 + container_detail::min_value(n1, size() - pos1),
+                        s, s + n2);
+   }
+
+   //! Requires: pos1 > size() and s points to an array of at least traits::length(s) + 1 elements of CharT.
+   //!
+   //! Throws: out_of_range if pos1 > size()
+   //!
+   //! Returns: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
+   int compare(size_type pos1, size_type n1, const CharT* s) const 
+   {  return this->compare(pos1, n1, s, Traits::length(s)); }
+
+   /// @cond
+   private:
+   static int s_compare(const_pointer f1, const_pointer l1,
+                        const_pointer f2, const_pointer l2) 
+   {
+      const difference_type n1 = l1 - f1;
+      const difference_type n2 = l2 - f2;
+      const int cmp = Traits::compare(container_detail::to_raw_pointer(f1), 
+                                      container_detail::to_raw_pointer(f2), 
+                                      container_detail::min_value(n1, n2));
+      return cmp != 0 ? cmp : (n1 < n2 ? -1 : (n1 > n2 ? 1 : 0));
+   }
+
+   template
+   void priv_shrink_to_fit_dynamic_buffer
+      ( AllocVersion
+      , typename container_detail::enable_if >::type* = 0)
+   {
+      //Allocate a new buffer.
+      size_type real_cap = 0;
+      pointer   long_addr    = this->priv_long_addr();
+      size_type long_size    = this->priv_long_size();
+      size_type long_storage = this->priv_long_storage();
+      //We can make this nothrow as chars are always NoThrowCopyables
+      try{
+         std::pair ret = this->allocation_command
+               (allocate_new, long_size+1, long_size+1, real_cap, long_addr);
+         //Copy and update
+         Traits::copy( container_detail::to_raw_pointer(ret.first)
+                     , container_detail::to_raw_pointer(this->priv_long_addr())
+                     , long_size+1);
+         this->priv_long_addr(ret.first);
+         this->priv_storage(real_cap);
+         //And release old buffer
+         this->alloc().deallocate(long_addr, long_storage);
+      }
+      catch(...){
+         return;
+      }
+   }
+
+   template
+   void priv_shrink_to_fit_dynamic_buffer
+      ( AllocVersion 
+      , typename container_detail::enable_if >::type* = 0)
+   {
+      size_type received_size;
+      if(this->alloc().allocation_command
+         ( shrink_in_place | nothrow_allocation
+         , this->priv_long_storage(), this->priv_long_size()+1
+         , received_size, this->priv_long_addr()).first){
+         this->priv_storage(received_size);
+      }
+   }
+
+   void priv_construct_null(pointer p)
+   {  this->construct(p, 0);  }
+
+   static CharT priv_null()
+   {  return (CharT) 0; }
+
+   // Helper functions used by constructors.  It is a severe error for
+   // any of them to be called anywhere except from within constructors.
+   void priv_terminate_string() 
+   {  this->priv_construct_null(this->priv_addr() + this->priv_size());  }
+
+   template 
+   void priv_range_initialize(InputIter f, InputIter l,
+                              std::input_iterator_tag)
+   {
+      this->allocate_initial_block(InternalBufferChars);
+      this->priv_construct_null(this->priv_addr() + this->priv_size());
+      this->append(f, l);
+   }
+
+   template 
+   void priv_range_initialize(ForwardIter f, ForwardIter l, 
+                              std::forward_iterator_tag)
+   {
+      difference_type n = std::distance(f, l);
+      this->allocate_initial_block(container_detail::max_value(n+1, InternalBufferChars));
+      priv_uninitialized_copy(f, l, this->priv_addr());
+      this->priv_size(n);
+      this->priv_terminate_string();
+   }
+
+   template 
+   void priv_range_initialize(InputIter f, InputIter l)
+   {
+      typedef typename std::iterator_traits::iterator_category Category;
+      this->priv_range_initialize(f, l, Category());
+   }
+
+   template 
+   void priv_initialize_dispatch(Integer n, Integer x, container_detail::true_)
+   {
+      this->allocate_initial_block(container_detail::max_value(n+1, InternalBufferChars));
+      priv_uninitialized_fill_n(this->priv_addr(), n, x);
+      this->priv_size(n);
+      this->priv_terminate_string();
+   }
+
+   template 
+   void priv_initialize_dispatch(InputIter f, InputIter l, container_detail::false_)
+   {  this->priv_range_initialize(f, l);  }
+ 
+   template inline
+   void priv_uninitialized_fill_n(FwdIt first, Count count, const CharT val)
+   {
+      //Save initial position
+      FwdIt init = first;
+
+      BOOST_TRY{
+         //Construct objects
+         for (; count--; ++first){
+            this->construct(first, val);
+         }
+      }
+      BOOST_CATCH(...){
+         //Call destructors
+         for (; init != first; ++init){
+            this->destroy(init);
+         }
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+   }
+
+   template inline
+   size_type priv_uninitialized_copy(InpIt first, InpIt last, FwdIt dest)
+   {
+      //Save initial destination position
+      FwdIt dest_init = dest;
+      size_type constructed = 0;
+
+      BOOST_TRY{
+         //Try to build objects
+         for (; first != last; ++dest, ++first, ++constructed){
+            this->construct(dest, *first);
+         }
+      }
+      BOOST_CATCH(...){
+         //Call destructors
+         for (; constructed--; ++dest_init){
+            this->destroy(dest_init);
+         }
+         BOOST_RETHROW
+      }
+      BOOST_CATCH_END
+      return (constructed);
+   }
+
+   template 
+   basic_string& priv_assign_dispatch(Integer n, Integer x, container_detail::true_) 
+   {  return this->assign((size_type) n, (CharT) x);   }
+
+   template 
+   basic_string& priv_assign_dispatch(InputIter f, InputIter l,
+                                      container_detail::false_)
+   {
+      size_type cur = 0;
+      CharT *ptr = container_detail::to_raw_pointer(this->priv_addr());
+      while (f != l && cur != this->priv_size()) {
+         Traits::assign(*ptr, *f);
+         ++f;
+         ++cur;
+         ++ptr;
+      }
+      if (f == l)
+         this->erase(this->priv_addr() + cur, this->priv_addr() + this->priv_size());
+      else
+         this->append(f, l);
+      return *this;
+   }
+
+   template 
+   void priv_insert(const_iterator p, InputIter first, InputIter last, std::input_iterator_tag)
+   {
+      for ( ; first != last; ++first, ++p) {
+         p = this->insert(p, *first);
+      }
+   }
+
+   template 
+   void priv_insert(const_iterator position, ForwardIter first, 
+                    ForwardIter last,  std::forward_iterator_tag)
+   {
+      if (first != last) {
+         size_type n = std::distance(first, last);
+         size_type remaining = this->capacity() - this->priv_size();
+         const size_type old_size = this->size();
+         pointer old_start = this->priv_addr();
+         bool enough_capacity = false;
+         std::pair allocation_ret;
+         size_type new_cap = 0;
+
+         //Check if we have enough capacity
+         if (remaining >= n){
+            enough_capacity = true;            
+         }
+         else {
+            //Otherwise expand current buffer or allocate new storage
+            new_cap  = this->next_capacity(n);
+            allocation_ret = this->allocation_command
+                  (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, 
+                     new_cap, new_cap, old_start);
+
+            //Check forward expansion
+            if(old_start == allocation_ret.first){
+               enough_capacity = true;
+               this->priv_storage(new_cap);
+            }
+         }
+
+         //Reuse same buffer
+         if(enough_capacity){
+            const size_type elems_after =
+               this->priv_size() - (position - this->priv_addr());
+            size_type old_length = this->priv_size();
+            if (elems_after >= n) {
+               pointer pointer_past_last = this->priv_addr() + this->priv_size() + 1;
+               priv_uninitialized_copy(this->priv_addr() + (this->priv_size() - n + 1),
+                                       pointer_past_last, pointer_past_last);
+
+               this->priv_size(this->priv_size()+n);
+               Traits::move(const_cast(container_detail::to_raw_pointer(position + n)),
+                           container_detail::to_raw_pointer(position),
+                           (elems_after - n) + 1);
+               this->priv_copy(first, last, const_cast(container_detail::to_raw_pointer(position)));
+            }
+            else {
+               ForwardIter mid = first;
+               std::advance(mid, elems_after + 1);
+
+               priv_uninitialized_copy(mid, last, this->priv_addr() + this->priv_size() + 1);
+               this->priv_size(this->priv_size() + (n - elems_after));
+               priv_uninitialized_copy
+                  (position, const_iterator(this->priv_addr() + old_length + 1),
+                  this->priv_addr() + this->priv_size());
+               this->priv_size(this->priv_size() + elems_after);
+               this->priv_copy(first, mid, const_cast(container_detail::to_raw_pointer(position)));
+            }
+         }
+         else{
+            pointer new_start = allocation_ret.first;
+            if(!allocation_ret.second){
+               //Copy data to new buffer
+               size_type new_length = 0;
+               //This can't throw, since characters are POD
+               new_length += priv_uninitialized_copy
+                              (const_iterator(this->priv_addr()), position, new_start);
+               new_length += priv_uninitialized_copy
+                              (first, last, new_start + new_length);
+               new_length += priv_uninitialized_copy
+                              (position, const_iterator(this->priv_addr() + this->priv_size()),
+                              new_start + new_length);
+               this->priv_construct_null(new_start + new_length);
+
+               this->deallocate_block();
+               this->is_short(false);
+               this->priv_long_addr(new_start);
+               this->priv_long_size(new_length);
+               this->priv_long_storage(new_cap);
+            }
+            else{
+               //value_type is POD, so backwards expansion is much easier 
+               //than with vector
+               value_type *oldbuf = container_detail::to_raw_pointer(old_start);
+               value_type *newbuf = container_detail::to_raw_pointer(new_start);
+               const value_type *pos    = container_detail::to_raw_pointer(position);
+               size_type  before  = pos - oldbuf;
+
+               //First move old data
+               Traits::move(newbuf, oldbuf, before);
+               Traits::move(newbuf + before + n, pos, old_size - before);
+               //Now initialize the new data
+               priv_uninitialized_copy(first, last, new_start + before);
+               this->priv_construct_null(new_start + (old_size + n));
+               this->is_short(false);
+               this->priv_long_addr(new_start);
+               this->priv_long_size(old_size + n);
+               this->priv_long_storage(new_cap);
+            }
+         }
+      }
+   }
+
+   template 
+   void priv_insert_dispatch(const_iterator p, Integer n, Integer x,
+                           container_detail::true_) 
+   {  insert(p, (size_type) n, (CharT) x);   }
+
+   template 
+   void priv_insert_dispatch(const_iterator p, InputIter first, InputIter last,
+                           container_detail::false_) 
+   {
+      typedef typename std::iterator_traits::iterator_category Category;
+      priv_insert(p, first, last, Category());
+   }
+
+   template 
+   void priv_copy(InputIterator first, InputIterator last, OutIterator result)
+   {
+      for ( ; first != last; ++first, ++result)
+         Traits::assign(*result, *first);
+   }
+
+   void priv_copy(const CharT* first, const CharT* last, CharT* result) 
+   {  Traits::copy(result, first, last - first);  }
+
+   template 
+   basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
+                                       Integer n, Integer x,
+                                       container_detail::true_) 
+   {  return this->replace(first, last, (size_type) n, (CharT) x);   }
+
+   template 
+   basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
+                                       InputIter f, InputIter l,
+                                       container_detail::false_) 
+   {
+      typedef typename std::iterator_traits::iterator_category Category;
+      return this->priv_replace(first, last, f, l, Category());
+   }
+
+
+   template 
+   basic_string& priv_replace(const_iterator first, const_iterator last,
+                              InputIter f, InputIter l, std::input_iterator_tag)
+   {
+      for ( ; first != last && f != l; ++first, ++f)
+         Traits::assign(*first, *f);
+
+      if (f == l)
+         this->erase(first, last);
+      else
+         this->insert(last, f, l);
+      return *this;
+   }
+
+   template 
+   basic_string& priv_replace(const_iterator first, const_iterator last,
+                              ForwardIter f, ForwardIter l, 
+                              std::forward_iterator_tag)
+   {
+      difference_type n = std::distance(f, l);
+      const difference_type len = last - first;
+      if (len >= n) {
+         this->priv_copy(f, l, const_cast(container_detail::to_raw_pointer(first)));
+         this->erase(first + n, last);
+      }
+      else {
+         ForwardIter m = f;
+         std::advance(m, len);
+         this->priv_copy(f, m, const_cast(container_detail::to_raw_pointer(first)));
+         this->insert(last, m, l);
+      }
+      return *this;
+   }
+   /// @endcond
+};
+
+//!Typedef for a basic_string of
+//!narrow characters
+typedef basic_string
+   
+   ,std::allocator >
+string;
+
+//!Typedef for a basic_string of
+//!narrow characters
+typedef basic_string
+   
+   ,std::allocator >
+wstring;
+
+/// @cond
+
+template  
+const typename basic_string::size_type 
+basic_string::npos 
+  = (typename basic_string::size_type) -1;
+
+/// @endcond
+
+// ------------------------------------------------------------
+// Non-member functions.
+
+// Operator+
+
+template 
+inline basic_string
+operator+(const basic_string& x,
+          const basic_string& y)
+{
+   typedef basic_string str_t;
+   typedef typename str_t::reserve_t reserve_t;
+   reserve_t reserve;
+   str_t result(reserve, x.size() + y.size(), x.get_stored_allocator());
+   result.append(x);
+   result.append(y);
+   return boost::move(result);
+}
+
+template  inline
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+   operator+(
+   BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
+   , BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
+{
+   mx += my;
+   return boost::move(mx);
+}
+
+template  inline
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+   operator+(
+   BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
+   , const basic_string& y)
+{
+   mx += y;
+   return boost::move(mx);
+}
+
+template  inline
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+   operator+(const basic_string& x,
+         BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
+{
+   typedef typename basic_string::size_type size_type;
+   my.replace(size_type(0), size_type(0), x);
+   return boost::move(my);
+}
+
+template 
+inline basic_string
+operator+(const CharT* s, const basic_string& y) 
+{
+   typedef basic_string str_t;
+   typedef typename str_t::reserve_t reserve_t;
+   reserve_t reserve;
+   const typename str_t::size_type n = Traits::length(s);
+   str_t result(reserve, n + y.size());
+   result.append(s, s + n);
+   result.append(y);
+   return boost::move(result);
+}
+
+template  inline
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+(const CharT* s,
+         BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
+{
+   typedef typename basic_string::size_type size_type;
+   return boost::move(my.replace(size_type(0), size_type(0), s));
+}
+
+template 
+inline basic_string
+operator+(CharT c, const basic_string& y) 
+{
+   typedef basic_string str_t;
+   typedef typename str_t::reserve_t reserve_t;
+   reserve_t reserve;
+   str_t result(reserve, 1 + y.size());
+   result.push_back(c);
+   result.append(y);
+   return boost::move(result);
+}
+
+template  inline
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+(CharT c,
+         BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) my)
+{
+   typedef typename basic_string::size_type size_type;
+   return boost::move(my.replace(size_type(0), size_type(0), &c, &c + 1));
+}
+
+template 
+inline basic_string
+operator+(const basic_string& x, const CharT* s) 
+{
+   typedef basic_string str_t;
+   typedef typename str_t::reserve_t reserve_t;
+   reserve_t reserve;
+   const typename str_t::size_type n = Traits::length(s);
+   str_t result(reserve, x.size() + n, x.get_stored_allocator());
+   result.append(x);
+   result.append(s, s + n);
+   return boost::move(result);
+}
+
+template 
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+(BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
+         , const CharT* s)
+{
+   mx += s;
+   return boost::move(mx);
+}
+
+template 
+inline basic_string
+operator+(const basic_string& x, const CharT c) 
+{
+   typedef basic_string str_t;
+   typedef typename str_t::reserve_t reserve_t;
+   reserve_t reserve;
+   str_t result(reserve, x.size() + 1, x.get_stored_allocator());
+   result.append(x);
+   result.push_back(c);
+   return boost::move(result);
+}
+
+template 
+BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A)
+operator+( BOOST_RV_REF_3_TEMPL_ARGS(basic_string, CharT, Traits, A) mx
+         , const CharT c)
+{
+   mx += c;
+   return boost::move(mx);
+}
+
+// Operator== and operator!=
+
+template 
+inline bool
+operator==(const basic_string& x,
+           const basic_string& y) 
+{
+   return x.size() == y.size() &&
+          Traits::compare(x.data(), y.data(), x.size()) == 0;
+}
+
+template 
+inline bool
+operator==(const CharT* s, const basic_string& y) 
+{
+   typename basic_string::size_type n = Traits::length(s);
+   return n == y.size() && Traits::compare(s, y.data(), n) == 0;
+}
+
+template 
+inline bool
+operator==(const basic_string& x, const CharT* s) 
+{
+   typename basic_string::size_type n = Traits::length(s);
+   return x.size() == n && Traits::compare(x.data(), s, n) == 0;
+}
+
+template 
+inline bool
+operator!=(const basic_string& x,
+           const basic_string& y) 
+   {  return !(x == y);  }
+
+template 
+inline bool
+operator!=(const CharT* s, const basic_string& y) 
+   {  return !(s == y); }
+
+template 
+inline bool
+operator!=(const basic_string& x, const CharT* s) 
+   {  return !(x == s);   }
+
+
+// Operator< (and also >, <=, and >=).
+
+template 
+inline bool
+operator<(const basic_string& x, const basic_string& y) 
+{
+   return x.compare(y) < 0;
+//   return basic_string
+//      ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0;
+}
+
+template 
+inline bool
+operator<(const CharT* s, const basic_string& y) 
+{
+   return y.compare(s) > 0;
+//   basic_string::size_type n = Traits::length(s);
+//   return basic_string
+//          ::s_compare(s, s + n, y.begin(), y.end()) < 0;
+}
+
+template 
+inline bool
+operator<(const basic_string& x,
+          const CharT* s) 
+{
+   return x.compare(s) < 0;
+//   basic_string::size_type n = Traits::length(s);
+//   return basic_string
+//      ::s_compare(x.begin(), x.end(), s, s + n) < 0;
+}
+
+template 
+inline bool
+operator>(const basic_string& x,
+          const basic_string& y) {
+   return y < x;
+}
+
+template 
+inline bool
+operator>(const CharT* s, const basic_string& y) {
+   return y < s;
+}
+
+template 
+inline bool
+operator>(const basic_string& x, const CharT* s) 
+{
+   return s < x;
+}
+
+template 
+inline bool
+operator<=(const basic_string& x,
+           const basic_string& y) 
+{
+  return !(y < x);
+}
+
+template 
+inline bool
+operator<=(const CharT* s, const basic_string& y) 
+   {  return !(y < s);  }
+
+template 
+inline bool
+operator<=(const basic_string& x, const CharT* s) 
+   {  return !(s < x);  }
+
+template 
+inline bool
+operator>=(const basic_string& x,
+           const basic_string& y) 
+   {  return !(x < y);  }
+
+template 
+inline bool
+operator>=(const CharT* s, const basic_string& y) 
+   {  return !(s < y);  }
+
+template 
+inline bool
+operator>=(const basic_string& x, const CharT* s) 
+   {  return !(x < s);  }
+
+// Swap.
+template 
+inline void swap(basic_string& x, basic_string& y) 
+{  x.swap(y);  }
+
+/// @cond
+// I/O.  
+namespace container_detail {
+
+template 
+inline bool
+string_fill(std::basic_ostream& os,
+                  std::basic_streambuf* buf,
+                  std::size_t n)
+{
+   CharT f = os.fill();
+   std::size_t i;
+   bool ok = true;
+
+   for (i = 0; i < n; i++)
+      ok = ok && !Traits::eq_int_type(buf->sputc(f), Traits::eof());
+   return ok;
+}
+
+}  //namespace container_detail {
+/// @endcond
+
+template 
+std::basic_ostream&
+operator<<(std::basic_ostream& os, const basic_string& s)
+{
+   typename std::basic_ostream::sentry sentry(os);
+   bool ok = false;
+
+   if (sentry) {
+      ok = true;
+      typename basic_string::size_type n = s.size();
+      typename basic_string::size_type pad_len = 0;
+      const bool left = (os.flags() & std::ios::left) != 0;
+      const std::size_t w = os.width(0);
+      std::basic_streambuf* buf = os.rdbuf();
+
+      if (w != 0 && n < w)
+         pad_len = w - n;
+       
+      if (!left)
+         ok = container_detail::string_fill(os, buf, pad_len);    
+
+      ok = ok && 
+            buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n);
+
+      if (left)
+         ok = ok && container_detail::string_fill(os, buf, pad_len);
+   }
+
+   if (!ok)
+      os.setstate(std::ios_base::failbit);
+
+   return os;
+}
+
+
+template 
+std::basic_istream& 
+operator>>(std::basic_istream& is, basic_string& s)
+{
+   typename std::basic_istream::sentry sentry(is);
+
+   if (sentry) {
+      std::basic_streambuf* buf = is.rdbuf();
+      const std::ctype& ctype = std::use_facet >(is.getloc());
+
+      s.clear();
+      std::size_t n = is.width(0);
+      if (n == 0)
+         n = static_cast(-1);
+      else
+         s.reserve(n);
+
+      while (n-- > 0) {
+         typename Traits::int_type c1 = buf->sbumpc();
+
+         if (Traits::eq_int_type(c1, Traits::eof())) {
+            is.setstate(std::ios_base::eofbit);
+            break;
+         }
+         else {
+            CharT c = Traits::to_char_type(c1);
+
+            if (ctype.is(std::ctype::space, c)) {
+               if (Traits::eq_int_type(buf->sputbackc(c), Traits::eof()))
+                  is.setstate(std::ios_base::failbit);
+               break;
+            }
+            else
+               s.push_back(c);
+         }
+      }
+      
+      // If we have read no characters, then set failbit.
+      if (s.size() == 0)
+         is.setstate(std::ios_base::failbit);
+   }
+   else
+      is.setstate(std::ios_base::failbit);
+
+   return is;
+}
+
+template     
+std::basic_istream& 
+getline(std::istream& is, basic_string& s,CharT delim)
+{
+   typename basic_string::size_type nread = 0;
+   typename std::basic_istream::sentry sentry(is, true);
+   if (sentry) {
+      std::basic_streambuf* buf = is.rdbuf();
+      s.clear();
+
+      while (nread < s.max_size()) {
+         int c1 = buf->sbumpc();
+         if (Traits::eq_int_type(c1, Traits::eof())) {
+            is.setstate(std::ios_base::eofbit);
+            break;
+         }
+         else {
+            ++nread;
+            CharT c = Traits::to_char_type(c1);
+            if (!Traits::eq(c, delim)) 
+               s.push_back(c);
+            else
+               break;              // Character is extracted but not appended.
+         }
+      }
+   }
+   if (nread == 0 || nread >= s.max_size())
+      is.setstate(std::ios_base::failbit);
+
+   return is;
+}
+
+template     
+inline std::basic_istream& 
+getline(std::basic_istream& is, basic_string& s)
+{
+   return getline(is, s, '\n');
+}
+
+template 
+inline std::size_t hash_value(basic_string, A> const& v)
+{
+   return hash_range(v.begin(), v.end());
+}
+
+}}
+
+/// @cond
+
+namespace boost {
+/*
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value;
+};
+*/
+}
+
+/// @endcond
+
+#include 
+
+#endif // BOOST_CONTAINER_STRING_HPP
diff --git a/src/third_party/boost/boost/container/vector.hpp b/src/third_party/boost/boost/container/vector.hpp
new file mode 100644
index 00000000000..742d00d37ef
--- /dev/null
+++ b/src/third_party/boost/boost/container/vector.hpp
@@ -0,0 +1,2036 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2005-2011. 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/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP
+#define BOOST_CONTAINER_CONTAINER_VECTOR_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace container {
+
+/// @cond
+
+namespace container_detail {
+
+//! Const vector_iterator used to iterate through a vector. 
+template 
+class vector_const_iterator
+{
+   public:
+	typedef std::random_access_iterator_tag                                          iterator_category;
+   typedef typename boost::intrusive::pointer_traits::element_type         value_type;
+   typedef typename boost::intrusive::pointer_traits::difference_type      difference_type;
+   typedef typename boost::intrusive::pointer_traits::template
+                                 rebind_pointer::type             pointer;
+   typedef  const value_type&                                                       reference;
+
+   /// @cond
+   protected:
+   Pointer m_ptr;
+
+   public:
+   Pointer get_ptr() const    {  return   m_ptr;  }
+   explicit vector_const_iterator(Pointer ptr)  : m_ptr(ptr){}
+   /// @endcond
+
+   public:
+
+   //Constructors
+   vector_const_iterator() : m_ptr(0){}
+
+   //Pointer like operators
+   reference operator*()   const  
+   {  return *m_ptr;  }
+
+   const value_type * operator->()  const  
+   {  return  container_detail::to_raw_pointer(m_ptr);  }
+
+   reference operator[](difference_type off) const
+   {  return m_ptr[off];   }
+
+   //Increment / Decrement
+   vector_const_iterator& operator++()       
+   { ++m_ptr;  return *this; }
+
+   vector_const_iterator operator++(int)      
+   {  Pointer tmp = m_ptr; ++*this; return vector_const_iterator(tmp);  }
+
+   vector_const_iterator& operator--()
+   {  --m_ptr; return *this;  }
+
+   vector_const_iterator operator--(int)
+   {  Pointer tmp = m_ptr; --*this; return vector_const_iterator(tmp); }
+
+   //Arithmetic
+   vector_const_iterator& operator+=(difference_type off)
+   {  m_ptr += off; return *this;   }
+
+   vector_const_iterator operator+(difference_type off) const
+   {  return vector_const_iterator(m_ptr+off);  }
+
+   friend vector_const_iterator operator+(difference_type off, const vector_const_iterator& right)
+   {  return vector_const_iterator(off + right.m_ptr); }
+
+   vector_const_iterator& operator-=(difference_type off)
+   {  m_ptr -= off; return *this;   }
+
+   vector_const_iterator operator-(difference_type off) const
+   {  return vector_const_iterator(m_ptr-off);  }
+
+   difference_type operator-(const vector_const_iterator& right) const
+   {  return m_ptr - right.m_ptr;   }
+
+   //Comparison operators
+   bool operator==   (const vector_const_iterator& r)  const
+   {  return m_ptr == r.m_ptr;  }
+
+   bool operator!=   (const vector_const_iterator& r)  const
+   {  return m_ptr != r.m_ptr;  }
+
+   bool operator<    (const vector_const_iterator& r)  const
+   {  return m_ptr < r.m_ptr;  }
+
+   bool operator<=   (const vector_const_iterator& r)  const
+   {  return m_ptr <= r.m_ptr;  }
+
+   bool operator>    (const vector_const_iterator& r)  const
+   {  return m_ptr > r.m_ptr;  }
+
+   bool operator>=   (const vector_const_iterator& r)  const
+   {  return m_ptr >= r.m_ptr;  }
+};
+
+//! Iterator used to iterate through a vector
+template 
+class vector_iterator
+   :  public vector_const_iterator
+{
+   public:
+   explicit vector_iterator(Pointer ptr)
+      : vector_const_iterator(ptr)
+   {}
+
+   public:
+	typedef std::random_access_iterator_tag                                       iterator_category;
+   typedef typename boost::intrusive::pointer_traits::element_type      value_type;
+   typedef typename boost::intrusive::pointer_traits::difference_type   difference_type;
+   typedef Pointer                                                               pointer;
+   typedef value_type&                                                           reference;
+
+   //Constructors
+   vector_iterator()
+   {}
+
+   //Pointer like operators
+   reference operator*()  const  
+   {  return *this->m_ptr;  }
+
+   value_type* operator->() const  
+   {  return  container_detail::to_raw_pointer(this->m_ptr);  }
+
+   reference operator[](difference_type off) const 
+   {  return this->m_ptr[off];   }
+
+   //Increment / Decrement
+   vector_iterator& operator++()  
+   {  ++this->m_ptr; return *this;  }
+
+   vector_iterator operator++(int)
+   {  pointer tmp = this->m_ptr; ++*this; return vector_iterator(tmp);  }
+   
+   vector_iterator& operator--()
+   {  --this->m_ptr; return *this;  }
+
+   vector_iterator operator--(int)
+   {  vector_iterator tmp = *this; --*this; return vector_iterator(tmp); }
+
+   // Arithmetic
+   vector_iterator& operator+=(difference_type off)
+   {  this->m_ptr += off;  return *this;  }
+
+   vector_iterator operator+(difference_type off) const
+   {  return vector_iterator(this->m_ptr+off);  }
+
+   friend vector_iterator operator+(difference_type off, const vector_iterator& right)
+   {  return vector_iterator(off + right.m_ptr); }
+
+   vector_iterator& operator-=(difference_type off)
+   {  this->m_ptr -= off; return *this;   }
+
+   vector_iterator operator-(difference_type off) const
+   {  return vector_iterator(this->m_ptr-off);  }
+
+   difference_type operator-(const vector_const_iterator& right) const
+   {  return static_cast&>(*this) - right;   }
+};
+
+template 
+struct vector_value_traits
+{
+   typedef T value_type;
+   typedef A allocator_type;
+   static const bool trivial_dctr = boost::has_trivial_destructor::value;
+   static const bool trivial_dctr_after_move = trivial_dctr;
+      //::boost::has_trivial_destructor_after_move::value || trivial_dctr;
+   //static const bool trivial_copy = has_trivial_copy::value;
+   //static const bool nothrow_copy = has_nothrow_copy::value;
+   //static const bool trivial_assign = has_trivial_assign::value;
+   //static const bool nothrow_assign = has_nothrow_assign::value;
+
+   static const bool trivial_copy = has_trivial_copy::value;
+   static const bool nothrow_copy = has_nothrow_copy::value;
+   static const bool trivial_assign = has_trivial_assign::value;
+   static const bool nothrow_assign = false;
+
+   //This is the anti-exception array destructor
+   //to deallocate values already constructed
+   typedef typename container_detail::if_c
+      
+      ,container_detail::scoped_destructor_n
+      >::type   OldArrayDestructor;
+   //This is the anti-exception array destructor
+   //to destroy objects created with copy construction
+   typedef typename container_detail::if_c
+      
+      ,container_detail::scoped_destructor_n
+      >::type   ArrayDestructor;
+   //This is the anti-exception array deallocator
+   typedef typename container_detail::if_c
+      
+      ,container_detail::scoped_array_deallocator
+      >::type   ArrayDeallocator;
+};
+
+//!This struct deallocates and allocated memory
+template 
+struct vector_alloc_holder 
+{
+   typedef boost::container::allocator_traits         allocator_traits_type;
+   typedef typename allocator_traits_type::pointer       pointer;
+   typedef typename allocator_traits_type::size_type     size_type;
+   typedef typename allocator_traits_type::value_type    value_type;
+   typedef vector_value_traits            value_traits;
+
+   //Constructor, does not throw
+   vector_alloc_holder()
+      BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor::value)
+      : members_()
+   {}
+
+   //Constructor, does not throw
+   template
+   explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_CONTAINER_NOEXCEPT
+      : members_(boost::forward(a))
+   {}
+
+   //Destructor
+   ~vector_alloc_holder()
+   {
+      this->prot_destroy_all();
+      this->prot_deallocate();
+   }
+
+   typedef container_detail::integral_constant      allocator_v1;
+   typedef container_detail::integral_constant      allocator_v2;
+   typedef container_detail::integral_constant::value> alloc_version;
+   std::pair
+      allocation_command(allocation_type command,
+                         size_type limit_size, 
+                         size_type preferred_size,
+                         size_type &received_size, const pointer &reuse = 0)
+   {
+      return allocation_command(command, limit_size, preferred_size,
+                               received_size, reuse, alloc_version());
+   }
+
+   std::pair
+      allocation_command(allocation_type command,
+                         size_type limit_size, 
+                         size_type preferred_size,
+                         size_type &received_size,
+                         const pointer &reuse,
+                         allocator_v1)
+   {
+      (void)limit_size;
+      (void)reuse;
+      if(!(command & allocate_new))
+         return std::pair(pointer(0), false);
+      received_size = preferred_size;
+      return std::make_pair(this->alloc().allocate(received_size), false);
+   }
+
+   std::pair
+      allocation_command(allocation_type command,
+                         size_type limit_size, 
+                         size_type preferred_size,
+                         size_type &received_size,
+                         const pointer &reuse,
+                         allocator_v2)
+   {
+      return this->alloc().allocation_command
+         (command, limit_size, preferred_size, received_size, reuse);
+   }
+
+   size_type next_capacity(size_type additional_objects) const
+   {
+      return get_next_capacity( allocator_traits_type::max_size(this->alloc())
+                              , this->members_.m_capacity, additional_objects);
+   }
+
+   struct members_holder
+      : public A
+   {
+      private:
+      members_holder(const members_holder&);
+
+      public:
+      template
+      explicit members_holder(BOOST_FWD_REF(Alloc) alloc)
+         :  A(boost::forward(alloc)), m_start(0), m_size(0), m_capacity(0)
+      {}
+
+      members_holder()
+         :  A(), m_start(0), m_size(0), m_capacity(0)
+      {}
+
+      pointer     m_start;
+      size_type   m_size;
+      size_type   m_capacity;
+   } members_;
+
+   void swap_members(vector_alloc_holder &x)
+   {
+      container_detail::do_swap(this->members_.m_start, x.members_.m_start);
+      container_detail::do_swap(this->members_.m_size, x.members_.m_size);
+      container_detail::do_swap(this->members_.m_capacity, x.members_.m_capacity);
+   }
+
+   A &alloc()
+   {  return members_;  }
+
+   const A &alloc() const
+   {  return members_;  }
+
+   protected:
+   void prot_deallocate()
+   {
+      if(!this->members_.m_capacity)   return;
+      this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+      this->members_.m_start     = 0;
+      this->members_.m_size      = 0;
+      this->members_.m_capacity  = 0;
+   }
+
+   void destroy(value_type* p)
+   {
+      if(!value_traits::trivial_dctr)
+         allocator_traits_type::destroy(this->alloc(), p);
+   }
+
+   void destroy_n(value_type* p, size_type n)
+   {
+      if(!value_traits::trivial_dctr){
+         for(; n--; ++p){
+            allocator_traits_type::destroy(this->alloc(), p);
+         }
+      }
+   }
+
+   void prot_destroy_all()
+   {
+      this->destroy_n(container_detail::to_raw_pointer(this->members_.m_start), this->members_.m_size);
+      this->members_.m_size = 0;
+   }
+};
+
+}  //namespace container_detail {
+/// @endcond
+
+//! \class vector
+//! A vector is a sequence that supports random access to elements, constant 
+//! time insertion and removal of elements at the end, and linear time insertion 
+//! and removal of elements at the beginning or in the middle. The number of 
+//! elements in a vector may vary dynamically; memory management is automatic.
+//! boost::container::vector is similar to std::vector but it's compatible
+//! with shared memory and memory mapped files.
+#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
+template  >
+#else
+template 
+#endif
+class vector : private container_detail::vector_alloc_holder
+{
+   /// @cond
+   typedef vector                   self_t;
+   typedef container_detail::vector_alloc_holder base_t;
+   typedef allocator_traits            allocator_traits_type;
+   /// @endcond
+   public:
+   //! The type of object, T, stored in the vector
+   typedef T                                                value_type;
+   //! Pointer to T
+   typedef typename allocator_traits_type::pointer          pointer;
+   //! Const pointer to T
+   typedef typename allocator_traits_type::const_pointer    const_pointer;
+   //! Reference to T
+   typedef typename allocator_traits_type::reference        reference;
+   //! Const reference to T
+   typedef typename allocator_traits_type::const_reference  const_reference;
+   //! An unsigned integral type
+   typedef typename allocator_traits_type::size_type        size_type;
+   //! A signed integral type
+   typedef typename allocator_traits_type::difference_type  difference_type;
+   //! The allocator type
+   typedef A                                       allocator_type;
+   //! The random access iterator
+   typedef container_detail::vector_iterator        iterator;
+   //! The random access const_iterator
+   typedef container_detail::vector_const_iterator  const_iterator;
+
+   //! Iterator used to iterate backwards through a vector. 
+   typedef std::reverse_iterator   
+      reverse_iterator;
+   //! Const iterator used to iterate backwards through a vector. 
+   typedef std::reverse_iterator                 
+      const_reverse_iterator;
+   //! The stored allocator type
+   typedef allocator_type                          stored_allocator_type;
+
+   /// @cond
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(vector)
+   typedef container_detail::advanced_insert_aux_int    advanced_insert_aux_int_t;
+   typedef container_detail::vector_value_traits value_traits;
+
+   typedef typename base_t::allocator_v1           allocator_v1;
+   typedef typename base_t::allocator_v2           allocator_v2;
+   typedef typename base_t::alloc_version          alloc_version;
+
+   typedef constant_iterator   cvalue_iterator;
+   typedef repeat_iterator     repeat_it;
+   typedef boost::move_iterator         repeat_move_it;
+   /// @endcond
+
+   public:
+
+   //! Effects: Constructs a vector taking the allocator as parameter.
+   //! 
+   //! Throws: If allocator_type's default constructor throws.
+   //! 
+   //! Complexity: Constant.
+   vector()
+      BOOST_CONTAINER_NOEXCEPT_IF(::boost::has_nothrow_default_constructor::value)
+      : base_t()
+   {}
+
+   //! Effects: Constructs a vector taking the allocator as parameter.
+   //! 
+   //! Throws: Nothing
+   //! 
+   //! Complexity: Constant.
+   explicit vector(const A& a) BOOST_CONTAINER_NOEXCEPT
+      : base_t(a)
+   {}
+
+   //! Effects: Constructs a vector that will use a copy of allocator a
+   //!   and inserts n default contructed values.
+   //!
+   //! Throws: If allocator_type's default constructor or allocation
+   //!   throws or T's default constructor throws.
+   //! 
+   //! Complexity: Linear to n.
+   explicit vector(size_type n)
+      :  base_t()
+   {
+      //Allocate
+      size_type real_cap;
+      std::pair ret =
+         this->allocation_command(allocate_new, n, n, real_cap, this->members_.m_start);
+      T *new_mem = container_detail::to_raw_pointer(ret.first);
+      //Anti-exception rollback
+      typename value_traits::ArrayDeallocator scoped_alloc(new_mem, this->alloc(), real_cap);
+      //Default constructor
+      container_detail::default_construct_aux_proxy proxy(this->alloc(), n);
+      proxy.uninitialized_copy_remaining_to(new_mem);
+      //All ok, commit
+      this->members_.m_start = ret.first;
+      this->members_.m_size  = n;
+      this->members_.m_capacity = real_cap;
+      scoped_alloc.release();
+   }
+
+   //! Effects: Constructs a vector that will use a copy of allocator a
+   //!   and inserts n copies of value.
+   //!
+   //! Throws: If allocator_type's default constructor or allocation
+   //!   throws or T's copy constructor throws.
+   //! 
+   //! Complexity: Linear to n.
+   vector(size_type n, const T& value, const allocator_type& a = allocator_type()) 
+      :  base_t(a)
+   {  this->insert(this->cend(), n, value); }
+
+   //! Effects: Copy constructs a vector.
+   //!
+   //! Postcondition: x == *this.
+   //! 
+   //! Throws: If allocator_type's default constructor or allocation
+   //!   throws or T's copy constructor throws.
+   //! 
+   //! Complexity: Linear to the elements x contains.
+   vector(const vector &x) 
+      :  base_t(allocator_traits_type::select_on_container_copy_construction(x.alloc()))
+   {
+      this->assign( container_detail::to_raw_pointer(x.members_.m_start)
+                  , container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size));
+   }
+
+   //! Effects: Move constructor. Moves mx's resources to *this.
+   //!
+   //! Throws: Nothing
+   //! 
+   //! Complexity: Constant.
+   vector(BOOST_RV_REF(vector) mx) BOOST_CONTAINER_NOEXCEPT
+      :  base_t(boost::move(mx.alloc()))
+   {  this->swap_members(mx);   }
+
+   //! Effects: Constructs a vector that will use a copy of allocator a
+   //!   and inserts a copy of the range [first, last) in the vector.
+   //!
+   //! Throws: If allocator_type's default constructor or allocation
+   //!   throws or T's constructor taking an dereferenced InIt throws.
+   //!
+   //! Complexity: Linear to the range [first, last).
+   template 
+   vector(InIt first, InIt last, const allocator_type& a = allocator_type())
+      :  base_t(a)
+   {  this->assign(first, last); }
+
+   //! Effects: Destroys the vector. All stored values are destroyed
+   //!   and used memory is deallocated.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements.
+   ~vector() BOOST_CONTAINER_NOEXCEPT
+   {} //vector_alloc_holder clears the data
+
+   //! Effects: Returns an iterator to the first element contained in the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator begin() BOOST_CONTAINER_NOEXCEPT
+   { return iterator(this->members_.m_start); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
+   { return const_iterator(this->members_.m_start); }
+
+   //! Effects: Returns an iterator to the end of the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   iterator end() BOOST_CONTAINER_NOEXCEPT
+   { return iterator(this->members_.m_start + this->members_.m_size); }
+
+   //! Effects: Returns a const_iterator to the end of the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator end() const BOOST_CONTAINER_NOEXCEPT
+   { return this->cend(); }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning 
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
+   { return reverse_iterator(this->end());      }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
+   { return this->crbegin(); }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
+   { return reverse_iterator(this->begin());       }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
+   { return this->crend(); }
+
+   //! Effects: Returns a const_iterator to the first element contained in the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
+   { return const_iterator(this->members_.m_start); }
+
+   //! Effects: Returns a const_iterator to the end of the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
+   { return const_iterator(this->members_.m_start + this->members_.m_size); }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning 
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
+   { return const_reverse_iterator(this->end());}
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //! of the reversed vector. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
+   { return const_reverse_iterator(this->begin()); }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a reference to the first
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference         front() BOOST_CONTAINER_NOEXCEPT
+   { return *this->members_.m_start; }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a const reference to the first
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference   front() const BOOST_CONTAINER_NOEXCEPT
+   { return *this->members_.m_start; }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a reference to the last
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference         back() BOOST_CONTAINER_NOEXCEPT
+   { return this->members_.m_start[this->members_.m_size - 1]; }
+
+   //! Requires: !empty()
+   //!
+   //! Effects: Returns a const reference to the last
+   //!   element of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference   back()  const BOOST_CONTAINER_NOEXCEPT
+   { return this->members_.m_start[this->members_.m_size - 1]; }
+
+   //! Returns: A pointer such that [data(),data() + size()) is a valid range.
+   //!   For a non-empty vector, data() == &front().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   pointer data() BOOST_CONTAINER_NOEXCEPT
+   { return this->members_.m_start; }
+
+   //! Returns: A pointer such that [data(),data() + size()) is a valid range.
+   //!   For a non-empty vector, data() == &front().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_pointer data()  const BOOST_CONTAINER_NOEXCEPT
+   { return this->members_.m_start; }
+
+   //! Effects: Returns the number of the elements contained in the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type size() const BOOST_CONTAINER_NOEXCEPT
+   { return this->members_.m_size; }
+
+   //! Effects: Returns the largest possible size of the vector.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type max_size() const BOOST_CONTAINER_NOEXCEPT
+   { return allocator_traits_type::max_size(this->alloc()); }
+
+   //! Effects: Number of elements for which memory has been allocated.
+   //!   capacity() is always greater than or equal to size().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   size_type capacity() const BOOST_CONTAINER_NOEXCEPT
+   { return this->members_.m_capacity; }
+
+   //! Effects: Returns true if the vector contains no elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   bool empty() const BOOST_CONTAINER_NOEXCEPT
+   { return !this->members_.m_size; }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   reference operator[](size_type n)         
+   { return this->members_.m_start[n]; }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a const reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT
+   { return this->members_.m_start[n]; }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: std::range_error if n >= size()
+   //! 
+   //! Complexity: Constant.
+   reference at(size_type n) 
+   { this->priv_check_range(n); return this->members_.m_start[n]; }
+
+   //! Requires: size() > n.
+   //!
+   //! Effects: Returns a const reference to the nth element 
+   //!   from the beginning of the container.
+   //! 
+   //! Throws: std::range_error if n >= size()
+   //! 
+   //! Complexity: Constant.
+   const_reference at(size_type n) const
+   { this->priv_check_range(n); return this->members_.m_start[n]; }
+
+   //! Effects: Returns a copy of the internal allocator.
+   //! 
+   //! Throws: If allocator's copy constructor throws.
+   //! 
+   //! Complexity: Constant.
+   allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
+   { return this->alloc();  }
+
+   //! Effects: Returns a reference to the internal allocator.
+   //! 
+   //! Throws: Nothing
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Non-standard extension.
+   const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
+   {  return this->alloc(); }
+
+   //! Effects: Returns a reference to the internal allocator.
+   //! 
+   //! Throws: Nothing
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Note: Non-standard extension.
+   stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
+   {  return this->alloc(); }
+
+   //! Effects: If n is less than or equal to capacity(), this call has no
+   //!   effect. Otherwise, it is a request for allocation of additional memory.
+   //!   If the request is successful, then capacity() is greater than or equal to
+   //!   n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
+   //! 
+   //! Throws: If memory allocation allocation throws or T's copy/move constructor throws.
+   void reserve(size_type new_cap)
+   {
+      if (this->capacity() < new_cap){
+         //There is not enough memory, allocate a new
+         //buffer or expand the old one.
+         bool same_buffer_start;
+         size_type real_cap = 0;
+         std::pair ret =
+            this->allocation_command
+               (allocate_new | expand_fwd | expand_bwd,
+                  new_cap, new_cap, real_cap, this->members_.m_start);
+
+         //Check for forward expansion
+         same_buffer_start = ret.second && this->members_.m_start == ret.first;
+         if(same_buffer_start){
+            #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+            ++this->num_expand_fwd;
+            #endif
+            this->members_.m_capacity  = real_cap;
+         }
+
+         //If there is no forward expansion, move objects
+         else{
+            //We will reuse insert code, so create a dummy input iterator
+            T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start));
+            container_detail::advanced_insert_aux_proxy, T*>
+               proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it));
+            //Backwards (and possibly forward) expansion
+            if(ret.second){
+               #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+               ++this->num_expand_bwd;
+               #endif
+               this->priv_range_insert_expand_backwards
+                  ( container_detail::to_raw_pointer(ret.first)
+                  , real_cap
+                  , container_detail::to_raw_pointer(this->members_.m_start)
+                  , 0
+                  , proxy);
+            }
+            //New buffer
+            else{
+               #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+               ++this->num_alloc;
+               #endif
+               this->priv_range_insert_new_allocation
+                  ( container_detail::to_raw_pointer(ret.first)
+                  , real_cap
+                  , container_detail::to_raw_pointer(this->members_.m_start)
+                  , 0
+                  , proxy);
+            }
+         }
+      }
+   }
+
+   //! Effects: Makes *this contain the same elements as x.
+   //!
+   //! Postcondition: this->size() == x.size(). *this contains a copy 
+   //! of each of x's elements. 
+   //!
+   //! Throws: If memory allocation throws or T's copy/move constructor/assignment throws.
+   //!
+   //! Complexity: Linear to the number of elements in x.
+   vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
+   {
+      if (&x != this){
+         allocator_type &this_alloc     = this->alloc();
+         const allocator_type &x_alloc  = x.alloc();
+         container_detail::bool_ flag;
+         if(flag && this_alloc != x_alloc){
+            this->clear();
+            this->shrink_to_fit();
+         }
+         container_detail::assign_alloc(this_alloc, x_alloc, flag);
+         this->assign( container_detail::to_raw_pointer(x.members_.m_start)
+                     , container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size));
+      }
+      return *this;
+   }
+
+   //! Effects: Move assignment. All mx's values are transferred to *this.
+   //!
+   //! Postcondition: x.empty(). *this contains a the elements x had
+   //!   before the function.
+   //!
+   //! Throws: Nothing
+   //!
+   //! Complexity: Linear.
+   vector& operator=(BOOST_RV_REF(vector) x)
+      //iG BOOST_CONTAINER_NOEXCEPT_IF(!allocator_type::propagate_on_container_move_assignment::value || is_nothrow_move_assignable::value);)
+      BOOST_CONTAINER_NOEXCEPT
+   {
+      if (&x != this){
+         allocator_type &this_alloc = this->alloc();
+         allocator_type &x_alloc    = x.alloc();
+         //If allocators are equal we can just swap pointers
+         if(this_alloc == x_alloc){
+            //Destroy objects but retain memory in case x reuses it in the future
+            this->clear();
+            this->swap_members(x);
+            //Move allocator if needed
+            container_detail::bool_ flag;
+            container_detail::move_alloc(this_alloc, x_alloc, flag);
+         }
+         //If unequal allocators, then do a one by one move
+         else{
+            this->assign( boost::make_move_iterator(container_detail::to_raw_pointer(x.members_.m_start))
+                        , boost::make_move_iterator(container_detail::to_raw_pointer(x.members_.m_start + x.members_.m_size)));
+         }
+      }
+      return *this;
+   }
+
+   //! Effects: Assigns the n copies of val to *this.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's copy/move constructor/assignment throws.
+   //!
+   //! Complexity: Linear to n.
+   void assign(size_type n, const value_type& val)
+   {  this->assign(cvalue_iterator(val, n), cvalue_iterator());   }
+
+   //! Effects: Assigns the the range [first, last) to *this.
+   //!
+   //! Throws: If memory allocation throws or T's copy/move constructor/assignment or
+   //!   T's constructor/assignment from dereferencing InpIt throws.
+   //!
+   //! Complexity: Linear to n.
+   template 
+   void assign(InIt first, InIt last) 
+   {
+      //Dispatch depending on integer/iterator
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_assign_dispatch(first, last, Result());
+   }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Effects: Inserts a copy of x at the end of the vector.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's copy/move constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_back(const T &x);
+
+   //! Effects: Constructs a new element in the end of the vector
+   //!   and moves the resources of mx to this new element.
+   //!
+   //! Throws: If memory allocation throws or
+   //!   T's move constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   void push_back(T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+   #endif
+
+   #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... in the end of the vector.
+   //!
+   //! Throws: If memory allocation throws or the in-place constructor throws or
+   //!   T's move constructor throws.
+   //!
+   //! Complexity: Amortized constant time.
+   template
+   void emplace_back(Args &&...args)
+   {
+      T* back_pos = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size;
+      if (this->members_.m_size < this->members_.m_capacity){
+         //There is more memory, just construct a new object at the end
+         allocator_traits_type::construct(this->alloc(), back_pos, ::boost::forward(args)...);
+         ++this->members_.m_size;
+      }
+      else{
+         typedef container_detail::advanced_insert_aux_emplace type;
+         type &&proxy = type(this->alloc(), ::boost::forward(args)...);
+         priv_range_insert(back_pos, 1, proxy);
+      }
+   }
+
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Inserts an object of type T constructed with
+   //!   std::forward(args)... before position
+   //!
+   //! Throws: If memory allocation throws or the in-place constructor throws or
+   //!   T's move constructor/assignment throws.
+   //!
+   //! Complexity: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   template
+   iterator emplace(const_iterator position, Args && ...args)
+   {
+      //Just call more general insert(pos, size, value) and return iterator
+      size_type pos_n = position - cbegin();
+      typedef container_detail::advanced_insert_aux_emplace type;
+      type &&proxy = type(this->alloc(), ::boost::forward(args)...);
+      priv_range_insert(position.get_ptr(), 1, proxy);
+      return iterator(this->members_.m_start + pos_n);
+   }
+
+   #else
+
+   #define BOOST_PP_LOCAL_MACRO(n)                                                              \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)       \
+   void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                        \
+   {                                                                                            \
+      T* back_pos = container_detail::to_raw_pointer                                            \
+         (this->members_.m_start) + this->members_.m_size;                                      \
+      if (this->members_.m_size < this->members_.m_capacity){                                   \
+         allocator_traits_type::construct (this->alloc()                                        \
+            , back_pos BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );        \
+         ++this->members_.m_size;                                                               \
+      }                                                                                         \
+      else{                                                                                     \
+         container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)      \
+             proxy                                   \
+            (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));     \
+         priv_range_insert(back_pos, 1, proxy);                                                 \
+      }                                                                                         \
+   }                                                                                            \
+                                                                                                \
+   BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)       \
+   iterator emplace(const_iterator pos                                                          \
+                    BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                \
+   {                                                                                            \
+      size_type pos_n = pos - cbegin();                                                         \
+         container_detail::BOOST_PP_CAT(BOOST_PP_CAT(advanced_insert_aux_emplace, n), arg)      \
+             proxy                                   \
+            (this->alloc() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));     \
+      priv_range_insert(container_detail::to_raw_pointer(pos.get_ptr()), 1, proxy);             \
+      return iterator(this->members_.m_start + pos_n);                                          \
+   }                                                                                            \
+   //!
+   #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
+   #include BOOST_PP_LOCAL_ITERATE()
+
+   #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+  
+   //! Effects: Swaps the contents of *this and x.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant.
+   void swap(vector& x)
+   {
+      //Just swap internals
+      this->swap_members(x);
+      //And now the allocator
+      container_detail::bool_ flag;
+      container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
+   }
+
+   #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a copy of x before position.
+   //!
+   //! Throws: If memory allocation throws or T's copy/move constructor/assignment throws.
+   //!
+   //! Complexity: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator position, const T &x);
+
+   //! Requires: position must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a new element before position with mx's resources.
+   //!
+   //! Throws: If memory allocation throws.
+   //!
+   //! Complexity: If position is end(), amortized constant time
+   //!   Linear time otherwise.
+   iterator insert(const_iterator position, T &&x);
+   #else
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator)
+   #endif
+
+   //! Requires: pos must be a valid iterator of *this.
+   //!
+   //! Effects: Insert a copy of the [first, last) range before pos.
+   //!
+   //! Throws: If memory allocation throws, T's constructor from a
+   //!   dereferenced InpIt throws or T's copy/move constructor/assignment throws.
+   //!
+   //! Complexity: Linear to std::distance [first, last).
+   template 
+   void insert(const_iterator pos, InIt first, InIt last)
+   {
+      //Dispatch depending on integer/iterator
+      const bool aux_boolean = container_detail::is_convertible::value;
+      typedef container_detail::bool_ Result;
+      this->priv_insert_dispatch(pos, first, last, Result());
+   }
+
+   //! Requires: pos must be a valid iterator of *this.
+   //!
+   //! Effects: Insert n copies of x before pos.
+   //!
+   //! Throws: If memory allocation throws or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to n.
+   void insert(const_iterator p, size_type n, const T& x)
+   {  this->insert(p, cvalue_iterator(x, n), cvalue_iterator());  }
+
+   //! Effects: Removes the last element from the vector.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Constant time.
+   void pop_back() 
+   {
+      //Destroy last element
+      --this->members_.m_size;
+      this->destroy(container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size);
+   }
+
+   //! Effects: Erases the element at position pos.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the elements between pos and the 
+   //!   last element. Constant if pos is the last element.
+   iterator erase(const_iterator position) 
+   {
+      T *pos = container_detail::to_raw_pointer(position.get_ptr());
+      T *beg = container_detail::to_raw_pointer(this->members_.m_start);
+      ::boost::move(pos + 1, beg + this->members_.m_size, pos);
+      --this->members_.m_size;
+      //Destroy last element
+      base_t::destroy(container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size);
+      return iterator(position.get_ptr());
+   }
+
+   //! Effects: Erases the elements pointed by [first, last).
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the distance between first and last
+   //!   plus linear to the elements between pos and the last element.
+   iterator erase(const_iterator first, const_iterator last) 
+   {
+      if (first != last){   // worth doing, copy down over hole
+         T* end_pos = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size;
+         T* ptr = container_detail::to_raw_pointer(boost::move
+            (container_detail::to_raw_pointer(last.get_ptr())
+            ,end_pos
+            ,container_detail::to_raw_pointer(first.get_ptr())
+            ));
+         size_type destroyed = (end_pos - ptr);
+         this->destroy_n(ptr, destroyed);
+         this->members_.m_size -= destroyed;
+      }
+      return iterator(first.get_ptr());
+   }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are copy constructed from x.
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type new_size, const T& x) 
+   {
+      pointer finish = this->members_.m_start + this->members_.m_size;
+      if (new_size < size()){
+         //Destroy last elements
+         this->erase(const_iterator(this->members_.m_start + new_size), this->end());
+      }
+      else{
+         //Insert new elements at the end
+         this->insert(const_iterator(finish), new_size - this->size(), x);
+      }
+   }
+
+   //! Effects: Inserts or erases elements at the end such that
+   //!   the size becomes n. New elements are default constructed.
+   //!
+   //! Throws: If memory allocation throws, or T's copy constructor throws.
+   //!
+   //! Complexity: Linear to the difference between size() and new_size.
+   void resize(size_type new_size) 
+   {
+      if (new_size < this->size()){
+         //Destroy last elements
+         this->erase(const_iterator(this->members_.m_start + new_size), this->end());
+      }
+      else{
+         size_type n = new_size - this->size();
+         this->reserve(new_size);
+         container_detail::default_construct_aux_proxy proxy(this->alloc(), n);
+         priv_range_insert(this->cend().get_ptr(), n, proxy);
+      }
+   }
+
+   //! Effects: Erases all the elements of the vector.
+   //!
+   //! Throws: Nothing.
+   //!
+   //! Complexity: Linear to the number of elements in the vector.
+   void clear() BOOST_CONTAINER_NOEXCEPT
+   {  this->prot_destroy_all();  }
+
+   //! Effects: Tries to deallocate the excess of memory created
+   //!   with previous allocations. The size of the vector is unchanged
+   //!
+   //! Throws: If memory allocation throws, or T's copy/move constructor throws.
+   //!
+   //! Complexity: Linear to size().
+   void shrink_to_fit()
+   {  priv_shrink_to_fit(alloc_version());   }
+
+   /// @cond
+
+   private:
+   iterator priv_insert(const_iterator position, const T &x) 
+   {
+      //Just call more general insert(pos, size, value) and return iterator
+      size_type pos_n = position - cbegin();
+      this->insert(position, (size_type)1, x);
+      return iterator(this->members_.m_start + pos_n);
+   }
+
+   iterator priv_insert(const_iterator position, BOOST_RV_REF(T) x) 
+   {
+      //Just call more general insert(pos, size, value) and return iterator
+      size_type pos_n = position - cbegin();
+      this->insert(position
+                  ,repeat_move_it(repeat_it(x, 1))
+                  ,repeat_move_it(repeat_it()));
+      return iterator(this->members_.m_start + pos_n);
+   }
+
+   template 
+   void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x)
+   {
+      if (this->members_.m_size < this->members_.m_capacity){
+         //There is more memory, just construct a new object at the end
+         allocator_traits_type::construct
+            ( this->alloc()
+            , container_detail::to_raw_pointer(this->members_.m_start + this->members_.m_size)
+            , ::boost::forward(x) );
+         ++this->members_.m_size;
+      }
+      else{
+         this->insert(this->cend(), ::boost::forward(x));
+      }
+   }
+
+   template
+   void priv_shrink_to_fit( AllocVersion
+                          , typename container_detail::enable_if_c<
+                              container_detail::is_same::value >::type * = 0)
+   {
+      if(this->members_.m_capacity){
+         if(!size()){
+            this->prot_deallocate();
+         }
+         else{
+            //Allocate a new buffer.
+            size_type real_cap = 0;
+            std::pair ret =
+               this->allocation_command
+                  (allocate_new, this->size(), this->size(), real_cap, this->members_.m_start);
+            if(real_cap < this->capacity()){
+               //We will reuse insert code, so create a dummy input iterator
+               T *dummy_it(container_detail::to_raw_pointer(this->members_.m_start));
+               container_detail::advanced_insert_aux_proxy, T*>
+                  proxy(this->alloc(), ::boost::make_move_iterator(dummy_it), ::boost::make_move_iterator(dummy_it));
+               #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+               ++this->num_alloc;
+               #endif
+               this->priv_range_insert_new_allocation
+                  ( container_detail::to_raw_pointer(ret.first)
+                  , real_cap
+                  , container_detail::to_raw_pointer(this->members_.m_start)
+                  , 0
+                  , proxy);
+            }
+            else{
+               this->alloc().deallocate(ret.first, real_cap);
+            }
+         }
+      }
+   }
+
+   template
+   void priv_shrink_to_fit(AllocVersion
+                          , typename container_detail::enable_if_c<
+                              !container_detail::is_same::value >::type * = 0)
+   {
+      if(this->members_.m_capacity){
+         if(!size()){
+            this->prot_deallocate();
+         }
+         else{
+            size_type received_size;
+            if(this->alloc().allocation_command
+               ( shrink_in_place | nothrow_allocation
+               , this->capacity(), this->size()
+               , received_size,   this->members_.m_start).first){
+               this->members_.m_capacity = received_size;
+               #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+               ++this->num_shrink;
+               #endif
+            }
+         }
+      }
+   }
+
+   template 
+   void priv_range_insert(const_iterator pos, FwdIt first, FwdIt last, std::forward_iterator_tag)
+   {
+      if(first != last){        
+         const size_type n = std::distance(first, last);
+         container_detail::advanced_insert_aux_proxy proxy(this->alloc(), first, last);
+         priv_range_insert(pos.get_ptr(), n, proxy);
+      }
+   }
+
+   template 
+   void priv_range_insert(const_iterator pos, InIt first, InIt last, std::input_iterator_tag)
+   {
+      for(;first != last; ++first){
+         this->emplace(pos, *first);
+      }
+   }
+
+   void priv_range_insert(pointer pos, const size_type n, advanced_insert_aux_int_t &interf)
+   {
+      //Check if we have enough memory or try to expand current memory
+      size_type remaining = this->members_.m_capacity - this->members_.m_size;
+      bool same_buffer_start;
+      std::pair ret;
+      size_type real_cap = this->members_.m_capacity;
+
+      //Check if we already have room
+      if (n <= remaining){
+         same_buffer_start = true;
+      }
+      else{
+         //There is not enough memory, allocate a new
+         //buffer or expand the old one.
+         size_type new_cap = this->next_capacity(n);
+         ret = this->allocation_command
+               (allocate_new | expand_fwd | expand_bwd,
+                  this->members_.m_size + n, new_cap, real_cap, this->members_.m_start);
+
+         //Check for forward expansion
+         same_buffer_start = ret.second && this->members_.m_start == ret.first;
+         if(same_buffer_start){
+            this->members_.m_capacity  = real_cap;
+         }
+      }
+      
+      //If we had room or we have expanded forward
+      if (same_buffer_start){
+         #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+         ++this->num_expand_fwd;
+         #endif
+         this->priv_range_insert_expand_forward
+            (container_detail::to_raw_pointer(pos), n, interf);
+      }
+      //Backwards (and possibly forward) expansion
+      else if(ret.second){
+         #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+         ++this->num_expand_bwd;
+         #endif
+         this->priv_range_insert_expand_backwards
+            ( container_detail::to_raw_pointer(ret.first)
+            , real_cap
+            , container_detail::to_raw_pointer(pos)
+            , n
+            , interf);
+      }
+      //New buffer
+      else{
+         #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+         ++this->num_alloc;
+         #endif
+         this->priv_range_insert_new_allocation
+            ( container_detail::to_raw_pointer(ret.first)
+            , real_cap
+            , container_detail::to_raw_pointer(pos)
+            , n
+            , interf);
+      }
+   }
+
+   void priv_range_insert_expand_forward(T* pos, size_type n, advanced_insert_aux_int_t &interf)
+   {
+      //n can't be 0, because there is nothing to do in that case
+      if(!n) return;
+      //There is enough memory
+      T* old_finish = container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size;
+      const size_type elems_after = old_finish - pos;
+
+      if (elems_after >= n){
+         //New elements can be just copied.
+         //Move to uninitialized memory last objects
+         ::boost::container::uninitialized_move_alloc
+            (this->alloc(), old_finish - n, old_finish, old_finish);
+         this->members_.m_size += n;
+         //Copy previous to last objects to the initialized end
+         boost::move_backward(pos, old_finish - n, old_finish);
+         //Insert new objects in the pos
+         interf.copy_remaining_to(pos);
+      }
+      else {
+         //The new elements don't fit in the [pos, end()) range. Copy
+         //to the beginning of the unallocated zone the last new elements.
+         interf.uninitialized_copy_some_and_update(old_finish, elems_after, false);
+         this->members_.m_size += n - elems_after;
+         //Copy old [pos, end()) elements to the uninitialized memory
+         ::boost::container::uninitialized_move_alloc
+            (this->alloc(), pos, old_finish, container_detail::to_raw_pointer(this->members_.m_start) + this->members_.m_size);
+         this->members_.m_size += elems_after;
+         //Copy first new elements in pos
+         interf.copy_remaining_to(pos);
+      }
+   }
+
+   void priv_range_insert_new_allocation
+      (T* new_start, size_type new_cap, T* pos, size_type n, advanced_insert_aux_int_t &interf)
+   {
+      //n can be zero, if we want to reallocate!
+      T *new_finish = new_start;
+      T *old_finish;
+      //Anti-exception rollbacks
+      typename value_traits::ArrayDeallocator scoped_alloc(new_start, this->alloc(), new_cap);
+      typename value_traits::ArrayDestructor constructed_values_destroyer(new_start, this->alloc(), 0u);
+
+      //Initialize with [begin(), pos) old buffer 
+      //the start of the new buffer
+      T *old_buffer = container_detail::to_raw_pointer(this->members_.m_start);
+      if(old_buffer){
+         new_finish = ::boost::container::uninitialized_move_alloc
+            (this->alloc(), container_detail::to_raw_pointer(this->members_.m_start), pos, old_finish = new_finish);
+         constructed_values_destroyer.increment_size(new_finish - old_finish);
+      }
+      //Initialize new objects, starting from previous point
+      interf.uninitialized_copy_remaining_to(old_finish = new_finish);
+      new_finish += n;
+      constructed_values_destroyer.increment_size(new_finish - old_finish);
+      //Initialize from the rest of the old buffer, 
+      //starting from previous point
+      if(old_buffer){
+         new_finish = ::boost::container::uninitialized_move_alloc
+            (this->alloc(), pos, old_buffer + this->members_.m_size, new_finish);
+         //Destroy and deallocate old elements
+         //If there is allocated memory, destroy and deallocate
+         if(!value_traits::trivial_dctr_after_move)
+            this->destroy_n(old_buffer, this->members_.m_size); 
+         this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+      }
+      this->members_.m_start     = new_start;
+      this->members_.m_size      = new_finish - new_start;
+      this->members_.m_capacity  = new_cap;
+      //All construction successful, disable rollbacks
+      constructed_values_destroyer.release();
+      scoped_alloc.release();
+   }
+
+   void priv_range_insert_expand_backwards
+         (T* new_start, size_type new_capacity,
+          T* pos, const size_type n, advanced_insert_aux_int_t &interf)
+   {
+      //n can be zero to just expand capacity
+      //Backup old data
+      T* old_start  = container_detail::to_raw_pointer(this->members_.m_start);
+      T* old_finish = old_start + this->members_.m_size;
+      size_type old_size = this->members_.m_size;
+
+      //We can have 8 possibilities:
+      const size_type elemsbefore   = (size_type)(pos - old_start);
+      const size_type s_before      = (size_type)(old_start - new_start);
+
+      //Update the vector buffer information to a safe state
+      this->members_.m_start      = new_start;
+      this->members_.m_capacity   = new_capacity;
+      this->members_.m_size = 0;
+
+      //If anything goes wrong, this object will destroy
+      //all the old objects to fulfill previous vector state
+      typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->alloc(), old_size);
+      //Check if s_before is big enough to hold the beginning of old data + new data
+      if(difference_type(s_before) >= difference_type(elemsbefore + n)){
+         //Copy first old values before pos, after that the new objects
+         ::boost::container::uninitialized_move_alloc(this->alloc(), old_start, pos, new_start);
+         this->members_.m_size = elemsbefore;
+         interf.uninitialized_copy_remaining_to(new_start + elemsbefore);
+         this->members_.m_size += n;
+         //Check if s_before is so big that even copying the old data + new data
+         //there is a gap between the new data and the old data
+         if(s_before >= (old_size + n)){
+            //Old situation:
+            // _________________________________________________________
+            //|            raw_mem                | old_begin | old_end |
+            //| __________________________________|___________|_________|
+            //
+            //New situation:
+            // _________________________________________________________
+            //| old_begin |    new   | old_end |         raw_mem        |
+            //|___________|__________|_________|________________________|
+            //
+            //Now initialize the rest of memory with the last old values
+            ::boost::container::uninitialized_move_alloc
+               (this->alloc(), pos, old_finish, new_start + elemsbefore + n);
+            //All new elements correctly constructed, avoid new element destruction
+            this->members_.m_size = old_size + n;
+            //Old values destroyed automatically with "old_values_destroyer"
+            //when "old_values_destroyer" goes out of scope unless the have trivial
+            //destructor after move.
+            if(value_traits::trivial_dctr_after_move)
+               old_values_destroyer.release();
+         }
+         //s_before is so big that divides old_end
+         else{
+            //Old situation:
+            // __________________________________________________
+            //|            raw_mem         | old_begin | old_end |
+            //| ___________________________|___________|_________|
+            //
+            //New situation:
+            // __________________________________________________
+            //| old_begin |   new    | old_end |  raw_mem        |
+            //|___________|__________|_________|_________________|
+            //
+            //Now initialize the rest of memory with the last old values
+            //All new elements correctly constructed, avoid new element destruction
+            size_type raw_gap = s_before - (elemsbefore + n);
+            //Now initialize the rest of s_before memory with the
+            //first of elements after new values
+            ::boost::container::uninitialized_move_alloc
+               (this->alloc(), pos, pos + raw_gap, new_start + elemsbefore + n);
+            //Update size since we have a contiguous buffer
+            this->members_.m_size = old_size + s_before;
+            //All new elements correctly constructed, avoid old element destruction
+            old_values_destroyer.release();
+            //Now copy remaining last objects in the old buffer begin
+            T *to_destroy = ::boost::move(pos + raw_gap, old_finish, old_start);
+            //Now destroy redundant elements except if they were moved and
+            //they have trivial destructor after move
+            size_type n_destroy =  old_finish - to_destroy;
+            if(!value_traits::trivial_dctr_after_move)
+               this->destroy_n(to_destroy, n_destroy);
+            this->members_.m_size -= n_destroy;
+         }
+      }
+      else{
+         //Check if we have to do the insertion in two phases
+         //since maybe s_before is not big enough and
+         //the buffer was expanded both sides
+         //
+         //Old situation:
+         // _________________________________________________
+         //| raw_mem | old_begin + old_end |  raw_mem        |
+         //|_________|_____________________|_________________|
+         //
+         //New situation with do_after:
+         // _________________________________________________
+         //|     old_begin + new + old_end     |  raw_mem    |
+         //|___________________________________|_____________|
+         //
+         //New without do_after:
+         // _________________________________________________
+         //| old_begin + new + old_end  |  raw_mem           |
+         //|____________________________|____________________|
+         //
+         bool do_after    = n > s_before;
+
+         //Now we can have two situations: the raw_mem of the
+         //beginning divides the old_begin, or the new elements:
+         if (s_before <= elemsbefore) {
+            //The raw memory divides the old_begin group:
+            //
+            //If we need two phase construction (do_after)
+            //new group is divided in new = new_beg + new_end groups
+            //In this phase only new_beg will be inserted
+            //
+            //Old situation:
+            // _________________________________________________
+            //| raw_mem | old_begin | old_end |  raw_mem        |
+            //|_________|___________|_________|_________________|
+            //
+            //New situation with do_after(1):
+            //This is not definitive situation, the second phase
+            //will include
+            // _________________________________________________
+            //| old_begin | new_beg | old_end |  raw_mem        |
+            //|___________|_________|_________|_________________|
+            //
+            //New situation without do_after:
+            // _________________________________________________
+            //| old_begin | new | old_end |  raw_mem            |
+            //|___________|_____|_________|_____________________|
+            //
+            //Copy the first part of old_begin to raw_mem
+            T *start_n = old_start + difference_type(s_before); 
+            ::boost::container::uninitialized_move_alloc
+               (this->alloc(), old_start, start_n, new_start);
+            //The buffer is all constructed until old_end,
+            //release destroyer and update size
+            old_values_destroyer.release();
+            this->members_.m_size = old_size + s_before;
+            //Now copy the second part of old_begin overwriting himself
+            T* next = ::boost::move(start_n, pos, old_start);
+            if(do_after){
+               //Now copy the new_beg elements
+               interf.copy_some_and_update(next, s_before, true);
+            }
+            else{
+               //Now copy the all the new elements
+               interf.copy_remaining_to(next);
+               T* move_start = next + n;
+               //Now displace old_end elements
+               T* move_end   = ::boost::move(pos, old_finish, move_start);
+               //Destroy remaining moved elements from old_end except if
+               //they have trivial destructor after being moved
+               difference_type n_destroy = s_before - n;
+               if(!value_traits::trivial_dctr_after_move)
+                  this->destroy_n(move_end, n_destroy);
+               this->members_.m_size -= n_destroy;
+            }
+         }
+         else {
+            //If we have to expand both sides,
+            //we will play if the first new values so
+            //calculate the upper bound of new values
+
+            //The raw memory divides the new elements
+            //
+            //If we need two phase construction (do_after)
+            //new group is divided in new = new_beg + new_end groups
+            //In this phase only new_beg will be inserted
+            //
+            //Old situation:
+            // _______________________________________________________
+            //|   raw_mem     | old_begin | old_end |  raw_mem        |
+            //|_______________|___________|_________|_________________|
+            //
+            //New situation with do_after():
+            // ____________________________________________________
+            //| old_begin |    new_beg    | old_end |  raw_mem     |
+            //|___________|_______________|_________|______________|
+            //
+            //New situation without do_after:
+            // ______________________________________________________
+            //| old_begin | new | old_end |  raw_mem                 |
+            //|___________|_____|_________|__________________________|
+            //
+            //First copy whole old_begin and part of new to raw_mem
+            ::boost::container::uninitialized_move_alloc
+               (this->alloc(), old_start, pos, new_start);
+            this->members_.m_size = elemsbefore;
+
+            const size_type mid_n = difference_type(s_before) - elemsbefore;
+            interf.uninitialized_copy_some_and_update(new_start + elemsbefore, mid_n, true);
+            this->members_.m_size = old_size + s_before;
+            //The buffer is all constructed until old_end,
+            //release destroyer and update size
+            old_values_destroyer.release();
+
+            if(do_after){
+               //Copy new_beg part
+               interf.copy_some_and_update(old_start, s_before - mid_n, true);
+            }
+            else{
+               //Copy all new elements
+               interf.copy_remaining_to(old_start);
+               T* move_start = old_start + (n-mid_n);
+               //Displace old_end
+               T* move_end = ::boost::move(pos, old_finish, move_start);
+               //Destroy remaining moved elements from old_end except if they
+               //have trivial destructor after being moved
+               difference_type n_destroy = s_before - n;
+               if(!value_traits::trivial_dctr_after_move)
+                  this->destroy_n(move_end, n_destroy);
+               this->members_.m_size -= n_destroy;
+            }
+         }
+
+         //This is only executed if two phase construction is needed
+         //This can be executed without exception handling since we
+         //have to just copy and append in raw memory and
+         //old_values_destroyer has been released in phase 1.
+         if(do_after){
+            //The raw memory divides the new elements
+            //
+            //Old situation:
+            // ______________________________________________________
+            //|   raw_mem    | old_begin |  old_end   |  raw_mem     |
+            //|______________|___________|____________|______________|
+            //
+            //New situation with do_after(1):
+            // _______________________________________________________
+            //| old_begin   +   new_beg  | new_end |old_end | raw_mem |
+            //|__________________________|_________|________|_________|
+            //
+            //New situation with do_after(2):
+            // ______________________________________________________
+            //| old_begin      +       new            | old_end |raw |
+            //|_______________________________________|_________|____|
+            //
+            const size_type n_after  = n - s_before;
+            const difference_type elemsafter = old_size - elemsbefore;
+
+            //We can have two situations:
+            if (elemsafter > difference_type(n_after)){
+               //The raw_mem from end will divide displaced old_end
+               //
+               //Old situation:
+               // ______________________________________________________
+               //|   raw_mem    | old_begin |  old_end   |  raw_mem     |
+               //|______________|___________|____________|______________|
+               //
+               //New situation with do_after(1):
+               // _______________________________________________________
+               //| old_begin   +   new_beg  | new_end |old_end | raw_mem |
+               //|__________________________|_________|________|_________|
+               //
+               //First copy the part of old_end raw_mem
+               T* finish_n = old_finish - difference_type(n_after);
+               ::boost::container::uninitialized_move_alloc
+                  (this->alloc(), finish_n, old_finish, old_finish);
+               this->members_.m_size += n_after;
+               //Displace the rest of old_end to the new position
+               boost::move_backward(pos, finish_n, old_finish);
+               //Now overwrite with new_end
+               //The new_end part is [first + (n - n_after), last)
+               interf.copy_remaining_to(pos);
+            }
+            else {
+               //The raw_mem from end will divide new_end part
+               //
+               //Old situation:
+               // _____________________________________________________________
+               //|   raw_mem    | old_begin |  old_end   |  raw_mem            |
+               //|______________|___________|____________|_____________________|
+               //
+               //New situation with do_after(2):
+               // _____________________________________________________________
+               //| old_begin   +   new_beg  |     new_end   |old_end | raw_mem |
+               //|__________________________|_______________|________|_________|
+               //
+               size_type mid_last_dist = n_after - elemsafter;
+               //First initialize data in raw memory
+               //The new_end part is [first + (n - n_after), last)
+               interf.uninitialized_copy_some_and_update(old_finish, elemsafter, false);
+               this->members_.m_size += mid_last_dist;
+               ::boost::container::uninitialized_move_alloc
+                  (this->alloc(), pos, old_finish, old_finish + mid_last_dist);
+               this->members_.m_size += n_after - mid_last_dist;
+               //Now copy the part of new_end over constructed elements
+               interf.copy_remaining_to(pos);
+            }
+         }
+      }
+   }
+
+   template 
+   void priv_assign_aux(InIt first, InIt last, std::input_iterator_tag)
+   {
+      //Overwrite all elements we can from [first, last)
+      iterator cur = begin();
+      for ( ; first != last && cur != end(); ++cur, ++first){
+         *cur = *first;
+      }
+
+      if (first == last){
+         //There are no more elements in the sequence, erase remaining
+         this->erase(cur, cend());
+      }
+      else{
+         //There are more elements in the range, insert the remaining ones
+         this->insert(this->cend(), first, last);
+      }
+   }
+
+   template 
+   void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag)
+   {
+      size_type n = std::distance(first, last);
+      if(!n){
+         this->prot_destroy_all();
+         return;
+      }
+      //Check if we have enough memory or try to expand current memory
+      size_type remaining = this->members_.m_capacity - this->members_.m_size;
+      bool same_buffer_start;
+      std::pair ret;
+      size_type real_cap = this->members_.m_capacity;
+
+      if (n <= remaining){
+         same_buffer_start = true;
+      }
+      else{
+         //There is not enough memory, allocate a new buffer
+         size_type new_cap = this->next_capacity(n);
+         ret = this->allocation_command
+               (allocate_new | expand_fwd | expand_bwd,
+                  this->size() + n, new_cap, real_cap, this->members_.m_start);
+         same_buffer_start = ret.second && this->members_.m_start == ret.first;
+         if(same_buffer_start){
+            this->members_.m_capacity  = real_cap;
+         }
+      }
+      
+      if(same_buffer_start){
+         T *start = container_detail::to_raw_pointer(this->members_.m_start);
+         if (this->size() >= n){
+            //There is memory, but there are more old elements than new ones
+            //Overwrite old elements with new ones
+            std::copy(first, last, start);
+            //Destroy remaining old elements
+            this->destroy_n(start + n, this->members_.m_size - n);
+            this->members_.m_size = n;
+         }
+         else{
+            //There is memory, but there are less old elements than new ones
+            //First overwrite some old elements with new ones
+            FwdIt mid = first;
+            std::advance(mid, this->size());
+            // iG T *end = std::copy(first, mid, start);
+            T *end = std::copy(first, mid, start);
+            //Initialize the remaining new elements in the uninitialized memory
+            ::boost::container::uninitialized_copy_or_move_alloc(this->alloc(), mid, last, end);
+            this->members_.m_size = n;
+         }
+      }
+      else if(!ret.second){
+         typename value_traits::ArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap);
+         ::boost::container::uninitialized_copy_or_move_alloc(this->alloc(), first, last, container_detail::to_raw_pointer(ret.first));
+         scoped_alloc.release();
+         //Destroy and deallocate old buffer
+         if(this->members_.m_start != 0){
+            this->destroy_n(container_detail::to_raw_pointer(this->members_.m_start), this->members_.m_size); 
+            this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity);
+         }
+         this->members_.m_start     = ret.first;
+         this->members_.m_size      = n;
+         this->members_.m_capacity  = real_cap;
+      }
+      else{
+         //Backwards expansion
+         //If anything goes wrong, this object will destroy old objects
+         T *old_start         = container_detail::to_raw_pointer(this->members_.m_start);
+         size_type old_size   = this->members_.m_size;
+         typename value_traits::OldArrayDestructor old_values_destroyer(old_start, this->alloc(), old_size);
+         //If something goes wrong size will be 0
+         //but holding the whole buffer
+         this->members_.m_size  = 0;
+         this->members_.m_start = ret.first;
+         this->members_.m_capacity = real_cap;
+         
+         //Backup old buffer data
+         size_type old_offset    = old_start - container_detail::to_raw_pointer(ret.first);
+         size_type first_count   = container_detail::min_value(n, old_offset);
+
+         FwdIt mid = first;
+         std::advance(mid, first_count);
+         ::boost::container::uninitialized_copy_or_move_alloc
+            (this->alloc(), first, mid, container_detail::to_raw_pointer(ret.first));
+
+         if(old_offset > n){
+            //All old elements will be destroyed by "old_values_destroyer" 
+            this->members_.m_size = n;
+         }
+         else{
+            //We have constructed objects from the new begin until
+            //the old end so release the rollback destruction
+            old_values_destroyer.release();
+            this->members_.m_start  = ret.first;
+            this->members_.m_size   = first_count + old_size;
+            //Now overwrite the old values
+            size_type second_count = container_detail::min_value(old_size, n - first_count);
+            FwdIt mid2 = mid;
+            std::advance(mid2, second_count);
+            // iG std::copy(mid, mid2, old_start);
+            std::copy(mid, mid2, old_start);
+            
+            //Check if we still have to append elements in the
+            //uninitialized end
+            if(second_count == old_size){
+               // iG std::copy(mid2, last, old_start + old_size);
+               std::copy(mid2, last, old_start + old_size);
+            }
+            else{
+               //We have to destroy some old values
+               this->destroy_n
+                  (old_start + second_count, old_size - second_count);
+               this->members_.m_size = n;
+            }
+            this->members_.m_size = n;                        
+         }
+      }
+   }
+
+   template 
+   void priv_assign_dispatch(Integer n, Integer val, container_detail::true_)
+   { this->assign((size_type) n, (value_type)val); }
+
+   template 
+   void priv_assign_dispatch(InIt first, InIt last, container_detail::false_)
+   { 
+      //Dispatch depending on integer/iterator
+      typedef typename std::iterator_traits::iterator_category ItCat;
+      this->priv_assign_aux(first, last, ItCat()); 
+   }
+
+   template 
+   void priv_insert_dispatch(const_iterator pos, Integer n, Integer val, container_detail::true_) 
+   {  this->insert(pos, (size_type)n, (T)val);  }
+
+   template 
+   void priv_insert_dispatch(const_iterator pos, InIt first, 
+                             InIt last,      container_detail::false_)
+   {
+      //Dispatch depending on integer/iterator
+      typedef typename std::iterator_traits::iterator_category ItCat;
+      this->priv_range_insert(pos, first, last, ItCat());
+   }
+
+   void priv_check_range(size_type n) const 
+   {
+      //If n is out of range, throw an out_of_range exception
+      if (n >= size())
+         throw std::out_of_range("vector::at");
+   }
+
+   #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
+   public:
+   unsigned int num_expand_fwd;
+   unsigned int num_expand_bwd;
+   unsigned int num_shrink;
+   unsigned int num_alloc;
+   void reset_alloc_stats()
+   {  num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0;   }
+   #endif
+   /// @endcond
+};
+
+template 
+inline bool 
+operator==(const vector& x, const vector& y)
+{
+   //Check first size and each element if needed
+   return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
+}
+
+template 
+inline bool 
+operator!=(const vector& x, const vector& y)
+{
+   //Check first size and each element if needed
+  return x.size() != y.size() || !std::equal(x.begin(), x.end(), y.begin());
+}
+
+template 
+inline bool 
+operator<(const vector& x, const vector& y)
+{
+   return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
+}
+
+template 
+inline void swap(vector& x, vector& y)
+{  x.swap(y);  }
+
+}}
+
+/// @cond
+
+namespace boost {
+
+/*
+
+//!has_trivial_destructor_after_move<> == true_type
+//!specialization for optimizations
+template 
+struct has_trivial_destructor_after_move >
+{
+   static const bool value = has_trivial_destructor::value;
+};
+
+*/
+
+}
+
+/// @endcond
+
+#include 
+
+#endif //   #ifndef  BOOST_CONTAINER_CONTAINER_VECTOR_HPP
+
diff --git a/src/third_party/boost/boost/intrusive/any_hook.hpp b/src/third_party/boost/boost/intrusive/any_hook.hpp
new file mode 100644
index 00000000000..cccc820e7d3
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/any_hook.hpp
@@ -0,0 +1,344 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_ANY_HOOK_HPP
+#define BOOST_INTRUSIVE_ANY_HOOK_HPP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+
+/// @cond
+template
+struct get_any_node_algo
+{
+   typedef any_algorithms type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c \c any_base_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+struct make_any_base_hook
+{
+   /// @cond
+   typedef typename pack_options
+      < hook_defaults,
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      O1, O2, O3
+      #else
+      Options...
+      #endif
+      >::type packed_options;
+   
+   typedef detail::generic_hook
+   < get_any_node_algo
+   , typename packed_options::tag
+   , packed_options::link_mode
+   , detail::AnyBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+//! Derive a class from this hook in order to store objects of that class
+//! in an intrusive container.
+//! 
+//! The hook admits the following options: \c tag<>, \c void_pointer<> and
+//! \c link_mode<>.
+//!
+//! \c tag<> defines a tag to identify the node. 
+//! The same tag value can be used in different classes, but if a class is 
+//! derived from more than one \c any_base_hook, then each \c any_base_hook needs its 
+//! unique tag.
+//!
+//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, \c safe_link).
+//!
+//! \c void_pointer<> is the pointer type that will be used internally in the hook
+//! and the the container configured to use this hook.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+class any_base_hook
+   :  public make_any_base_hook
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type
+{
+   #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+   public:
+   //! Effects: If link_mode is or \c safe_link
+   //!   initializes the node to an unlinked state.
+   //! 
+   //! Throws: Nothing. 
+   any_base_hook();
+
+   //! Effects: If link_mode is or \c safe_link
+   //!   initializes the node to an unlinked state. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing a copy-constructor
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   any_base_hook(const any_base_hook& );
+
+   //! Effects: Empty function. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing an assignment operator 
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   any_base_hook& operator=(const any_base_hook& );
+
+   //! Effects: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in a container an assertion is raised.
+   //! 
+   //! Throws: Nothing. 
+   ~any_base_hook();
+
+   //! Precondition: link_mode must be \c safe_link.
+   //!
+   //! Returns: true, if the node belongs to a container, false
+   //!   otherwise. This function can be used to test whether \c container::iterator_to 
+   //!   will return a valid iterator. 
+   //!
+   //! Complexity: Constant 
+   bool is_linked() const;
+   #endif
+};
+
+//! Helper metafunction to define a \c \c any_member_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+struct make_any_member_hook
+{
+   /// @cond
+   typedef typename pack_options
+      < hook_defaults, 
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      O1, O2, O3
+      #else
+      Options...
+      #endif
+      >::type packed_options;
+
+   typedef detail::generic_hook
+   < get_any_node_algo
+   , member_tag
+   , packed_options::link_mode
+   , detail::NoBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+//! Store this hook in a class to be inserted
+//! in an intrusive container.
+//! 
+//! The hook admits the following options: \c void_pointer<> and
+//! \c link_mode<>.
+//! 
+//! \c link_mode<> will specify the linking mode of the hook (\c normal_link or \c safe_link).
+//!
+//! \c void_pointer<> is the pointer type that will be used internally in the hook
+//! and the the container configured to use this hook.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+class any_member_hook
+   :  public make_any_member_hook
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type
+{
+   #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+   public:
+   //! Effects: If link_mode is or \c safe_link
+   //!   initializes the node to an unlinked state.
+   //! 
+   //! Throws: Nothing. 
+   any_member_hook();
+
+   //! Effects: If link_mode is or \c safe_link
+   //!   initializes the node to an unlinked state. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing a copy-constructor
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   any_member_hook(const any_member_hook& );
+
+   //! Effects: Empty function. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing an assignment operator 
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   any_member_hook& operator=(const any_member_hook& );
+
+   //! Effects: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in a container an assertion is raised.
+   //! 
+   //! Throws: Nothing. 
+   ~any_member_hook();
+
+   //! Precondition: link_mode must be \c safe_link.
+   //!
+   //! Returns: true, if the node belongs to a container, false
+   //!   otherwise. This function can be used to test whether \c container::iterator_to 
+   //!   will return a valid iterator. 
+   //!
+   //! Complexity: Constant 
+   bool is_linked() const;
+   #endif
+};
+
+/// @cond
+
+namespace detail{
+
+template
+struct any_to_get_base_pointer_type
+{
+   typedef typename pointer_traits::template
+      rebind_pointer::type type;
+};
+
+template
+struct any_to_get_member_pointer_type
+{
+   typedef typename pointer_traits
+      ::template rebind_pointer::type type;
+};
+
+//!This option setter specifies that the container
+//!must use the specified base hook
+template class NodeTraits>
+struct any_to_some_hook
+{
+   typedef typename BaseHook::template pack::value_traits old_value_traits;
+   template
+   struct pack : public Base
+   {
+      struct value_traits : public old_value_traits
+      {
+         static const bool is_any_hook = true;
+         typedef typename detail::eval_if_c
+            < detail::internal_base_hook_bool_is_true::value
+            , any_to_get_base_pointer_type
+            , any_to_get_member_pointer_type
+            >::type void_pointer;
+         typedef NodeTraits node_traits;
+      };
+   };
+};
+
+}  //namespace detail{
+
+/// @endcond
+
+//!This option setter specifies that
+//!any hook should behave as an slist hook
+template
+struct any_to_slist_hook
+/// @cond
+   :  public detail::any_to_some_hook
+/// @endcond
+{};
+
+//!This option setter specifies that
+//!any hook should behave as an list hook
+template
+struct any_to_list_hook
+/// @cond
+   :  public detail::any_to_some_hook
+/// @endcond
+{};
+
+//!This option setter specifies that
+//!any hook should behave as a set hook
+template
+struct any_to_set_hook
+/// @cond
+   :  public detail::any_to_some_hook
+/// @endcond
+{};
+
+//!This option setter specifies that
+//!any hook should behave as an avl_set hook
+template
+struct any_to_avl_set_hook
+/// @cond
+   :  public detail::any_to_some_hook
+/// @endcond
+{};
+
+//!This option setter specifies that any
+//!hook should behave as a bs_set hook
+template
+struct any_to_bs_set_hook
+/// @cond
+   :  public detail::any_to_some_hook
+/// @endcond
+{};
+
+//!This option setter specifies that any hook
+//!should behave as an unordered set hook
+template
+struct any_to_unordered_set_hook
+/// @cond
+   :  public detail::any_to_some_hook
+/// @endcond
+{};
+
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_ANY_HOOK_HPP
diff --git a/src/third_party/boost/boost/intrusive/avl_set.hpp b/src/third_party/boost/boost/intrusive/avl_set.hpp
new file mode 100644
index 00000000000..92baf473ce9
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/avl_set.hpp
@@ -0,0 +1,2358 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_AVL_SET_HPP
+#define BOOST_INTRUSIVE_AVL_SET_HPP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+
+//! The class template avl_set is an intrusive container, that mimics most of 
+//! the interface of std::set as described in the C++ standard.
+//! 
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
+//!
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<>, \c size_type<> and
+//! \c compare<>.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+class avl_set_impl
+{
+   /// @cond
+   typedef avltree_impl tree_type;
+   //! This class is
+   //! movable
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set_impl)
+
+   typedef tree_type implementation_defined;
+   /// @endcond
+
+   public:
+   typedef typename implementation_defined::value_type               value_type;
+   typedef typename implementation_defined::value_traits             value_traits;
+   typedef typename implementation_defined::pointer                  pointer;
+   typedef typename implementation_defined::const_pointer            const_pointer;
+   typedef typename implementation_defined::reference                reference;
+   typedef typename implementation_defined::const_reference          const_reference;
+   typedef typename implementation_defined::difference_type          difference_type;
+   typedef typename implementation_defined::size_type                size_type;
+   typedef typename implementation_defined::value_compare            value_compare;
+   typedef typename implementation_defined::key_compare              key_compare;
+   typedef typename implementation_defined::iterator                 iterator;
+   typedef typename implementation_defined::const_iterator           const_iterator;
+   typedef typename implementation_defined::reverse_iterator         reverse_iterator;
+   typedef typename implementation_defined::const_reverse_iterator   const_reverse_iterator;
+   typedef typename implementation_defined::insert_commit_data       insert_commit_data;
+   typedef typename implementation_defined::node_traits              node_traits;
+   typedef typename implementation_defined::node                     node;
+   typedef typename implementation_defined::node_ptr                 node_ptr;
+   typedef typename implementation_defined::const_node_ptr           const_node_ptr;
+   typedef typename implementation_defined::node_algorithms          node_algorithms;
+
+   static const bool constant_time_size = Config::constant_time_size;
+
+   /// @cond
+   private:
+   tree_type tree_;
+   /// @endcond
+
+   public:
+   //! Effects: Constructs an empty avl_set. 
+   //!   
+   //! Complexity: Constant. 
+   //! 
+   //! Throws: If value_traits::node_traits::node
+   //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+   //!   or the copy constructor of the value_compare object throws. 
+   avl_set_impl( const value_compare &cmp = value_compare()
+           , const value_traits &v_traits = value_traits()) 
+      :  tree_(cmp, v_traits)
+   {}
+
+   //! Requires: Dereferencing iterator must yield an lvalue of type value_type. 
+   //!   cmp must be a comparison function that induces a strict weak ordering.
+   //! 
+   //! Effects: Constructs an empty avl_set and inserts elements from 
+   //!   [b, e).
+   //! 
+   //! Complexity: Linear in N if [b, e) is already sorted using 
+   //!   comp and otherwise N * log N, where N is std::distance(last, first).
+   //! 
+   //! Throws: If value_traits::node_traits::node
+   //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+   //!   or the copy constructor/operator() of the value_compare object throws. 
+   template
+   avl_set_impl( Iterator b, Iterator e
+           , const value_compare &cmp = value_compare()
+           , const value_traits &v_traits = value_traits())
+      : tree_(true, b, e, cmp, v_traits)
+   {}
+
+   //! Effects: to-do
+   //!   
+   avl_set_impl(BOOST_RV_REF(avl_set_impl) x) 
+      :  tree_(::boost::move(x.tree_))
+   {}
+
+   //! Effects: to-do
+   //!   
+   avl_set_impl& operator=(BOOST_RV_REF(avl_set_impl) x) 
+   {  tree_ = ::boost::move(x.tree_);  return *this;  }
+
+   //! Effects: Detaches all elements from this. The objects in the avl_set 
+   //!   are not deleted (i.e. no destructors are called).
+   //! 
+   //! Complexity: Linear to the number of elements on the container.
+   //!   if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
+   //! 
+   //! Throws: Nothing.
+   ~avl_set_impl() 
+   {}
+
+   //! Effects: Returns an iterator pointing to the beginning of the avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   iterator begin()
+   { return tree_.begin();  }
+
+   //! Effects: Returns a const_iterator pointing to the beginning of the avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator begin() const
+   { return tree_.begin();  }
+
+   //! Effects: Returns a const_iterator pointing to the beginning of the avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator cbegin() const
+   { return tree_.cbegin();  }
+
+   //! Effects: Returns an iterator pointing to the end of the avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   iterator end()
+   { return tree_.end();  }
+
+   //! Effects: Returns a const_iterator pointing to the end of the avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator end() const
+   { return tree_.end();  }
+
+   //! Effects: Returns a const_iterator pointing to the end of the avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator cend() const
+   { return tree_.cend();  }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning of the
+   //!    reversed avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   reverse_iterator rbegin()
+   { return tree_.rbegin();  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning
+   //!    of the reversed avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator rbegin() const
+   { return tree_.rbegin();  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning
+   //!    of the reversed avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator crbegin() const
+   { return tree_.crbegin();  }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //!    of the reversed avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   reverse_iterator rend()
+   { return tree_.rend();  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //!    of the reversed avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator rend() const
+   { return tree_.rend();  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //!    of the reversed avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator crend() const
+   { return tree_.crend();  }
+
+   //! Precondition: end_iterator must be a valid end iterator
+   //!   of avl_set.
+   //! 
+   //! Effects: Returns a const reference to the avl_set associated to the end iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   static avl_set_impl &container_from_end_iterator(iterator end_iterator)
+   {
+      return *detail::parent_from_member
+         ( &tree_type::container_from_end_iterator(end_iterator)
+         , &avl_set_impl::tree_);
+   }
+
+   //! Precondition: end_iterator must be a valid end const_iterator
+   //!   of avl_set.
+   //! 
+   //! Effects: Returns a const reference to the set associated to the end iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   static const avl_set_impl &container_from_end_iterator(const_iterator end_iterator)
+   {
+      return *detail::parent_from_member
+         ( &tree_type::container_from_end_iterator(end_iterator)
+         , &avl_set_impl::tree_);
+   }
+
+   //! Precondition: it must be a valid iterator of set.
+   //! 
+   //! Effects: Returns a reference to the set associated to the iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Logarithmic.
+   static avl_set_impl &container_from_iterator(iterator it)
+   {
+      return *detail::parent_from_member
+         ( &tree_type::container_from_iterator(it)
+         , &avl_set_impl::tree_);
+   }
+
+   //! Precondition: it must be a valid const_iterator of set.
+   //! 
+   //! Effects: Returns a const reference to the set associated to the iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Logarithmic.
+   static const avl_set_impl &container_from_iterator(const_iterator it)
+   {
+      return *detail::parent_from_member
+         ( &tree_type::container_from_iterator(it)
+         , &avl_set_impl::tree_);
+   }
+
+   //! Effects: Returns the key_compare object used by the avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: If key_compare copy-constructor throws.
+   key_compare key_comp() const
+   { return tree_.value_comp(); }
+
+   //! Effects: Returns the value_compare object used by the avl_set.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: If value_compare copy-constructor throws.
+   value_compare value_comp() const
+   { return tree_.value_comp(); }
+
+   //! Effects: Returns true is the container is empty.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   bool empty() const
+   { return tree_.empty(); }
+
+   //! Effects: Returns the number of elements stored in the avl_set.
+   //! 
+   //! Complexity: Linear to elements contained in *this if,
+   //!   constant-time size option is enabled. Constant-time otherwise.
+   //! 
+   //! Throws: Nothing.
+   size_type size() const
+   { return tree_.size(); }
+
+   //! Effects: Swaps the contents of two sets.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: If the swap() call for the comparison functor
+   //!   found using ADL throws. Strong guarantee.
+   void swap(avl_set_impl& other)
+   { tree_.swap(other.tree_); }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!   Cloner should yield to nodes equivalent to the original nodes.
+   //!
+   //! Effects: Erases all the elements from *this
+   //!   calling Disposer::operator()(pointer), clones all the 
+   //!   elements from src calling Cloner::operator()(const_reference )
+   //!   and inserts them on *this. Copies the predicate from the source container.
+   //!
+   //!   If cloner throws, all cloned elements are unlinked and disposed
+   //!   calling Disposer::operator()(pointer).
+   //!   
+   //! Complexity: Linear to erased plus inserted elements.
+   //! 
+   //! Throws: If cloner throws or predicate copy assignment throws. Basic guarantee.
+   template 
+   void clone_from(const avl_set_impl &src, Cloner cloner, Disposer disposer)
+   {  tree_.clone_from(src.tree_, cloner, disposer);  }
+
+   //! Requires: value must be an lvalue
+   //! 
+   //! Effects: Treaps to inserts value into the avl_set.
+   //!
+   //! Returns: If the value
+   //!   is not already present inserts it and returns a pair containing the
+   //!   iterator to the new value and true. If there is an equivalent value
+   //!   returns a pair containing an iterator to the already present value
+   //!   and false.
+   //! 
+   //! Complexity: Average complexity for insert element is at
+   //!   most logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Strong guarantee.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   std::pair insert(reference value)
+   {  return tree_.insert_unique(value);  }
+
+   //! Requires: value must be an lvalue
+   //! 
+   //! Effects: Treaps to to insert x into the avl_set, using "hint" 
+   //!   as a hint to where it will be inserted.
+   //!
+   //! Returns: An iterator that points to the position where the 
+   //!   new element was inserted into the avl_set.
+   //! 
+   //! Complexity: Logarithmic in general, but it's amortized
+   //!   constant time if t is inserted immediately before hint.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Strong guarantee.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   iterator insert(const_iterator hint, reference value)
+   {  return tree_.insert_unique(hint, value);  }
+
+   //! Requires: key_value_comp must be a comparison function that induces 
+   //!   the same strict weak ordering as value_compare. The difference is that
+   //!   key_value_comp compares an arbitrary key with the contained values.
+   //! 
+   //! Effects: Checks if a value can be inserted in the avl_set, using
+   //!   a user provided key instead of the value itself.
+   //!
+   //! Returns: If there is an equivalent value
+   //!   returns a pair containing an iterator to the already present value
+   //!   and false. If the value can be inserted returns true in the returned
+   //!   pair boolean and fills "commit_data" that is meant to be used with
+   //!   the "insert_commit" function.
+   //! 
+   //! Complexity: Average complexity is at most logarithmic.
+   //!
+   //! Throws: If the key_value_comp ordering function throws. Strong guarantee.
+   //! 
+   //! Notes: This function is used to improve performance when constructing
+   //!   a value_type is expensive: if there is an equivalent value
+   //!   the constructed object must be discarded. Many times, the part of the
+   //!   node that is used to impose the order is much cheaper to construct
+   //!   than the value_type and this function offers the possibility to use that 
+   //!   part to check if the insertion will be successful.
+   //!
+   //!   If the check is successful, the user can construct the value_type and use
+   //!   "insert_commit" to insert the object in constant-time. This gives a total
+   //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
+   //!
+   //!   "commit_data" remains valid for a subsequent "insert_commit" only if no more
+   //!   objects are inserted or erased from the avl_set.
+   template
+   std::pair insert_check
+      (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+   {  return tree_.insert_unique_check(key, key_value_comp, commit_data); }
+
+   //! Requires: key_value_comp must be a comparison function that induces 
+   //!   the same strict weak ordering as value_compare. The difference is that
+   //!   key_value_comp compares an arbitrary key with the contained values.
+   //! 
+   //! Effects: Checks if a value can be inserted in the avl_set, using
+   //!   a user provided key instead of the value itself, using "hint" 
+   //!   as a hint to where it will be inserted.
+   //!
+   //! Returns: If there is an equivalent value
+   //!   returns a pair containing an iterator to the already present value
+   //!   and false. If the value can be inserted returns true in the returned
+   //!   pair boolean and fills "commit_data" that is meant to be used with
+   //!   the "insert_commit" function.
+   //! 
+   //! Complexity: Logarithmic in general, but it's amortized
+   //!   constant time if t is inserted immediately before hint.
+   //!
+   //! Throws: If the key_value_comp ordering function throws. Strong guarantee.
+   //! 
+   //! Notes: This function is used to improve performance when constructing
+   //!   a value_type is expensive: if there is an equivalent value
+   //!   the constructed object must be discarded. Many times, the part of the
+   //!   constructing that is used to impose the order is much cheaper to construct
+   //!   than the value_type and this function offers the possibility to use that key 
+   //!   to check if the insertion will be successful.
+   //!
+   //!   If the check is successful, the user can construct the value_type and use
+   //!   "insert_commit" to insert the object in constant-time. This can give a total
+   //!   constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
+   //!   
+   //!   "commit_data" remains valid for a subsequent "insert_commit" only if no more
+   //!   objects are inserted or erased from the avl_set.
+   template
+   std::pair insert_check
+      (const_iterator hint, const KeyType &key
+      ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+   {  return tree_.insert_unique_check(hint, key, key_value_comp, commit_data); }
+
+   //! Requires: value must be an lvalue of type value_type. commit_data
+   //!   must have been obtained from a previous call to "insert_check".
+   //!   No objects should have been inserted or erased from the avl_set between
+   //!   the "insert_check" that filled "commit_data" and the call to "insert_commit".
+   //! 
+   //! Effects: Inserts the value in the avl_set using the information obtained
+   //!   from the "commit_data" that a previous "insert_check" filled.
+   //!
+   //! Returns: An iterator to the newly inserted object.
+   //! 
+   //! Complexity: Constant time.
+   //!
+   //! Throws: Nothing.
+   //! 
+   //! Notes: This function has only sense if a "insert_check" has been
+   //!   previously executed to fill "commit_data". No value should be inserted or
+   //!   erased between the "insert_check" and "insert_commit" calls.
+   iterator insert_commit(reference value, const insert_commit_data &commit_data)
+   {  return tree_.insert_unique_commit(value, commit_data); }
+
+   //! Requires: Dereferencing iterator must yield an lvalue 
+   //!   of type value_type.
+   //! 
+   //! Effects: Inserts a range into the avl_set.
+   //! 
+   //! Complexity: Insert range is in general O(N * log(N)), where N is the
+   //!   size of the range. However, it is linear in N if the range is already sorted
+   //!   by value_comp().
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Basic guarantee.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   template
+   void insert(Iterator b, Iterator e)
+   {  tree_.insert_unique(b, e);  }
+
+   //! Requires: value must be an lvalue, "pos" must be
+   //!   a valid iterator (or end) and must be the succesor of value
+   //!   once inserted according to the predicate. "value" must not be equal to any
+   //!   inserted key according to the predicate.
+   //!
+   //! Effects: Inserts x into the tree before "pos".
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function does not check preconditions so if "pos" is not
+   //! the successor of "value" or "value" is not unique tree ordering and uniqueness
+   //! invariants will be broken respectively.
+   //! This is a low-level function to be used only for performance reasons
+   //! by advanced users.
+   iterator insert_before(const_iterator pos, reference value)
+   {  return tree_.insert_before(pos, value);  }
+
+   //! Requires: value must be an lvalue, and it must be greater than
+   //!   any inserted key according to the predicate.
+   //!
+   //! Effects: Inserts x into the tree in the last position.
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function does not check preconditions so if value is
+   //!   less than or equal to the greatest inserted key tree ordering invariant will be broken.
+   //!   This function is slightly more efficient than using "insert_before".
+   //!   This is a low-level function to be used only for performance reasons
+   //!   by advanced users.
+   void push_back(reference value)
+   {  tree_.push_back(value);  }
+
+   //! Requires: value must be an lvalue, and it must be less
+   //!   than any inserted key according to the predicate.
+   //!
+   //! Effects: Inserts x into the tree in the first position.
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function does not check preconditions so if value is
+   //!   greater than or equal to the the mimum inserted key tree ordering or uniqueness
+   //!   invariants will be broken.
+   //!   This function is slightly more efficient than using "insert_before".
+   //!   This is a low-level function to be used only for performance reasons
+   //!   by advanced users.
+   void push_front(reference value)
+   {  tree_.push_front(value);  }
+
+   //! Effects: Erases the element pointed to by pos. 
+   //! 
+   //! Complexity: Average complexity is constant time.
+   //! 
+   //! Returns: An iterator to the element after the erased element.
+   //!
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   iterator erase(const_iterator i)
+   {  return tree_.erase(i);  }
+
+   //! Effects: Erases the range pointed to by b end e. 
+   //! 
+   //! Complexity: Average complexity for erase range is at most 
+   //!   O(log(size() + N)), where N is the number of elements in the range.
+   //! 
+   //! Returns: An iterator to the element after the erased elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   iterator erase(const_iterator b, const_iterator e)
+   {  return tree_.erase(b, e);  }
+
+   //! Effects: Erases all the elements with the given value.
+   //! 
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size()) + this->count(value)).
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Basic guarantee.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   size_type erase(const_reference value)
+   {  return tree_.erase(value);  }
+
+   //! Effects: Erases all the elements that compare equal with
+   //!   the given key and the given comparison functor.
+   //! 
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size() + this->count(key, comp)).
+   //! 
+   //! Throws: If the comp ordering function throws. Basic guarantee.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   template
+   size_type erase(const KeyType& key, KeyValueCompare comp
+                  /// @cond
+                  , typename detail::enable_if_c::value >::type * = 0
+                  /// @endcond
+                  )
+   {  return tree_.erase(key, comp);  }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Effects: Erases the element pointed to by pos. 
+   //!   Disposer::operator()(pointer) is called for the removed element.
+   //! 
+   //! Complexity: Average complexity for erase element is constant time. 
+   //! 
+   //! Returns: An iterator to the element after the erased element.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators 
+   //!    to the erased elements.
+   template
+   iterator erase_and_dispose(const_iterator i, Disposer disposer)
+   {  return tree_.erase_and_dispose(i, disposer);  }
+
+   #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+   template
+   iterator erase_and_dispose(iterator i, Disposer disposer)
+   {  return this->erase_and_dispose(const_iterator(i), disposer);   }
+   #endif
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Effects: Erases the range pointed to by b end e.
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //! 
+   //! Complexity: Average complexity for erase range is at most 
+   //!   O(log(size() + N)), where N is the number of elements in the range.
+   //! 
+   //! Returns: An iterator to the element after the erased elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators
+   //!    to the erased elements.
+   template
+   iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
+   {  return tree_.erase_and_dispose(b, e, disposer);  }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Effects: Erases all the elements with the given value.
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   //! 
+   //! Complexity: O(log(size() + this->count(value)). Basic guarantee.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   template
+   size_type erase_and_dispose(const_reference value, Disposer disposer)
+   {  return tree_.erase_and_dispose(value, disposer);  }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Effects: Erases all the elements with the given key.
+   //!   according to the comparison functor "comp".
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //!
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size() + this->count(key, comp)).
+   //! 
+   //! Throws: If comp ordering function throws. Basic guarantee.
+   //! 
+   //! Note: Invalidates the iterators
+   //!    to the erased elements.
+   template
+   size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+                  /// @cond
+                  , typename detail::enable_if_c::value >::type * = 0
+                  /// @endcond
+                  )
+   {  return tree_.erase_and_dispose(key, comp, disposer);  }
+
+   //! Effects: Erases all the elements of the container.
+   //! 
+   //! Complexity: Linear to the number of elements on the container.
+   //!   if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   void clear()
+   {  return tree_.clear();  }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //! 
+   //! Effects: Erases all the elements of the container.
+   //! 
+   //! Complexity: Linear to the number of elements on the container.
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   template
+   void clear_and_dispose(Disposer disposer)
+   {  return tree_.clear_and_dispose(disposer);  }
+
+   //! Effects: Returns the number of contained elements with the given key
+   //! 
+   //! Complexity: Logarithmic to the number of elements contained plus lineal
+   //!   to number of objects with the given key.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   size_type count(const_reference value) const
+   {  return tree_.find(value) != end();  }
+
+   //! Effects: Returns the number of contained elements with the same key
+   //!   compared with the given comparison functor.
+   //! 
+   //! Complexity: Logarithmic to the number of elements contained plus lineal
+   //!   to number of objects with the given key.
+   //! 
+   //! Throws: If comp ordering function throws.
+   template
+   size_type count(const KeyType& key, KeyValueCompare comp) const
+   {  return tree_.find(key, comp) != end();  }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is not less than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   iterator lower_bound(const_reference value)
+   {  return tree_.lower_bound(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Returns an iterator to the first element whose
+   //!   key according to the comparison functor is not less than k or 
+   //!   end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //! 
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   iterator lower_bound(const KeyType& key, KeyValueCompare comp)
+   {  return tree_.lower_bound(key, comp);  }
+
+   //! Effects: Returns a const iterator to the first element whose
+   //!   key is not less than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   const_iterator lower_bound(const_reference value) const
+   {  return tree_.lower_bound(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Returns a const_iterator to the first element whose
+   //!   key according to the comparison functor is not less than k or 
+   //!   end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //! 
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const
+   {  return tree_.lower_bound(key, comp);  }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is greater than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   iterator upper_bound(const_reference value)
+   {  return tree_.upper_bound(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Returns an iterator to the first element whose
+   //!   key according to the comparison functor is greater than key or 
+   //!   end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   iterator upper_bound(const KeyType& key, KeyValueCompare comp)
+   {  return tree_.upper_bound(key, comp);  }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is greater than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   const_iterator upper_bound(const_reference value) const
+   {  return tree_.upper_bound(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Returns a const_iterator to the first element whose
+   //!   key according to the comparison functor is greater than key or 
+   //!   end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const
+   {  return tree_.upper_bound(key, comp);  }
+
+   //! Effects: Finds an iterator to the first element whose value is 
+   //!   "value" or end() if that element does not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   iterator find(const_reference value)
+   {  return tree_.find(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Finds an iterator to the first element whose key is 
+   //!   "key" according to the comparison functor or end() if that element 
+   //!   does not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   iterator find(const KeyType& key, KeyValueCompare comp)
+   {  return tree_.find(key, comp);  }
+
+   //! Effects: Finds a const_iterator to the first element whose value is 
+   //!   "value" or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   const_iterator find(const_reference value) const
+   {  return tree_.find(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Finds a const_iterator to the first element whose key is 
+   //!   "key" according to the comparison functor or end() if that element 
+   //!   does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   const_iterator find(const KeyType& key, KeyValueCompare comp) const
+   {  return tree_.find(key, comp);  }
+
+   //! Effects: Finds a range containing all elements whose key is k or
+   //!   an empty range that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   std::pair equal_range(const_reference value)
+   {  return tree_.equal_range(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Finds a range containing all elements whose key is k 
+   //!   according to the comparison functor or an empty range 
+   //!   that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   std::pair equal_range(const KeyType& key, KeyValueCompare comp)
+   {  return tree_.equal_range(key, comp);  }
+
+   //! Effects: Finds a range containing all elements whose key is k or
+   //!   an empty range that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   std::pair
+      equal_range(const_reference value) const
+   {  return tree_.equal_range(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Finds a range containing all elements whose key is k 
+   //!   according to the comparison functor or an empty range 
+   //!   that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   std::pair
+      equal_range(const KeyType& key, KeyValueCompare comp) const
+   {  return tree_.equal_range(key, comp);  }
+
+   //! Requires: value must be an lvalue and shall be in a avl_set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid iterator i belonging to the avl_set
+   //!   that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This static function is available only if the value traits
+   //!   is stateless.
+   static iterator s_iterator_to(reference value)
+   {  return tree_type::s_iterator_to(value);  }
+
+   //! Requires: value must be an lvalue and shall be in a avl_set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid const_iterator i belonging to the
+   //!   avl_set that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This static function is available only if the value traits
+   //!   is stateless.
+   static const_iterator s_iterator_to(const_reference value)
+   {  return tree_type::s_iterator_to(value);  }
+
+   //! Requires: value must be an lvalue and shall be in a avl_set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid iterator i belonging to the avl_set
+   //!   that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   iterator iterator_to(reference value)
+   {  return tree_.iterator_to(value);  }
+
+   //! Requires: value must be an lvalue and shall be in a avl_set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid const_iterator i belonging to the
+   //!   avl_set that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator iterator_to(const_reference value) const
+   {  return tree_.iterator_to(value);  }
+
+   //! Requires: value shall not be in a avl_set/avl_multiset.
+   //! 
+   //! Effects: init_node puts the hook of a value in a well-known default
+   //!   state.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Note: This function puts the hook in the well-known default state
+   //!   used by auto_unlink and safe hooks.
+   static void init_node(reference value)
+   { tree_type::init_node(value);   }
+
+   //! Effects: Unlinks the leftmost node from the tree.
+   //! 
+   //! Complexity: Average complexity is constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Notes: This function breaks the tree and the tree can
+   //!   only be used for more unlink_leftmost_without_rebalance calls.
+   //!   This function is normally used to achieve a step by step
+   //!   controlled destruction of the tree.
+   pointer unlink_leftmost_without_rebalance()
+   {  return tree_.unlink_leftmost_without_rebalance();  }
+
+   //! Requires: replace_this must be a valid iterator of *this
+   //!   and with_this must not be inserted in any tree.
+   //! 
+   //! Effects: Replaces replace_this in its position in the
+   //!   tree with with_this. The tree does not need to be rebalanced.
+   //! 
+   //! Complexity: Constant. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function will break container ordering invariants if
+   //!   with_this is not equivalent to *replace_this according to the
+   //!   ordering rules. This function is faster than erasing and inserting
+   //!   the node, since no rebalancing or comparison is needed.
+   void replace_node(iterator replace_this, reference with_this)
+   {  tree_.replace_node(replace_this, with_this);   }
+
+   /// @cond
+   friend bool operator==(const avl_set_impl &x, const avl_set_impl &y)
+   {  return x.tree_ == y.tree_;  }
+
+   friend bool operator<(const avl_set_impl &x, const avl_set_impl &y)
+   {  return x.tree_ < y.tree_;  }
+   /// @endcond
+};
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator!=
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avl_set_impl &x, const avl_set_impl &y)
+#else
+(const avl_set_impl &x, const avl_set_impl &y)
+#endif
+{  return !(x == y); }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator>
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avl_set_impl &x, const avl_set_impl &y)
+#else
+(const avl_set_impl &x, const avl_set_impl &y)
+#endif
+{  return y < x;  }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator<=
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avl_set_impl &x, const avl_set_impl &y)
+#else
+(const avl_set_impl &x, const avl_set_impl &y)
+#endif
+{  return !(y < x);  }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator>=
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avl_set_impl &x, const avl_set_impl &y)
+#else
+(const avl_set_impl &x, const avl_set_impl &y)
+#endif
+{  return !(x < y);  }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline void swap
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(avl_set_impl &x, avl_set_impl &y)
+#else
+(avl_set_impl &x, avl_set_impl &y)
+#endif
+{  x.swap(y);  }
+
+//! Helper metafunction to define a \c avl_set that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+struct make_avl_set
+{
+   /// @cond
+   typedef avl_set_impl
+      < typename make_avltree_opt
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type
+      > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+class avl_set
+   :  public make_avl_set
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type
+{
+   typedef typename make_avl_set
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type   Base;
+
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_set)
+   public:
+   typedef typename Base::value_compare      value_compare;
+   typedef typename Base::value_traits       value_traits;
+   typedef typename Base::iterator           iterator;
+   typedef typename Base::const_iterator     const_iterator;
+
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same::value));
+
+   avl_set( const value_compare &cmp = value_compare()
+         , const value_traits &v_traits = value_traits())
+      :  Base(cmp, v_traits)
+   {}
+
+   template
+   avl_set( Iterator b, Iterator e
+      , const value_compare &cmp = value_compare()
+      , const value_traits &v_traits = value_traits())
+      :  Base(b, e, cmp, v_traits)
+   {}
+
+   avl_set(BOOST_RV_REF(avl_set) x)
+      :  Base(::boost::move(static_cast(x)))
+   {}
+
+   avl_set& operator=(BOOST_RV_REF(avl_set) x)
+   {  this->Base::operator=(::boost::move(static_cast(x))); return *this;  }
+
+   static avl_set &container_from_end_iterator(iterator end_iterator)
+   {  return static_cast(Base::container_from_end_iterator(end_iterator));   }
+
+   static const avl_set &container_from_end_iterator(const_iterator end_iterator)
+   {  return static_cast(Base::container_from_end_iterator(end_iterator));   }
+
+   static avl_set &container_from_iterator(iterator end_iterator)
+   {  return static_cast(Base::container_from_iterator(end_iterator));   }
+
+   static const avl_set &container_from_iterator(const_iterator end_iterator)
+   {  return static_cast(Base::container_from_iterator(end_iterator));   }
+};
+
+#endif
+
+//! The class template avl_multiset is an intrusive container, that mimics most of 
+//! the interface of std::avl_multiset as described in the C++ standard.
+//! 
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
+//!
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<>, \c size_type<> and
+//! \c compare<>.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+class avl_multiset_impl
+{
+   /// @cond
+   typedef avltree_impl tree_type;
+
+   //Movable
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset_impl)
+   typedef tree_type implementation_defined;
+   /// @endcond
+
+   public:
+   typedef typename implementation_defined::value_type               value_type;
+   typedef typename implementation_defined::value_traits             value_traits;
+   typedef typename implementation_defined::pointer                  pointer;
+   typedef typename implementation_defined::const_pointer            const_pointer;
+   typedef typename implementation_defined::reference                reference;
+   typedef typename implementation_defined::const_reference          const_reference;
+   typedef typename implementation_defined::difference_type          difference_type;
+   typedef typename implementation_defined::size_type                size_type;
+   typedef typename implementation_defined::value_compare            value_compare;
+   typedef typename implementation_defined::key_compare              key_compare;
+   typedef typename implementation_defined::iterator                 iterator;
+   typedef typename implementation_defined::const_iterator           const_iterator;
+   typedef typename implementation_defined::reverse_iterator         reverse_iterator;
+   typedef typename implementation_defined::const_reverse_iterator   const_reverse_iterator;
+   typedef typename implementation_defined::insert_commit_data       insert_commit_data;
+   typedef typename implementation_defined::node_traits              node_traits;
+   typedef typename implementation_defined::node                     node;
+   typedef typename implementation_defined::node_ptr                 node_ptr;
+   typedef typename implementation_defined::const_node_ptr           const_node_ptr;
+   typedef typename implementation_defined::node_algorithms          node_algorithms;
+
+   static const bool constant_time_size = Config::constant_time_size;
+
+   /// @cond
+   private:
+   tree_type tree_;
+   /// @endcond
+
+   public:
+   //! Effects: Constructs an empty avl_multiset. 
+   //!   
+   //! Complexity: Constant. 
+   //! 
+   //! Throws: If value_traits::node_traits::node
+   //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+   //!   or the copy constructor/operator() of the value_compare object throws. 
+   avl_multiset_impl( const value_compare &cmp = value_compare()
+                , const value_traits &v_traits = value_traits()) 
+      :  tree_(cmp, v_traits)
+   {}
+
+   //! Requires: Dereferencing iterator must yield an lvalue of type value_type. 
+   //!   cmp must be a comparison function that induces a strict weak ordering.
+   //! 
+   //! Effects: Constructs an empty avl_multiset and inserts elements from 
+   //!   [b, e).
+   //! 
+   //! Complexity: Linear in N if [b, e) is already sorted using
+   //!   comp and otherwise N * log N, where N is the distance between first and last
+   //! 
+   //! Throws: If value_traits::node_traits::node
+   //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+   //!   or the copy constructor/operator() of the value_compare object throws. 
+   template
+   avl_multiset_impl( Iterator b, Iterator e
+                , const value_compare &cmp = value_compare()
+                , const value_traits &v_traits = value_traits())
+      : tree_(false, b, e, cmp, v_traits)
+   {}
+
+   //! Effects: to-do
+   //!   
+   avl_multiset_impl(BOOST_RV_REF(avl_multiset_impl) x) 
+      :  tree_(::boost::move(x.tree_))
+   {}
+
+   //! Effects: to-do
+   //!   
+   avl_multiset_impl& operator=(BOOST_RV_REF(avl_multiset_impl) x) 
+   {  tree_ = ::boost::move(x.tree_);  return *this;  }
+
+   //! Effects: Detaches all elements from this. The objects in the avl_multiset 
+   //!   are not deleted (i.e. no destructors are called).
+   //! 
+   //! Complexity: Linear to the number of elements on the container.
+   //!   if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
+   //! 
+   //! Throws: Nothing.
+   ~avl_multiset_impl() 
+   {}
+
+   //! Effects: Returns an iterator pointing to the beginning of the avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   iterator begin()
+   { return tree_.begin();  }
+
+   //! Effects: Returns a const_iterator pointing to the beginning of the avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator begin() const
+   { return tree_.begin();  }
+
+   //! Effects: Returns a const_iterator pointing to the beginning of the avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator cbegin() const
+   { return tree_.cbegin();  }
+
+   //! Effects: Returns an iterator pointing to the end of the avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   iterator end()
+   { return tree_.end();  }
+
+   //! Effects: Returns a const_iterator pointing to the end of the avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator end() const
+   { return tree_.end();  }
+
+   //! Effects: Returns a const_iterator pointing to the end of the avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator cend() const
+   { return tree_.cend();  }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning of the
+   //!    reversed avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   reverse_iterator rbegin()
+   { return tree_.rbegin();  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning
+   //!    of the reversed avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator rbegin() const
+   { return tree_.rbegin();  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning
+   //!    of the reversed avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator crbegin() const
+   { return tree_.crbegin();  }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //!    of the reversed avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   reverse_iterator rend()
+   { return tree_.rend();  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //!    of the reversed avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator rend() const
+   { return tree_.rend();  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //!    of the reversed avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator crend() const
+   { return tree_.crend();  }
+
+   //! Precondition: end_iterator must be a valid end iterator
+   //!   of avl_multiset.
+   //! 
+   //! Effects: Returns a const reference to the avl_multiset associated to the end iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   static avl_multiset_impl &container_from_end_iterator(iterator end_iterator)
+   {
+      return *detail::parent_from_member
+         ( &tree_type::container_from_end_iterator(end_iterator)
+         , &avl_multiset_impl::tree_);
+   }
+
+   //! Precondition: end_iterator must be a valid end const_iterator
+   //!   of avl_multiset.
+   //! 
+   //! Effects: Returns a const reference to the avl_multiset associated to the end iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   static const avl_multiset_impl &container_from_end_iterator(const_iterator end_iterator)
+   {
+      return *detail::parent_from_member
+         ( &tree_type::container_from_end_iterator(end_iterator)
+         , &avl_multiset_impl::tree_);
+   }
+
+   //! Precondition: it must be a valid iterator of multiset.
+   //! 
+   //! Effects: Returns a const reference to the multiset associated to the iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Logarithmic.
+   static avl_multiset_impl &container_from_iterator(iterator it)
+   {
+      return *detail::parent_from_member
+         ( &tree_type::container_from_iterator(it)
+         , &avl_multiset_impl::tree_);
+   }
+
+   //! Precondition: it must be a valid const_iterator of multiset.
+   //! 
+   //! Effects: Returns a const reference to the multiset associated to the iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Logarithmic.
+   static const avl_multiset_impl &container_from_iterator(const_iterator it)
+   {
+      return *detail::parent_from_member
+         ( &tree_type::container_from_iterator(it)
+         , &avl_multiset_impl::tree_);
+   }
+
+   //! Effects: Returns the key_compare object used by the avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: If key_compare copy-constructor throws.
+   key_compare key_comp() const
+   { return tree_.value_comp(); }
+
+   //! Effects: Returns the value_compare object used by the avl_multiset.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: If value_compare copy-constructor throws.
+   value_compare value_comp() const
+   { return tree_.value_comp(); }
+
+   //! Effects: Returns true is the container is empty.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   bool empty() const
+   { return tree_.empty(); }
+
+   //! Effects: Returns the number of elements stored in the avl_multiset.
+   //! 
+   //! Complexity: Linear to elements contained in *this if,
+   //!   constant-time size option is enabled. Constant-time otherwise.
+   //! 
+   //! Throws: Nothing.
+   size_type size() const
+   { return tree_.size(); }
+
+   //! Effects: Swaps the contents of two avl_multisets.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: If the swap() call for the comparison functor
+   //!   found using ADL throws. Strong guarantee.
+   void swap(avl_multiset_impl& other)
+   { tree_.swap(other.tree_); }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!   Cloner should yield to nodes equivalent to the original nodes.
+   //!
+   //! Effects: Erases all the elements from *this
+   //!   calling Disposer::operator()(pointer), clones all the 
+   //!   elements from src calling Cloner::operator()(const_reference )
+   //!   and inserts them on *this. Copies the predicate from the source container.
+   //!
+   //!   If cloner throws, all cloned elements are unlinked and disposed
+   //!   calling Disposer::operator()(pointer).
+   //!   
+   //! Complexity: Linear to erased plus inserted elements.
+   //! 
+   //! Throws: If cloner throws or predicate copy assignment throws. Basic guarantee.
+   template 
+   void clone_from(const avl_multiset_impl &src, Cloner cloner, Disposer disposer)
+   {  tree_.clone_from(src.tree_, cloner, disposer);  }
+
+   //! Requires: value must be an lvalue
+   //! 
+   //! Effects: Inserts value into the avl_multiset.
+   //! 
+   //! Returns: An iterator that points to the position where the new
+   //!   element was inserted.
+   //! 
+   //! Complexity: Average complexity for insert element is at
+   //!   most logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Strong guarantee.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   iterator insert(reference value)
+   {  return tree_.insert_equal(value);  }
+
+   //! Requires: value must be an lvalue
+   //! 
+   //! Effects: Inserts x into the avl_multiset, using pos as a hint to
+   //!   where it will be inserted.
+   //! 
+   //! Returns: An iterator that points to the position where the new
+   //!   element was inserted.
+   //! 
+   //! Complexity: Logarithmic in general, but it is amortized
+   //!   constant time if t is inserted immediately before hint.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Strong guarantee.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   iterator insert(const_iterator hint, reference value)
+   {  return tree_.insert_equal(hint, value);  }
+
+   //! Requires: Dereferencing iterator must yield an lvalue 
+   //!   of type value_type.
+   //! 
+   //! Effects: Inserts a range into the avl_multiset.
+   //! 
+   //! Returns: An iterator that points to the position where the new
+   //!   element was inserted.
+   //! 
+   //! Complexity: Insert range is in general O(N * log(N)), where N is the
+   //!   size of the range. However, it is linear in N if the range is already sorted
+   //!   by value_comp().
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Basic guarantee.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   template
+   void insert(Iterator b, Iterator e)
+   {  tree_.insert_equal(b, e);  }
+
+   //! Requires: value must be an lvalue, "pos" must be
+   //!   a valid iterator (or end) and must be the succesor of value
+   //!   once inserted according to the predicate. "value" must not be equal to any
+   //!   inserted key according to the predicate.
+   //!
+   //! Effects: Inserts x into the tree before "pos".
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function does not check preconditions so if "pos" is not
+   //! the successor of "value" or "value" is not unique tree ordering and uniqueness
+   //! invariants will be broken respectively.
+   //! This is a low-level function to be used only for performance reasons
+   //! by advanced users.
+   iterator insert_before(const_iterator pos, reference value)
+   {  return tree_.insert_before(pos, value);  }
+
+   //! Requires: value must be an lvalue, and it must be greater than
+   //!   any inserted key according to the predicate.
+   //!
+   //! Effects: Inserts x into the tree in the last position.
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function does not check preconditions so if value is
+   //!   less than or equal to the greatest inserted key tree ordering invariant will be broken.
+   //!   This function is slightly more efficient than using "insert_before".
+   //!   This is a low-level function to be used only for performance reasons
+   //!   by advanced users.
+   void push_back(reference value)
+   {  tree_.push_back(value);  }
+
+   //! Requires: value must be an lvalue, and it must be less
+   //!   than any inserted key according to the predicate.
+   //!
+   //! Effects: Inserts x into the tree in the first position.
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function does not check preconditions so if value is
+   //!   greater than or equal to the the mimum inserted key tree ordering or uniqueness
+   //!   invariants will be broken.
+   //!   This function is slightly more efficient than using "insert_before".
+   //!   This is a low-level function to be used only for performance reasons
+   //!   by advanced users.
+   void push_front(reference value)
+   {  tree_.push_front(value);  }
+
+   //! Effects: Erases the element pointed to by pos. 
+   //! 
+   //! Complexity: Average complexity is constant time.
+   //! 
+   //! Returns: An iterator to the element after the erased element.
+   //!
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   iterator erase(const_iterator i)
+   {  return tree_.erase(i);  }
+
+   //! Effects: Erases the range pointed to by b end e. 
+   //!
+   //! Returns: An iterator to the element after the erased elements.
+   //! 
+   //! Complexity: Average complexity for erase range is at most 
+   //!   O(log(size() + N)), where N is the number of elements in the range.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   iterator erase(const_iterator b, const_iterator e)
+   {  return tree_.erase(b, e);  }
+
+   //! Effects: Erases all the elements with the given value.
+   //! 
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size() + this->count(value)).
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Basic guarantee.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   size_type erase(const_reference value)
+   {  return tree_.erase(value);  }
+
+   //! Effects: Erases all the elements that compare equal with
+   //!   the given key and the given comparison functor.
+   //! 
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size() + this->count(key, comp)).
+   //! 
+   //! Throws: If comp ordering function throws. Basic guarantee.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   template
+   size_type erase(const KeyType& key, KeyValueCompare comp
+                  /// @cond
+                  , typename detail::enable_if_c::value >::type * = 0
+                  /// @endcond
+                  )
+   {  return tree_.erase(key, comp);  }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Returns: An iterator to the element after the erased element.
+   //!
+   //! Effects: Erases the element pointed to by pos. 
+   //!   Disposer::operator()(pointer) is called for the removed element.
+   //! 
+   //! Complexity: Average complexity for erase element is constant time. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators 
+   //!    to the erased elements.
+   template
+   iterator erase_and_dispose(const_iterator i, Disposer disposer)
+   {  return tree_.erase_and_dispose(i, disposer);  }
+
+   #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+   template
+   iterator erase_and_dispose(iterator i, Disposer disposer)
+   {  return this->erase_and_dispose(const_iterator(i), disposer);   }
+   #endif
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Returns: An iterator to the element after the erased elements.
+   //!
+   //! Effects: Erases the range pointed to by b end e.
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //! 
+   //! Complexity: Average complexity for erase range is at most 
+   //!   O(log(size() + N)), where N is the number of elements in the range.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators
+   //!    to the erased elements.
+   template
+   iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
+   {  return tree_.erase_and_dispose(b, e, disposer);  }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Effects: Erases all the elements with the given value.
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //! 
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size() + this->count(value)).
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Basic guarantee.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   template
+   size_type erase_and_dispose(const_reference value, Disposer disposer)
+   {  return tree_.erase_and_dispose(value, disposer);  }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Effects: Erases all the elements with the given key.
+   //!   according to the comparison functor "comp".
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //!
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size() + this->count(key, comp)).
+   //! 
+   //! Throws: If comp ordering function throws. Basic guarantee.
+   //! 
+   //! Note: Invalidates the iterators
+   //!    to the erased elements.
+   template
+   size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+                  /// @cond
+                  , typename detail::enable_if_c::value >::type * = 0
+                  /// @endcond
+                  )
+   {  return tree_.erase_and_dispose(key, comp, disposer);  }
+
+   //! Effects: Erases all the elements of the container.
+   //! 
+   //! Complexity: Linear to the number of elements on the container.
+   //!   if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   void clear()
+   {  return tree_.clear();  }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //! 
+   //! Effects: Erases all the elements of the container.
+   //! 
+   //! Complexity: Linear to the number of elements on the container.
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   template
+   void clear_and_dispose(Disposer disposer)
+   {  return tree_.clear_and_dispose(disposer);  }
+
+   //! Effects: Returns the number of contained elements with the given key
+   //! 
+   //! Complexity: Logarithmic to the number of elements contained plus lineal
+   //!   to number of objects with the given key.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   size_type count(const_reference value) const
+   {  return tree_.count(value);  }
+
+   //! Effects: Returns the number of contained elements with the same key
+   //!   compared with the given comparison functor.
+   //! 
+   //! Complexity: Logarithmic to the number of elements contained plus lineal
+   //!   to number of objects with the given key.
+   //! 
+   //! Throws: If comp ordering function throws.
+   template
+   size_type count(const KeyType& key, KeyValueCompare comp) const
+   {  return tree_.count(key, comp);  }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is not less than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   iterator lower_bound(const_reference value)
+   {  return tree_.lower_bound(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Returns an iterator to the first element whose
+   //!   key according to the comparison functor is not less than k or 
+   //!   end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //! 
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   iterator lower_bound(const KeyType& key, KeyValueCompare comp)
+   {  return tree_.lower_bound(key, comp);  }
+
+   //! Effects: Returns a const iterator to the first element whose
+   //!   key is not less than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   const_iterator lower_bound(const_reference value) const
+   {  return tree_.lower_bound(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Returns a const_iterator to the first element whose
+   //!   key according to the comparison functor is not less than k or 
+   //!   end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //! 
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const
+   {  return tree_.lower_bound(key, comp);  }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is greater than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   iterator upper_bound(const_reference value)
+   {  return tree_.upper_bound(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Returns an iterator to the first element whose
+   //!   key according to the comparison functor is greater than key or 
+   //!   end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   iterator upper_bound(const KeyType& key, KeyValueCompare comp)
+   {  return tree_.upper_bound(key, comp);  }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is greater than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   const_iterator upper_bound(const_reference value) const
+   {  return tree_.upper_bound(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Returns a const_iterator to the first element whose
+   //!   key according to the comparison functor is greater than key or 
+   //!   end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const
+   {  return tree_.upper_bound(key, comp);  }
+
+   //! Effects: Finds an iterator to the first element whose value is 
+   //!   "value" or end() if that element does not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   iterator find(const_reference value)
+   {  return tree_.find(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Finds an iterator to the first element whose key is 
+   //!   "key" according to the comparison functor or end() if that element 
+   //!   does not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   iterator find(const KeyType& key, KeyValueCompare comp)
+   {  return tree_.find(key, comp);  }
+
+   //! Effects: Finds a const_iterator to the first element whose value is 
+   //!   "value" or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   const_iterator find(const_reference value) const
+   {  return tree_.find(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Finds a const_iterator to the first element whose key is 
+   //!   "key" according to the comparison functor or end() if that element 
+   //!   does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   const_iterator find(const KeyType& key, KeyValueCompare comp) const
+   {  return tree_.find(key, comp);  }
+
+   //! Effects: Finds a range containing all elements whose key is k or
+   //!   an empty range that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   std::pair equal_range(const_reference value)
+   {  return tree_.equal_range(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Finds a range containing all elements whose key is k 
+   //!   according to the comparison functor or an empty range 
+   //!   that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   std::pair equal_range(const KeyType& key, KeyValueCompare comp)
+   {  return tree_.equal_range(key, comp);  }
+
+   //! Effects: Finds a range containing all elements whose key is k or
+   //!   an empty range that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws.
+   std::pair
+      equal_range(const_reference value) const
+   {  return tree_.equal_range(value);  }
+
+   //! Requires: comp must imply the same element order as
+   //!   value_compare. Usually key is the part of the value_type
+   //!   that is used in the ordering functor.
+   //!
+   //! Effects: Finds a range containing all elements whose key is k 
+   //!   according to the comparison functor or an empty range 
+   //!   that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If comp ordering function throws.
+   //!
+   //! Note: This function is used when constructing a value_type
+   //!   is expensive and the value_type can be compared with a cheaper
+   //!   key type. Usually this key is part of the value_type.
+   template
+   std::pair
+      equal_range(const KeyType& key, KeyValueCompare comp) const
+   {  return tree_.equal_range(key, comp);  }
+
+   //! Requires: value must be an lvalue and shall be in a avl_multiset of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid iterator i belonging to the avl_multiset
+   //!   that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This static function is available only if the value traits
+   //!   is stateless.
+   static iterator s_iterator_to(reference value)
+   {  return tree_type::s_iterator_to(value);  }
+
+   //! Requires: value must be an lvalue and shall be in a avl_multiset of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid const_iterator i belonging to the
+   //!   avl_multiset that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This static function is available only if the value traits
+   //!   is stateless.
+   static const_iterator s_iterator_to(const_reference value)
+   {  return tree_type::s_iterator_to(value);  }
+
+   //! Requires: value must be an lvalue and shall be in a avl_multiset of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid iterator i belonging to the avl_multiset
+   //!   that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   iterator iterator_to(reference value)
+   {  return tree_.iterator_to(value);  }
+
+   //! Requires: value must be an lvalue and shall be in a avl_multiset of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid const_iterator i belonging to the
+   //!   avl_multiset that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator iterator_to(const_reference value) const
+   {  return tree_.iterator_to(value);  }
+
+   //! Requires: value shall not be in a avl_multiset/avl_multiset.
+   //! 
+   //! Effects: init_node puts the hook of a value in a well-known default
+   //!   state.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Note: This function puts the hook in the well-known default state
+   //!   used by auto_unlink and safe hooks.
+   static void init_node(reference value)
+   { tree_type::init_node(value);   }
+
+   //! Effects: Unlinks the leftmost node from the tree.
+   //! 
+   //! Complexity: Average complexity is constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Notes: This function breaks the tree and the tree can
+   //!   only be used for more unlink_leftmost_without_rebalance calls.
+   //!   This function is normally used to achieve a step by step
+   //!   controlled destruction of the tree.
+   pointer unlink_leftmost_without_rebalance()
+   {  return tree_.unlink_leftmost_without_rebalance();  }
+
+   //! Requires: replace_this must be a valid iterator of *this
+   //!   and with_this must not be inserted in any tree.
+   //! 
+   //! Effects: Replaces replace_this in its position in the
+   //!   tree with with_this. The tree does not need to be rebalanced.
+   //! 
+   //! Complexity: Constant. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function will break container ordering invariants if
+   //!   with_this is not equivalent to *replace_this according to the
+   //!   ordering rules. This function is faster than erasing and inserting
+   //!   the node, since no rebalancing or comparison is needed.
+   void replace_node(iterator replace_this, reference with_this)
+   {  tree_.replace_node(replace_this, with_this);   }
+
+   /// @cond
+   friend bool operator==(const avl_multiset_impl &x, const avl_multiset_impl &y)
+   {  return x.tree_ == y.tree_;  }
+
+   friend bool operator<(const avl_multiset_impl &x, const avl_multiset_impl &y)
+   {  return x.tree_ < y.tree_;  }
+   /// @endcond
+};
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator!=
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avl_multiset_impl &x, const avl_multiset_impl &y)
+#else
+(const avl_multiset_impl &x, const avl_multiset_impl &y)
+#endif
+{  return !(x == y); }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator>
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avl_multiset_impl &x, const avl_multiset_impl &y)
+#else
+(const avl_multiset_impl &x, const avl_multiset_impl &y)
+#endif
+{  return y < x;  }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator<=
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avl_multiset_impl &x, const avl_multiset_impl &y)
+#else
+(const avl_multiset_impl &x, const avl_multiset_impl &y)
+#endif
+{  return !(y < x);  }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator>=
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avl_multiset_impl &x, const avl_multiset_impl &y)
+#else
+(const avl_multiset_impl &x, const avl_multiset_impl &y)
+#endif
+{  return !(x < y);  }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline void swap
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(avl_multiset_impl &x, avl_multiset_impl &y)
+#else
+(avl_multiset_impl &x, avl_multiset_impl &y)
+#endif
+{  x.swap(y);  }
+
+//! Helper metafunction to define a \c avl_multiset that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+struct make_avl_multiset
+{
+   /// @cond
+   typedef avl_multiset_impl
+      < typename make_avltree_opt
+         #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+         
+         #else
+         
+         #endif
+         ::type
+      > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+class avl_multiset
+   :  public make_avl_multiset::type
+{
+   typedef typename make_avl_multiset
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type   Base;
+
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(avl_multiset)
+   public:
+   typedef typename Base::value_compare      value_compare;
+   typedef typename Base::value_traits       value_traits;
+   typedef typename Base::iterator           iterator;
+   typedef typename Base::const_iterator     const_iterator;
+
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same::value));
+
+   avl_multiset( const value_compare &cmp = value_compare()
+           , const value_traits &v_traits = value_traits())
+      :  Base(cmp, v_traits)
+   {}
+
+   template
+   avl_multiset( Iterator b, Iterator e
+           , const value_compare &cmp = value_compare()
+           , const value_traits &v_traits = value_traits())
+      :  Base(b, e, cmp, v_traits)
+   {}
+
+   avl_multiset(BOOST_RV_REF(avl_multiset) x)
+      :  Base(::boost::move(static_cast(x)))
+   {}
+
+   avl_multiset& operator=(BOOST_RV_REF(avl_multiset) x)
+   {  this->Base::operator=(::boost::move(static_cast(x))); return *this;  }
+
+   static avl_multiset &container_from_end_iterator(iterator end_iterator)
+   {  return static_cast(Base::container_from_end_iterator(end_iterator));   }
+
+   static const avl_multiset &container_from_end_iterator(const_iterator end_iterator)
+   {  return static_cast(Base::container_from_end_iterator(end_iterator));   }
+
+   static avl_multiset &container_from_iterator(iterator end_iterator)
+   {  return static_cast(Base::container_from_iterator(end_iterator));   }
+
+   static const avl_multiset &container_from_iterator(const_iterator end_iterator)
+   {  return static_cast(Base::container_from_iterator(end_iterator));   }
+};
+
+#endif
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_AVL_SET_HPP
diff --git a/src/third_party/boost/boost/intrusive/avl_set_hook.hpp b/src/third_party/boost/boost/intrusive/avl_set_hook.hpp
new file mode 100644
index 00000000000..23b1f0bd8f2
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/avl_set_hook.hpp
@@ -0,0 +1,297 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_AVL_SET_HOOK_HPP
+#define BOOST_INTRUSIVE_AVL_SET_HOOK_HPP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+
+/// @cond
+template
+struct get_avl_set_node_algo
+{
+   typedef avltree_algorithms > type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c avl_set_base_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+struct make_avl_set_base_hook
+{
+   /// @cond
+   typedef typename pack_options
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type packed_options;
+
+   typedef detail::generic_hook
+   < get_avl_set_node_algo
+   , typename packed_options::tag
+   , packed_options::link_mode
+   , detail::AvlSetBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+//! Derive a class from avl_set_base_hook in order to store objects in 
+//! in an avl_set/avl_multiset. avl_set_base_hook holds the data necessary to maintain 
+//! the avl_set/avl_multiset and provides an appropriate value_traits class for avl_set/avl_multiset.
+//! 
+//! The hook admits the following options: \c tag<>, \c void_pointer<>,
+//! \c link_mode<> and \c optimize_size<>.
+//!
+//! \c tag<> defines a tag to identify the node. 
+//! The same tag value can be used in different classes, but if a class is 
+//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its 
+//! unique tag.
+//!
+//! \c void_pointer<> is the pointer type that will be used internally in the hook
+//! and the the container configured to use this hook.
+//!
+//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
+//! \c auto_unlink or \c safe_link).
+//!
+//! \c optimize_size<> will tell the hook to optimize the hook for size instead
+//! of speed.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+class avl_set_base_hook
+   :  public make_avl_set_base_hook
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type
+{
+   #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+   public:
+   //! Effects: If link_mode is \c auto_unlink or \c safe_link
+   //!   initializes the node to an unlinked state.
+   //! 
+   //! Throws: Nothing. 
+   avl_set_base_hook();
+
+   //! Effects: If link_mode is \c auto_unlink or \c safe_link
+   //!   initializes the node to an unlinked state. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing a copy-constructor
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   avl_set_base_hook(const avl_set_base_hook& );
+
+   //! Effects: Empty function. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing an assignment operator 
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   avl_set_base_hook& operator=(const avl_set_base_hook& );
+
+   //! Effects: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in a set an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
+   //! 
+   //! Throws: Nothing. 
+   ~avl_set_base_hook();
+
+   //! Effects: Swapping two nodes swaps the position of the elements 
+   //!   related to those nodes in one or two containers. That is, if the node 
+   //!   this is part of the element e1, the node x is part of the element e2 
+   //!   and both elements are included in the containers s1 and s2, then after 
+   //!   the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 
+   //!   at the position of e1. If one element is not in a container, then 
+   //!   after the swap-operation the other element is not in a container. 
+   //!   Iterators to e1 and e2 related to those nodes are invalidated. 
+   //!
+   //! Complexity: Constant 
+   //!
+   //! Throws: Nothing. 
+   void swap_nodes(avl_set_base_hook &other);
+
+   //! Precondition: link_mode must be \c safe_link or \c auto_unlink.
+   //!
+   //! Returns: true, if the node belongs to a container, false
+   //!   otherwise. This function can be used to test whether \c set::iterator_to 
+   //!   will return a valid iterator. 
+   //!
+   //! Complexity: Constant 
+   bool is_linked() const;
+
+   //! Effects: Removes the node if it's inserted in a container.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
+   //! 
+   //! Throws: Nothing. 
+   void unlink();
+   #endif
+};
+
+//! Helper metafunction to define a \c avl_set_member_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+struct make_avl_set_member_hook
+{
+   /// @cond
+   typedef typename pack_options
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type packed_options;
+
+   typedef detail::generic_hook
+   < get_avl_set_node_algo
+   , member_tag
+   , packed_options::link_mode
+   , detail::NoBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+//! Put a public data member avl_set_member_hook in order to store objects of this class in
+//! an avl_set/avl_multiset. avl_set_member_hook holds the data necessary for maintaining the
+//! avl_set/avl_multiset and provides an appropriate value_traits class for avl_set/avl_multiset.
+//! 
+//! The hook admits the following options: \c void_pointer<>,
+//! \c link_mode<> and \c optimize_size<>.
+//!
+//! \c void_pointer<> is the pointer type that will be used internally in the hook
+//! and the the container configured to use this hook.
+//!
+//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
+//! \c auto_unlink or \c safe_link).
+//!
+//! \c optimize_size<> will tell the hook to optimize the hook for size instead
+//! of speed.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+class avl_set_member_hook
+   :  public make_avl_set_member_hook
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type
+{
+   #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+   public:
+   //! Effects: If link_mode is \c auto_unlink or \c safe_link
+   //!   initializes the node to an unlinked state.
+   //! 
+   //! Throws: Nothing. 
+   avl_set_member_hook();
+
+   //! Effects: If link_mode is \c auto_unlink or \c safe_link
+   //!   initializes the node to an unlinked state. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing a copy-constructor
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   avl_set_member_hook(const avl_set_member_hook& );
+
+   //! Effects: Empty function. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing an assignment operator 
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   avl_set_member_hook& operator=(const avl_set_member_hook& );
+
+   //! Effects: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in a set an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
+   //! 
+   //! Throws: Nothing. 
+   ~avl_set_member_hook();
+
+   //! Effects: Swapping two nodes swaps the position of the elements 
+   //!   related to those nodes in one or two containers. That is, if the node 
+   //!   this is part of the element e1, the node x is part of the element e2 
+   //!   and both elements are included in the containers s1 and s2, then after 
+   //!   the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 
+   //!   at the position of e1. If one element is not in a container, then 
+   //!   after the swap-operation the other element is not in a container. 
+   //!   Iterators to e1 and e2 related to those nodes are invalidated. 
+   //!
+   //! Complexity: Constant 
+   //!
+   //! Throws: Nothing. 
+   void swap_nodes(avl_set_member_hook &other);
+
+   //! Precondition: link_mode must be \c safe_link or \c auto_unlink.
+   //!
+   //! Returns: true, if the node belongs to a container, false
+   //!   otherwise. This function can be used to test whether \c set::iterator_to 
+   //!   will return a valid iterator. 
+   //!
+   //! Complexity: Constant 
+   bool is_linked() const;
+
+   //! Effects: Removes the node if it's inserted in a container.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
+   //! 
+   //! Throws: Nothing. 
+   void unlink();
+   #endif
+};
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_AVL_SET_HOOK_HPP
diff --git a/src/third_party/boost/boost/intrusive/avltree.hpp b/src/third_party/boost/boost/intrusive/avltree.hpp
new file mode 100644
index 00000000000..20903ddef77
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/avltree.hpp
@@ -0,0 +1,1688 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_INTRUSIVE_AVLTREE_HPP
+#define BOOST_INTRUSIVE_AVLTREE_HPP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+
+/// @cond
+
+template 
+struct avl_setopt
+{
+   typedef ValueTraits  value_traits;
+   typedef Compare      compare;
+   typedef SizeType     size_type;
+   static const bool constant_time_size = ConstantTimeSize;
+};
+
+template 
+struct avl_set_defaults
+   :  pack_options
+      < none
+      , base_hook
+      , constant_time_size
+      , size_type
+      , compare >
+      >::type
+{};
+
+/// @endcond
+
+//! The class template avltree is an intrusive AVL tree container, that
+//! is used to construct intrusive avl_set and avl_multiset containers.
+//! The no-throw guarantee holds only, if the value_compare object 
+//! doesn't throw.
+//!
+//! The template parameter \c T is the type to be managed by the container.
+//! The user can specify additional options and if no options are provided
+//! default options are used.
+//!
+//! The container supports the following options:
+//! \c base_hook<>/member_hook<>/value_traits<>,
+//! \c constant_time_size<>, \c size_type<> and
+//! \c compare<>.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+class avltree_impl
+   :  private detail::clear_on_destructor_base >
+{
+   template friend class detail::clear_on_destructor_base;
+   public:
+   typedef typename Config::value_traits                             value_traits;
+   /// @cond
+   static const bool external_value_traits =
+      detail::external_value_traits_is_true::value;
+   typedef typename detail::eval_if_c
+      < external_value_traits
+      , detail::eval_value_traits
+      , detail::identity
+      >::type                                                        real_value_traits;
+   /// @endcond
+   typedef typename real_value_traits::pointer                       pointer;
+   typedef typename real_value_traits::const_pointer                 const_pointer;
+   typedef typename boost::intrusive::
+      pointer_traits::element_type                          value_type;
+   typedef value_type                                                key_type;
+   typedef typename boost::intrusive::
+      pointer_traits::reference                             reference;
+   typedef typename boost::intrusive::
+      pointer_traits::reference                       const_reference;
+   typedef typename boost::intrusive::
+      pointer_traits::difference_type                       difference_type;
+   typedef typename Config::size_type                                size_type;
+   typedef typename Config::compare                                  value_compare;
+   typedef value_compare                                             key_compare;
+   typedef tree_iterator                        iterator;
+   typedef tree_iterator                         const_iterator;
+   typedef boost::intrusive::detail::reverse_iterator      reverse_iterator;
+   typedef boost::intrusive::detail::reverse_iteratorconst_reverse_iterator;
+   typedef typename real_value_traits::node_traits                   node_traits;
+   typedef typename node_traits::node                                node;
+   typedef typename pointer_traits
+      ::template rebind_pointer
+         ::type                                                node_ptr;
+   typedef typename pointer_traits
+      ::template rebind_pointer
+         ::type                                          const_node_ptr;
+   typedef avltree_algorithms                           node_algorithms;
+
+   static const bool constant_time_size = Config::constant_time_size;
+   static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value;
+
+   /// @cond
+   private:
+   typedef detail::size_holder        size_traits;
+
+   //noncopyable, movable
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(avltree_impl)
+
+   enum { safemode_or_autounlink  = 
+            (int)real_value_traits::link_mode == (int)auto_unlink   ||
+            (int)real_value_traits::link_mode == (int)safe_link     };
+
+   //Constant-time size is incompatible with auto-unlink hooks!
+   BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
+
+   struct header_plus_size : public size_traits
+   {  node header_;  };
+
+   struct node_plus_pred_t : public detail::ebo_functor_holder
+   {
+      node_plus_pred_t(const value_compare &comp)
+         :  detail::ebo_functor_holder(comp)
+      {}
+      header_plus_size header_plus_size_;
+   };
+
+   struct data_t : public avltree_impl::value_traits
+   {
+      typedef typename avltree_impl::value_traits value_traits;
+      data_t(const value_compare & comp, const value_traits &val_traits)
+         :  value_traits(val_traits), node_plus_pred_(comp)
+      {}
+      node_plus_pred_t node_plus_pred_;
+   } data_;
+  
+   const value_compare &priv_comp() const
+   {  return data_.node_plus_pred_.get();  }
+
+   value_compare &priv_comp()
+   {  return data_.node_plus_pred_.get();  }
+
+   const value_traits &priv_value_traits() const
+   {  return data_;  }
+
+   value_traits &priv_value_traits()
+   {  return data_;  }
+
+   node_ptr priv_header_ptr()
+   {  return pointer_traits::pointer_to(data_.node_plus_pred_.header_plus_size_.header_);  }
+
+   const_node_ptr priv_header_ptr() const
+   {  return pointer_traits::pointer_to(data_.node_plus_pred_.header_plus_size_.header_);  }
+
+   static node_ptr uncast(const const_node_ptr & ptr)
+   {  return pointer_traits::const_cast_from(ptr);  }
+
+   size_traits &priv_size_traits()
+   {  return data_.node_plus_pred_.header_plus_size_;  }
+
+   const size_traits &priv_size_traits() const
+   {  return data_.node_plus_pred_.header_plus_size_;  }
+
+   const real_value_traits &get_real_value_traits(detail::bool_) const
+   {  return data_;  }
+
+   const real_value_traits &get_real_value_traits(detail::bool_) const
+   {  return data_.get_value_traits(*this);  }
+
+   real_value_traits &get_real_value_traits(detail::bool_)
+   {  return data_;  }
+
+   real_value_traits &get_real_value_traits(detail::bool_)
+   {  return data_.get_value_traits(*this);  }
+
+   /// @endcond
+
+   public:
+
+   const real_value_traits &get_real_value_traits() const
+   {  return this->get_real_value_traits(detail::bool_());  }
+
+   real_value_traits &get_real_value_traits()
+   {  return this->get_real_value_traits(detail::bool_());  }
+
+   typedef typename node_algorithms::insert_commit_data insert_commit_data;
+
+   //! Effects: Constructs an empty tree. 
+   //!   
+   //! Complexity: Constant. 
+   //! 
+   //! Throws: If value_traits::node_traits::node
+   //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+   //!   or the copy constructor of the value_compare object throws. Basic guarantee.
+   avltree_impl( const value_compare &cmp = value_compare()
+               , const value_traits &v_traits = value_traits()) 
+      :  data_(cmp, v_traits)
+   {  
+      node_algorithms::init_header(this->priv_header_ptr());  
+      this->priv_size_traits().set_size(size_type(0));
+   }
+
+   //! Requires: Dereferencing iterator must yield an lvalue of type value_type.
+   //!   cmp must be a comparison function that induces a strict weak ordering.
+   //!
+   //! Effects: Constructs an empty tree and inserts elements from
+   //!   [b, e).
+   //!
+   //! Complexity: Linear in N if [b, e) is already sorted using
+   //!   comp and otherwise N * log N, where N is the distance between first and last.
+   //! 
+   //! Throws: If value_traits::node_traits::node
+   //!   constructor throws (this does not happen with predefined Boost.Intrusive hooks)
+   //!   or the copy constructor/operator() of the value_compare object throws. Basic guarantee.
+   template
+   avltree_impl( bool unique, Iterator b, Iterator e
+              , const value_compare &cmp     = value_compare()
+              , const value_traits &v_traits = value_traits())
+      : data_(cmp, v_traits)
+   {
+      node_algorithms::init_header(this->priv_header_ptr());
+      this->priv_size_traits().set_size(size_type(0));
+      if(unique)
+         this->insert_unique(b, e);
+      else
+         this->insert_equal(b, e);
+   }
+
+   //! Effects: to-do
+   //!   
+   avltree_impl(BOOST_RV_REF(avltree_impl) x)
+      : data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits()))
+   {
+      node_algorithms::init_header(this->priv_header_ptr());  
+      this->priv_size_traits().set_size(size_type(0));
+      this->swap(x);
+   }
+
+   //! Effects: to-do
+   //!   
+   avltree_impl& operator=(BOOST_RV_REF(avltree_impl) x) 
+   {  this->swap(x); return *this;  }
+
+   //! Effects: Detaches all elements from this. The objects in the set 
+   //!   are not deleted (i.e. no destructors are called), but the nodes according to 
+   //!   the value_traits template parameter are reinitialized and thus can be reused. 
+   //! 
+   //! Complexity: Linear to elements contained in *this.
+   //! 
+   //! Throws: Nothing.
+   ~avltree_impl() 
+   {}
+
+   //! Effects: Returns an iterator pointing to the beginning of the tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   iterator begin()
+   {  return iterator (node_traits::get_left(this->priv_header_ptr()), this);   }
+
+   //! Effects: Returns a const_iterator pointing to the beginning of the tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator begin() const
+   {  return cbegin();   }
+
+   //! Effects: Returns a const_iterator pointing to the beginning of the tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator cbegin() const
+   {  return const_iterator (node_traits::get_left(this->priv_header_ptr()), this);   }
+
+   //! Effects: Returns an iterator pointing to the end of the tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   iterator end()
+   {  return iterator (this->priv_header_ptr(), this);  }
+
+   //! Effects: Returns a const_iterator pointing to the end of the tree.
+   //!
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator end() const
+   {  return cend();  }
+
+   //! Effects: Returns a const_iterator pointing to the end of the tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator cend() const
+   {  return const_iterator (uncast(this->priv_header_ptr()), this);  }
+
+   //! Effects: Returns a reverse_iterator pointing to the beginning of the
+   //!    reversed tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   reverse_iterator rbegin()
+   {  return reverse_iterator(end());  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning
+   //!    of the reversed tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator rbegin() const
+   {  return const_reverse_iterator(end());  }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the beginning
+   //!    of the reversed tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator crbegin() const
+   {  return const_reverse_iterator(end());  }
+
+   //! Effects: Returns a reverse_iterator pointing to the end
+   //!    of the reversed tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   reverse_iterator rend()
+   {  return reverse_iterator(begin());   }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //!    of the reversed tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator rend() const
+   {  return const_reverse_iterator(begin());   }
+
+   //! Effects: Returns a const_reverse_iterator pointing to the end
+   //!    of the reversed tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_reverse_iterator crend() const
+   {  return const_reverse_iterator(begin());   }
+
+   //! Precondition: end_iterator must be a valid end iterator
+   //!   of avltree.
+   //! 
+   //! Effects: Returns a const reference to the avltree associated to the end iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   static avltree_impl &container_from_end_iterator(iterator end_iterator)
+   {  return priv_container_from_end_iterator(end_iterator);   }
+
+   //! Precondition: end_iterator must be a valid end const_iterator
+   //!   of avltree.
+   //! 
+   //! Effects: Returns a const reference to the avltree associated to the end iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant.
+   static const avltree_impl &container_from_end_iterator(const_iterator end_iterator)
+   {  return priv_container_from_end_iterator(end_iterator);   }
+
+   //! Precondition: it must be a valid iterator
+   //!   of rbtree.
+   //! 
+   //! Effects: Returns a const reference to the tree associated to the iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Logarithmic.
+   static avltree_impl &container_from_iterator(iterator it)
+   {  return priv_container_from_iterator(it);   }
+
+   //! Precondition: it must be a valid end const_iterator
+   //!   of rbtree.
+   //! 
+   //! Effects: Returns a const reference to the tree associated to the iterator
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Logarithmic.
+   static const avltree_impl &container_from_iterator(const_iterator it)
+   {  return priv_container_from_iterator(it);   }
+
+   //! Effects: Returns the value_compare object used by the tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: If value_compare copy-constructor throws.
+   value_compare value_comp() const
+   {  return priv_comp();   }
+
+   //! Effects: Returns true if the container is empty.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   bool empty() const
+   {  return node_algorithms::unique(this->priv_header_ptr());   }
+
+   //! Effects: Returns the number of elements stored in the tree.
+   //! 
+   //! Complexity: Linear to elements contained in *this
+   //!   if constant-time size option is disabled. Constant time otherwise.
+   //! 
+   //! Throws: Nothing.
+   size_type size() const
+   {
+      if(constant_time_size)
+         return this->priv_size_traits().get_size();
+      else{
+         return (size_type)node_algorithms::size(this->priv_header_ptr());
+      }
+   }
+
+   //! Effects: Swaps the contents of two avltrees.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: If the comparison functor's swap call throws.
+   void swap(avltree_impl& other)
+   {
+      //This can throw
+      using std::swap;
+      swap(priv_comp(), priv_comp());
+      //These can't throw
+      node_algorithms::swap_tree(this->priv_header_ptr(), other.priv_header_ptr());
+      if(constant_time_size){
+         size_type backup = this->priv_size_traits().get_size();
+         this->priv_size_traits().set_size(other.priv_size_traits().get_size());
+         other.priv_size_traits().set_size(backup);
+      }
+   }
+
+   //! Requires: value must be an lvalue
+   //! 
+   //! Effects: Inserts value into the tree before the upper bound.
+   //! 
+   //! Complexity: Average complexity for insert element is at
+   //!   most logarithmic.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Strong guarantee.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   iterator insert_equal(reference value)
+   {
+      detail::key_nodeptr_comp
+         key_node_comp(priv_comp(), this);
+      node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+      iterator ret(node_algorithms::insert_equal_upper_bound
+         (this->priv_header_ptr(), to_insert, key_node_comp), this);
+      this->priv_size_traits().increment();
+      return ret;
+   }
+
+   //! Requires: value must be an lvalue, and "hint" must be
+   //!   a valid iterator.
+   //! 
+   //! Effects: Inserts x into the tree, using "hint" as a hint to
+   //!   where it will be inserted. If "hint" is the upper_bound
+   //!   the insertion takes constant time (two comparisons in the worst case)
+   //! 
+   //! Complexity: Logarithmic in general, but it is amortized
+   //!   constant time if t is inserted immediately before hint.
+   //! 
+   //! Throws: If the internal value_compare ordering function throws. Strong guarantee.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   iterator insert_equal(const_iterator hint, reference value)
+   {
+      detail::key_nodeptr_comp
+         key_node_comp(priv_comp(), this);
+      node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+      iterator ret(node_algorithms::insert_equal
+         (this->priv_header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this);
+      this->priv_size_traits().increment();
+      return ret;
+   }
+
+   //! Requires: Dereferencing iterator must yield an lvalue 
+   //!   of type value_type.
+   //! 
+   //! Effects: Inserts a each element of a range into the tree
+   //!   before the upper bound of the key of each element.
+   //! 
+   //! Complexity: Insert range is in general O(N * log(N)), where N is the
+   //!   size of the range. However, it is linear in N if the range is already sorted
+   //!   by value_comp().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   template
+   void insert_equal(Iterator b, Iterator e)
+   {
+      iterator end(this->end());
+      for (; b != e; ++b)
+         this->insert_equal(end, *b);
+   }
+
+   //! Requires: value must be an lvalue
+   //! 
+   //! Effects: Inserts value into the tree if the value
+   //!   is not already present.
+   //! 
+   //! Complexity: Average complexity for insert element is at
+   //!   most logarithmic.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   std::pair insert_unique(reference value)
+   {
+      insert_commit_data commit_data;
+      std::pair ret = insert_unique_check(value, priv_comp(), commit_data);
+      if(!ret.second)
+         return ret;
+      return std::pair (insert_unique_commit(value, commit_data), true);
+   }
+
+   //! Requires: value must be an lvalue, and "hint" must be
+   //!   a valid iterator
+   //! 
+   //! Effects: Tries to insert x into the tree, using "hint" as a hint
+   //!   to where it will be inserted.
+   //! 
+   //! Complexity: Logarithmic in general, but it is amortized
+   //!   constant time (two comparisons in the worst case)
+   //!   if t is inserted immediately before hint.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   iterator insert_unique(const_iterator hint, reference value)
+   {
+      insert_commit_data commit_data;
+      std::pair ret = insert_unique_check(hint, value, priv_comp(), commit_data);
+      if(!ret.second)
+         return ret.first;
+      return insert_unique_commit(value, commit_data);
+   }
+
+   //! Requires: Dereferencing iterator must yield an lvalue 
+   //!   of type value_type.
+   //! 
+   //! Effects: Tries to insert each element of a range into the tree.
+   //! 
+   //! Complexity: Insert range is in general O(N * log(N)), where N is the 
+   //!   size of the range. However, it is linear in N if the range is already sorted 
+   //!   by value_comp().
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Does not affect the validity of iterators and references.
+   //!   No copy-constructors are called.
+   template
+   void insert_unique(Iterator b, Iterator e)
+   {
+      if(this->empty()){
+         iterator end(this->end());
+         for (; b != e; ++b)
+            this->insert_unique(end, *b);
+      }
+      else{
+         for (; b != e; ++b)
+            this->insert_unique(*b);
+      }
+   }
+
+   //! Requires: key_value_comp must be a comparison function that induces 
+   //!   the same strict weak ordering as value_compare. The difference is that
+   //!   key_value_comp compares an arbitrary key with the contained values.
+   //! 
+   //! Effects: Checks if a value can be inserted in the container, using
+   //!   a user provided key instead of the value itself.
+   //!
+   //! Returns: If there is an equivalent value
+   //!   returns a pair containing an iterator to the already present value
+   //!   and false. If the value can be inserted returns true in the returned
+   //!   pair boolean and fills "commit_data" that is meant to be used with
+   //!   the "insert_commit" function.
+   //! 
+   //! Complexity: Average complexity is at most logarithmic.
+   //!
+   //! Throws: If the key_value_comp ordering function throws. Strong guarantee.
+   //! 
+   //! Notes: This function is used to improve performance when constructing
+   //!   a value_type is expensive: if there is an equivalent value
+   //!   the constructed object must be discarded. Many times, the part of the
+   //!   node that is used to impose the order is much cheaper to construct
+   //!   than the value_type and this function offers the possibility to use that 
+   //!   part to check if the insertion will be successful.
+   //!
+   //!   If the check is successful, the user can construct the value_type and use
+   //!   "insert_commit" to insert the object in constant-time. This gives a total
+   //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
+   //!
+   //!   "commit_data" remains valid for a subsequent "insert_commit" only if no more
+   //!   objects are inserted or erased from the container.
+   template
+   std::pair insert_unique_check
+      (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+   {
+      detail::key_nodeptr_comp
+         comp(key_value_comp, this);
+      std::pair ret = 
+         (node_algorithms::insert_unique_check
+            (this->priv_header_ptr(), key, comp, commit_data));
+      return std::pair(iterator(ret.first, this), ret.second);
+   }
+
+   //! Requires: key_value_comp must be a comparison function that induces 
+   //!   the same strict weak ordering as value_compare. The difference is that
+   //!   key_value_comp compares an arbitrary key with the contained values.
+   //! 
+   //! Effects: Checks if a value can be inserted in the container, using
+   //!   a user provided key instead of the value itself, using "hint" 
+   //!   as a hint to where it will be inserted.
+   //!
+   //! Returns: If there is an equivalent value
+   //!   returns a pair containing an iterator to the already present value
+   //!   and false. If the value can be inserted returns true in the returned
+   //!   pair boolean and fills "commit_data" that is meant to be used with
+   //!   the "insert_commit" function.
+   //! 
+   //! Complexity: Logarithmic in general, but it's amortized
+   //!   constant time if t is inserted immediately before hint.
+   //!
+   //! Throws: If the key_value_comp ordering function throws. Strong guarantee.
+   //! 
+   //! Notes: This function is used to improve performance when constructing
+   //!   a value_type is expensive: if there is an equivalent value
+   //!   the constructed object must be discarded. Many times, the part of the
+   //!   constructing that is used to impose the order is much cheaper to construct
+   //!   than the value_type and this function offers the possibility to use that key 
+   //!   to check if the insertion will be successful.
+   //!
+   //!   If the check is successful, the user can construct the value_type and use
+   //!   "insert_commit" to insert the object in constant-time. This can give a total
+   //!   constant-time complexity to the insertion: check(O(1)) + commit(O(1)).
+   //!   
+   //!   "commit_data" remains valid for a subsequent "insert_commit" only if no more
+   //!   objects are inserted or erased from the container.
+   template
+   std::pair insert_unique_check
+      (const_iterator hint, const KeyType &key
+      ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
+   {
+      detail::key_nodeptr_comp
+         comp(key_value_comp, this);
+      std::pair ret = 
+         (node_algorithms::insert_unique_check
+            (this->priv_header_ptr(), hint.pointed_node(), key, comp, commit_data));
+      return std::pair(iterator(ret.first, this), ret.second);
+   }
+
+   //! Requires: value must be an lvalue of type value_type. commit_data
+   //!   must have been obtained from a previous call to "insert_check".
+   //!   No objects should have been inserted or erased from the container between
+   //!   the "insert_check" that filled "commit_data" and the call to "insert_commit".
+   //! 
+   //! Effects: Inserts the value in the avl_set using the information obtained
+   //!   from the "commit_data" that a previous "insert_check" filled.
+   //!
+   //! Returns: An iterator to the newly inserted object.
+   //! 
+   //! Complexity: Constant time.
+   //!
+   //! Throws: Nothing.
+   //! 
+   //! Notes: This function has only sense if a "insert_check" has been
+   //!   previously executed to fill "commit_data". No value should be inserted or
+   //!   erased between the "insert_check" and "insert_commit" calls.
+   iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
+   {
+      node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+      node_algorithms::insert_unique_commit
+               (this->priv_header_ptr(), to_insert, commit_data);
+      this->priv_size_traits().increment();
+      return iterator(to_insert, this);
+   }
+
+   //! Requires: value must be an lvalue, "pos" must be
+   //!   a valid iterator (or end) and must be the succesor of value
+   //!   once inserted according to the predicate
+   //!
+   //! Effects: Inserts x into the tree before "pos".
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function does not check preconditions so if "pos" is not
+   //! the successor of "value" tree ordering invariant will be broken.
+   //! This is a low-level function to be used only for performance reasons
+   //! by advanced users.
+   iterator insert_before(const_iterator pos, reference value)
+   {
+      node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+      iterator ret(node_algorithms::insert_before
+         (this->priv_header_ptr(), pos.pointed_node(), to_insert), this);
+      this->priv_size_traits().increment();
+      return ret;
+   }
+
+   //! Requires: value must be an lvalue, and it must be no less
+   //!   than the greatest inserted key
+   //!
+   //! Effects: Inserts x into the tree in the last position.
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function does not check preconditions so if value is
+   //!   less than the greatest inserted key tree ordering invariant will be broken.
+   //!   This function is slightly more efficient than using "insert_before".
+   //!   This is a low-level function to be used only for performance reasons
+   //!   by advanced users.
+   void push_back(reference value)
+   {
+      node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+      node_algorithms::push_back(this->priv_header_ptr(), to_insert);
+      this->priv_size_traits().increment();
+   }
+
+   //! Requires: value must be an lvalue, and it must be no greater
+   //!   than the minimum inserted key
+   //!
+   //! Effects: Inserts x into the tree in the first position.
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function does not check preconditions so if value is
+   //!   greater than the minimum inserted key tree ordering invariant will be broken.
+   //!   This function is slightly more efficient than using "insert_before".
+   //!   This is a low-level function to be used only for performance reasons
+   //!   by advanced users.
+   void push_front(reference value)
+   {
+      node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+      node_algorithms::push_front(this->priv_header_ptr(), to_insert);
+      this->priv_size_traits().increment();
+   }
+
+   //! Effects: Erases the element pointed to by pos. 
+   //! 
+   //! Complexity: Average complexity for erase element is constant time. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   iterator erase(const_iterator i)
+   {
+      const_iterator ret(i);
+      ++ret;
+      node_ptr to_erase(i.pointed_node());
+      if(safemode_or_autounlink)
+         BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
+      node_algorithms::erase(this->priv_header_ptr(), to_erase);
+      this->priv_size_traits().decrement();
+      if(safemode_or_autounlink)
+         node_algorithms::init(to_erase);
+      return ret.unconst();
+   }
+
+   //! Effects: Erases the range pointed to by b end e. 
+   //! 
+   //! Complexity: Average complexity for erase range is at most 
+   //!   O(log(size() + N)), where N is the number of elements in the range.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   iterator erase(const_iterator b, const_iterator e)
+   {  size_type n;   return private_erase(b, e, n);   }
+
+   //! Effects: Erases all the elements with the given value.
+   //! 
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size() + N).
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   size_type erase(const_reference value)
+   {  return this->erase(value, priv_comp());   }
+
+   //! Effects: Erases all the elements with the given key.
+   //!   according to the comparison functor "comp".
+   //!
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size() + N).
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   template
+   size_type erase(const KeyType& key, KeyValueCompare comp
+                  /// @cond
+                  , typename detail::enable_if_c::value >::type * = 0
+                  /// @endcond
+                  )
+   {
+      std::pair p = this->equal_range(key, comp);
+      size_type n;
+      private_erase(p.first, p.second, n);
+      return n;
+   }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Effects: Erases the element pointed to by pos. 
+   //!   Disposer::operator()(pointer) is called for the removed element.
+   //! 
+   //! Complexity: Average complexity for erase element is constant time. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators 
+   //!    to the erased elements.
+   template
+   iterator erase_and_dispose(const_iterator i, Disposer disposer)
+   {
+      node_ptr to_erase(i.pointed_node());
+      iterator ret(this->erase(i));
+      disposer(get_real_value_traits().to_value_ptr(to_erase));
+      return ret;
+   }
+
+   #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+   template
+   iterator erase_and_dispose(iterator i, Disposer disposer)
+   {  return this->erase_and_dispose(const_iterator(i), disposer);   }
+   #endif
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Effects: Erases the range pointed to by b end e.
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //! 
+   //! Complexity: Average complexity for erase range is at most 
+   //!   O(log(size() + N)), where N is the number of elements in the range.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators
+   //!    to the erased elements.
+   template
+   iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
+   {  size_type n;   return private_erase(b, e, n, disposer);   }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Effects: Erases all the elements with the given value.
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //! 
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size() + N).
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   template
+   size_type erase_and_dispose(const_reference value, Disposer disposer)
+   {
+      std::pair p = this->equal_range(value);
+      size_type n;
+      private_erase(p.first, p.second, n, disposer);
+      return n;
+   }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!
+   //! Effects: Erases all the elements with the given key.
+   //!   according to the comparison functor "comp".
+   //!   Disposer::operator()(pointer) is called for the removed elements.
+   //!
+   //! Returns: The number of erased elements.
+   //! 
+   //! Complexity: O(log(size() + N).
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators
+   //!    to the erased elements.
+   template
+   size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer
+                  /// @cond
+                  , typename detail::enable_if_c::value >::type * = 0
+                  /// @endcond
+                  )
+   {
+      std::pair p = this->equal_range(key, comp);
+      size_type n;
+      private_erase(p.first, p.second, n, disposer);
+      return n;
+   }
+
+   //! Effects: Erases all of the elements. 
+   //! 
+   //! Complexity: Linear to the number of elements on the container.
+   //!   if it's a safe-mode or auto-unlink value_type. Constant time otherwise.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. No destructors are called.
+   void clear()
+   {
+      if(safemode_or_autounlink){
+         this->clear_and_dispose(detail::null_disposer());
+      }
+      else{
+         node_algorithms::init_header(this->priv_header_ptr());
+         this->priv_size_traits().set_size(0);
+      }
+   }
+
+   //! Effects: Erases all of the elements calling disposer(p) for
+   //!   each node to be erased.
+   //! Complexity: Average complexity for is at most O(log(size() + N)),
+   //!   where N is the number of elements in the container.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: Invalidates the iterators (but not the references)
+   //!    to the erased elements. Calls N times to disposer functor.
+   template
+   void clear_and_dispose(Disposer disposer)
+   {
+      node_algorithms::clear_and_dispose(this->priv_header_ptr()
+         , detail::node_disposer(disposer, this));
+      node_algorithms::init_header(this->priv_header_ptr());
+      this->priv_size_traits().set_size(0);
+   }
+
+   //! Effects: Returns the number of contained elements with the given value
+   //! 
+   //! Complexity: Logarithmic to the number of elements contained plus lineal
+   //!   to number of objects with the given value.
+   //! 
+   //! Throws: Nothing.
+   size_type count(const_reference value) const
+   {  return this->count(value, priv_comp());   }
+
+   //! Effects: Returns the number of contained elements with the given key
+   //! 
+   //! Complexity: Logarithmic to the number of elements contained plus lineal
+   //!   to number of objects with the given key.
+   //! 
+   //! Throws: Nothing.
+   template
+   size_type count(const KeyType &key, KeyValueCompare comp) const
+   {
+      std::pair ret = this->equal_range(key, comp);
+      return std::distance(ret.first, ret.second);
+   }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is not less than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   iterator lower_bound(const_reference value)
+   {  return this->lower_bound(value, priv_comp());   }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is not less than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   const_iterator lower_bound(const_reference value) const
+   {  return this->lower_bound(value, priv_comp());   }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is not less than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   template
+   iterator lower_bound(const KeyType &key, KeyValueCompare comp)
+   {
+      detail::key_nodeptr_comp
+         key_node_comp(comp, this);
+      return iterator(node_algorithms::lower_bound
+         (this->priv_header_ptr(), key, key_node_comp), this);
+   }
+
+   //! Effects: Returns a const iterator to the first element whose
+   //!   key is not less than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   template
+   const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const
+   {
+      detail::key_nodeptr_comp
+         key_node_comp(comp, this);
+      return const_iterator(node_algorithms::lower_bound
+         (this->priv_header_ptr(), key, key_node_comp), this);
+   }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is greater than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   iterator upper_bound(const_reference value)
+   {  return this->upper_bound(value, priv_comp());   }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is greater than k according to comp or end() if that element
+   //!   does not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   template
+   iterator upper_bound(const KeyType &key, KeyValueCompare comp)
+   {
+      detail::key_nodeptr_comp
+         key_node_comp(comp, this);
+      return iterator(node_algorithms::upper_bound
+         (this->priv_header_ptr(), key, key_node_comp), this);
+   }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is greater than k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   const_iterator upper_bound(const_reference value) const
+   {  return this->upper_bound(value, priv_comp());   }
+
+   //! Effects: Returns an iterator to the first element whose
+   //!   key is greater than k according to comp or end() if that element
+   //!   does not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   template
+   const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const
+   {
+      detail::key_nodeptr_comp
+         key_node_comp(comp, this);
+      return const_iterator(node_algorithms::upper_bound
+         (this->priv_header_ptr(), key, key_node_comp), this);
+   }
+
+   //! Effects: Finds an iterator to the first element whose key is 
+   //!   k or end() if that element does not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   iterator find(const_reference value)
+   {  return this->find(value, priv_comp()); }
+
+   //! Effects: Finds an iterator to the first element whose key is 
+   //!   k or end() if that element does not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   template
+   iterator find(const KeyType &key, KeyValueCompare comp)
+   {
+      detail::key_nodeptr_comp
+         key_node_comp(comp, this);
+      return iterator
+         (node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
+   }
+
+   //! Effects: Finds a const_iterator to the first element whose key is 
+   //!   k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   const_iterator find(const_reference value) const
+   {  return this->find(value, priv_comp()); }
+
+   //! Effects: Finds a const_iterator to the first element whose key is 
+   //!   k or end() if that element does not exist.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   template
+   const_iterator find(const KeyType &key, KeyValueCompare comp) const
+   {
+      detail::key_nodeptr_comp
+         key_node_comp(comp, this);
+      return const_iterator
+         (node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
+   }
+
+   //! Effects: Finds a range containing all elements whose key is k or
+   //!   an empty range that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   std::pair equal_range(const_reference value)
+   {  return this->equal_range(value, priv_comp());   }
+
+   //! Effects: Finds a range containing all elements whose key is k or
+   //!   an empty range that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   template
+   std::pair equal_range(const KeyType &key, KeyValueCompare comp)
+   {
+      detail::key_nodeptr_comp
+         key_node_comp(comp, this);
+      std::pair ret
+         (node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
+      return std::pair(iterator(ret.first, this), iterator(ret.second, this));
+   }
+
+   //! Effects: Finds a range containing all elements whose key is k or
+   //!   an empty range that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   std::pair
+      equal_range(const_reference value) const
+   {  return this->equal_range(value, priv_comp());   }
+
+   //! Effects: Finds a range containing all elements whose key is k or
+   //!   an empty range that indicates the position where those elements would be
+   //!   if they there is no elements with key k.
+   //! 
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   template
+   std::pair
+      equal_range(const KeyType &key, KeyValueCompare comp) const
+   {
+      detail::key_nodeptr_comp
+         key_node_comp(comp, this);
+      std::pair ret
+         (node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
+      return std::pair(const_iterator(ret.first, this), const_iterator(ret.second, this));
+   }
+
+   //! Requires: Disposer::operator()(pointer) shouldn't throw.
+   //!   Cloner should yield to nodes equivalent to the original nodes.
+   //!
+   //! Effects: Erases all the elements from *this
+   //!   calling Disposer::operator()(pointer), clones all the 
+   //!   elements from src calling Cloner::operator()(const_reference )
+   //!   and inserts them on *this. Copies the predicate from the source container.
+   //!
+   //!   If cloner throws, all cloned elements are unlinked and disposed
+   //!   calling Disposer::operator()(pointer).
+   //!   
+   //! Complexity: Linear to erased plus inserted elements.
+   //! 
+   //! Throws: If cloner throws or predicate copy assignment throws. Basic guarantee.
+   template 
+   void clone_from(const avltree_impl &src, Cloner cloner, Disposer disposer)
+   {
+      this->clear_and_dispose(disposer);
+      if(!src.empty()){
+         detail::exception_disposer
+            rollback(*this, disposer);
+         node_algorithms::clone
+            (src.priv_header_ptr()
+            ,this->priv_header_ptr()
+            ,detail::node_cloner(cloner, this)
+            ,detail::node_disposer(disposer, this));
+         this->priv_size_traits().set_size(src.priv_size_traits().get_size());
+         this->priv_comp() = src.priv_comp();
+         rollback.release();
+      }
+   }
+
+   //! Effects: Unlinks the leftmost node from the tree.
+   //! 
+   //! Complexity: Average complexity is constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Notes: This function breaks the tree and the tree can
+   //!   only be used for more unlink_leftmost_without_rebalance calls.
+   //!   This function is normally used to achieve a step by step
+   //!   controlled destruction of the tree.
+   pointer unlink_leftmost_without_rebalance()
+   {
+      node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
+                           (this->priv_header_ptr()));
+      if(!to_be_disposed)
+         return 0;
+      this->priv_size_traits().decrement();
+      if(safemode_or_autounlink)//If this is commented does not work with normal_link
+         node_algorithms::init(to_be_disposed);
+      return get_real_value_traits().to_value_ptr(to_be_disposed);
+   }
+
+   //! Requires: replace_this must be a valid iterator of *this
+   //!   and with_this must not be inserted in any tree.
+   //! 
+   //! Effects: Replaces replace_this in its position in the
+   //!   tree with with_this. The tree does not need to be rebalanced.
+   //! 
+   //! Complexity: Constant. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function will break container ordering invariants if
+   //!   with_this is not equivalent to *replace_this according to the
+   //!   ordering rules. This function is faster than erasing and inserting
+   //!   the node, since no rebalancing or comparison is needed.
+   void replace_node(iterator replace_this, reference with_this)
+   {
+      node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
+                                   , this->priv_header_ptr()
+                                   , get_real_value_traits().to_node_ptr(with_this));
+      if(safemode_or_autounlink)
+         node_algorithms::init(replace_this.pointed_node());
+   }
+
+   //! Requires: value must be an lvalue and shall be in a set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid iterator i belonging to the set
+   //!   that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This static function is available only if the value traits
+   //!   is stateless.
+   static iterator s_iterator_to(reference value)
+   {
+      BOOST_STATIC_ASSERT((!stateful_value_traits));
+      return iterator (value_traits::to_node_ptr(value), 0);
+   }
+
+   //! Requires: value must be an lvalue and shall be in a set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid const_iterator i belonging to the
+   //!   set that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This static function is available only if the value traits
+   //!   is stateless.
+   static const_iterator s_iterator_to(const_reference value) 
+   {
+      BOOST_STATIC_ASSERT((!stateful_value_traits));
+      return const_iterator (value_traits::to_node_ptr(const_cast (value)), 0);
+   }
+
+   //! Requires: value must be an lvalue and shall be in a set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid iterator i belonging to the set
+   //!   that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   iterator iterator_to(reference value)
+   {  return iterator (value_traits::to_node_ptr(value), this); }
+
+   //! Requires: value must be an lvalue and shall be in a set of
+   //!   appropriate type. Otherwise the behavior is undefined.
+   //! 
+   //! Effects: Returns: a valid const_iterator i belonging to the
+   //!   set that points to the value
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   const_iterator iterator_to(const_reference value) const
+   {  return const_iterator (value_traits::to_node_ptr(const_cast (value)), this); }
+
+   //! Requires: value shall not be in a tree.
+   //! 
+   //! Effects: init_node puts the hook of a value in a well-known default
+   //!   state.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Note: This function puts the hook in the well-known default state
+   //!   used by auto_unlink and safe hooks.
+   static void init_node(reference value)
+   { node_algorithms::init(value_traits::to_node_ptr(value)); }
+
+/*
+   //! Effects: removes x from a tree of the appropriate type. It has no effect,
+   //! if x is not in such a tree. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Note: This static function is only usable with the "safe mode"
+   //! hook and non-constant time size lists. Otherwise, the user must use
+   //! the non-static "erase(reference )" member. If the user calls
+   //! this function with a non "safe mode" or constant time size list
+   //! a compilation error will be issued.
+   template
+   static void remove_node(T& value)
+   {
+      //This function is only usable for safe mode hooks and non-constant
+      //time lists. 
+      //BOOST_STATIC_ASSERT((!(safemode_or_autounlink && constant_time_size)));
+      BOOST_STATIC_ASSERT((!constant_time_size));
+      BOOST_STATIC_ASSERT((boost::is_convertible::value));
+      node_ptr to_remove(value_traits::to_node_ptr(value));
+      node_algorithms::unlink_and_rebalance(to_remove);
+      if(safemode_or_autounlink)
+         node_algorithms::init(to_remove);
+   }
+*/
+
+   /// @cond
+
+   private:
+   template
+   iterator private_erase(const_iterator b, const_iterator e, size_type &n, Disposer disposer)
+   {
+      for(n = 0; b != e; ++n)
+        this->erase_and_dispose(b++, disposer);
+      return b.unconst();
+   }
+
+   iterator private_erase(const_iterator b, const_iterator e, size_type &n)
+   {
+      for(n = 0; b != e; ++n)
+        this->erase(b++);
+      return b.unconst();
+   }
+   /// @endcond
+
+   private:
+   static avltree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
+   {
+      header_plus_size *r = detail::parent_from_member
+         ( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
+      node_plus_pred_t *n = detail::parent_from_member
+         (r, &node_plus_pred_t::header_plus_size_);
+      data_t *d = detail::parent_from_member(n, &data_t::node_plus_pred_);
+      avltree_impl *avl  = detail::parent_from_member(d, &avltree_impl::data_);
+      return *avl;
+   }
+
+   static avltree_impl &priv_container_from_iterator(const const_iterator &it)
+   {  return priv_container_from_end_iterator(it.end_iterator_from_it());   }
+};
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator<
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avltree_impl &x, const avltree_impl &y)
+#else
+(const avltree_impl &x, const avltree_impl &y)
+#endif
+{  return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());  }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+bool operator==
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avltree_impl &x, const avltree_impl &y)
+#else
+(const avltree_impl &x, const avltree_impl &y)
+#endif
+{
+   typedef avltree_impl tree_type;
+   typedef typename tree_type::const_iterator const_iterator;
+
+   if(tree_type::constant_time_size && x.size() != y.size()){
+      return false;
+   }
+   const_iterator end1 = x.end();
+   const_iterator i1 = x.begin();
+   const_iterator i2 = y.begin();
+   if(tree_type::constant_time_size){
+      while (i1 != end1 && *i1 == *i2) {
+         ++i1;
+         ++i2;
+      }
+      return i1 == end1;
+   }
+   else{
+      const_iterator end2 = y.end();
+      while (i1 != end1 && i2 != end2 && *i1 == *i2) {
+         ++i1;
+         ++i2;
+      }
+      return i1 == end1 && i2 == end2;
+   }
+}
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator!=
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avltree_impl &x, const avltree_impl &y)
+#else
+(const avltree_impl &x, const avltree_impl &y)
+#endif
+{  return !(x == y); }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator>
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avltree_impl &x, const avltree_impl &y)
+#else
+(const avltree_impl &x, const avltree_impl &y)
+#endif
+{  return y < x;  }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator<=
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avltree_impl &x, const avltree_impl &y)
+#else
+(const avltree_impl &x, const avltree_impl &y)
+#endif
+{  return !(y < x);  }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline bool operator>=
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(const avltree_impl &x, const avltree_impl &y)
+#else
+(const avltree_impl &x, const avltree_impl &y)
+#endif
+{  return !(x < y);  }
+
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+template
+#else
+template
+#endif
+inline void swap
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+(avltree_impl &x, avltree_impl &y)
+#else
+(avltree_impl &x, avltree_impl &y)
+#endif
+{  x.swap(y);  }
+
+/// @cond
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+struct make_avltree_opt
+{
+   typedef typename pack_options
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      < avl_set_defaults, O1, O2, O3, O4>
+      #else
+      < avl_set_defaults, Options...>
+      #endif
+      ::type packed_options;
+
+   typedef typename detail::get_value_traits
+      ::type value_traits;
+
+   typedef avl_setopt
+         < value_traits
+         , typename packed_options::compare
+         , typename packed_options::size_type
+         , packed_options::constant_time_size
+         > type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c avltree that yields to the same type when the
+//! same options (either explicitly or implicitly) are used.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+struct make_avltree
+{
+   /// @cond
+   typedef avltree_impl
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      < typename make_avltree_opt::type
+      #else
+      < typename make_avltree_opt::type
+      #endif
+      > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
+
+#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+class avltree
+   #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+   :  public make_avltree::type
+   #else
+   :  public make_avltree::type
+   #endif
+{
+   typedef typename make_avltree
+   #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+   #else
+      
+   #endif
+      ::type   Base;
+
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(avltree)
+
+   public:
+   typedef typename Base::value_compare      value_compare;
+   typedef typename Base::value_traits       value_traits;
+   typedef typename Base::real_value_traits  real_value_traits;
+   typedef typename Base::iterator           iterator;
+   typedef typename Base::const_iterator     const_iterator;
+
+   //Assert if passed value traits are compatible with the type
+   BOOST_STATIC_ASSERT((detail::is_same::value));
+
+   avltree( const value_compare &cmp      = value_compare()
+          , const value_traits &v_traits  = value_traits())
+      :  Base(cmp, v_traits)
+   {}
+
+   template
+   avltree( bool unique, Iterator b, Iterator e
+         , const value_compare &cmp = value_compare()
+         , const value_traits &v_traits = value_traits())
+      :  Base(unique, b, e, cmp, v_traits)
+   {}
+
+   avltree(BOOST_RV_REF(avltree) x)
+      :  Base(::boost::move(static_cast(x)))
+   {}
+
+   avltree& operator=(BOOST_RV_REF(avltree) x)
+   {  this->Base::operator=(::boost::move(static_cast(x))); return *this;  }
+
+   static avltree &container_from_end_iterator(iterator end_iterator)
+   {  return static_cast(Base::container_from_end_iterator(end_iterator));   }
+
+   static const avltree &container_from_end_iterator(const_iterator end_iterator)
+   {  return static_cast(Base::container_from_end_iterator(end_iterator));   }
+
+   static avltree &container_from_iterator(iterator it)
+   {  return static_cast(Base::container_from_iterator(it));   }
+
+   static const avltree &container_from_iterator(const_iterator it)
+   {  return static_cast(Base::container_from_iterator(it));   }
+};
+
+#endif
+
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_AVLTREE_HPP
diff --git a/src/third_party/boost/boost/intrusive/avltree_algorithms.hpp b/src/third_party/boost/boost/intrusive/avltree_algorithms.hpp
new file mode 100644
index 00000000000..9b917c767d7
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/avltree_algorithms.hpp
@@ -0,0 +1,943 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Daniel K. O. 2005.
+// (C) Copyright Ion Gaztanaga 2007.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP
+#define BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP
+
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+
+namespace boost {
+namespace intrusive {
+
+//! avltree_algorithms is configured with a NodeTraits class, which encapsulates the
+//! information about the node to be manipulated. NodeTraits must support the
+//! following interface:
+//!
+//! Typedefs:
+//!
+//! node: The type of the node that forms the circular list
+//!
+//! node_ptr: A pointer to a node
+//!
+//! const_node_ptr: A pointer to a const node
+//!
+//! balance: The type of the balance factor
+//!
+//! Static functions:
+//!
+//! static node_ptr get_parent(const_node_ptr n);
+//! 
+//! static void set_parent(node_ptr n, node_ptr parent);
+//!
+//! static node_ptr get_left(const_node_ptr n);
+//! 
+//! static void set_left(node_ptr n, node_ptr left);
+//!
+//! static node_ptr get_right(const_node_ptr n);
+//! 
+//! static void set_right(node_ptr n, node_ptr right);
+//! 
+//! static balance get_balance(const_node_ptr n);
+//! 
+//! static void set_balance(node_ptr n, balance b);
+//! 
+//! static balance negative();
+//! 
+//! static balance zero();
+//! 
+//! static balance positive();
+template
+class avltree_algorithms
+{
+   public:
+   typedef typename NodeTraits::node            node;
+   typedef NodeTraits                           node_traits;
+   typedef typename NodeTraits::node_ptr        node_ptr;
+   typedef typename NodeTraits::const_node_ptr  const_node_ptr;
+   typedef typename NodeTraits::balance         balance;
+
+   /// @cond
+   private:
+   typedef detail::tree_algorithms  tree_algorithms;
+
+   template
+   struct avltree_node_cloner
+      :  private detail::ebo_functor_holder
+   {
+      typedef detail::ebo_functor_holder                 base_t;
+
+      avltree_node_cloner(F f)
+         :  base_t(f)
+      {}
+      
+      node_ptr operator()(const node_ptr &p)
+      {
+         node_ptr n = base_t::get()(p);
+         NodeTraits::set_balance(n, NodeTraits::get_balance(p));
+         return n;
+      }
+   };
+
+   struct avltree_erase_fixup
+   {
+      void operator()(const node_ptr &to_erase, const node_ptr &successor)
+      {  NodeTraits::set_balance(successor, NodeTraits::get_balance(to_erase));  }
+   };
+
+   static node_ptr uncast(const const_node_ptr & ptr)
+   {  return pointer_traits::const_cast_from(ptr);  }
+   /// @endcond
+
+   public:
+   static node_ptr begin_node(const const_node_ptr & header)
+   {  return tree_algorithms::begin_node(header);   }
+
+   static node_ptr end_node(const const_node_ptr & header)
+   {  return tree_algorithms::end_node(header);   }
+
+   //! This type is the information that will be
+   //! filled by insert_unique_check
+   typedef typename tree_algorithms::insert_commit_data insert_commit_data;
+
+   //! Requires: header1 and header2 must be the header nodes
+   //!  of two trees.
+   //! 
+   //! Effects: Swaps two trees. After the function header1 will contain 
+   //!   links to the second tree and header2 will have links to the first tree.
+   //! 
+   //! Complexity: Constant. 
+   //! 
+   //! Throws: Nothing.
+   static void swap_tree(const node_ptr & header1, const node_ptr & header2)
+   {  return tree_algorithms::swap_tree(header1, header2);  }
+
+   //! Requires: node1 and node2 can't be header nodes
+   //!  of two trees.
+   //! 
+   //! Effects: Swaps two nodes. After the function node1 will be inserted
+   //!   in the position node2 before the function. node2 will be inserted in the
+   //!   position node1 had before the function.
+   //! 
+   //! Complexity: Logarithmic. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function will break container ordering invariants if
+   //!   node1 and node2 are not equivalent according to the ordering rules.
+   //!
+   //!Experimental function
+   static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
+   {
+      if(node1 == node2)
+         return;
+   
+      node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2));
+      swap_nodes(node1, header1, node2, header2);
+   }
+
+   //! Requires: node1 and node2 can't be header nodes
+   //!  of two trees with header header1 and header2.
+   //! 
+   //! Effects: Swaps two nodes. After the function node1 will be inserted
+   //!   in the position node2 before the function. node2 will be inserted in the
+   //!   position node1 had before the function.
+   //! 
+   //! Complexity: Constant. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function will break container ordering invariants if
+   //!   node1 and node2 are not equivalent according to the ordering rules.
+   //!
+   //!Experimental function
+   static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
+   {
+      if(node1 == node2)   return;
+
+      tree_algorithms::swap_nodes(node1, header1, node2, header2);
+      //Swap balance
+      balance c = NodeTraits::get_balance(node1);
+      NodeTraits::set_balance(node1, NodeTraits::get_balance(node2)); 
+      NodeTraits::set_balance(node2, c); 
+   }
+
+   //! Requires: node_to_be_replaced must be inserted in a tree
+   //!   and new_node must not be inserted in a tree.
+   //! 
+   //! Effects: Replaces node_to_be_replaced in its position in the
+   //!   tree with new_node. The tree does not need to be rebalanced
+   //! 
+   //! Complexity: Logarithmic. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function will break container ordering invariants if
+   //!   new_node is not equivalent to node_to_be_replaced according to the
+   //!   ordering rules. This function is faster than erasing and inserting
+   //!   the node, since no rebalancing and comparison is needed.
+   //!
+   //!Experimental function
+   static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
+   {
+      if(node_to_be_replaced == new_node)
+         return;
+      replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node);
+   }
+
+   //! Requires: node_to_be_replaced must be inserted in a tree
+   //!   with header "header" and new_node must not be inserted in a tree.
+   //! 
+   //! Effects: Replaces node_to_be_replaced in its position in the
+   //!   tree with new_node. The tree does not need to be rebalanced
+   //! 
+   //! Complexity: Constant. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: This function will break container ordering invariants if
+   //!   new_node is not equivalent to node_to_be_replaced according to the
+   //!   ordering rules. This function is faster than erasing and inserting
+   //!   the node, since no rebalancing or comparison is needed.
+   //!
+   //!Experimental function
+   static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
+   {
+      tree_algorithms::replace_node(node_to_be_replaced, header, new_node);
+      NodeTraits::set_balance(new_node, NodeTraits::get_balance(node_to_be_replaced)); 
+   }
+
+   //! Requires: node is a tree node but not the header.
+   //! 
+   //! Effects: Unlinks the node and rebalances the tree.
+   //! 
+   //! Complexity: Average complexity is constant time.
+   //! 
+   //! Throws: Nothing.
+   static void unlink(const node_ptr & node)
+   {
+      node_ptr x = NodeTraits::get_parent(node);
+      if(x){
+         while(!is_header(x))
+            x = NodeTraits::get_parent(x);
+         erase(x, node);
+      }
+   }
+
+   //! Requires: header is the header of a tree.
+   //! 
+   //! Effects: Unlinks the leftmost node from the tree, and
+   //!   updates the header link to the new leftmost node.
+   //! 
+   //! Complexity: Average complexity is constant time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Notes: This function breaks the tree and the tree can
+   //!   only be used for more unlink_leftmost_without_rebalance calls.
+   //!   This function is normally used to achieve a step by step
+   //!   controlled destruction of the tree.
+   static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header)
+   {  return tree_algorithms::unlink_leftmost_without_rebalance(header);   }
+
+   //! Requires: node is a node of the tree or an node initialized
+   //!   by init(...).
+   //! 
+   //! Effects: Returns true if the node is initialized by init().
+   //! 
+   //! Complexity: Constant time.
+   //! 
+   //! Throws: Nothing.
+   static bool unique(const const_node_ptr & node)
+   {  return tree_algorithms::unique(node);  }
+
+   //! Requires: node is a node of the tree but it's not the header.
+   //! 
+   //! Effects: Returns the number of nodes of the subtree.
+   //! 
+   //! Complexity: Linear time.
+   //! 
+   //! Throws: Nothing.
+   static std::size_t count(const const_node_ptr & node)
+   {  return tree_algorithms::count(node);   }
+
+   //! Requires: header is the header node of the tree.
+   //! 
+   //! Effects: Returns the number of nodes above the header.
+   //! 
+   //! Complexity: Linear time.
+   //! 
+   //! Throws: Nothing.
+   static std::size_t size(const const_node_ptr & header)
+   {  return tree_algorithms::size(header);   }
+
+   //! Requires: p is a node from the tree except the header.
+   //! 
+   //! Effects: Returns the next node of the tree.
+   //! 
+   //! Complexity: Average constant time.
+   //! 
+   //! Throws: Nothing.
+   static node_ptr next_node(const node_ptr & p)
+   {  return tree_algorithms::next_node(p); }
+
+   //! Requires: p is a node from the tree except the leftmost node.
+   //! 
+   //! Effects: Returns the previous node of the tree.
+   //! 
+   //! Complexity: Average constant time.
+   //! 
+   //! Throws: Nothing.
+   static node_ptr prev_node(const node_ptr & p)
+   {  return tree_algorithms::prev_node(p); }
+
+   //! Requires: node must not be part of any tree.
+   //!
+   //! Effects: After the function unique(node) == true.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   //!
+   //! Nodes: If node is inserted in a tree, this function corrupts the tree.
+   static void init(const node_ptr & node)
+   {  tree_algorithms::init(node);  }
+
+   //! Requires: node must not be part of any tree.
+   //!
+   //! Effects: Initializes the header to represent an empty tree.
+   //!   unique(header) == true.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   //!
+   //! Nodes: If node is inserted in a tree, this function corrupts the tree.
+   static void init_header(const node_ptr & header)
+   {
+      tree_algorithms::init_header(header);
+      NodeTraits::set_balance(header, NodeTraits::zero()); 
+   }
+
+   //! Requires: header must be the header of a tree, z a node
+   //!    of that tree and z != header.
+   //!
+   //! Effects: Erases node "z" from the tree with header "header".
+   //! 
+   //! Complexity: Amortized constant time.
+   //! 
+   //! Throws: Nothing.
+   static node_ptr erase(const node_ptr & header, const node_ptr & z)
+   {
+      typename tree_algorithms::data_for_rebalance info;
+      tree_algorithms::erase(header, z, avltree_erase_fixup(), info);
+      node_ptr x = info.x;
+      node_ptr x_parent = info.x_parent;
+
+      //Rebalance avltree
+      rebalance_after_erasure(header, x, x_parent);
+      return z;
+   }
+
+   //! Requires: "cloner" must be a function
+   //!   object taking a node_ptr and returning a new cloned node of it. "disposer" must
+   //!   take a node_ptr and shouldn't throw.
+   //!
+   //! Effects: First empties target tree calling 
+   //!   void disposer::operator()(const node_ptr &) for every node of the tree
+   //!    except the header.
+   //!    
+   //!   Then, duplicates the entire tree pointed by "source_header" cloning each
+   //!   source node with node_ptr Cloner::operator()(const node_ptr &) to obtain 
+   //!   the nodes of the target tree. If "cloner" throws, the cloned target nodes
+   //!   are disposed using void disposer(const node_ptr &).
+   //! 
+   //! Complexity: Linear to the number of element of the source tree plus the.
+   //!   number of elements of tree target tree when calling this function.
+   //! 
+   //! Throws: If cloner functor throws. If this happens target nodes are disposed.
+   template 
+   static void clone
+      (const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
+   {
+      avltree_node_cloner new_cloner(cloner);
+      tree_algorithms::clone(source_header, target_header, new_cloner, disposer);
+   }
+
+   //! Requires: "disposer" must be an object function
+   //!   taking a node_ptr parameter and shouldn't throw.
+   //!
+   //! Effects: Empties the target tree calling 
+   //!   void disposer::operator()(const node_ptr &) for every node of the tree
+   //!    except the header.
+   //! 
+   //! Complexity: Linear to the number of element of the source tree plus the.
+   //!   number of elements of tree target tree when calling this function.
+   //! 
+   //! Throws: If cloner functor throws. If this happens target nodes are disposed.
+   template
+   static void clear_and_dispose(const node_ptr & header, Disposer disposer)
+   {  tree_algorithms::clear_and_dispose(header, disposer); }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   KeyNodePtrCompare is a function object that induces a strict weak
+   //!   ordering compatible with the strict weak ordering used to create the
+   //!   the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
+   //!
+   //! Effects: Returns an node_ptr to the first element that is
+   //!   not less than "key" according to "comp" or "header" if that element does
+   //!   not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If "comp" throws.
+   template
+   static node_ptr lower_bound
+      (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
+   {  return tree_algorithms::lower_bound(header, key, comp);  }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   KeyNodePtrCompare is a function object that induces a strict weak
+   //!   ordering compatible with the strict weak ordering used to create the
+   //!   the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
+   //!
+   //! Effects: Returns an node_ptr to the first element that is greater
+   //!   than "key" according to "comp" or "header" if that element does not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If "comp" throws.
+   template
+   static node_ptr upper_bound
+      (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
+   {  return tree_algorithms::upper_bound(header, key, comp);  }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   KeyNodePtrCompare is a function object that induces a strict weak
+   //!   ordering compatible with the strict weak ordering used to create the
+   //!   the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
+   //!
+   //! Effects: Returns an node_ptr to the element that is equivalent to
+   //!   "key" according to "comp" or "header" if that element does not exist.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If "comp" throws.
+   template
+   static node_ptr find
+      (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
+   {  return tree_algorithms::find(header, key, comp);  }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   KeyNodePtrCompare is a function object that induces a strict weak
+   //!   ordering compatible with the strict weak ordering used to create the
+   //!   the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
+   //!
+   //! Effects: Returns an a pair of node_ptr delimiting a range containing
+   //!   all elements that are equivalent to "key" according to "comp" or an
+   //!   empty range that indicates the position where those elements would be
+   //!   if they there are no equivalent elements.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: If "comp" throws.
+   template
+   static std::pair equal_range
+      (const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
+   {  return tree_algorithms::equal_range(header, key, comp);  }
+
+   //! Requires: "h" must be the header node of a tree.
+   //!   NodePtrCompare is a function object that induces a strict weak
+   //!   ordering compatible with the strict weak ordering used to create the
+   //!   the tree. NodePtrCompare compares two node_ptrs.
+   //!
+   //! Effects: Inserts new_node into the tree before the upper bound
+   //!   according to "comp".
+   //! 
+   //! Complexity: Average complexity for insert element is at
+   //!   most logarithmic.
+   //! 
+   //! Throws: If "comp" throws.
+   template
+   static node_ptr insert_equal_upper_bound
+      (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
+   {
+      tree_algorithms::insert_equal_upper_bound(h, new_node, comp);
+      rebalance_after_insertion(h, new_node);
+      return new_node;
+   }
+
+   //! Requires: "h" must be the header node of a tree.
+   //!   NodePtrCompare is a function object that induces a strict weak
+   //!   ordering compatible with the strict weak ordering used to create the
+   //!   the tree. NodePtrCompare compares two node_ptrs.
+   //!
+   //! Effects: Inserts new_node into the tree before the lower bound
+   //!   according to "comp".
+   //! 
+   //! Complexity: Average complexity for insert element is at
+   //!   most logarithmic.
+   //! 
+   //! Throws: If "comp" throws.
+   template
+   static node_ptr insert_equal_lower_bound
+      (const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
+   {
+      tree_algorithms::insert_equal_lower_bound(h, new_node, comp);
+      rebalance_after_insertion(h, new_node);
+      return new_node;
+   }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   NodePtrCompare is a function object that induces a strict weak
+   //!   ordering compatible with the strict weak ordering used to create the
+   //!   the tree. NodePtrCompare compares two node_ptrs. "hint" is node from
+   //!   the "header"'s tree.
+   //!   
+   //! Effects: Inserts new_node into the tree, using "hint" as a hint to
+   //!   where it will be inserted. If "hint" is the upper_bound
+   //!   the insertion takes constant time (two comparisons in the worst case).
+   //!
+   //! Complexity: Logarithmic in general, but it is amortized
+   //!   constant time if new_node is inserted immediately before "hint".
+   //! 
+   //! Throws: If "comp" throws.
+   template
+   static node_ptr insert_equal
+      (const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp)
+   {
+      tree_algorithms::insert_equal(header, hint, new_node, comp);
+      rebalance_after_insertion(header, new_node);
+      return new_node;
+   }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   "pos" must be a valid iterator or header (end) node.
+   //!   "pos" must be an iterator pointing to the successor to "new_node"
+   //!   once inserted according to the order of already inserted nodes. This function does not
+   //!   check "pos" and this precondition must be guaranteed by the caller.
+   //!   
+   //! Effects: Inserts new_node into the tree before "pos".
+   //!
+   //! Complexity: Constant-time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: If "pos" is not the successor of the newly inserted "new_node"
+   //! tree invariants might be broken.
+   static node_ptr insert_before
+      (const node_ptr & header, const node_ptr & pos, const node_ptr & new_node)
+   {
+      tree_algorithms::insert_before(header, pos, new_node);
+      rebalance_after_insertion(header, new_node);
+      return new_node;
+   }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   "new_node" must be, according to the used ordering no less than the
+   //!   greatest inserted key.
+   //!   
+   //! Effects: Inserts new_node into the tree before "pos".
+   //!
+   //! Complexity: Constant-time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: If "new_node" is less than the greatest inserted key
+   //! tree invariants are broken. This function is slightly faster than
+   //! using "insert_before".
+   static void push_back(const node_ptr & header, const node_ptr & new_node)
+   {
+      tree_algorithms::push_back(header, new_node);
+      rebalance_after_insertion(header, new_node);
+   }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   "new_node" must be, according to the used ordering, no greater than the
+   //!   lowest inserted key.
+   //!   
+   //! Effects: Inserts new_node into the tree before "pos".
+   //!
+   //! Complexity: Constant-time.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Note: If "new_node" is greater than the lowest inserted key
+   //! tree invariants are broken. This function is slightly faster than
+   //! using "insert_before".
+   static void push_front(const node_ptr & header, const node_ptr & new_node)
+   {
+      tree_algorithms::push_front(header, new_node);
+      rebalance_after_insertion(header, new_node);
+   }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   KeyNodePtrCompare is a function object that induces a strict weak
+   //!   ordering compatible with the strict weak ordering used to create the
+   //!   the tree. NodePtrCompare compares KeyType with a node_ptr.
+   //! 
+   //! Effects: Checks if there is an equivalent node to "key" in the
+   //!   tree according to "comp" and obtains the needed information to realize
+   //!   a constant-time node insertion if there is no equivalent node.
+   //!
+   //! Returns: If there is an equivalent value
+   //!   returns a pair containing a node_ptr to the already present node
+   //!   and false. If there is not equivalent key can be inserted returns true
+   //!   in the returned pair's boolean and fills "commit_data" that is meant to
+   //!   be used with the "insert_commit" function to achieve a constant-time
+   //!   insertion function.
+   //! 
+   //! Complexity: Average complexity is at most logarithmic.
+   //!
+   //! Throws: If "comp" throws.
+   //! 
+   //! Notes: This function is used to improve performance when constructing
+   //!   a node is expensive and the user does not want to have two equivalent nodes
+   //!   in the tree: if there is an equivalent value
+   //!   the constructed object must be discarded. Many times, the part of the
+   //!   node that is used to impose the order is much cheaper to construct
+   //!   than the node and this function offers the possibility to use that part
+   //!   to check if the insertion will be successful.
+   //!
+   //!   If the check is successful, the user can construct the node and use
+   //!   "insert_commit" to insert the node in constant-time. This gives a total
+   //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
+   //!
+   //!   "commit_data" remains valid for a subsequent "insert_unique_commit" only
+   //!   if no more objects are inserted or erased from the set.
+   template
+   static std::pair insert_unique_check
+      (const const_node_ptr & header,  const KeyType &key
+      ,KeyNodePtrCompare comp, insert_commit_data &commit_data)
+   {  return tree_algorithms::insert_unique_check(header, key, comp, commit_data);  }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   KeyNodePtrCompare is a function object that induces a strict weak
+   //!   ordering compatible with the strict weak ordering used to create the
+   //!   the tree. NodePtrCompare compares KeyType with a node_ptr.
+   //!   "hint" is node from the "header"'s tree.
+   //! 
+   //! Effects: Checks if there is an equivalent node to "key" in the
+   //!   tree according to "comp" using "hint" as a hint to where it should be
+   //!   inserted and obtains the needed information to realize
+   //!   a constant-time node insertion if there is no equivalent node. 
+   //!   If "hint" is the upper_bound the function has constant time 
+   //!   complexity (two comparisons in the worst case).
+   //!
+   //! Returns: If there is an equivalent value
+   //!   returns a pair containing a node_ptr to the already present node
+   //!   and false. If there is not equivalent key can be inserted returns true
+   //!   in the returned pair's boolean and fills "commit_data" that is meant to
+   //!   be used with the "insert_commit" function to achieve a constant-time
+   //!   insertion function.
+   //! 
+   //! Complexity: Average complexity is at most logarithmic, but it is
+   //!   amortized constant time if new_node should be inserted immediately before "hint".
+   //!
+   //! Throws: If "comp" throws.
+   //! 
+   //! Notes: This function is used to improve performance when constructing
+   //!   a node is expensive and the user does not want to have two equivalent nodes
+   //!   in the tree: if there is an equivalent value
+   //!   the constructed object must be discarded. Many times, the part of the
+   //!   node that is used to impose the order is much cheaper to construct
+   //!   than the node and this function offers the possibility to use that part
+   //!   to check if the insertion will be successful.
+   //!
+   //!   If the check is successful, the user can construct the node and use
+   //!   "insert_commit" to insert the node in constant-time. This gives a total
+   //!   logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
+   //!
+   //!   "commit_data" remains valid for a subsequent "insert_unique_commit" only
+   //!   if no more objects are inserted or erased from the set.
+   template
+   static std::pair insert_unique_check
+      (const const_node_ptr & header, const node_ptr &hint, const KeyType &key
+      ,KeyNodePtrCompare comp, insert_commit_data &commit_data)
+   {  return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data);  }
+
+   //! Requires: "header" must be the header node of a tree.
+   //!   "commit_data" must have been obtained from a previous call to
+   //!   "insert_unique_check". No objects should have been inserted or erased
+   //!   from the set between the "insert_unique_check" that filled "commit_data"
+   //!   and the call to "insert_commit". 
+   //! 
+   //! 
+   //! Effects: Inserts new_node in the set using the information obtained
+   //!   from the "commit_data" that a previous "insert_check" filled.
+   //!
+   //! Complexity: Constant time.
+   //!
+   //! Throws: Nothing.
+   //! 
+   //! Notes: This function has only sense if a "insert_unique_check" has been
+   //!   previously executed to fill "commit_data". No value should be inserted or
+   //!   erased between the "insert_check" and "insert_commit" calls.
+   static void insert_unique_commit
+      (const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data)
+   {
+      tree_algorithms::insert_unique_commit(header, new_value, commit_data);
+      rebalance_after_insertion(header, new_value);
+   }
+
+   //! Requires: "n" must be a node inserted in a tree.
+   //!
+   //! Effects: Returns a pointer to the header node of the tree.
+   //!
+   //! Complexity: Logarithmic.
+   //! 
+   //! Throws: Nothing.
+   static node_ptr get_header(const node_ptr & n)
+   {  return tree_algorithms::get_header(n);   }
+
+   /// @cond
+   private:
+
+   //! Requires: p is a node of a tree.
+   //! 
+   //! Effects: Returns true if p is the header of the tree.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   static bool is_header(const const_node_ptr & p)
+   {  return NodeTraits::get_balance(p) == NodeTraits::zero() && tree_algorithms::is_header(p);  }
+
+   static void rebalance_after_erasure(const node_ptr & header, const node_ptr & xnode, const node_ptr & xnode_parent)
+   {
+      node_ptr x(xnode), x_parent(xnode_parent);
+      for (node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)) {
+         const balance x_parent_balance = NodeTraits::get_balance(x_parent);
+         if(x_parent_balance == NodeTraits::zero()){
+            NodeTraits::set_balance(x_parent, 
+               (x == NodeTraits::get_right(x_parent) ? NodeTraits::negative() : NodeTraits::positive()));
+            break;       // the height didn't change, let's stop here
+         }
+         else if(x_parent_balance == NodeTraits::negative()){
+            if (x == NodeTraits::get_left(x_parent)) {
+               NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
+               x = x_parent;
+               x_parent = NodeTraits::get_parent(x_parent);
+            }
+            else {
+               // x is right child
+               // a is left child
+               node_ptr a = NodeTraits::get_left(x_parent);
+               BOOST_INTRUSIVE_INVARIANT_ASSERT(a);
+               if (NodeTraits::get_balance(a) == NodeTraits::positive()) {
+                  // a MUST have a right child
+                  BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(a));
+                  rotate_left_right(x_parent, header);
+                  x = NodeTraits::get_parent(x_parent);
+                  x_parent = NodeTraits::get_parent(x);
+               }
+               else {
+                  rotate_right(x_parent, header);
+                  x = NodeTraits::get_parent(x_parent);
+                  x_parent = NodeTraits::get_parent(x);
+               }
+
+               // if changed from negative to NodeTraits::positive(), no need to check above
+               if (NodeTraits::get_balance(x) == NodeTraits::positive()){
+                  break;
+               }
+            }
+         }
+         else if(x_parent_balance == NodeTraits::positive()){
+            if (x == NodeTraits::get_right(x_parent)) {
+               NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
+               x = x_parent;
+               x_parent = NodeTraits::get_parent(x_parent);
+            }
+            else {
+               // x is left child
+               // a is right child
+               node_ptr a = NodeTraits::get_right(x_parent);
+               BOOST_INTRUSIVE_INVARIANT_ASSERT(a);
+               if (NodeTraits::get_balance(a) == NodeTraits::negative()) {
+                  // a MUST have then a left child
+                  BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(a));
+                  rotate_right_left(x_parent, header);
+
+                  x = NodeTraits::get_parent(x_parent);
+                  x_parent = NodeTraits::get_parent(x);
+               }
+               else {
+                  rotate_left(x_parent, header);
+                  x = NodeTraits::get_parent(x_parent);
+                  x_parent = NodeTraits::get_parent(x);
+               }
+               // if changed from NodeTraits::positive() to negative, no need to check above
+               if (NodeTraits::get_balance(x) == NodeTraits::negative()){
+                  break;
+               }
+            }
+         }
+         else{
+            BOOST_INTRUSIVE_INVARIANT_ASSERT(false);  // never reached
+         }
+      }
+   }
+
+   static void rebalance_after_insertion(const node_ptr & header, const node_ptr & xnode)
+   {
+      node_ptr x(xnode);
+      NodeTraits::set_balance(x, NodeTraits::zero());
+      // Rebalance.
+      for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){
+         const balance x_parent_balance = NodeTraits::get_balance(NodeTraits::get_parent(x));
+
+         if(x_parent_balance == NodeTraits::zero()){
+            // if x is left, parent will have parent->bal_factor = negative
+            // else, parent->bal_factor = NodeTraits::positive()
+            NodeTraits::set_balance( NodeTraits::get_parent(x)
+                                    , x == NodeTraits::get_left(NodeTraits::get_parent(x))
+                                       ? NodeTraits::negative() : NodeTraits::positive()  );
+            x = NodeTraits::get_parent(x);
+         }
+         else if(x_parent_balance == NodeTraits::positive()){
+            // if x is a left child, parent->bal_factor = zero
+            if (x == NodeTraits::get_left(NodeTraits::get_parent(x)))
+               NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero());
+            else{        // x is a right child, needs rebalancing
+               if (NodeTraits::get_balance(x) == NodeTraits::negative())
+                  rotate_right_left(NodeTraits::get_parent(x), header);
+               else
+                  rotate_left(NodeTraits::get_parent(x), header);
+            }
+            break;
+         }
+         else if(x_parent_balance == NodeTraits::negative()){
+            // if x is a left child, needs rebalancing
+            if (x == NodeTraits::get_left(NodeTraits::get_parent(x))) {
+               if (NodeTraits::get_balance(x) == NodeTraits::positive())
+                  rotate_left_right(NodeTraits::get_parent(x), header);
+               else
+                  rotate_right(NodeTraits::get_parent(x), header);
+            }
+            else
+               NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero());
+            break;
+         }
+         else{
+            BOOST_INTRUSIVE_INVARIANT_ASSERT(false);  // never reached
+         }
+      }
+   }
+
+   static void left_right_balancing(const node_ptr & a, const node_ptr & b, const node_ptr & c)
+   {
+      // balancing...
+      const balance c_balance = NodeTraits::get_balance(c);
+      const balance zero_balance = NodeTraits::zero();
+      NodeTraits::set_balance(c, zero_balance);
+      if(c_balance == NodeTraits::negative()){
+         NodeTraits::set_balance(a, NodeTraits::positive());
+         NodeTraits::set_balance(b, zero_balance);
+      }
+      else if(c_balance == zero_balance){
+         NodeTraits::set_balance(a, zero_balance);
+         NodeTraits::set_balance(b, zero_balance);
+      }
+      else if(c_balance == NodeTraits::positive()){
+         NodeTraits::set_balance(a, zero_balance);
+         NodeTraits::set_balance(b, NodeTraits::negative());
+      }
+      else{
+         BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
+      }
+   }
+
+   static void rotate_left_right(const node_ptr a, const node_ptr & hdr)
+   {
+      //             |                               |         //
+      //             a(-2)                           c         //
+      //            / \                             / \        //
+      //           /   \        ==>                /   \       //
+      //      (pos)b    [g]                       b     a      //
+      //          / \                            / \   / \     //
+      //        [d]  c                         [d]  e f  [g]   //
+      //           / \                                         //
+      //          e   f                                        //
+      node_ptr b = NodeTraits::get_left(a), c = NodeTraits::get_right(b);
+      tree_algorithms::rotate_left(b, hdr);
+      tree_algorithms::rotate_right(a, hdr);
+      left_right_balancing(a, b, c);
+   }
+
+   static void rotate_right_left(const node_ptr a, const node_ptr & hdr)
+   {
+      //              |                               |           //
+      //              a(pos)                          c           //
+      //             / \                             / \          //
+      //            /   \                           /   \         //
+      //          [d]   b(neg)         ==>         a     b        //
+      //               / \                        / \   / \       //
+      //              c  [g]                    [d] e  f  [g]     //
+      //             / \                                          //
+      //            e   f                                         //
+      node_ptr b = NodeTraits::get_right(a), c = NodeTraits::get_left(b);
+      tree_algorithms::rotate_right(b, hdr);
+      tree_algorithms::rotate_left(a, hdr);
+      left_right_balancing(b, a, c);
+   }
+
+   static void rotate_left(const node_ptr x, const node_ptr & hdr)
+   {
+      const node_ptr y = NodeTraits::get_right(x);
+      tree_algorithms::rotate_left(x, hdr);
+
+      // reset the balancing factor
+      if (NodeTraits::get_balance(y) == NodeTraits::positive()) {
+         NodeTraits::set_balance(x, NodeTraits::zero());
+         NodeTraits::set_balance(y, NodeTraits::zero());
+      }
+      else {        // this doesn't happen during insertions
+         NodeTraits::set_balance(x, NodeTraits::positive());
+         NodeTraits::set_balance(y, NodeTraits::negative());
+      }
+   }
+
+   static void rotate_right(const node_ptr x, const node_ptr & hdr)
+   {
+      const node_ptr y = NodeTraits::get_left(x);
+      tree_algorithms::rotate_right(x, hdr);
+
+      // reset the balancing factor
+      if (NodeTraits::get_balance(y) == NodeTraits::negative()) {
+         NodeTraits::set_balance(x, NodeTraits::zero());
+         NodeTraits::set_balance(y, NodeTraits::zero());
+      }
+      else {        // this doesn't happen during insertions
+         NodeTraits::set_balance(x, NodeTraits::negative());
+         NodeTraits::set_balance(y, NodeTraits::positive());
+      }
+   }
+
+   /// @endcond
+};
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP
diff --git a/src/third_party/boost/boost/intrusive/bs_set_hook.hpp b/src/third_party/boost/boost/intrusive/bs_set_hook.hpp
new file mode 100644
index 00000000000..bf8e2de09a6
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/bs_set_hook.hpp
@@ -0,0 +1,296 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_BS_SET_HOOK_HPP
+#define BOOST_INTRUSIVE_BS_SET_HOOK_HPP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+
+/// @cond
+template
+struct get_bs_set_node_algo
+{
+   typedef detail::tree_algorithms > type;
+};
+/// @endcond
+
+//! Helper metafunction to define a \c bs_set_base_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+struct make_bs_set_base_hook
+{
+   /// @cond
+   typedef typename pack_options
+   #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      < hook_defaults, O1, O2, O3>
+   #else
+      < hook_defaults, Options...>
+   #endif
+   ::type packed_options;
+
+   //Scapegoat trees can't be auto unlink trees
+   BOOST_STATIC_ASSERT(((int)packed_options::link_mode != (int)auto_unlink));
+
+   typedef detail::generic_hook
+   < get_bs_set_node_algo
+   , typename packed_options::tag
+   , packed_options::link_mode
+   , detail::BsSetBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+//! Derive a class from bs_set_base_hook in order to store objects in 
+//! in a bs_set/bs_multiset. bs_set_base_hook holds the data necessary to maintain 
+//! the bs_set/bs_multiset and provides an appropriate value_traits class for bs_set/bs_multiset.
+//! 
+//! The hook admits the following options: \c tag<>, \c void_pointer<>,
+//! \c link_mode<>.
+//!
+//! \c tag<> defines a tag to identify the node. 
+//! The same tag value can be used in different classes, but if a class is 
+//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its 
+//! unique tag.
+//!
+//! \c void_pointer<> is the pointer type that will be used internally in the hook
+//! and the the container configured to use this hook.
+//!
+//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
+//! \c auto_unlink or \c safe_link).
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+class bs_set_base_hook
+   :  public make_bs_set_base_hook
+   #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+   #else
+      
+   #endif
+   ::type
+
+{
+   #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+   public:
+   //! Effects: If link_mode is \c auto_unlink or \c safe_link
+   //!   initializes the node to an unlinked state.
+   //! 
+   //! Throws: Nothing. 
+   bs_set_base_hook();
+
+   //! Effects: If link_mode is \c auto_unlink or \c safe_link
+   //!   initializes the node to an unlinked state. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing a copy-constructor
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   bs_set_base_hook(const bs_set_base_hook& );
+
+   //! Effects: Empty function. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing an assignment operator 
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   bs_set_base_hook& operator=(const bs_set_base_hook& );
+
+   //! Effects: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in a set an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
+   //! 
+   //! Throws: Nothing. 
+   ~bs_set_base_hook();
+
+   //! Effects: Swapping two nodes swaps the position of the elements 
+   //!   related to those nodes in one or two containers. That is, if the node 
+   //!   this is part of the element e1, the node x is part of the element e2 
+   //!   and both elements are included in the containers s1 and s2, then after 
+   //!   the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 
+   //!   at the position of e1. If one element is not in a container, then 
+   //!   after the swap-operation the other element is not in a container. 
+   //!   Iterators to e1 and e2 related to those nodes are invalidated. 
+   //!
+   //! Complexity: Constant 
+   //!
+   //! Throws: Nothing. 
+   void swap_nodes(bs_set_base_hook &other);
+
+   //! Precondition: link_mode must be \c safe_link or \c auto_unlink.
+   //!
+   //! Returns: true, if the node belongs to a container, false
+   //!   otherwise. This function can be used to test whether \c set::iterator_to 
+   //!   will return a valid iterator. 
+   //!
+   //! Complexity: Constant 
+   bool is_linked() const;
+
+   //! Effects: Removes the node if it's inserted in a container.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
+   //! 
+   //! Throws: Nothing. 
+   void unlink();
+   #endif
+};
+
+//! Helper metafunction to define a \c bs_set_member_hook that yields to the same
+//! type when the same options (either explicitly or implicitly) are used.
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+struct make_bs_set_member_hook
+{
+   /// @cond
+   typedef typename pack_options
+   #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      < hook_defaults, O1, O2, O3>
+   #else
+      < hook_defaults, Options...>
+   #endif
+
+   ::type packed_options;
+
+   //Scapegoat trees can't be auto unlink trees
+   BOOST_STATIC_ASSERT(((int)packed_options::link_mode != (int)auto_unlink));
+
+   typedef detail::generic_hook
+   < get_bs_set_node_algo
+   , member_tag
+   , packed_options::link_mode
+   , detail::NoBaseHook
+   > implementation_defined;
+   /// @endcond
+   typedef implementation_defined type;
+};
+
+//! Put a public data member bs_set_member_hook in order to store objects of this class in
+//! a bs_set/bs_multiset. bs_set_member_hook holds the data necessary for maintaining the
+//! bs_set/bs_multiset and provides an appropriate value_traits class for bs_set/bs_multiset.
+//! 
+//! The hook admits the following options: \c void_pointer<>, \c link_mode<>.
+//!
+//! \c void_pointer<> is the pointer type that will be used internally in the hook
+//! and the the container configured to use this hook.
+//!
+//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
+//! \c auto_unlink or \c safe_link).
+#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+template
+#else
+template
+#endif
+class bs_set_member_hook
+   :  public make_bs_set_member_hook
+      #if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
+      
+      #else
+      
+      #endif
+      ::type
+{
+   #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+   public:
+   //! Effects: If link_mode is \c auto_unlink or \c safe_link
+   //!   initializes the node to an unlinked state.
+   //! 
+   //! Throws: Nothing. 
+   bs_set_member_hook();
+
+   //! Effects: If link_mode is \c auto_unlink or \c safe_link
+   //!   initializes the node to an unlinked state. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing a copy-constructor
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   bs_set_member_hook(const bs_set_member_hook& );
+
+   //! Effects: Empty function. The argument is ignored.
+   //! 
+   //! Throws: Nothing. 
+   //! 
+   //! Rationale: Providing an assignment operator 
+   //!   makes classes using the hook STL-compliant without forcing the 
+   //!   user to do some additional work. \c swap can be used to emulate
+   //!   move-semantics.
+   bs_set_member_hook& operator=(const bs_set_member_hook& );
+
+   //! Effects: If link_mode is \c normal_link, the destructor does
+   //!   nothing (ie. no code is generated). If link_mode is \c safe_link and the
+   //!   object is stored in a set an assertion is raised. If link_mode is
+   //!   \c auto_unlink and \c is_linked() is true, the node is unlinked.
+   //! 
+   //! Throws: Nothing. 
+   ~bs_set_member_hook();
+
+   //! Effects: Swapping two nodes swaps the position of the elements 
+   //!   related to those nodes in one or two containers. That is, if the node 
+   //!   this is part of the element e1, the node x is part of the element e2 
+   //!   and both elements are included in the containers s1 and s2, then after 
+   //!   the swap-operation e1 is in s2 at the position of e2 and e2 is in s1 
+   //!   at the position of e1. If one element is not in a container, then 
+   //!   after the swap-operation the other element is not in a container. 
+   //!   Iterators to e1 and e2 related to those nodes are invalidated. 
+   //!
+   //! Complexity: Constant 
+   //!
+   //! Throws: Nothing. 
+   void swap_nodes(bs_set_member_hook &other);
+
+   //! Precondition: link_mode must be \c safe_link or \c auto_unlink.
+   //!
+   //! Returns: true, if the node belongs to a container, false
+   //!   otherwise. This function can be used to test whether \c set::iterator_to 
+   //!   will return a valid iterator. 
+   //!
+   //! Complexity: Constant 
+   bool is_linked() const;
+
+   //! Effects: Removes the node if it's inserted in a container.
+   //!   This function is only allowed if link_mode is \c auto_unlink.
+   //! 
+   //! Throws: Nothing. 
+   void unlink();
+   #endif
+};
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_BS_SET_HOOK_HPP
diff --git a/src/third_party/boost/boost/intrusive/circular_list_algorithms.hpp b/src/third_party/boost/boost/intrusive/circular_list_algorithms.hpp
new file mode 100644
index 00000000000..c5de423b629
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/circular_list_algorithms.hpp
@@ -0,0 +1,413 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP
+#define BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP
+
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+
+//! circular_list_algorithms provides basic algorithms to manipulate nodes
+//! forming a circular doubly linked list. An empty circular list is formed by a node
+//! whose pointers point to itself.
+//!
+//! circular_list_algorithms is configured with a NodeTraits class, which encapsulates the
+//! information about the node to be manipulated. NodeTraits must support the
+//! following interface:
+//!
+//! Typedefs:
+//!
+//! node: The type of the node that forms the circular list
+//!
+//! node_ptr: A pointer to a node
+//!
+//! const_node_ptr: A pointer to a const node
+//!
+//! Static functions:
+//!
+//! static node_ptr get_previous(const_node_ptr n);
+//! 
+//! static void set_previous(node_ptr n, node_ptr prev);
+//! 
+//! static node_ptr get_next(const_node_ptr n);
+//! 
+//! static void set_next(node_ptr n, node_ptr next);
+template
+class circular_list_algorithms
+{
+   public:
+   typedef typename NodeTraits::node            node;
+   typedef typename NodeTraits::node_ptr        node_ptr;
+   typedef typename NodeTraits::const_node_ptr  const_node_ptr;
+   typedef NodeTraits                           node_traits;
+
+   //! Effects: Constructs an non-used list element, so that
+   //! inited(this_node) == true
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void init(const node_ptr &this_node)
+   {
+      NodeTraits::set_next(this_node, node_ptr());
+      NodeTraits::set_previous(this_node, node_ptr());
+   }
+
+   //! Effects: Returns true is "this_node" is in a non-used state
+   //! as if it was initialized by the "init" function.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static bool inited(const const_node_ptr &this_node)  
+   {  return !NodeTraits::get_next(this_node); }
+
+   //! Effects: Constructs an empty list, making this_node the only
+   //!   node of the circular list:
+   //!  NodeTraits::get_next(this_node) == NodeTraits::get_previous(this_node)
+   //!  == this_node.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void init_header(const node_ptr &this_node)
+   {
+      NodeTraits::set_next(this_node, this_node);
+      NodeTraits::set_previous(this_node, this_node);
+   }
+
+
+   //! Requires: this_node must be in a circular list or be an empty circular list.
+   //! 
+   //! Effects: Returns true is "this_node" is the only node of a circular list:
+   //!  return NodeTraits::get_next(this_node) == this_node
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static bool unique(const const_node_ptr &this_node)
+   {
+      node_ptr next = NodeTraits::get_next(this_node);
+      return !next || next == this_node;
+   }
+
+   //! Requires: this_node must be in a circular list or be an empty circular list.
+   //! 
+   //! Effects: Returns the number of nodes in a circular list. If the circular list
+   //!  is empty, returns 1.
+   //! 
+   //! Complexity: Linear 
+   //! 
+   //! Throws: Nothing.
+   static std::size_t count(const const_node_ptr &this_node) 
+   {
+      std::size_t result = 0;
+      const_node_ptr p = this_node;
+      do{
+         p = NodeTraits::get_next(p);
+         ++result;
+      }while (p != this_node);
+      return result;
+   }
+
+   //! Requires: this_node must be in a circular list or be an empty circular list.
+   //! 
+   //! Effects: Unlinks the node from the circular list.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static node_ptr unlink(const node_ptr &this_node)
+   {
+      node_ptr next(NodeTraits::get_next(this_node));
+      if(next){
+         node_ptr prev(NodeTraits::get_previous(this_node));
+         NodeTraits::set_next(prev, next);
+         NodeTraits::set_previous(next, prev);
+         return next;
+      }
+      else{
+         return this_node;
+      }
+   }
+
+   //! Requires: b and e must be nodes of the same circular list or an empty range.
+   //! 
+   //! Effects: Unlinks the node [b, e) from the circular list.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void unlink(const node_ptr &b, const node_ptr &e)
+   {
+      if (b != e) {
+         node_ptr prevb(NodeTraits::get_previous(b));
+         NodeTraits::set_previous(e, prevb);
+         NodeTraits::set_next(prevb, e);
+      }
+   }
+
+   //! Requires: nxt_node must be a node of a circular list.
+   //! 
+   //! Effects: Links this_node before nxt_node in the circular list.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void link_before(const node_ptr &nxt_node, const node_ptr &this_node)
+   {
+      node_ptr prev(NodeTraits::get_previous(nxt_node));
+      NodeTraits::set_previous(this_node, prev);
+      NodeTraits::set_next(this_node, nxt_node);
+      //nxt_node might be an alias for prev->next_
+      //so use it before update it before NodeTraits::set_next(prev, ...)
+      //is called and the reference changes it's value
+      NodeTraits::set_previous(nxt_node, this_node);
+      NodeTraits::set_next(prev, this_node);
+   }
+
+   //! Requires: prev_node must be a node of a circular list.
+   //! 
+   //! Effects: Links this_node after prev_node in the circular list.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void link_after(const node_ptr &prev_node, const node_ptr &this_node)
+   {
+      node_ptr next(NodeTraits::get_next(prev_node));
+      NodeTraits::set_previous(this_node, prev_node);
+      NodeTraits::set_next(this_node, next);
+      //prev_node might be an alias for next->next_
+      //so use it before update it before NodeTraits::set_previous(next, ...)
+      //is called and the reference changes it's value
+      NodeTraits::set_next(prev_node, this_node);
+      NodeTraits::set_previous(next, this_node);
+   }
+
+   //! Requires: this_node and other_node must be nodes inserted
+   //!  in circular lists or be empty circular lists.
+   //! 
+   //! Effects: Swaps the position of the nodes: this_node is inserted in
+   //!   other_nodes position in the second circular list and the other_node is inserted
+   //!   in this_node's position in the first circular list.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+/*
+   static void swap_nodes(const node_ptr &this_node, const node_ptr &other_node)
+   {
+
+      if (other_node == this_node)
+         return;
+      bool empty1 = unique(this_node);
+      bool empty2 = unique(other_node);
+
+      node_ptr next_this(NodeTraits::get_next(this_node));
+      node_ptr prev_this(NodeTraits::get_previous(this_node));
+      node_ptr next_other(NodeTraits::get_next(other_node));
+      node_ptr prev_other(NodeTraits::get_previous(other_node));
+
+      //Do the swap
+      NodeTraits::set_next(this_node, next_other);
+      NodeTraits::set_next(other_node, next_this);
+
+      NodeTraits::set_previous(this_node, prev_other);
+      NodeTraits::set_previous(other_node, prev_this);
+
+      if (empty2){
+         init(this_node);
+      }
+      else{
+         NodeTraits::set_next(prev_other, this_node);
+         NodeTraits::set_previous(next_other, this_node);
+      }
+      if (empty1){
+         init(other_node);
+      }
+      else{
+         NodeTraits::set_next(prev_this, other_node);
+         NodeTraits::set_previous(next_this, other_node);
+      }
+   }
+*/
+
+   //Watanabe version
+   private: 
+   static void swap_prev(const node_ptr &this_node, const node_ptr &other_node) 
+   { 
+      node_ptr temp(NodeTraits::get_previous(this_node)); 
+      NodeTraits::set_previous(this_node, NodeTraits::get_previous(other_node)); 
+      NodeTraits::set_previous(other_node, temp); 
+   } 
+   static void swap_next(const node_ptr &this_node, const node_ptr &other_node) 
+   { 
+      node_ptr temp(NodeTraits::get_next(this_node)); 
+      NodeTraits::set_next(this_node, NodeTraits::get_next(other_node)); 
+      NodeTraits::set_next(other_node, temp); 
+   } 
+
+   public: 
+   static void swap_nodes(const node_ptr &this_node, const node_ptr &other_node) 
+   {
+      if (other_node == this_node)
+         return;
+      bool this_inited  = inited(this_node);
+      bool other_inited = inited(other_node);
+      if(this_inited){
+         init_header(this_node);
+      }
+      if(other_inited){
+         init_header(other_node);
+      }
+
+      node_ptr next_this(NodeTraits::get_next(this_node)); 
+      node_ptr prev_this(NodeTraits::get_previous(this_node)); 
+      node_ptr next_other(NodeTraits::get_next(other_node)); 
+      node_ptr prev_other(NodeTraits::get_previous(other_node)); 
+      //these first two swaps must happen before the other two 
+      swap_prev(next_this, next_other); 
+      swap_next(prev_this, prev_other); 
+      swap_next(this_node, other_node); 
+      swap_prev(this_node, other_node); 
+
+      if(this_inited){
+         init(other_node);
+      }
+      if(other_inited){
+         init(this_node);
+      }
+   }
+
+   //! Requires: b and e must be nodes of the same circular list or an empty range.
+   //!   and p must be a node of a different circular list or may not be an iterator in 
+   //    [b, e).
+   //! 
+   //! Effects: Removes the nodes from [b, e) range from their circular list and inserts
+   //!   them before p in p's circular list.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void transfer(const node_ptr &p, const node_ptr &b, const node_ptr &e)
+   {
+      if (b != e) {
+         node_ptr prev_p(NodeTraits::get_previous(p));
+         node_ptr prev_b(NodeTraits::get_previous(b));
+         node_ptr prev_e(NodeTraits::get_previous(e));
+         NodeTraits::set_next(prev_e, p);
+         NodeTraits::set_previous(p, prev_e);
+         NodeTraits::set_next(prev_b, e);
+         NodeTraits::set_previous(e, prev_b);
+         NodeTraits::set_next(prev_p, b);
+         NodeTraits::set_previous(b, prev_p);
+      }
+   }
+
+   //! Requires: i must a node of a circular list
+   //!   and p must be a node of a different circular list.
+   //! 
+   //! Effects: Removes the node i from its circular list and inserts
+   //!   it before p in p's circular list. 
+   //!   If p == i or p == NodeTraits::get_next(i), this function is a null operation.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void transfer(const node_ptr &p, const node_ptr &i)
+   {
+      node_ptr n(NodeTraits::get_next(i));
+      if(n != p && i != p){
+         node_ptr prev_p(NodeTraits::get_previous(p));
+         node_ptr prev_i(NodeTraits::get_previous(i));
+         NodeTraits::set_next(prev_p, i);
+         NodeTraits::set_previous(i, prev_p);
+         NodeTraits::set_next(i, p);
+         NodeTraits::set_previous(p, i);
+         NodeTraits::set_previous(n, prev_i);
+         NodeTraits::set_next(prev_i, n);
+
+      }
+   }
+
+   //! Effects: Reverses the order of elements in the list. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: This function is linear time.
+   static void reverse(const node_ptr &p)
+   {
+      node_ptr f(NodeTraits::get_next(p));
+      node_ptr i(NodeTraits::get_next(f)), e(p);
+      
+      while(i != e) {
+         node_ptr n = i;
+         i = NodeTraits::get_next(i);
+         transfer(f, n, i);
+         f = n;
+      }
+   }
+
+   //! Effects: Moves the node p n positions towards the end of the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear to the number of moved positions.
+   static void move_backwards(const node_ptr &p, std::size_t n)
+   {
+      //Null shift, nothing to do
+      if(!n) return;
+      node_ptr first  = NodeTraits::get_next(p);
+      //size() == 0 or 1, nothing to do
+      if(first == NodeTraits::get_previous(p)) return;
+      unlink(p);
+      //Now get the new first node
+      while(n--){
+         first = NodeTraits::get_next(first);
+      }
+      link_before(first, p);
+   }
+
+   //! Effects: Moves the node p n positions towards the beginning of the list.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear to the number of moved positions.
+   static void move_forward(const node_ptr &p, std::size_t n)
+   {
+      //Null shift, nothing to do
+      if(!n)   return;
+      node_ptr last  = NodeTraits::get_previous(p);
+      //size() == 0 or 1, nothing to do
+      if(last == NodeTraits::get_next(p))   return;
+
+      unlink(p);
+      //Now get the new last node
+      while(n--){
+         last = NodeTraits::get_previous(last);
+      }
+      link_after(last, p);
+   }
+};
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_CIRCULAR_LIST_ALGORITHMS_HPP
diff --git a/src/third_party/boost/boost/intrusive/circular_slist_algorithms.hpp b/src/third_party/boost/boost/intrusive/circular_slist_algorithms.hpp
new file mode 100644
index 00000000000..b843590c153
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/circular_slist_algorithms.hpp
@@ -0,0 +1,405 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP
+#define BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+
+//! circular_slist_algorithms provides basic algorithms to manipulate nodes
+//! forming a circular singly linked list. An empty circular list is formed by a node
+//! whose pointer to the next node points to itself.
+//!
+//! circular_slist_algorithms is configured with a NodeTraits class, which encapsulates the
+//! information about the node to be manipulated. NodeTraits must support the
+//! following interface:
+//!
+//! Typedefs:
+//!
+//! node: The type of the node that forms the circular list
+//!
+//! node_ptr: A pointer to a node
+//!
+//! const_node_ptr: A pointer to a const node
+//!
+//! Static functions:
+//!
+//! static node_ptr get_next(const_node_ptr n);
+//! 
+//! static void set_next(node_ptr n, node_ptr next);
+template
+class circular_slist_algorithms
+   /// @cond
+   : public detail::common_slist_algorithms
+   /// @endcond
+{
+   /// @cond
+   typedef detail::common_slist_algorithms base_t;
+   /// @endcond
+   public:
+   typedef typename NodeTraits::node            node;
+   typedef typename NodeTraits::node_ptr        node_ptr;
+   typedef typename NodeTraits::const_node_ptr  const_node_ptr;
+   typedef NodeTraits                           node_traits;
+
+   #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
+   //! Effects: Constructs an non-used list element, putting the next
+   //!   pointer to null:
+   //!  NodeTraits::get_next(this_node) == node_ptr()
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void init(node_ptr this_node);
+
+   //! Requires: this_node must be in a circular list or be an empty circular list.
+   //! 
+   //! Effects: Returns true is "this_node" is the only node of a circular list:
+   //!  or it's a not inserted node:
+   //!  return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node
+   //! 
+   //! Complexity: Constant
+   //! 
+   //! Throws: Nothing.
+   static bool unique(const_node_ptr this_node);
+
+   //! Effects: Returns true is "this_node" has the same state as
+   //!  if it was inited using "init(node_ptr)"
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static bool inited(const_node_ptr this_node);
+
+   //! Requires: prev_node must be in a circular list or be an empty circular list.
+   //! 
+   //! Effects: Unlinks the next node of prev_node from the circular list.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void unlink_after(node_ptr prev_node);
+
+   //! Requires: prev_node and last_node must be in a circular list
+   //!  or be an empty circular list.
+   //!
+   //! Effects: Unlinks the range (prev_node, last_node) from the circular list.
+   //!
+   //! Complexity: Constant 
+   //!
+   //! Throws: Nothing.
+   static void unlink_after(node_ptr prev_node, node_ptr last_node);
+
+   //! Requires: prev_node must be a node of a circular list.
+   //! 
+   //! Effects: Links this_node after prev_node in the circular list.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void link_after(node_ptr prev_node, node_ptr this_node);
+
+   //! Requires: b and e must be nodes of the same circular list or an empty range.
+   //!   and p must be a node of a different circular list.
+   //! 
+   //! Effects: Removes the nodes from (b, e] range from their circular list and inserts
+   //!   them after p in p's circular list.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void transfer_after(node_ptr p, node_ptr b, node_ptr e);
+
+   #endif   //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+
+   //! Effects: Constructs an empty list, making this_node the only
+   //!   node of the circular list:
+   //!  NodeTraits::get_next(this_node) == this_node.
+   //! 
+   //! Complexity: Constant 
+   //! 
+   //! Throws: Nothing.
+   static void init_header(const node_ptr &this_node)
+   {  NodeTraits::set_next(this_node, this_node);  } 
+
+   //! Requires: this_node and prev_init_node must be in the same circular list.
+   //! 
+   //! Effects: Returns the previous node of this_node in the circular list starting.
+   //!   the search from prev_init_node. The first node checked for equality
+   //!   is NodeTraits::get_next(prev_init_node).
+   //! 
+   //! Complexity: Linear to the number of elements between prev_init_node and this_node.
+   //! 
+   //! Throws: Nothing.
+   static node_ptr get_previous_node(const node_ptr &prev_init_node, const node_ptr &this_node)
+   {  return base_t::get_previous_node(prev_init_node, this_node);   }
+
+   //! Requires: this_node must be in a circular list or be an empty circular list.
+   //! 
+   //! Effects: Returns the previous node of this_node in the circular list.
+   //! 
+   //! Complexity: Linear to the number of elements in the circular list.
+   //! 
+   //! Throws: Nothing.
+   static node_ptr get_previous_node(const node_ptr & this_node)
+   {  return base_t::get_previous_node(this_node, this_node); }
+
+   //! Requires: this_node must be in a circular list or be an empty circular list.
+   //! 
+   //! Effects: Returns the previous node of the previous node of this_node in the circular list.
+   //! 
+   //! Complexity: Linear to the number of elements in the circular list.
+   //! 
+   //! Throws: Nothing.
+   static node_ptr get_previous_previous_node(const node_ptr & this_node)
+   {  return get_previous_previous_node(this_node, this_node); }
+
+   //! Requires: this_node and prev_prev_init_node must be in the same circular list.
+   //! 
+   //! Effects: Returns the previous node of the previous node of this_node in the
+   //!   circular list starting. the search from prev_init_node. The first node checked
+   //!   for equality is NodeTraits::get_next((NodeTraits::get_next(prev_prev_init_node)).
+   //! 
+   //! Complexity: Linear to the number of elements in the circular list.
+   //! 
+   //! Throws: Nothing.
+   static node_ptr get_previous_previous_node(const node_ptr & prev_prev_init_node, const node_ptr & this_node)
+   {
+      node_ptr p = prev_prev_init_node;
+      node_ptr p_next = NodeTraits::get_next(p);
+      node_ptr p_next_next = NodeTraits::get_next(p_next);
+      while (this_node != p_next_next){
+         p = p_next;
+         p_next = p_next_next;
+         p_next_next = NodeTraits::get_next(p_next);
+      }
+      return p;
+   }
+
+   //! Requires: this_node must be in a circular list or be an empty circular list.
+   //! 
+   //! Effects: Returns the number of nodes in a circular list. If the circular list
+   //!  is empty, returns 1.
+   //! 
+   //! Complexity: Linear 
+   //! 
+   //! Throws: Nothing.
+   static std::size_t count(const const_node_ptr & this_node) 
+   {
+      std::size_t result = 0;
+      const_node_ptr p = this_node;
+      do{
+         p = NodeTraits::get_next(p);
+         ++result;
+      } while (p != this_node);
+      return result;
+   }
+
+   //! Requires: this_node must be in a circular list, be an empty circular list or be inited.
+   //! 
+   //! Effects: Unlinks the node from the circular list.
+   //! 
+   //! Complexity: Linear to the number of elements in the circular list 
+   //! 
+   //! Throws: Nothing.
+   static void unlink(const node_ptr & this_node)
+   {
+      if(NodeTraits::get_next(this_node))
+         base_t::unlink_after(get_previous_node(this_node));
+   }
+
+   //! Requires: nxt_node must be a node of a circular list.
+   //! 
+   //! Effects: Links this_node before nxt_node in the circular list.
+   //! 
+   //! Complexity: Linear to the number of elements in the circular list. 
+   //! 
+   //! Throws: Nothing.
+   static void link_before (const node_ptr & nxt_node, const node_ptr & this_node)
+   {  base_t::link_after(get_previous_node(nxt_node), this_node);   }
+
+   //! Requires: this_node and other_node must be nodes inserted
+   //!  in circular lists or be empty circular lists.
+   //! 
+   //! Effects: Swaps the position of the nodes: this_node is inserted in
+   //!   other_nodes position in the second circular list and the other_node is inserted
+   //!   in this_node's position in the first circular list.
+   //! 
+   //! Complexity: Linear to number of elements of both lists 
+   //! 
+   //! Throws: Nothing.
+   static void swap_nodes(const node_ptr & this_node, const node_ptr & other_node)
+   {
+      if (other_node == this_node)
+         return;
+      bool this_inited  = base_t::inited(this_node);
+      bool other_inited = base_t::inited(other_node);
+      if(this_inited){
+         base_t::init_header(this_node);
+      }
+      if(other_inited){
+         base_t::init_header(other_node);
+      }
+
+      bool empty1 = base_t::unique(this_node);
+      bool empty2 = base_t::unique(other_node);
+      node_ptr prev_this (get_previous_node(this_node));
+      node_ptr prev_other(get_previous_node(other_node));
+
+      node_ptr this_next (NodeTraits::get_next(this_node));
+      node_ptr other_next(NodeTraits::get_next(other_node));
+      NodeTraits::set_next(this_node, other_next);
+      NodeTraits::set_next(other_node, this_next);
+      NodeTraits::set_next(empty1 ? other_node : prev_this, other_node);
+      NodeTraits::set_next(empty2 ? this_node  : prev_other, this_node);
+
+      if(this_inited){
+         base_t::init(other_node);
+      }
+      if(other_inited){
+         base_t::init(this_node);
+      }
+   }
+
+   //! Effects: Reverses the order of elements in the list. 
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: This function is linear to the contained elements.
+   static void reverse(const node_ptr & p)
+   {
+      node_ptr i = NodeTraits::get_next(p), e(p); 
+      for (;;) {
+         node_ptr nxt(NodeTraits::get_next(i));
+         if (nxt == e)
+            break;
+         base_t::transfer_after(e, i, nxt);
+      }
+   }
+
+   //! Effects: Moves the node p n positions towards the end of the list.
+   //!
+   //! Returns: The previous node of p after the function if there has been any movement,
+   //!   Null if n leads to no movement.
+   //!
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear to the number of elements plus the number moved positions.
+   static node_ptr move_backwards(const node_ptr & p, std::size_t n)
+   {
+      //Null shift, nothing to do
+      if(!n) return node_ptr();
+      node_ptr first  = NodeTraits::get_next(p);
+
+      //count() == 1 or 2, nothing to do
+      if(NodeTraits::get_next(first) == p)
+         return node_ptr();
+
+      bool end_found = false;
+      node_ptr new_last = node_ptr();
+
+      //Now find the new last node according to the shift count.
+      //If we find p before finding the new last node
+      //unlink p, shortcut the search now that we know the size of the list
+      //and continue.
+      for(std::size_t i = 1; i <= n; ++i){
+         new_last = first;
+         first = NodeTraits::get_next(first);
+         if(first == p){
+            //Shortcut the shift with the modulo of the size of the list
+            n %= i;
+            if(!n)
+               return node_ptr();
+            i = 0;
+            //Unlink p and continue the new first node search
+            first = NodeTraits::get_next(p);
+            base_t::unlink_after(new_last);
+            end_found = true;
+         }
+      }
+
+      //If the p has not been found in the previous loop, find it
+      //starting in the new first node and unlink it
+      if(!end_found){
+         base_t::unlink_after(base_t::get_previous_node(first, p));
+      }
+
+      //Now link p after the new last node
+      base_t::link_after(new_last, p);
+      return new_last;
+   }
+
+   //! Effects: Moves the node p n positions towards the beginning of the list.
+   //! 
+   //! Returns: The previous node of p after the function if there has been any movement,
+   //!   Null if n leads equals to no movement.
+   //! 
+   //! Throws: Nothing.
+   //! 
+   //! Complexity: Linear to the number of elements plus the number moved positions.
+   static node_ptr move_forward(const node_ptr & p, std::size_t n)
+   {
+      //Null shift, nothing to do
+      if(!n) return node_ptr();
+      node_ptr first  = node_traits::get_next(p);
+
+      //count() == 1 or 2, nothing to do
+      if(node_traits::get_next(first) == p) return node_ptr();
+
+      //Iterate until p is found to know where the current last node is.
+      //If the shift count is less than the size of the list, we can also obtain
+      //the position of the new last node after the shift.
+      node_ptr old_last(first), next_to_it, new_last(p);
+      std::size_t distance = 1;
+      while(p != (next_to_it = node_traits::get_next(old_last))){
+         if(++distance > n)
+            new_last = node_traits::get_next(new_last);
+         old_last = next_to_it;
+      }
+      //If the shift was bigger or equal than the size, obtain the equivalent
+      //forward shifts and find the new last node.
+      if(distance <= n){
+         //Now find the equivalent forward shifts.
+         //Shortcut the shift with the modulo of the size of the list
+         std::size_t new_before_last_pos = (distance - (n % distance))% distance;
+         //If the shift is a multiple of the size there is nothing to do
+         if(!new_before_last_pos)   return node_ptr();
+         
+         for( new_last = p
+            ; new_before_last_pos--
+            ; new_last = node_traits::get_next(new_last)){
+            //empty
+         }
+      }
+
+      //Now unlink p and link it after the new last node
+      base_t::unlink_after(old_last);
+      base_t::link_after(new_last, p);
+      return new_last;
+   }
+};
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP
diff --git a/src/third_party/boost/boost/intrusive/derivation_value_traits.hpp b/src/third_party/boost/boost/intrusive/derivation_value_traits.hpp
new file mode 100644
index 00000000000..38c5aa57cfe
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/derivation_value_traits.hpp
@@ -0,0 +1,70 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
+#define BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
+
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+
+//!This value traits template is used to create value traits
+//!from user defined node traits where value_traits::value_type will
+//!derive from node_traits::node
+template
+struct derivation_value_traits
+{
+   public:
+   typedef NodeTraits                                                node_traits;
+   typedef T                                                         value_type;
+   typedef typename node_traits::node                                node;
+   typedef typename node_traits::node_ptr                            node_ptr;
+   typedef typename node_traits::const_node_ptr                      const_node_ptr;
+   typedef typename boost::pointer_to_other::type       pointer;
+   typedef typename boost::pointer_to_other::type const_pointer;
+   typedef typename boost::intrusive::
+      pointer_traits::reference                             reference;
+   typedef typename boost::intrusive::
+      pointer_traits::reference                       const_reference;
+   static const link_mode_type link_mode = LinkMode;
+
+   static node_ptr to_node_ptr(reference value)
+   { return node_ptr(&value); }
+
+   static const_node_ptr to_node_ptr(const_reference value)
+   { return node_ptr(&value); }
+
+   static pointer to_value_ptr(const node_ptr &n) 
+   {
+//      This still fails in gcc < 4.4 so forget about it
+//      using ::boost::static_pointer_cast;
+//      return static_pointer_cast(n));
+      return pointer(&static_cast(*n));
+   }
+
+   static const_pointer to_value_ptr(const const_node_ptr &n)
+   {
+//      This still fails in gcc < 4.4 so forget about it
+//      using ::boost::static_pointer_cast;
+//      return static_pointer_cast(n));
+      return const_pointer(&static_cast(*n));
+   }
+};
+
+} //namespace intrusive 
+} //namespace boost 
+
+#endif //BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/any_node_and_algorithms.hpp b/src/third_party/boost/boost/intrusive/detail/any_node_and_algorithms.hpp
new file mode 100644
index 00000000000..bda9ad3c45a
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/any_node_and_algorithms.hpp
@@ -0,0 +1,297 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_ANY_NODE_HPP
+#define BOOST_INTRUSIVE_ANY_NODE_HPP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include  
+#include 
+
+namespace boost {
+namespace intrusive {
+
+template
+struct any_node
+{
+   typedef typename pointer_traits
+      ::template rebind_pointer::type   node_ptr;
+   node_ptr    node_ptr_1;
+   node_ptr    node_ptr_2;
+   node_ptr    node_ptr_3;
+   std::size_t size_t_1;
+};
+
+template
+struct any_list_node_traits
+{
+   typedef any_node node;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type node_ptr;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type const_node_ptr;
+
+   static const node_ptr &get_next(const const_node_ptr & n)
+   {  return n->node_ptr_1;  }
+
+   static void set_next(const node_ptr & n, const node_ptr & next)
+   {  n->node_ptr_1 = next;  }
+
+   static const node_ptr &get_previous(const const_node_ptr & n)
+   {  return n->node_ptr_2;  }
+
+   static void set_previous(const node_ptr & n, const node_ptr & prev)
+   {  n->node_ptr_2 = prev;  }
+};
+
+
+template
+struct any_slist_node_traits
+{
+   typedef any_node node;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type         node_ptr;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type   const_node_ptr;
+
+   static const node_ptr &get_next(const const_node_ptr & n)
+   {  return n->node_ptr_1;  }
+
+   static void set_next(const node_ptr & n, const node_ptr & next)
+   {  n->node_ptr_1 = next;  }
+};
+
+
+template
+struct any_unordered_node_traits
+   :  public any_slist_node_traits
+{
+   typedef any_slist_node_traits                  reduced_slist_node_traits;
+   typedef typename reduced_slist_node_traits::node            node;
+   typedef typename reduced_slist_node_traits::node_ptr        node_ptr;
+   typedef typename reduced_slist_node_traits::const_node_ptr  const_node_ptr;
+
+   static const bool store_hash        = true;
+   static const bool optimize_multikey = true;
+
+   static const node_ptr &get_next(const const_node_ptr & n)
+   {  return n->node_ptr_1;   }
+
+   static void set_next(const node_ptr & n, const node_ptr & next)
+   {  n->node_ptr_1 = next;  }
+
+   static node_ptr get_prev_in_group(const const_node_ptr & n)
+   {  return n->node_ptr_2;  }
+
+   static void set_prev_in_group(const node_ptr & n, const node_ptr & prev)
+   {  n->node_ptr_2 = prev;  }
+
+   static std::size_t get_hash(const const_node_ptr & n)
+   {  return n->size_t_1;  }  
+
+   static void set_hash(const node_ptr & n, std::size_t h)
+   {  n->size_t_1 = h;  }  
+};
+
+
+template
+struct any_rbtree_node_traits
+{
+   typedef any_node node;
+
+   typedef typename pointer_traits
+      ::template rebind_pointer::type         node_ptr;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type   const_node_ptr;
+
+   typedef std::size_t color;
+
+   static const node_ptr &get_parent(const const_node_ptr & n)
+   {  return n->node_ptr_1;  }
+
+   static void set_parent(const node_ptr & n, const node_ptr & p)
+   {  n->node_ptr_1 = p;  }
+
+   static const node_ptr &get_left(const const_node_ptr & n)
+   {  return n->node_ptr_2;  }
+
+   static void set_left(const node_ptr & n, const node_ptr & l)
+   {  n->node_ptr_2 = l;  }
+
+   static const node_ptr &get_right(const const_node_ptr & n)
+   {  return n->node_ptr_3;  }
+
+   static void set_right(const node_ptr & n, const node_ptr & r)
+   {  n->node_ptr_3 = r;  }
+
+   static color get_color(const const_node_ptr & n)
+   {  return n->size_t_1;  }
+
+   static void set_color(const node_ptr & n, color c)
+   {  n->size_t_1 = c;  }
+
+   static color black()
+   {  return 0u;  }
+
+   static color red()
+   {  return 1u;  }
+};
+
+
+template
+struct any_avltree_node_traits
+{
+   typedef any_node node;
+
+   typedef typename pointer_traits
+      ::template rebind_pointer::type         node_ptr;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type   const_node_ptr;
+   typedef std::size_t balance;
+
+   static const node_ptr &get_parent(const const_node_ptr & n)
+   {  return n->node_ptr_1;  }
+
+   static void set_parent(const node_ptr & n, const node_ptr & p)
+   {  n->node_ptr_1 = p;  }
+
+   static const node_ptr &get_left(const const_node_ptr & n)
+   {  return n->node_ptr_2;  }
+
+   static void set_left(const node_ptr & n, const node_ptr & l)
+   {  n->node_ptr_2 = l;  }
+
+   static const node_ptr &get_right(const const_node_ptr & n)
+   {  return n->node_ptr_3;  }
+
+   static void set_right(const node_ptr & n, const node_ptr & r)
+   {  n->node_ptr_3 = r;  }
+
+   static balance get_balance(const const_node_ptr & n)
+   {  return n->size_t_1;  }
+
+   static void set_balance(const node_ptr & n, balance b)
+   {  n->size_t_1 = b;  }
+
+   static balance negative()
+   {  return 0u;  }
+
+   static balance zero()
+   {  return 1u;  }
+
+   static balance positive()
+   {  return 2u;  }
+};
+
+
+template
+struct any_tree_node_traits
+{
+   typedef any_node node;
+
+   typedef typename pointer_traits
+      ::template rebind_pointer::type         node_ptr;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type   const_node_ptr;
+
+   static const node_ptr &get_parent(const const_node_ptr & n)
+   {  return n->node_ptr_1;  }
+
+   static void set_parent(const node_ptr & n, const node_ptr & p)
+   {  n->node_ptr_1 = p;  }
+
+   static const node_ptr &get_left(const const_node_ptr & n)
+   {  return n->node_ptr_2;  }
+
+   static void set_left(const node_ptr & n, const node_ptr & l)
+   {  n->node_ptr_2 = l;  }
+
+   static const node_ptr &get_right(const const_node_ptr & n)
+   {  return n->node_ptr_3;  }
+
+   static void set_right(const node_ptr & n, const node_ptr & r)
+   {  n->node_ptr_3 = r;  }
+};
+
+template
+class any_node_traits
+{
+   public:
+   typedef any_node          node;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type         node_ptr;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type   const_node_ptr;
+};
+
+template
+class any_algorithms
+{
+   template 
+   static void function_not_available_for_any_hooks(typename detail::enable_if >::type)
+   {}
+
+   public:
+   typedef any_node             node;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type         node_ptr;
+   typedef typename pointer_traits
+      ::template rebind_pointer::type   const_node_ptr;
+   typedef any_node_traits      node_traits;
+
+   //! Requires: node must not be part of any tree.
+   //!
+   //! Effects: After the function unique(node) == true.
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   //!
+   //! Nodes: If node is inserted in a tree, this function corrupts the tree.
+   static void init(const node_ptr & node)
+   {  node->node_ptr_1 = 0;   };
+
+   //! Effects: Returns true if node is in the same state as if called init(node)
+   //! 
+   //! Complexity: Constant.
+   //! 
+   //! Throws: Nothing.
+   static bool inited(const const_node_ptr & node)
+   {  return !node->node_ptr_1;  };
+
+   static bool unique(const const_node_ptr & node)
+   {  return 0 == node->node_ptr_1; }
+
+   static void unlink(const node_ptr &)
+   {
+      //Auto-unlink hooks and unlink() are not available for any hooks
+      any_algorithms::template function_not_available_for_any_hooks();
+   }
+
+   static void swap_nodes(const node_ptr & l, const node_ptr & r)
+   {
+      //Any nodes have no swap_nodes capability because they don't know
+      //what algorithm they must use to unlink the node from the container
+      any_algorithms::template function_not_available_for_any_hooks();
+   }
+};
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_ANY_NODE_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/assert.hpp b/src/third_party/boost/boost/intrusive/detail/assert.hpp
new file mode 100644
index 00000000000..cfe392bfb08
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/assert.hpp
@@ -0,0 +1,41 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
+#define BOOST_INTRUSIVE_DETAIL_ASSERT_HPP 
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#if !defined(BOOST_INTRUSIVE_INVARIANT_ASSERT)
+   #include 
+   #define BOOST_INTRUSIVE_INVARIANT_ASSERT BOOST_ASSERT
+#elif defined(BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE)
+   #include BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE
+#endif
+
+#if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT)
+   #include 
+   #define BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT BOOST_ASSERT
+#elif defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE)
+   #include BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE
+#endif
+
+#if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT)
+   #include 
+   #define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT BOOST_ASSERT
+#elif defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE)
+   #include BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE
+#endif
+
+#endif //BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/avltree_node.hpp b/src/third_party/boost/boost/intrusive/detail/avltree_node.hpp
new file mode 100644
index 00000000000..dc600e6695f
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/avltree_node.hpp
@@ -0,0 +1,185 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_AVLTREE_NODE_HPP
+#define BOOST_INTRUSIVE_AVLTREE_NODE_HPP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+//                Generic node_traits for any pointer type                 //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+//This is the compact representation: 3 pointers
+template
+struct compact_avltree_node
+{
+   typedef typename pointer_traits
+      ::template rebind_pointer
+          >::type node_ptr;
+   enum balance { negative_t, zero_t, positive_t };
+   node_ptr parent_, left_, right_;
+};
+
+//This is the normal representation: 3 pointers + enum
+template
+struct avltree_node
+{
+   typedef typename pointer_traits
+      ::template rebind_pointer
+          >::type node_ptr;
+   enum balance { negative_t, zero_t, positive_t };
+   node_ptr parent_, left_, right_;
+   balance balance_;
+};
+
+//This is the default node traits implementation
+//using a node with 3 generic pointers plus an enum
+template
+struct default_avltree_node_traits_impl
+{
+   typedef avltree_node node;
+
+   typedef typename pointer_traits
+      ::template rebind_pointer
+         ::type node_ptr;
+   typedef typename pointer_traits
+      ::template rebind_pointer
+         ::type const_node_ptr;
+
+   typedef typename node::balance balance;
+
+   static const node_ptr & get_parent(const const_node_ptr & n)
+   {  return n->parent_;  }
+
+   static void set_parent(const node_ptr & n, const node_ptr & p)
+   {  n->parent_ = p;  }
+
+   static const node_ptr & get_left(const const_node_ptr & n)
+   {  return n->left_;  }
+
+   static void set_left(const node_ptr & n, const node_ptr & l)
+   {  n->left_ = l;  }
+
+   static const node_ptr & get_right(const const_node_ptr & n)
+   {  return n->right_;  }
+
+   static void set_right(const node_ptr & n, const node_ptr & r)
+   {  n->right_ = r;  }
+
+   static balance get_balance(const const_node_ptr & n)
+   {  return n->balance_;  }
+
+   static void set_balance(const node_ptr & n, balance b)
+   {  n->balance_ = b;  }
+
+   static balance negative()
+   {  return node::negative_t;  }
+
+   static balance zero()
+   {  return node::zero_t;  }
+
+   static balance positive()
+   {  return node::positive_t;  }
+};
+
+//This is the compact node traits implementation
+//using a node with 3 generic pointers
+template
+struct compact_avltree_node_traits_impl
+{
+   typedef compact_avltree_node node;
+
+   typedef typename pointer_traits
+      ::template rebind_pointer
+         ::type node_ptr;
+   typedef typename pointer_traits
+      ::template rebind_pointer
+         ::type const_node_ptr;
+   typedef typename node::balance balance;
+
+   typedef pointer_plus_bits ptr_bit;
+
+   static node_ptr get_parent(const const_node_ptr & n)
+   {  return ptr_bit::get_pointer(n->parent_);  }
+
+   static void set_parent(const node_ptr & n, const node_ptr & p)
+   {  ptr_bit::set_pointer(n->parent_, p);  }
+
+   static const node_ptr & get_left(const const_node_ptr & n)
+   {  return n->left_;  }
+
+   static void set_left(const node_ptr & n, const node_ptr & l)
+   {  n->left_ = l;  }
+
+   static const node_ptr & get_right(const const_node_ptr & n)
+   {  return n->right_;  }
+
+   static void set_right(const node_ptr & n, const node_ptr & r)
+   {  n->right_ = r;  }
+
+   static balance get_balance(const const_node_ptr & n)
+   {  return (balance)ptr_bit::get_bits(n->parent_);  }
+
+   static void set_balance(const node_ptr & n, balance b)
+   {  ptr_bit::set_bits(n->parent_, (std::size_t)b);  }
+
+   static balance negative()
+   {  return node::negative_t;  }
+
+   static balance zero()
+   {  return node::zero_t;  }
+
+   static balance positive()
+   {  return node::positive_t;  }
+};
+
+//Dispatches the implementation based on the boolean
+template
+struct avltree_node_traits_dispatch
+   :  public default_avltree_node_traits_impl
+{};
+
+template
+struct avltree_node_traits_dispatch
+   :  public compact_avltree_node_traits_impl
+{};
+
+//Inherit from the detail::link_dispatch depending on the embedding capabilities
+template
+struct avltree_node_traits
+   :  public avltree_node_traits_dispatch
+         < VoidPointer
+         , OptimizeSize &&
+            max_pointer_plus_bits
+            < VoidPointer
+            , detail::alignment_of >::value 
+            >::value >= 2u
+         >
+{};
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_AVLTREE_NODE_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/clear_on_destructor_base.hpp b/src/third_party/boost/boost/intrusive/detail/clear_on_destructor_base.hpp
new file mode 100644
index 00000000000..6765dfa05df
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/clear_on_destructor_base.hpp
@@ -0,0 +1,36 @@
+//////}  // ///////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2009. 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DETAIL_CLEAR_ON_DESTRUCTOR_HPP
+#define BOOST_INTRUSIVE_DETAIL_CLEAR_ON_DESTRUCTOR_HPP
+
+#include 
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template
+class clear_on_destructor_base
+{
+   protected:
+   ~clear_on_destructor_base()
+   {
+      static_cast(this)->clear();
+   }
+};
+
+}  // namespace detail {
+}  // namespace intrusive {
+}  // namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_INTRUSIVE_DETAIL_CLEAR_ON_DESTRUCTOR_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/common_slist_algorithms.hpp b/src/third_party/boost/boost/intrusive/detail/common_slist_algorithms.hpp
new file mode 100644
index 00000000000..15d6b3ff29b
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/common_slist_algorithms.hpp
@@ -0,0 +1,103 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP
+#define BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP
+
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template
+class common_slist_algorithms
+{
+   public:
+   typedef typename NodeTraits::node            node;
+   typedef typename NodeTraits::node_ptr        node_ptr;
+   typedef typename NodeTraits::const_node_ptr  const_node_ptr;
+   typedef NodeTraits                           node_traits;
+
+   static node_ptr get_previous_node(const node_ptr & prev_init_node, const node_ptr & this_node)
+   {
+      node_ptr p = prev_init_node;
+      for( node_ptr p_next
+         ; this_node != (p_next = NodeTraits::get_next(p))
+         ; p = p_next){
+         //Logic error: possible use of linear lists with
+         //operations only permitted with lists
+         BOOST_INTRUSIVE_INVARIANT_ASSERT(p);
+      }
+      return p;
+   }
+
+   static void init_header(const node_ptr & this_node)  
+   {  NodeTraits::set_next(this_node, this_node);  }  
+
+   static void init(const node_ptr & this_node)  
+   {  NodeTraits::set_next(this_node, node_ptr());  }  
+
+   static bool unique(const const_node_ptr & this_node)
+   {
+      node_ptr next = NodeTraits::get_next(this_node);
+      return !next || next == this_node;
+   }
+
+   static bool inited(const const_node_ptr & this_node)  
+   {  return !NodeTraits::get_next(this_node); }
+
+   static void unlink_after(const node_ptr & prev_node)
+   {
+      const_node_ptr this_node(NodeTraits::get_next(prev_node));
+      NodeTraits::set_next(prev_node, NodeTraits::get_next(this_node));
+   }
+
+   static void unlink_after(const node_ptr & prev_node, const node_ptr & last_node)
+   {  NodeTraits::set_next(prev_node, last_node);  }
+
+   static void link_after(const node_ptr & prev_node, const node_ptr & this_node)
+   {
+      NodeTraits::set_next(this_node, NodeTraits::get_next(prev_node));
+      NodeTraits::set_next(prev_node, this_node);
+   }
+
+   static void incorporate_after(const node_ptr & bp, const node_ptr & b, const node_ptr & be)
+   {
+      node_ptr p(NodeTraits::get_next(bp));
+      NodeTraits::set_next(bp, b);
+      NodeTraits::set_next(be, p);
+   }
+   
+   static void transfer_after(const node_ptr & bp, const node_ptr & bb, const node_ptr & be)
+   {
+      if (bp != bb && bp != be && bb != be) {
+         node_ptr next_b = NodeTraits::get_next(bb);
+         node_ptr next_e = NodeTraits::get_next(be);
+         node_ptr next_p = NodeTraits::get_next(bp);
+         NodeTraits::set_next(bb, next_e);
+         NodeTraits::set_next(be, next_p);
+         NodeTraits::set_next(bp, next_b);
+      }
+   }
+};
+
+} //namespace detail
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/config_begin.hpp b/src/third_party/boost/boost/intrusive/detail/config_begin.hpp
new file mode 100644
index 00000000000..bb126fcdf06
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/config_begin.hpp
@@ -0,0 +1,52 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_CONFIG_INCLUDED
+#define BOOST_INTRUSIVE_CONFIG_INCLUDED
+#include 
+#endif
+
+#ifdef BOOST_MSVC
+
+   #pragma warning (push)
+   //
+   //'function' : resolved overload was found by argument-dependent lookup
+   //A function found by argument-dependent lookup (Koenig lookup) was eventually 
+   //chosen by overload resolution.
+   //
+   //In Visual C++ .NET and earlier compilers, a different function would have 
+   //been called. To pick the original function, use an explicitly qualified name.
+   //
+
+   //warning C4275: non dll-interface class 'x' used as base for
+   //dll-interface class 'Y'
+   #pragma warning (disable : 4275)
+   //warning C4251: 'x' : class 'y' needs to have dll-interface to
+   //be used by clients of class 'z'
+   #pragma warning (disable : 4251)
+   #pragma warning (disable : 4675)
+   #pragma warning (disable : 4996)
+   #pragma warning (disable : 4503)
+   #pragma warning (disable : 4284) // odd return type for operator->
+   #pragma warning (disable : 4244) // possible loss of data
+   #pragma warning (disable : 4521) ////Disable "multiple copy constructors specified"
+   #pragma warning (disable : 4522)
+   #pragma warning (disable : 4146)
+   #pragma warning (disable : 4267) //conversion from 'X' to 'Y', possible loss of data
+   #pragma warning (disable : 4127) //conditional expression is constant
+   #pragma warning (disable : 4706) //assignment within conditional expression
+   #pragma warning (disable : 4541) //'typeid' used on polymorphic type 'boost::exception' with /GR-
+   #pragma warning (disable : 4512) //'typeid' used on polymorphic type 'boost::exception' with /GR-
+#endif
+
+//#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE
+//#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
diff --git a/src/third_party/boost/boost/intrusive/detail/config_end.hpp b/src/third_party/boost/boost/intrusive/detail/config_end.hpp
new file mode 100644
index 00000000000..4277cb576f8
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/config_end.hpp
@@ -0,0 +1,15 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined BOOST_MSVC
+   #pragma warning (pop)
+#endif
diff --git a/src/third_party/boost/boost/intrusive/detail/ebo_functor_holder.hpp b/src/third_party/boost/boost/intrusive/detail/ebo_functor_holder.hpp
new file mode 100644
index 00000000000..d4c2d1593bf
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/ebo_functor_holder.hpp
@@ -0,0 +1,95 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Joaquin M Lopez Munoz  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
+#define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
+
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template
+class ebo_functor_holder_impl
+{
+   public:
+   ebo_functor_holder_impl()
+   {}
+   ebo_functor_holder_impl(const T& t)
+      :  t_(t)
+   {}
+   template
+   ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2)
+      :  t_(arg1, arg2)
+   {}
+
+   T&       get(){return t_;}
+   const T& get()const{return t_;}
+
+   private:
+   T t_;
+};
+
+template
+class ebo_functor_holder_impl
+   :  public T
+{
+   public:
+   ebo_functor_holder_impl()
+   {}
+   ebo_functor_holder_impl(const T& t)
+      :  T(t)
+   {}
+   template
+   ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2)
+      :  T(arg1, arg2)
+   {}
+
+   T&       get(){return *this;}
+   const T& get()const{return *this;}
+};
+
+template
+class ebo_functor_holder
+   :  public ebo_functor_holder_impl::value>
+{
+   private:
+   typedef ebo_functor_holder_impl::value> super;
+
+   public:
+   ebo_functor_holder(){}
+   ebo_functor_holder(const T& t)
+      :  super(t)
+   {}
+
+   template
+   ebo_functor_holder(const Arg1& arg1, const Arg2& arg2)
+      :  super(arg1, arg2)
+   {}
+
+   ebo_functor_holder& operator=(const ebo_functor_holder& x)
+   {
+      this->get()=x.get();
+      return *this;
+   }
+};
+
+
+}  //namespace detail {
+}  //namespace intrusive {
+}  //namespace boost {
+
+#include 
+
+#endif   //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/function_detector.hpp b/src/third_party/boost/boost/intrusive/detail/function_detector.hpp
new file mode 100644
index 00000000000..e00a7efcf21
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/function_detector.hpp
@@ -0,0 +1,88 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2009-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+//  This code was modified from the code posted by Alexandre Courpron in his
+//  article "Interface Detection" in The Code Project:
+//  http://www.codeproject.com/KB/architecture/Detector.aspx
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2007 Alexandre Courpron
+//
+// Permission to use, copy, modify, redistribute and sell this software, 
+// provided that this copyright notice appears on all copies of the software.
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
+#define BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
+
+#include 
+
+namespace boost {
+namespace intrusive {
+namespace function_detector {
+
+    typedef char NotFoundType;
+    struct StaticFunctionType { NotFoundType x [2]; };
+    struct NonStaticFunctionType { NotFoundType x [3]; };
+
+    enum
+         { NotFound          = 0,
+           StaticFunction    = sizeof( StaticFunctionType )    - sizeof( NotFoundType ),
+           NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType )
+         };
+
+}  //namespace boost {
+}  //namespace intrusive {
+}  //namespace function_detector {
+
+#define BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \
+   namespace boost { \
+   namespace intrusive { \
+   namespace function_detector { \
+   template < class T, \
+            class NonStaticType, \
+            class NonStaticConstType, \
+            class StaticType > \
+   class DetectMember_##InstantiationKey_##Identifier { \
+      template < NonStaticType > \
+      struct TestNonStaticNonConst ; \
+      \
+      template < NonStaticConstType > \
+      struct TestNonStaticConst ; \
+      \
+      template < StaticType > \
+      struct TestStatic ; \
+      \
+      template  \
+      static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \
+      \
+      template  \
+      static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \
+      \
+      template  \
+      static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \
+      \
+      template  \
+      static NotFoundType Test( ... ); \
+   public : \
+      static const int check = NotFound + (sizeof(Test(0, 0)) - sizeof(NotFoundType));\
+   };\
+}}} //namespace boost::intrusive::function_detector { 
+
+#define BOOST_INTRUSIVE_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \
+    ::boost::intrusive::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\
+                                         ReturnType (Class::*)Params,\
+                                         ReturnType (Class::*)Params const,\
+                                         ReturnType (*)Params \
+                                       >::check
+
+#include 
+
+#endif   //@ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/generic_hook.hpp b/src/third_party/boost/boost/intrusive/detail/generic_hook.hpp
new file mode 100644
index 00000000000..fc35610b8d4
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/generic_hook.hpp
@@ -0,0 +1,209 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_GENERIC_HOOK_HPP
+#define BOOST_INTRUSIVE_GENERIC_HOOK_HPP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+/// @cond
+
+enum
+{  NoBaseHook
+,  ListBaseHook
+,  SlistBaseHook
+,  SetBaseHook
+,  UsetBaseHook
+,  SplaySetBaseHook
+,  AvlSetBaseHook
+,  BsSetBaseHook
+,  AnyBaseHook
+};
+
+struct no_default_definer{};
+
+template 
+struct default_definer;
+
+template 
+struct default_definer
+{  typedef Hook default_list_hook;  };
+
+template 
+struct default_definer
+{  typedef Hook default_slist_hook;  };
+
+template 
+struct default_definer
+{  typedef Hook default_set_hook;  };
+
+template 
+struct default_definer
+{  typedef Hook default_uset_hook;  };
+
+template 
+struct default_definer
+{  typedef Hook default_splay_set_hook;  };
+
+template 
+struct default_definer
+{  typedef Hook default_avl_set_hook;  };
+
+template 
+struct default_definer
+{  typedef Hook default_bs_set_hook;  };
+
+template 
+struct default_definer
+{  typedef Hook default_any_hook;  };
+
+template 
+struct make_default_definer
+{
+   typedef typename detail::if_c
+      < BaseHookType != 0
+      , default_definer
+      , no_default_definer>::type type;
+};
+
+template
+   < class GetNodeAlgorithms
+   , class Tag
+   , link_mode_type LinkMode
+   , int HookType
+   >
+struct make_node_holder
+{
+   typedef typename detail::if_c
+      ::value
+      , detail::node_holder
+         < typename GetNodeAlgorithms::type::node
+         , Tag
+         , LinkMode
+         , HookType>
+      , typename GetNodeAlgorithms::type::node
+      >::type type;
+};
+
+/// @endcond
+
+template
+   < class GetNodeAlgorithms
+   , class Tag
+   , link_mode_type LinkMode
+   , int HookType
+   >
+class generic_hook
+   /// @cond
+
+   //If the hook is a base hook, derive generic hook from detail::node_holder
+   //so that a unique base class is created to convert from the node
+   //to the type. This mechanism will be used by base_hook_traits.
+   //
+   //If the hook is a member hook, generic hook will directly derive
+   //from the hook.
+   : public make_default_definer
+      < generic_hook
+      , detail::is_same::value*HookType
+      >::type
+   , public make_node_holder::type
+   /// @endcond
+{
+   /// @cond
+   typedef typename GetNodeAlgorithms::type           node_algorithms;
+   typedef typename node_algorithms::node             node;
+   typedef typename node_algorithms::node_ptr         node_ptr;
+   typedef typename node_algorithms::const_node_ptr   const_node_ptr;
+
+   public:
+   struct boost_intrusive_tags
+   {
+      static const int hook_type = HookType;
+      static const link_mode_type link_mode = LinkMode;
+      typedef Tag                                           tag;
+      typedef typename GetNodeAlgorithms::type::node_traits node_traits;
+      static const bool is_base_hook = !detail::is_same::value;
+      static const bool safemode_or_autounlink = 
+         (int)link_mode == (int)auto_unlink || (int)link_mode == (int)safe_link;
+   };
+
+   node_ptr this_ptr()
+   {  return pointer_traits::pointer_to(static_cast(*this)); }
+
+   const_node_ptr this_ptr() const
+   {  return pointer_traits::pointer_to(static_cast(*this)); }
+
+   public:
+   /// @endcond
+
+   generic_hook()
+   {
+      if(boost_intrusive_tags::safemode_or_autounlink){
+         node_algorithms::init(this->this_ptr());
+      }
+   }
+
+   generic_hook(const generic_hook& ) 
+   {
+      if(boost_intrusive_tags::safemode_or_autounlink){
+         node_algorithms::init(this->this_ptr());
+      }
+   }
+
+   generic_hook& operator=(const generic_hook& ) 
+   {  return *this;  }
+
+   ~generic_hook()
+   {
+      destructor_impl
+         (*this, detail::link_dispatch());
+   }
+
+   void swap_nodes(generic_hook &other) 
+   {
+      node_algorithms::swap_nodes
+         (this->this_ptr(), other.this_ptr());
+   }
+
+   bool is_linked() const 
+   {
+      //is_linked() can be only used in safe-mode or auto-unlink
+      BOOST_STATIC_ASSERT(( boost_intrusive_tags::safemode_or_autounlink ));
+      return !node_algorithms::unique(this->this_ptr());
+   }
+
+   void unlink()
+   {
+      BOOST_STATIC_ASSERT(( (int)boost_intrusive_tags::link_mode == (int)auto_unlink ));
+      node_algorithms::unlink(this->this_ptr());
+      node_algorithms::init(this->this_ptr());
+   }
+};
+
+} //namespace detail
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_GENERIC_HOOK_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/has_member_function_callable_with.hpp b/src/third_party/boost/boost/intrusive/detail/has_member_function_callable_with.hpp
new file mode 100644
index 00000000000..33811e32100
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/has_member_function_callable_with.hpp
@@ -0,0 +1,356 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2011. 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/intrusive for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+// sample.h
+
+#if !BOOST_PP_IS_ITERATING
+
+   #ifndef BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
+   #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
+
+      #include 
+      #include 
+      #include 
+      #include 
+      #include 
+
+      //Mark that we don't support 0 arg calls due to compiler ICE in GCC 3.4/4.0/4.1 and 
+      //wrong SFINAE for GCC 4.2/4.3
+      #if defined(__GNUC__) && !defined(__clang__) && ((__GNUC__*100 + __GNUC_MINOR__*10) >= 340) && ((__GNUC__*100 + __GNUC_MINOR__*10) <= 430)
+      #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
+      #elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200 )
+      #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED
+      #endif
+
+      namespace boost_intrusive_has_member_function_callable_with {
+
+      struct dont_care
+      {
+         dont_care(...);
+      };
+
+      struct private_type
+      {
+         static private_type p;
+         private_type const &operator,(int) const;
+      };
+
+      typedef char yes_type;            // sizeof(yes_type) == 1
+      struct no_type{ char dummy[2]; }; // sizeof(no_type)  == 2
+
+      template
+      no_type is_private_type(T const &);
+      yes_type is_private_type(private_type const &);
+
+      }  //boost_intrusive_has_member_function_callable_with
+
+      #include 
+
+   #endif   //BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
+
+#else //!BOOST_PP_IS_ITERATING
+
+   #ifndef  BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
+   #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME not defined!"
+   #endif
+
+   #ifndef  BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
+   #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN not defined!"
+   #endif
+
+   #ifndef  BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
+   #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!"
+   #endif
+
+   #if BOOST_PP_ITERATION_START() != 0
+   #error "BOOST_PP_ITERATION_START() must be zero (0)"
+   #endif
+
+   #if BOOST_PP_ITERATION() == 0
+
+      BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
+
+      template 
+      class BOOST_PP_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+      {
+         struct BaseMixin
+         {
+            void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME();
+         };
+
+         struct Base : public Type, public BaseMixin { Base(); };
+         template  class Helper{};
+
+         template 
+         static boost_intrusive_has_member_function_callable_with::no_type  deduce
+            (U*, Helper* = 0);
+         static boost_intrusive_has_member_function_callable_with::yes_type deduce(...);
+
+         public:
+         static const bool value =
+            sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0)));
+      };
+
+      #if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
+
+         template
+         struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl);
+         //!
+
+         template
+         struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
+            
+         {
+            static const bool value = false;
+         };
+         //!
+
+         #if !defined(_MSC_VER) || (_MSC_VER != 1600)
+
+            #if defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
+
+            template
+            struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
+               
+            {
+               //Mark that we don't support 0 arg calls due to compiler ICE in GCC 3.4/4.0/4.1 and 
+               //wrong SFINAE for GCC 4.2/4.3
+               static const bool value = true;
+            };
+
+            #else
+
+            //Special case for 0 args
+            template< class F
+                  , std::size_t N = 
+                        sizeof((boost::move_detail::declval().
+                           BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))>
+            struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+            {
+               boost_intrusive_has_member_function_callable_with::yes_type dummy;
+               BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
+            };
+
+            //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not
+            //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0.
+            template
+            struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+            {
+               boost_intrusive_has_member_function_callable_with::no_type dummy;
+               BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
+            };
+
+            template
+            struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
+               
+            {
+               template
+               static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+                  Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*);
+
+               template  
+               static boost_intrusive_has_member_function_callable_with::no_type Test(...);
+               
+               static const bool value = sizeof(Test< Fun >(0))
+                                    == sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
+            };
+            #endif
+
+         #else //#if !defined(_MSC_VER) || (_MSC_VER != 1600)
+            template
+            struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
+               
+            {
+               template
+               static decltype( boost::move_detail::declval().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()
+                              , boost_intrusive_has_member_function_callable_with::yes_type())
+                  Test(Fun*);
+
+               template
+               static boost_intrusive_has_member_function_callable_with::no_type Test(...);
+
+               static const bool value = sizeof(Test(0))
+                                    == sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
+            };
+         #endif   //#if !defined(_MSC_VER) || (_MSC_VER != 1600)
+
+      #else   //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
+
+         template
+         struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl);
+
+         template
+         struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
+            
+         {
+            static const bool value = false;
+         };
+
+         //Special case for 0 args
+         template< class F
+               , std::size_t N = 
+                     sizeof((boost::move_detail::declval().
+                        BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))>
+         struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+         {
+            boost_intrusive_has_member_function_callable_with::yes_type dummy;
+            BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
+         };
+
+         //For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not
+         //SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0.
+         template
+         struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+         {
+            boost_intrusive_has_member_function_callable_with::no_type dummy;
+            BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
+         };
+
+         template
+         struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
+            
+         {
+            template
+            static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+                Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*);
+
+            template  
+            static boost_intrusive_has_member_function_callable_with::no_type Test(...);
+            
+            static const bool value = sizeof(Test< Fun >(0))
+                                 == sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
+         };
+
+         template
+         struct BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )
+            : Fun
+         {
+            BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )();
+            using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;
+
+            boost_intrusive_has_member_function_callable_with::private_type
+               BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
+                  ( DontCares...)  const;
+         };
+
+         template
+         struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
+            
+         {
+            template
+            struct make_dontcare
+            {
+               typedef boost_intrusive_has_member_function_callable_with::dont_care type;
+            };
+
+            typedef BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )
+               ::type...> FunWrap;
+
+            static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) ==
+                                       sizeof(boost_intrusive_has_member_function_callable_with::is_private_type
+                                                ( (::boost::move_detail::declval< FunWrap >().
+                                          BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
+                                             ( ::boost::move_detail::declval()... ), 0) )
+                                             )
+                                       );
+         };
+
+         template
+         struct BOOST_PP_CAT( has_member_function_callable_with_
+                            , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+            : public BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_
+                                 , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
+               < Fun
+               , BOOST_PP_CAT( has_member_function_named_
+                             , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )::value
+               , Args... >
+         {};
+
+      #endif   //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
+
+      BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
+
+   #else   //BOOST_PP_ITERATION() == 0
+
+      #if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
+
+         BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
+
+         template
+         struct BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION())
+                           , BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME))
+            : Fun
+         {
+            BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION())
+                        , BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME))();
+
+            using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;
+            boost_intrusive_has_member_function_callable_with::private_type
+               BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
+                  ( BOOST_PP_ENUM(BOOST_PP_ITERATION()
+                  , BOOST_INTRUSIVE_PP_IDENTITY
+                  , boost_intrusive_has_member_function_callable_with::dont_care))  const;
+         };
+
+         template
+         struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_
+                            , BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
+            
+         {
+            typedef BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION())
+                              , BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME))
+                     FunWrap;
+            static bool const value =
+            (sizeof(boost_intrusive_has_member_function_callable_with::no_type) ==
+               sizeof(boost_intrusive_has_member_function_callable_with::is_private_type
+                        (  (boost::move_detail::declval().
+                              BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
+                                 ( BOOST_PP_ENUM( BOOST_PP_ITERATION(), BOOST_INTRUSIVE_PP_DECLVAL, _) ), 0
+                           )
+                        )
+                     )
+            );
+         };
+
+         BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
+      #endif   //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
+
+   #endif   //BOOST_PP_ITERATION() == 0
+
+   #if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH()
+
+      #if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
+
+         BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
+
+         template
+         struct BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
+            : public BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
+               ::value
+               BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), P) >
+         {};
+
+         BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
+
+      #endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
+
+      #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
+      #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
+      #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
+
+   #endif   //#if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH()
+
+#endif   //!BOOST_PP_IS_ITERATING
diff --git a/src/third_party/boost/boost/intrusive/detail/hashtable_node.hpp b/src/third_party/boost/boost/intrusive/detail/hashtable_node.hpp
new file mode 100644
index 00000000000..ac6ab81948c
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/hashtable_node.hpp
@@ -0,0 +1,249 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2007-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_HASHTABLE_NODE_HPP
+#define BOOST_INTRUSIVE_HASHTABLE_NODE_HPP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+//#include  //remove-me
+#include 
+#include 
+#include 
+#include 
+
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template
+struct prime_list_holder
+{
+   static const std::size_t prime_list[];
+   static const std::size_t prime_list_size;
+};
+
+template
+const std::size_t prime_list_holder::prime_list[] = {
+   3ul, 7ul, 11ul, 17ul, 29ul, 
+   53ul, 97ul, 193ul, 389ul, 769ul,
+   1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
+   49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
+   1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
+   50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
+   1610612741ul, 3221225473ul, 4294967291ul };
+
+template
+const std::size_t prime_list_holder::prime_list_size
+   = sizeof(prime_list)/sizeof(std::size_t);
+
+template 
+struct bucket_impl : public Slist
+{
+   typedef Slist slist_type;
+   bucket_impl()
+   {}
+
+   bucket_impl(const bucket_impl &)
+   {}
+
+   ~bucket_impl()
+   {
+      //This bucket is still being used!
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty());
+   }
+
+   bucket_impl &operator=(const bucket_impl&)
+   {
+      //This bucket is still in use!
+      BOOST_INTRUSIVE_INVARIANT_ASSERT(Slist::empty());
+      //Slist::clear();
+      return *this;
+   }
+};
+
+template
+struct bucket_traits_impl
+{
+   private:
+   BOOST_COPYABLE_AND_MOVABLE(bucket_traits_impl)
+
+   public:
+   /// @cond
+
+   typedef typename pointer_traits
+      ::template rebind_pointer
+         < bucket_impl >::type                                bucket_ptr;
+   typedef typename Slist::size_type size_type;
+   /// @endcond
+
+   bucket_traits_impl(bucket_ptr buckets, size_type len)
+      :  buckets_(buckets), buckets_len_(len)
+   {}
+
+   bucket_traits_impl(const bucket_traits_impl &x)
+      : buckets_(x.buckets_), buckets_len_(x.buckets_len_)
+   {}
+
+
+   bucket_traits_impl(BOOST_RV_REF(bucket_traits_impl) x)
+      : buckets_(x.buckets_), buckets_len_(x.buckets_len_)
+   {  x.buckets_ = bucket_ptr();   x.buckets_len_ = 0;  }
+
+   bucket_traits_impl& operator=(BOOST_RV_REF(bucket_traits_impl) x)
+   {
+      buckets_ = x.buckets_; buckets_len_ = x.buckets_len_;
+      x.buckets_ = bucket_ptr();   x.buckets_len_ = 0; return *this;
+   }
+
+   bucket_traits_impl& operator=(BOOST_COPY_ASSIGN_REF(bucket_traits_impl) x)
+   {
+      buckets_ = x.buckets_;  buckets_len_ = x.buckets_len_; return *this;
+   }
+
+   const bucket_ptr &bucket_begin() const
+   {  return buckets_;  }
+
+   size_type  bucket_count() const
+   {  return buckets_len_;  }
+
+   private:
+   bucket_ptr  buckets_;
+   size_type   buckets_len_;
+};
+
+template
+class hashtable_iterator
+   :  public std::iterator
+         < std::forward_iterator_tag
+         , typename Container::value_type
+         , typename pointer_traits::difference_type
+         , typename detail::add_const_if_c
+                     ::type *
+         , typename detail::add_const_if_c
+                     ::type &
+         >
+{
+   typedef typename Container::real_value_traits                  real_value_traits;
+   typedef typename Container::siterator                          siterator;
+   typedef typename Container::const_siterator                    const_siterator;
+   typedef typename Container::bucket_type                        bucket_type;
+
+   typedef typename pointer_traits
+      ::template rebind_pointer
+         < const Container >::type                                const_cont_ptr;
+   typedef typename Container::size_type                          size_type;
+
+   static typename Container::node_ptr downcast_bucket(typename bucket_type::node_ptr p)
+   {
+      return pointer_traits::
+         pointer_to(static_cast(*p));
+   }
+
+   public:
+   typedef typename Container::value_type    value_type;
+   typedef  typename detail::add_const_if_c
+                     ::type *pointer;
+   typedef typename detail::add_const_if_c
+                     ::type &reference;
+
+   hashtable_iterator ()
+   {}
+
+   explicit hashtable_iterator(siterator ptr, const Container *cont)
+      :  slist_it_ (ptr),   cont_ (cont ? pointer_traits::pointer_to(*cont) : const_cont_ptr() )
+   {}
+
+   hashtable_iterator(const hashtable_iterator &other)
+      :  slist_it_(other.slist_it()), cont_(other.get_container())
+   {}
+
+   const siterator &slist_it() const
+   { return slist_it_; }
+
+   hashtable_iterator unconst() const
+   {  return hashtable_iterator(this->slist_it(), this->get_container());   }
+
+   public:
+   hashtable_iterator& operator++() 
+   {  this->increment();   return *this;   }
+   
+   hashtable_iterator operator++(int)
+   {
+      hashtable_iterator result (*this);
+      this->increment();
+      return result;
+   }
+
+   friend bool operator== (const hashtable_iterator& i, const hashtable_iterator& i2)
+   { return i.slist_it_ == i2.slist_it_; }
+
+   friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2)
+   { return !(i == i2); }
+
+   reference operator*() const
+   { return *this->operator ->(); }
+
+   pointer operator->() const
+   {
+      return boost::intrusive::detail::to_raw_pointer(this->get_real_value_traits()->to_value_ptr
+         (downcast_bucket(slist_it_.pointed_node())));
+   }
+
+   const const_cont_ptr &get_container() const
+   {  return cont_;  }
+
+   const real_value_traits *get_real_value_traits() const
+   {  return &this->get_container()->get_real_value_traits();  }
+
+   private:
+   void increment()
+   {
+      const Container *cont =  boost::intrusive::detail::to_raw_pointer(cont_);
+      bucket_type* buckets = boost::intrusive::detail::to_raw_pointer(cont->bucket_pointer());
+      size_type   buckets_len    = cont->bucket_count();
+
+      ++slist_it_;
+      if(buckets[0].cend().pointed_node()    <= slist_it_.pointed_node() && 
+         slist_it_.pointed_node()<= buckets[buckets_len].cend().pointed_node()      ){
+         //Now get the bucket_impl from the iterator
+         const bucket_type &b = static_cast
+            (bucket_type::slist_type::container_from_end_iterator(slist_it_));
+
+         //Now just calculate the index b has in the bucket array
+         size_type n_bucket = static_cast(&b - &buckets[0]);
+         do{
+            if (++n_bucket == buckets_len){
+               slist_it_ = (&buckets[0] + buckets_len)->end();
+               break;
+            }
+            slist_it_ = buckets[n_bucket].begin();
+         }
+         while (slist_it_ == buckets[n_bucket].end());
+      }
+   }
+
+   siterator      slist_it_;
+   const_cont_ptr cont_;
+};
+
+}  //namespace detail {
+}  //namespace intrusive {
+}  //namespace boost {
+
+#endif
diff --git a/src/third_party/boost/boost/intrusive/detail/is_stateful_value_traits.hpp b/src/third_party/boost/boost/intrusive/detail/is_stateful_value_traits.hpp
new file mode 100644
index 00000000000..e38f4de4592
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/is_stateful_value_traits.hpp
@@ -0,0 +1,77 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2009-2009.
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
+#define BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
+
+#include 
+
+#if defined(_MSC_VER) && (_MSC_VER <= 1310)
+
+#include 
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template
+struct is_stateful_value_traits
+{
+   static const bool value = !detail::is_empty_class::value;
+};
+
+}}}
+
+#else
+
+#include 
+
+BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_node_ptr, boost_intrusive)
+BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_value_ptr, boost_intrusive)
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template
+struct is_stateful_value_traits
+{
+   typedef typename ValueTraits::node_ptr       node_ptr;
+   typedef typename ValueTraits::pointer        pointer;
+   typedef typename ValueTraits::value_type     value_type;
+   typedef typename ValueTraits::const_node_ptr const_node_ptr;
+   typedef typename ValueTraits::const_pointer  const_pointer;
+
+   typedef ValueTraits value_traits;
+
+   static const bool value =
+      (boost::intrusive::function_detector::NonStaticFunction ==
+         (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, node_ptr, to_node_ptr, (value_type&) )))
+      ||
+      (boost::intrusive::function_detector::NonStaticFunction ==
+         (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, pointer, to_value_ptr, (node_ptr) )))
+      ||
+      (boost::intrusive::function_detector::NonStaticFunction ==
+         (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_node_ptr, to_node_ptr, (const value_type&) )))
+      ||
+      (boost::intrusive::function_detector::NonStaticFunction ==
+         (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_pointer, to_value_ptr, (const_node_ptr) )))
+      ;
+};
+
+}}}
+
+#endif
+
+#include 
+
+#endif   //@ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/list_node.hpp b/src/third_party/boost/boost/intrusive/detail/list_node.hpp
new file mode 100644
index 00000000000..df99912dd23
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/list_node.hpp
@@ -0,0 +1,190 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Olaf Krzikalla 2004-2006.
+// (C) Copyright Ion Gaztanaga  2006-2009
+//
+// 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/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_LIST_NODE_HPP
+#define BOOST_INTRUSIVE_LIST_NODE_HPP
+
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+
+// list_node_traits can be used with circular_list_algorithms and supplies
+// a list_node holding the pointers needed for a double-linked list
+// it is used by list_derived_node and list_member_node
+
+template
+struct list_node
+{
+   typedef typename pointer_traits
+      :: template rebind_pointer::type    node_ptr;
+   node_ptr next_;
+   node_ptr prev_;
+};
+
+template
+struct list_node_traits
+{
+   typedef list_node node;
+   typedef typename pointer_traits
+      :: template rebind_pointer::type         node_ptr;
+   typedef typename pointer_traits
+      :: template rebind_pointer::type   const_node_ptr;
+
+   static const node_ptr &get_previous(const const_node_ptr & n)
+   {  return n->prev_;  }
+
+   static void set_previous(const node_ptr & n, const node_ptr & prev)
+   {  n->prev_ = prev;  }
+
+   static const node_ptr &get_next(const const_node_ptr & n)
+   {  return n->next_;  }
+
+   static void set_next(const node_ptr & n, const node_ptr & next)
+   {  n->next_ = next;  }
+};
+
+// list_iterator provides some basic functions for a 
+// node oriented bidirectional iterator:
+template
+class list_iterator
+   :  public std::iterator
+         < std::bidirectional_iterator_tag
+         , typename Container::value_type
+         , typename Container::difference_type
+         , typename detail::if_c::type
+         , typename detail::if_c::type
+         >
+{
+   protected:
+   typedef typename Container::real_value_traits   real_value_traits;
+   typedef typename real_value_traits::node_traits node_traits;
+   typedef typename node_traits::node              node;
+   typedef typename node_traits::node_ptr          node_ptr;
+   typedef typename pointer_traits::
+      template rebind_pointer::type          void_pointer;
+   static const bool store_container_ptr = 
+      detail::store_cont_ptr_on_it::value;
+
+   public:
+   typedef typename Container::value_type    value_type;
+   typedef typename detail::if_c::type pointer;
+   typedef typename detail::if_c::type reference;
+
+   list_iterator()
+      : members_ (node_ptr(), 0)
+   {}
+
+   explicit list_iterator(const node_ptr & node, const Container *cont_ptr)
+      : members_ (node, cont_ptr)
+   {}
+
+   list_iterator(list_iterator const& other)
+      :  members_(other.pointed_node(), other.get_container())
+   {}
+
+   const node_ptr &pointed_node() const
+   { return members_.nodeptr_; }
+
+   list_iterator &operator=(const node_ptr &node)
+   {  members_.nodeptr_ = node;  return static_cast(*this);  }
+
+   public:
+   list_iterator& operator++() 
+   {
+      node_ptr p = node_traits::get_next(members_.nodeptr_);
+      members_.nodeptr_ = p;
+      //members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); 
+      return static_cast (*this); 
+   }
+   
+   list_iterator operator++(int)
+   {
+      list_iterator result (*this);
+      members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
+      return result;
+   }
+
+   list_iterator& operator--() 
+   { 
+      members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_); 
+      return static_cast (*this); 
+   }
+   
+   list_iterator operator--(int)
+   {
+      list_iterator result (*this);
+      members_.nodeptr_ = node_traits::get_previous(members_.nodeptr_);
+      return result;
+   }
+
+   friend bool operator== (const list_iterator& l, const list_iterator& r)
+   {  return l.pointed_node() == r.pointed_node();   }
+
+   friend bool operator!= (const list_iterator& l, const list_iterator& r)
+   {  return !(l == r); }
+
+   reference operator*() const
+   {  return *operator->();   }
+
+   pointer operator->() const
+   { return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); }
+
+   const Container *get_container() const
+   {
+      if(store_container_ptr){
+         const Container* c = static_cast(members_.get_ptr());
+         BOOST_INTRUSIVE_INVARIANT_ASSERT(c != 0);
+         return c;
+      }
+      else{
+         return 0;
+      }
+   }
+
+   const real_value_traits *get_real_value_traits() const
+   {
+      if(store_container_ptr)
+         return &this->get_container()->get_real_value_traits();
+      else
+         return 0;
+   }
+
+   list_iterator unconst() const
+   {  return list_iterator(this->pointed_node(), this->get_container());   }
+
+   private:
+   struct members
+      :  public detail::select_constptr
+         ::type
+   {
+      typedef typename detail::select_constptr
+         ::type Base;
+
+      members(const node_ptr &n_ptr, const void *cont)
+         :  Base(cont), nodeptr_(n_ptr)
+      {}
+
+      node_ptr nodeptr_;
+   } members_;
+};
+
+} //namespace intrusive 
+} //namespace boost 
+
+#include 
+
+#endif //BOOST_INTRUSIVE_LIST_NODE_HPP
diff --git a/src/third_party/boost/boost/intrusive/detail/memory_util.hpp b/src/third_party/boost/boost/intrusive/detail/memory_util.hpp
new file mode 100644
index 00000000000..ad026c6d618
--- /dev/null
+++ b/src/third_party/boost/boost/intrusive/detail/memory_util.hpp
@@ -0,0 +1,279 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Pablo Halpern 2009. 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)
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2011-2011. 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/intrusive for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
+#define BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
+
+#if (defined _MSC_VER) && (_MSC_VER >= 1200)
+#  pragma once
+#endif
+
+#include 
+#include 
+#include 
+#include 
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template 
+inline T* addressof(T& obj)
+{
+   return static_cast
+      (static_cast
+         (const_cast
+            (&reinterpret_cast(obj))
+         )
+      );
+}
+
+template  struct unvoid { typedef T type; };
+template <> struct unvoid { struct type { }; };
+template <> struct unvoid { struct type { }; };
+
+template 
+struct LowPriorityConversion
+{
+    // Convertible from T with user-defined-conversion rank.
+    LowPriorityConversion(const T&) { }
+};
+
+// Infrastructure for providing a default type for T::TNAME if absent.
+#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME)              \
+   template                              \
+   struct boost_intrusive_default_type_ ## TNAME                           \
+   {                                                                       \
+      template                                                 \
+      static char test(int, typename X::TNAME*);                           \
+                                                                           \
+      template                                                 \
+      static int test(boost::intrusive::detail::                           \
+         LowPriorityConversion, void*);                               \
+                                                                           \
+      struct DefaultWrap { typedef DefaultType TNAME; };                   \
+                                                                           \
+      static const bool value = (1 == sizeof(test(0, 0)));              \
+                                                                           \
+      typedef typename                                                     \
+         ::boost::intrusive::detail::if_c                                  \
+            ::type::TNAME type;                     \
+   };                                                                      \
+                                                                           \
+   template                              \
+   struct boost_intrusive_eval_default_type_ ## TNAME                      \
+   {                                                                       \
+      template                                                 \
+      static char test(int, typename X::TNAME*);                           \
+                                                                           \
+      template                                                 \
+      static int test(boost::intrusive::detail::                           \
+         LowPriorityConversion, void*);                               \
+                                                                           \
+      struct DefaultWrap                                                   \
+      { typedef typename DefaultType::type TNAME; };                       \
+                                                                           \
+      static const bool value = (1 == sizeof(test(0, 0)));              \
+                                                                           \
+      typedef typename                                                     \
+         ::boost::intrusive::detail::eval_if_c                             \
+            < value                                                        \
+            , ::boost::intrusive::detail::identity                      \
+            , ::boost::intrusive::detail::identity            \
+            >::type::TNAME type;                                           \
+   };                                                                      \
+//
+
+#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL)   \
+      typename INSTANTIATION_NS_PREFIX                                                       \
+         boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type                            \
+//
+
+#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
+      typename INSTANTIATION_NS_PREFIX                                                          \
+         boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type                          \
+//
+
+}}}   //namespace boost::intrusive::detail
+
+#include 
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME pointer_to
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, ))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME static_cast_from
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, ))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME const_cast_from
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, ))
+#include BOOST_PP_ITERATE()
+
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME dynamic_cast_from
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
+#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END   }}}
+#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, ))
+#include BOOST_PP_ITERATE()
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(element_type)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type)
+
+//////////////////////
+//struct first_param
+//////////////////////
+
+template  struct first_param
+{  typedef void type;   };
+
+#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
+
+   template