• STL


    Many thanks to the people who devote themselft to the common libs.

    STL four components

     

    Global Constructor and Destructor

     

    STL Allocator

     

    STL Vector

     

    STL List

     

    STL Tree

    asdfsdf

     

    Introduction to the Standard Template Library.

    1. The Standard Template Library ( abbreviated as STL ) is a C++ library consisting of three components which are container classes, algorithms, and iterators providing many of the basic algorithms and data structures and data accessing easily of computer science.
    2. You should make sure that you understand how templates work with C++ before you use the STL. 
    3. Templates = replacement = code expansion at compiling-time.
    4. Like many class library, The STL includes container classes whose purpose is to contain other objects, including the classes:vector, list, deque, set, multiset, map, multimap, hash_set, hash_multiset, hash_map and hash_multimap.
    5. The STL also includes a large collection of algorithms that manipulate the data stored in containers.
    6. There are two important points to notice about this call to reverse(). First, it is a global function, not a member function. Second, it takes two arguments rather than one: it operates on a range of elements, rather than on a container. In this particular case the range happens to be the entire container.
    7. reverse( objectOfcontainer.begin(), objectOfcontainer.end())
    8. Iterators are the mechanism that makes it possible to decouple algorithms from containers: algorithms are templates, and are parameterized by the type of iterator, so they are not restricted to a single type of container. Traverse all element in container.
    9. Proceed from the beginning to the end, and stops either when it finds an iterator that points to value or when it reaches the end of the range.
    10. One very important question to ask about any template function, not just about STL algorithms is what the set of types is that may correctly be substituted for the formal template parameters.
    11. Concepts are not a part of the C++ language; there is no way to declare a concept in a program, or to declare that particular type is a model of a concept. Nevertheless, concepts are an extremely important part of the STL. Using concepts makes it possible to write programs that cleanly separate interface from implementation.
    12. Concept programming, Generic programming 

    Classification of STL components

    1. The STL components are divided into six broad categories on the basis of functionality: Containers, Iterator, Algorithms, Function Objects, Utilities, and Allocator.
    2. The STL documentation contains two indices ( index). One of them, the Main Index, list all components in alphabetical order. The other, the Divided Index, contains a separate alphabetical listing for each category.
    3. The format of a concept page. A page that documents a concept has the following sections: Summary; Refinement of; Associated types; Notation; Definitions; Valid Expressions; Expression Semantics; Complexity Guarantees; Invariants; Models; Notes; See Also;
    4.   1 //////////////////////////////////////////////////////////////////////////////
        2 //
        3 // (C) Copyright Pablo Halpern 2009. Distributed under the Boost
        4 // Software License, Version 1.0. (See accompanying file
        5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
        6 //
        7 //////////////////////////////////////////////////////////////////////////////
        8 //
        9 // (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
       10 // Software License, Version 1.0. (See accompanying file
       11 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       12 //
       13 // See http://www.boost.org/libs/container for documentation.
       14 //
       15 //////////////////////////////////////////////////////////////////////////////
       16 
       17 #ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
       18 #define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
       19 
       20 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
       21 #  pragma once
       22 #endif
       23 #include <boost/container/detail/config_begin.hpp>
       24 #include <boost/container/detail/workaround.hpp>
       25 #include <boost/intrusive/pointer_traits.hpp>
       26 #include <boost/intrusive/detail/memory_util.hpp>
       27 #include <boost/container/detail/memory_util.hpp>
       28 #include <boost/type_traits/integral_constant.hpp>
       29 #include <boost/container/detail/mpl.hpp>
       30 #include <boost/move/utility.hpp>
       31 #include <limits> //numeric_limits<>::max()
       32 #include <new>    //placement new
       33 #include <memory> //std::allocator
       34 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
       35 #include <boost/container/detail/preprocessor.hpp>
       36 #endif
       37 
       38 namespace boost {
       39 namespace container {
       40 namespace container_detail {
       41 
       42 template<class A>
       43 struct is_std_allocator
       44 {  static const bool value = false; };
       45 
       46 template<class T>
       47 struct is_std_allocator< std::allocator<T> >
       48 {  static const bool value = true; };
       49 
       50 }  //namespace container_detail {
       51 
       52 template <typename Alloc>
       53 struct allocator_traits
       54 {
       55    //allocator_type
       56    typedef Alloc allocator_type;
       57    //value_type
       58    typedef typename Alloc::value_type         value_type;
       59 
       60    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
       61  
       62       typedef unspecified pointer;
       63       typedef see_documentation const_pointer;
       64       typedef see_documentation reference;
       65       typedef see_documentation const_reference;
       66       typedef see_documentation void_pointer;
       67       typedef see_documentation const_void_pointer;
       68       typedef see_documentation difference_type;
       69       typedef see_documentation size_type;
       70       typedef see_documentation propagate_on_container_copy_assignment;
       71       typedef see_documentation propagate_on_container_move_assignment;
       72       typedef see_documentation propagate_on_container_swap;
       73       template <class T> using rebind_alloc = see_documentation;
       74       template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >;
       75       template <class T>
       76       struct portable_rebind_alloc
       77       {  typedef see_documentation type;  };
       78    #else
       79       //pointer
       80       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
       81          pointer, value_type*)
       82             pointer;
       83       //const_pointer
       84       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
       85          const_pointer, typename boost::intrusive::pointer_traits<pointer>::template
       86             rebind_pointer<const value_type>)
       87                const_pointer;
       88       //reference
       89       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
       90          reference, typename container_detail::unvoid<value_type>::type&)
       91             reference;
       92       //const_reference
       93       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
       94          const_reference, const typename container_detail::unvoid<value_type>::type&)
       95                const_reference;
       96       //void_pointer
       97       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
       98          void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
       99             rebind_pointer<void>)
      100                void_pointer;
      101       //const_void_pointer
      102       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::container_detail::, Alloc,
      103          const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template
      104             rebind_pointer<const void>)
      105                const_void_pointer;
      106       //difference_type
      107       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
      108          difference_type, std::ptrdiff_t)
      109             difference_type;
      110       //size_type
      111       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
      112          size_type, std::size_t)
      113             size_type;
      114       //propagate_on_container_copy_assignment
      115       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
      116          propagate_on_container_copy_assignment, boost::false_type)
      117             propagate_on_container_copy_assignment;
      118       //propagate_on_container_move_assignment
      119       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
      120          propagate_on_container_move_assignment, boost::false_type)
      121             propagate_on_container_move_assignment;
      122       //propagate_on_container_swap
      123       typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, Alloc,
      124          propagate_on_container_swap, boost::false_type)
      125             propagate_on_container_swap;
      126 
      127       #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
      128          //C++11
      129          template <typename T> using rebind_alloc  = typename boost::intrusive::detail::type_rebinder<Alloc, T>::type;
      130          template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >;
      131       #else    // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
      132          //Some workaround for C++03 or C++11 compilers with no template aliases
      133          template <typename T>
      134          struct rebind_alloc : boost::intrusive::detail::type_rebinder<Alloc,T>::type
      135          {
      136             typedef typename boost::intrusive::detail::type_rebinder<Alloc,T>::type Base;
      137             #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
      138             template <typename... Args>
      139             rebind_alloc(BOOST_FWD_REF(Args)... args)
      140                : Base(boost::forward<Args>(args)...)
      141             {}
      142             #else    // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
      143             #define BOOST_PP_LOCAL_MACRO(n)                                                        
      144             BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) 
      145             rebind_alloc(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                       
      146                : Base(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))                       
      147             {}                                                                                     
      148             //
      149             #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
      150             #include BOOST_PP_LOCAL_ITERATE()
      151             #endif   // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
      152          };
      153 
      154          template <typename T>
      155          struct rebind_traits
      156             : allocator_traits<typename boost::intrusive::detail::type_rebinder<Alloc, T>::type>
      157          {};
      158       #endif   // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
      159       template <class T>
      160       struct portable_rebind_alloc
      161       {  typedef typename boost::intrusive::detail::type_rebinder<Alloc, T>::type type;  };
      162    #endif   //BOOST_CONTAINER_DOXYGEN_INVOKED
      163 
      164    static pointer allocate(Alloc &a, size_type n)
      165    {  return a.allocate(n);  }
      166 
      167    static void deallocate(Alloc &a, pointer p, size_type n)
      168    {  a.deallocate(p, n);  }
      169 
      170    //! <b>Effects</b>: calls `a.allocate(n, p)` if that call is well-formed;
      171    //! otherwise, invokes `a.allocate(n)`
      172    static pointer allocate(Alloc &a, size_type n, const_void_pointer p)
      173    {
      174       const bool value = boost::container::container_detail::
      175          has_member_function_callable_with_allocate
      176             <Alloc, const size_type, const const_void_pointer>::value;
      177       ::boost::integral_constant<bool, value> flag;
      178       return allocator_traits::priv_allocate(flag, a, n, p);
      179    }
      180 
      181    //! <b>Effects</b>: calls `a.destroy(p)` if that call is well-formed;
      182    //! otherwise, invokes `p->~T()`.
      183    template<class T>
      184    static void destroy(Alloc &a, T*p)
      185    {
      186       typedef T* destroy_pointer;
      187       const bool value = boost::container::container_detail::
      188          has_member_function_callable_with_destroy
      189             <Alloc, const destroy_pointer>::value;
      190       ::boost::integral_constant<bool, value> flag;
      191       allocator_traits::priv_destroy(flag, a, p);
      192    }
      193    static size_type max_size(const Alloc &a)
      194    {
      195       const bool value = boost::container::container_detail::
      196          has_member_function_callable_with_max_size
      197             <const Alloc>::value;
      198       ::boost::integral_constant<bool, value> flag;
      199       return allocator_traits::priv_max_size(flag, a);
      200    }
      201 
      202    static
      203    #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
      204    typename container_detail::if_c
      205       <  boost::container::container_detail::
      206                   has_member_function_callable_with_select_on_container_copy_construction
      207                      <const Alloc>::value
      208       , Alloc
      209       , const Alloc &
      210       >::type
      211    #else
      212    Alloc
      213    #endif
      214    select_on_container_copy_construction(const Alloc &a)
      215    {
      216       const bool value = boost::container::container_detail::
      217          has_member_function_callable_with_select_on_container_copy_construction
      218             <const Alloc>::value;
      219       ::boost::integral_constant<bool, value> flag;
      220       return allocator_traits::priv_select_on_container_copy_construction(flag, a);
      221    }
      222       template <class T, class ...Args>
      223       static void construct(Alloc & a, T* p, BOOST_FWD_REF(Args)... args)
      224       {
      225          ::boost::integral_constant<bool, container_detail::is_std_allocator<Alloc>::value> flag;
      226          allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...);
      227       }
      228    #endif
      229    ///@cond
      230    #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
      231       private:
      232       static pointer priv_allocate(boost::true_type, Alloc &a, size_type n, const_void_pointer p)
      233       {  return a.allocate(n, p);  }
      234 
      235       static pointer priv_allocate(boost::false_type, Alloc &a, size_type n, const_void_pointer)
      236       {  return allocator_traits::allocate(a, n);  }
      237 
      238       template<class T>
      239       static void priv_destroy(boost::true_type, Alloc &a, T* p)
      240       {  a.destroy(p);  }
      241 
      242       template<class T>
      243       static void priv_destroy(boost::false_type, Alloc &, T* p)
      244       {  p->~T(); (void)p;  }
      245 
      246       static size_type priv_max_size(boost::true_type, const Alloc &a)
      247       {  return a.max_size();  }
      248 
      249       static size_type priv_max_size(boost::false_type, const Alloc &)
      250       {  return (std::numeric_limits<size_type>::max)();  }
      251 
      252       static Alloc priv_select_on_container_copy_construction(boost::true_type, const Alloc &a)
      253       {  return a.select_on_container_copy_construction();  }
      254 
      255       static const Alloc &priv_select_on_container_copy_construction(boost::false_type, const Alloc &a)
      256       {  return a;  }
      257 
      258       #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
      259          template<class T, class ...Args>
      260          static void priv_construct(boost::false_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)                   
      261          {                                                                                                 
      262             const bool value = boost::container::container_detail::
      263                   has_member_function_callable_with_construct
      264                      < Alloc, T*, Args... >::value;
      265             ::boost::integral_constant<bool, value> flag;
      266             priv_construct_dispatch2(flag, a, p, ::boost::forward<Args>(args)...);
      267          }
      268 
      269          template<class T, class ...Args>
      270          static void priv_construct(boost::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
      271          {
      272             priv_construct_dispatch2(boost::false_type(), a, p, ::boost::forward<Args>(args)...);
      273          }
      274 
      275          template<class T, class ...Args>
      276          static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p, BOOST_FWD_REF(Args) ...args)
      277          {  a.construct( p, ::boost::forward<Args>(args)...);  }
      278 
      279          template<class T, class ...Args>
      280          static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, BOOST_FWD_REF(Args) ...args)
      281          {  ::new((void*)p) T(::boost::forward<Args>(args)...); }
      282       #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
      283          public:
      284          #define BOOST_PP_LOCAL_MACRO(n)                                                              
      285          template<class T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) >                                 
      286          static void construct(Alloc &a, T *p                                                         
      287                               BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))            
      288          {                                                                                            
      289             ::boost::integral_constant<bool, container_detail::is_std_allocator<Alloc>::value> flag;  
      290             allocator_traits::priv_construct(flag, a, p                                               
      291                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));                       
      292          }                                                                                            
      293          //
      294          #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
      295          #include BOOST_PP_LOCAL_ITERATE()
      296      
      297          private:
      298          #define BOOST_PP_LOCAL_MACRO(n)                                                                    
      299          template<class T  BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) >                                      
      300          static void priv_construct(boost::false_type, Alloc &a, T *p                                       
      301                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_))                         
      302          {                                                                                                  
      303             const bool value =                                                                              
      304                boost::container::container_detail::has_member_function_callable_with_construct              
      305                      < Alloc, T* BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_FWD_TYPE, _) >::value;        
      306             ::boost::integral_constant<bool, value> flag;                                                   
      307             priv_construct_dispatch2(flag, a, p                                                             
      308                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );                            
      309          }                                                                                                  
      310                                                                                                             
      311          template<class T  BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) >                                      
      312          static void priv_construct(boost::true_type, Alloc &a, T *p                                        
      313                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_))                         
      314          {                                                                                                  
      315             priv_construct_dispatch2(boost::false_type(), a, p                                              
      316                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );                            
      317          }                                                                                                  
      318                                                                                                             
      319          template<class T  BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) >                                      
      320          static void priv_construct_dispatch2(boost::true_type, Alloc &a, T *p                              
      321                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST,_))                         
      322          {  a.construct( p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) );  }             
      323                                                                                                             
      324          template<class T  BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) >                                      
      325          static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p                              
      326                         BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _) )                       
      327          {  ::new((void*)p) T(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }                     
      328          //
      329          #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
      330          #include BOOST_PP_LOCAL_ITERATE()
      331       #endif   // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
      332    #endif   //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
      333 
      334    ///@endcond
      335 };
      336 
      337 }  //namespace container {
      338 }  //namespace boost {
      339 
      340 #include <boost/container/detail/config_end.hpp>
      341 
      342 #endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP)
      View Code

     Container-->Concepts-->General concepts-->Container

    1. A container is an object that stores other objects (its elements), and that has methods for accessing its elements. In particular, every type that is a model of Container has an associated iterator type that can be used to iterate/traverse through the Container’s elements.
    2. There is no guarantee that the elements of a Container are stored in any definite order; the order might, in fact, be different upon each iteration through the container. Nor is there a guarantee that more than one iterator into a Container may be active at any one time.
    3. Associated Type (which are defined in Allocator):
      • Value type (X:: value_type);
      • Iterator type ( X::iterator);
      • Const iterator type (X::const_iterator);
      • Reference type (X:: reference);
      • Const reference type (X::const_reference);
      • Pointer type( X:: pointer);
      • Distance type( X::difference_type);
      • Size type(X::size_type); 
    4.  Valid expression: Beginning of range ( a.begin(); End of range ( a.end() ); Size (a.size()); Maximum size ( a.max_size()); Empty container(a.empty()); Swap (a.swap(b));

    Container-->Concepts-->General concepts-->Forward Container

    1. A forward container is a Container whose elements are arranged in a definite order: the ordering will not change spontaneously/naturally/unaffectedly from iteration to iteration. The requirements of a definite ordering allows the definition of element-by-element equality (if the container’s element type is Equality Comparable) and of lexicographical (edited by vocabulary) ordering ( in the container’s element type is LessThan Comparable).
    2. Complexity Guarantees: The equality and inequality operations are linear in the container’s size.
    3. Invariants: Two different iterations through a forward container will access its elements in the same order, providing that there have been no intervening mutative operations.
    4. Must support functions: EqualityComparable, LessThanComparable.

    Container-->Concepts-->General concepts-->Reversible Container

    1. A reversible container is a forward container whose iterators are bidirectional iterators. It allows backwards iteration through the container.
    2. Two new types are introduced. In addition, the iterator and the const iterator type must satisfy a more stringent/severe/tight/strict requirement than for a Forward Container. The iterator and reverse iterator types must be Bidirectional iterators, not merely Forward Iterators.
    3. X::reverse_iterator: A Reverse Iterator adaptor whose base iterator type is container’s iterator type. Incrementing an object of type reverse_iterator moved backwards through the container: the Reverse Iterator adaptor maps operator++ to operator--.
    4.  X::const_reverse_iterator: A Reverse Iterator adaptor whose base iterator type is the container’s const iterator type.
    5. a.rbegin() == X::reverse_iterator (a.end() ); a.rend() == X::reverse_iterator (a.begin() );

    Container-->Concepts-->General concepts-->Random Access Container

    1. A Random Access Container is a Reversible Container whose iterator type is a Random Access Iterator. It provides amortized constant time access to arbitrary elements.
    2. No additional types beyond those defined in Reversible Container. However, the requirements for the iterator type are strengthened: it must be a Random Access Iterator.
    3. The element returned by a[n] is the same as the one obtained by incrementing a.begin() n times and then dereferencing the resulting iterator.

    Sequences->Sequence Container

    1. A sequence is a variable-sized Container whose elements are arranged in a strict linear order. It supports insertion and removal of elements.
    2. Forward Container; Default Constructible
    3. The fill constructor, default constructor and range constructor are linear
    4. Front is amortized constant time.
    5. Fill insert, range insert, and range erase are linear.
    6. The complexities of single-element insert and erase are sequence dependent.
    7. Models: vector; deque; list; slist
    8. Note that p being equal to a.begin() means to insert something at the beginning of a( that is, before any elements already in a), and p being equal to a.end() means to append something to the end of a.
    9. There is no guarantee that a valid iterator on a is still valid after an insertion or an erasure/removal. In some cases iterators do remain valid, and in other cases they do not. The details are different for each sequence class.
    10. a.insert(p, n, t) is guaranteed to be no slower than calling a.insert( p, t) n times, In some cases it is significantly faster.
    11. Vector is usually preferable to deque and list . Deque is useful in the case of frequent insertions ato both the beginning an end of the sequence, and list and slist are useful in the case of frequent insertions in the middle of the sequence. In almost all other situations, vector is more efficient.

    Sequences->Front Insertion Sequence

    1. A Front Insertion Sequence is a Sequence where it is possible to insert an element at the beginning, or to access the first element, in amortized constant time. Front Insertion Sequence have special member functions as a short hand for those operations.
    2. Front, push front, and pop front are amortized constant time.
    3. Models: list; deque
    4. Front is actually defined in Sequence, since it is always possible to implement it in amortized constant time. Its definition is repealed/abolished here, along with push front and pop front, in the interest of clarity.
    5. This complexity guarantee is the only reason that front(), push_front(), and pop_front are defined : they provided no additional functionality. Not every sequence must define these operations, but it is guaranteed that they are efficient if they exist at all.

    Sequences->Back Insertion Sequence

    1. A Back Insertion Sequence is a Sequence where it is possible to append an element to the end, or to access the last element, in amortized constant time. Back Insertion Sequence have special member functions as a shorthand for those operations.
    2. Back, push back, and pop back are amortized constant time.
    3. Models: vector, list, deque
    4. This complexity guarantee is the only reason that back(), push_back() and pop_back() are defined: they provide no additional functionality. Not every sequence must define these operations, but it is guaranteed that they are efficient if they exist at all.

    Associative->Associative Container

    1. An Associative Container is a variable-sized Container that supports efficient retrieval of elements /values based on keys. It supports insertion and removal / erasure, but differs from a Sequence in that it does not provide a mechanism for inserting an element at specific position.
    2. As with all containers, the elements in an Associative Container are of type value_type. Additionally, each element in an Associative Container has a key, being of type key_type. 
    3. In some Associative Containers, Simple Associative Containers, the value_type and key_type are the same: elements are their own keys. In others, the key is some specific part of the value. Since elements are stored according to their keys, it is essential that the key associated with each element is immutable.
    4. In Simple Associative Containers this means that the elements themselves are immutable, while in other types of Associative Containers, such as Pair Associative Containers, the elements themselves are mutable but the part of an element that is its key cannot be modified. This means that an Associative Containers’ value type is not Assignable /Allocative.
    5. The fact that the value type of an Associative Container is not Assignable has an important consequence: associative containers cannot have mutable iterators. This is simply because a mutable iterator (as defined in the Trivial Iterator requirements) must allow assignment. That is, if I is a mutable iterator and t is an object of I’s value type, then *I = t must be a valid expression.
    6. In Simple Associative Containers, where the elements are the keys, the elements are completely mutable; the nested /types iterator and const_iterator are therefore the same. Other types of associative containers, however, do have mutable elements, and do provide iterators through which elements can be modified.
    7. Pair Associative Containers, for example, have two different nested types iterator and const_iterator. Even in this case, iterator is not a mutable iterator: as explained above, it does not provide the expression *I = t. It is, however, possible to modify an element through such an iterator: if, for example, I is of type map<int, double>, then (*i).second = 3 is a valid expression.
    8. In some associative containers, Unique Associative Containers, it is guaranteed that no two elements have the same key. In other associative containers. Multiple Associative Containers, multiple elements with the same key are permitted.
    9. Models: set; multiset; hash_set; hash_multiset; map; multimap; hash_map; hash_multimap
    10. Red-Black Tree:http://en.wikipedia.org/wiki/Red%E2%80%93black_tree
    11.    1 //////////////////////////////////////////////////////////////////////////////
         2 //
         3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
         4 // Software License, Version 1.0. (See accompanying file
         5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
         6 //
         7 // See http://www.boost.org/libs/container for documentation.
         8 //
         9 //////////////////////////////////////////////////////////////////////////////
        10 
        11 #ifndef BOOST_CONTAINER_TREE_HPP
        12 #define BOOST_CONTAINER_TREE_HPP
        13 
        14 #include "config_begin.hpp"
        15 #include <boost/container/detail/workaround.hpp>
        16 #include <boost/container/container_fwd.hpp>
        17 
        18 #include <boost/move/utility.hpp>
        19 #include <boost/intrusive/pointer_traits.hpp>
        20 #include <boost/type_traits/has_trivial_destructor.hpp>
        21 #include <boost/detail/no_exceptions_support.hpp>
        22 #include <boost/intrusive/rbtree.hpp>
        23 
        24 #include <boost/container/detail/utilities.hpp>
        25 #include <boost/container/detail/algorithms.hpp>
        26 #include <boost/container/detail/node_alloc_holder.hpp>
        27 #include <boost/container/detail/destroyers.hpp>
        28 #include <boost/container/detail/pair.hpp>
        29 #include <boost/container/detail/type_traits.hpp>
        30 #include <boost/container/allocator_traits.hpp>
        31 #include <boost/detail/no_exceptions_support.hpp>
        32 #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
        33 #include <boost/container/detail/preprocessor.hpp>
        34 #endif
        35 
        36 #include <utility>   //std::pair
        37 #include <iterator>
        38 #include <algorithm>
        39 
        40 namespace boost {
        41 namespace container {
        42 namespace container_detail {
        43 
        44 template<class Key, class Value, class KeyCompare, class KeyOfValue>
        45 struct tree_value_compare:  public KeyCompare
        46 {
        47    typedef Value        value_type;
        48    typedef KeyCompare   key_compare;
        49    typedef KeyOfValue   key_of_value;
        50    typedef Key          key_type;
        51 
        52    tree_value_compare(const key_compare &kcomp)
        53       :  key_compare(kcomp)
        54    {}
        55 
        56    const key_compare &key_comp() const
        57    {  return static_cast<const key_compare &>(*this);  }
        58 
        59    key_compare &key_comp()
        60    {  return static_cast<key_compare &>(*this);  }
        61 
        62    template<class T>
        63    struct is_key
        64    {
        65       static const bool value = is_same<const T, const key_type>::value;
        66    };
        67 
        68    template<class T>
        69    typename enable_if_c<is_key<T>::value, const key_type &>::type key_forward(const T &key) const
        70    {  return key; }
        71 
        72    template<class T>
        73    typename enable_if_c<!is_key<T>::value, const key_type &>::type key_forward(const T &key) const
        74    {  return KeyOfValue()(key);  }
        75 
        76    template<class KeyType, class KeyType2>
        77    bool operator()(const KeyType &key1, const KeyType2 &key2) const
        78    {  return key_compare::operator()(this->key_forward(key1), this->key_forward(key2));  }
        79 };
        80 
        81 template<class VoidPointer>
        82 struct rbtree_hook
        83 {
        84    typedef typename container_detail::bi::make_set_base_hook
        85       < container_detail::bi::void_pointer<VoidPointer>
        86       , container_detail::bi::link_mode<container_detail::bi::normal_link>
        87       , container_detail::bi::optimize_size<true>
        88       >::type  type;
        89 };
        90 
        91 //This trait is used to type-pun std::pair because in C++03
        92 //compilers std::pair is useless for C++11 features
        93 template<class T>
        94 struct rbtree_internal_data_type
        95 {
        96    typedef T type;
        97 };
        98 
        99 template<class T1, class T2>
       100 struct rbtree_internal_data_type< std::pair<T1, T2> >
       101 {
       102    typedef pair<T1, T2> type;
       103 };
       104 //The node to be store in the tree
       105 template <class T, class VoidPointer>
       106 struct rbtree_node:  public rbtree_hook<VoidPointer>::type
       107 {
       108    private:
       109    //BOOST_COPYABLE_AND_MOVABLE(rbtree_node)
       110    rbtree_node();
       111    public:
       112    typedef typename rbtree_hook<VoidPointer>::type hook_type;
       113    typedef T value_type;
       114    typedef typename rbtree_internal_data_type<T>::type internal_type;
       115    typedef rbtree_node<T, VoidPointer> node_type;
       116    T &get_data()
       117    {
       118       T* ptr = reinterpret_cast<T*>(&this->m_data);
       119       return *ptr;
       120    }
       121    const T &get_data() const
       122    {
       123       const T* ptr = reinterpret_cast<const T*>(&this->m_data);
       124       return *ptr;
       125    }
       126    internal_type m_data;
       127    template<class A, class B>
       128    void do_assign(const std::pair<const A, B> &p)
       129    {
       130       const_cast<A&>(m_data.first) = p.first;
       131       m_data.second  = p.second;
       132    }
       133    template<class A, class B>
       134    void do_assign(const pair<const A, B> &p)
       135    {
       136       const_cast<A&>(m_data.first) = p.first;
       137       m_data.second  = p.second;
       138    }
       139    template<class V>
       140    void do_assign(const V &v)
       141    {  m_data = v; }
       142 
       143    template<class A, class B>
       144    void do_move_assign(std::pair<const A, B> &p)
       145    {
       146       const_cast<A&>(m_data.first) = ::boost::move(p.first);
       147       m_data.second = ::boost::move(p.second);
       148    }
       149    template<class A, class B>
       150    void do_move_assign(pair<const A, B> &p)
       151    {
       152       const_cast<A&>(m_data.first) = ::boost::move(p.first);
       153       m_data.second  = ::boost::move(p.second);
       154    }
       155    template<class V>
       156    void do_move_assign(V &v)
       157    {  m_data = ::boost::move(v); }
       158 };
       159 
       160 }//namespace container_detail {
       161 
       162 namespace container_detail {
       163 template<class A, class ValueCompare>
       164 struct intrusive_rbtree_type
       165 {
       166    typedef typename boost::container::
       167       allocator_traits<A>::value_type              value_type;
       168    typedef typename boost::container::
       169       allocator_traits<A>::void_pointer            void_pointer;
       170    typedef typename boost::container::
       171       allocator_traits<A>::size_type               size_type;
       172    typedef typename container_detail::rbtree_node
       173          <value_type, void_pointer>                node_type;
       174    typedef node_compare<ValueCompare, node_type>   node_compare_type;
       175    typedef typename container_detail::bi::make_rbtree
       176       <node_type
       177       ,container_detail::bi::compare<node_compare_type>
       178       ,container_detail::bi::base_hook<typename rbtree_hook<void_pointer>::type>
       179       ,container_detail::bi::constant_time_size<true>
       180       ,container_detail::bi::size_type<size_type>
       181       >::type                                      container_type;
       182    typedef container_type                          type ;
       183 };
       184 }  //namespace container_detail {
       185 
       186 namespace container_detail {
       187 template <class Key, class Value, class KeyOfValue,class KeyCompare, class A>
       188 class rbtree: protected container_detail::node_alloc_holder
       189       < A
       190       , typename container_detail::intrusive_rbtree_type
       191          <A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue> 
       192          >::type
       193       , KeyCompare
       194       >
       195 {
       196    typedef typename container_detail::intrusive_rbtree_type
       197          < A, tree_value_compare
       198             <Key, Value, KeyCompare, KeyOfValue>
       199          >::type                                            Icont;
       200    typedef container_detail::node_alloc_holder<A, Icont, KeyCompare>   AllocHolder;
       201    typedef typename AllocHolder::NodePtr                    NodePtr;
       202    typedef rbtree < Key, Value, KeyOfValue, KeyCompare, A>  ThisType;
       203    typedef typename AllocHolder::NodeAlloc                  NodeAlloc;
       204    typedef typename AllocHolder::ValAlloc                   ValAlloc;
       205    typedef typename AllocHolder::Node                       Node;
       206    typedef typename Icont::iterator                         iiterator;
       207    typedef typename Icont::const_iterator                   iconst_iterator;
       208    typedef container_detail::allocator_destroyer<NodeAlloc> Destroyer;
       209    typedef typename AllocHolder::allocator_v1               allocator_v1;
       210    typedef typename AllocHolder::allocator_v2               allocator_v2;
       211    typedef typename AllocHolder::alloc_version              alloc_version;
       212 
       213    class RecyclingCloner;
       214    friend class RecyclingCloner;
       215 
       216    class RecyclingCloner
       217    {
       218       public:
       219       RecyclingCloner(AllocHolder &holder, Icont &irbtree)
       220          :  m_holder(holder), m_icont(irbtree)
       221       {}
       222 
       223       NodePtr operator()(const Node &other) const
       224       {
       225          if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
       226             //First recycle a node (this can't throw)
       227             BOOST_TRY{
       228                //This can throw
       229                p->do_assign(other.m_data);
       230                return p;
       231             }
       232             BOOST_CATCH(...){
       233                //If there is an exception destroy the whole source
       234                m_holder.destroy_node(p);
       235                while((p = m_icont.unlink_leftmost_without_rebalance())){
       236                   m_holder.destroy_node(p);
       237                }
       238                BOOST_RETHROW
       239             }
       240             BOOST_CATCH_END
       241          }
       242          else{
       243             return m_holder.create_node(other.m_data);
       244          }
       245       }
       246 
       247       AllocHolder &m_holder;
       248       Icont &m_icont;
       249    };
       250    class RecyclingMoveCloner;
       251    friend class RecyclingMoveCloner;
       252    class RecyclingMoveCloner
       253    {
       254       public:
       255       RecyclingMoveCloner(AllocHolder &holder, Icont &irbtree):  m_holder(holder), m_icont(irbtree)
       256       {}
       257 
       258       NodePtr operator()(const Node &other) const
       259       {
       260          if(NodePtr p = m_icont.unlink_leftmost_without_rebalance()){
       261             //First recycle a node (this can't throw)
       262             BOOST_TRY{
       263                //This can throw
       264                p->do_move_assign(const_cast<Node &>(other).m_data);
       265                return p;
       266             }
       267             BOOST_CATCH(...){
       268                //If there is an exception destroy the whole source
       269                m_holder.destroy_node(p);
       270                while((p = m_icont.unlink_leftmost_without_rebalance())){
       271                   m_holder.destroy_node(p);
       272                }
       273                BOOST_RETHROW
       274             }
       275             BOOST_CATCH_END
       276          }
       277          else{
       278             return m_holder.create_node(other.m_data);
       279          }
       280       }
       281 
       282       AllocHolder &m_holder;
       283       Icont &m_icont;
       284    };
       285 
       286    BOOST_COPYABLE_AND_MOVABLE(rbtree)
       287 
       288    public:
       289    typedef Key                                        key_type;
       290    typedef Value                                      value_type;
       291    typedef A                                          allocator_type;
       292    typedef KeyCompare                                 key_compare;
       293    typedef tree_value_compare< Key, Value, KeyCompare, KeyOfValue>  value_compare;
       294    typedef typename boost::container::allocator_traits<A>::pointer     pointer;
       295    typedef typename boost::container::allocator_traits<A>::const_pointer   const_pointer;
       296    typedef typename boost::container::allocator_traits<A>::reference  reference;
       297    typedef typename boost::container::allocator_traits<A>::const_reference    const_reference;
       298    typedef typename boost::container::allocator_traits<A>::size_type           size_type;
       299    typedef typename boost::container::allocator_traits<A>::difference_type    difference_type;
       300    typedef difference_type                            rbtree_difference_type;
       301    typedef pointer                                    rbtree_pointer;
       302    typedef const_pointer                              rbtree_const_pointer;
       303    typedef reference                                  rbtree_reference;
       304    typedef const_reference                            rbtree_const_reference;
       305    typedef NodeAlloc                                  stored_allocator_type;
       306 
       307    private:
       308 
       309    template<class KeyValueCompare>
       310    struct key_node_compare:  private KeyValueCompare
       311    {
       312       key_node_compare(const KeyValueCompare &comp)
       313          :  KeyValueCompare(comp)
       314       {}
       315 
       316       template<class T>
       317       struct is_node
       318       {
       319          static const bool value = is_same<T, Node>::value;
       320       };
       321 
       322       template<class T>
       323       typename enable_if_c<is_node<T>::value, const value_type &>::type key_forward(const T &node) const
       324       {  return node.get_data();  }
       325 
       326       template<class T>
       327       typename enable_if_c<!is_node<T>::value, const T &>::type key_forward(const T &key) const
       328       {  return key; }
       329 
       330       template<class KeyType, class KeyType2>
       331       bool operator()(const KeyType &key1, const KeyType2 &key2) const
       332       {  return KeyValueCompare::operator()(this->key_forward(key1), this->key_forward(key2));  }
       333    };
       334 
       335    typedef key_node_compare<value_compare>  KeyNodeCompare;
       336 
       337    public:
       338    //rbtree const_iterator
       339    class const_iterator
       340       : public std::iterator
       341          < std::bidirectional_iterator_tag
       342          , value_type            , rbtree_difference_type
       343          , rbtree_const_pointer  , rbtree_const_reference>
       344    {
       345       protected:
       346       typedef typename Icont::iterator  iiterator;
       347       iiterator m_it;
       348       explicit const_iterator(iiterator it)  : m_it(it){}
       349       void prot_incr() { ++m_it; }
       350       void prot_decr() { --m_it; }
       351       private:
       352       iiterator get()
       353       {  return this->m_it;   }
       354 
       355       public:
       356       friend class rbtree <Key, Value, KeyOfValue, KeyCompare, A>;
       357       typedef rbtree_difference_type        difference_type;
       358 
       359       //Constructors
       360       const_iterator():  m_it()
       361       {}
       362 
       363       //Pointer like operators
       364       const_reference operator*()  const
       365       { return  m_it->get_data();  }
       366 
       367       const_pointer   operator->() const
       368       { return  const_pointer(&m_it->get_data()); }
       369 
       370       //Increment / Decrement
       371       const_iterator& operator++()      
       372       { prot_incr();  return *this; }
       373 
       374       const_iterator operator++(int)     
       375       { iiterator tmp = m_it; ++*this; return const_iterator(tmp);  }
       376 
       377       const_iterator& operator--()
       378       {   prot_decr(); return *this;   }
       379 
       380       const_iterator operator--(int)
       381       {  iiterator tmp = m_it; --*this; return const_iterator(tmp); }
       382 
       383       //Comparison operators
       384       bool operator==   (const const_iterator& r)  const
       385       {  return m_it == r.m_it;  }
       386 
       387       bool operator!=   (const const_iterator& r)  const
       388       {  return m_it != r.m_it;  }
       389    };
       390 
       391    //rbtree iterator
       392    class iterator : public const_iterator
       393    {
       394       private:
       395       explicit iterator(iiterator it)
       396          :  const_iterator(it)
       397       {}  
       398       iiterator get()
       399       {  return this->m_it;   }
       400       public:
       401       friend class rbtree <Key, Value, KeyOfValue, KeyCompare, A>;
       402       typedef rbtree_pointer       pointer;
       403       typedef rbtree_reference     reference;
       404       //Constructors
       405       iterator(){}
       406       //Pointer like operators
       407       reference operator*()  const  {  return this->m_it->get_data();  }
       408       pointer   operator->() const
       409          {  return boost::intrusive::pointer_traits<pointer>::pointer_to(this->m_it->get_data());  }
       410       //Increment / Decrement
       411       iterator& operator++(){ this->prot_incr(); return *this;  }
       412 
       413       iterator operator++(int){ iiterator tmp = this->m_it; ++*this; return iterator(tmp); }
       414      
       415       iterator& operator--(){  this->prot_decr(); return *this;  }
       416 
       417       iterator operator--(int){  iterator tmp = *this; --*this; return tmp; }
       418    };
       419 
       420    typedef std::reverse_iterator<iterator>        reverse_iterator;
       421    typedef std::reverse_iterator<const_iterator>  const_reverse_iterator;
       422 
       423    rbtree(): AllocHolder(key_compare())
       424    {}
       425 
       426    rbtree(const key_compare& comp, const allocator_type& a = allocator_type()): AllocHolder(a, comp)
       427    {}
       428 
       429    template <class InputIterator>
       430    rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
       431           const allocator_type& a
       432       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
       433       , typename container_detail::enable_if_c
       434          < container_detail::is_input_iterator<InputIterator>::value
       435             || container_detail::is_same<alloc_version, allocator_v1>::value
       436          >::type * = 0
       437       #endif
       438          )
       439       : AllocHolder(a, comp)
       440    {
       441       if(unique_insertion){
       442          this->insert_unique(first, last);
       443       }
       444       else{
       445          this->insert_equal(first, last);
       446       }
       447    }
       448    template <class InputIterator>
       449    rbtree(bool unique_insertion, InputIterator first, InputIterator last, const key_compare& comp,
       450           const allocator_type& a
       451       #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
       452       , typename container_detail::enable_if_c
       453          < !(container_detail::is_input_iterator<InputIterator>::value
       454             || container_detail::is_same<alloc_version, allocator_v1>::value)
       455          >::type * = 0
       456       #endif
       457          )
       458       : AllocHolder(a, comp)
       459    {
       460       if(unique_insertion){
       461          this->insert_unique(first, last);
       462       }
       463       else{
       464          //Optimized allocation and construction
       465          this->allocate_many_and_construct
       466             (first, std::distance(first, last), insert_equal_end_hint_functor(this->icont()));
       467       }
       468    }
       469 
       470    template <class InputIterator>
       471    rbtree( ordered_range_t, InputIterator first, InputIterator last
       472          , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
       473          #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
       474          , typename container_detail::enable_if_c
       475             < container_detail::is_input_iterator<InputIterator>::value
       476                || container_detail::is_same<alloc_version, allocator_v1>::value
       477             >::type * = 0
       478          #endif
       479          )
       480       : AllocHolder(a, comp)
       481    {
       482       this->insert_equal(first, last);
       483    }
       484 
       485    template <class InputIterator>
       486    rbtree( ordered_range_t, InputIterator first, InputIterator last
       487          , const key_compare& comp = key_compare(), const allocator_type& a = allocator_type()
       488          #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
       489          , typename container_detail::enable_if_c
       490             < !(container_detail::is_input_iterator<InputIterator>::value
       491                || container_detail::is_same<alloc_version, allocator_v1>::value)
       492             >::type * = 0
       493          #endif
       494          )
       495       : AllocHolder(a, comp)
       496    {
       497       //Optimized allocation and construction
       498       this->allocate_many_and_construct(first, std::distance(first, last), push_back_functor(this->icont()));
       499    }
       500 
       501    rbtree(const rbtree& x):AllocHolder(x, x.key_comp())
       502    {
       503       this->icont().clone_from(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
       504    }
       505 
       506    rbtree(BOOST_RV_REF(rbtree) x):AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.key_comp())
       507    {}
       508 
       509    rbtree(const rbtree& x, const allocator_type &a):  AllocHolder(a, x.key_comp())
       510    {
       511       this->icont().clone_from(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
       512    }
       513 
       514    rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a):  AllocHolder(a, x.key_comp())
       515    {
       516       if(this->node_alloc() == x.node_alloc()){
       517          this->icont().swap(x.icont());
       518       }
       519       else{
       520          this->icont().clone_from
       521             (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
       522       }
       523    }
       524 
       525    ~rbtree()
       526    {} //AllocHolder clears the tree
       527 
       528    rbtree& operator=(BOOST_COPY_ASSIGN_REF(rbtree) x)
       529    {
       530       if (&x != this){
       531          NodeAlloc &this_alloc     = this->get_stored_allocator();
       532          const NodeAlloc &x_alloc  = x.get_stored_allocator();
       533          container_detail::bool_<allocator_traits<NodeAlloc>::
       534             propagate_on_container_copy_assignment::value> flag;
       535          if(flag && this_alloc != x_alloc){
       536             this->clear();
       537          }
       538          this->AllocHolder::copy_assign_alloc(x);
       539          //Transfer all the nodes to a temporary tree
       540          //If anything goes wrong, all the nodes will be destroyed
       541          //automatically
       542          Icont other_tree(::boost::move(this->icont()));
       543 
       544          //Now recreate the source tree reusing nodes stored by other_tree
       545          this->icont().clone_from
       546             (x.icont()
       547             , RecyclingCloner(*this, other_tree)
       548             , Destroyer(this->node_alloc()));
       549 
       550          //If there are remaining nodes, destroy them
       551          NodePtr p;
       552          while((p = other_tree.unlink_leftmost_without_rebalance())){
       553             AllocHolder::destroy_node(p);
       554          }
       555       }
       556       return *this;
       557    }
       558 
       559    rbtree& operator=(BOOST_RV_REF(rbtree) x)
       560    {
       561       if (&x != this){
       562          NodeAlloc &this_alloc = this->node_alloc();
       563          NodeAlloc &x_alloc    = x.node_alloc();
       564          //If allocators are equal we can just swap pointers
       565          if(this_alloc == x_alloc){
       566             //Destroy and swap pointers
       567             this->clear();
       568             this->icont() = ::boost::move(x.icont());
       569             //Move allocator if needed
       570             this->AllocHolder::move_assign_alloc(x);
       571          }
       572          //If unequal allocators, then do a one by one move
       573          else{
       574             //Transfer all the nodes to a temporary tree
       575             //If anything goes wrong, all the nodes will be destroyed
       576             //automatically
       577             Icont other_tree(::boost::move(this->icont()));
       578 
       579             //Now recreate the source tree reusing nodes stored by other_tree
       580             this->icont().clone_from
       581                (x.icont()
       582                , RecyclingMoveCloner(*this, other_tree)
       583                , Destroyer(this->node_alloc()));
       584 
       585             //If there are remaining nodes, destroy them
       586             NodePtr p;
       587             while((p = other_tree.unlink_leftmost_without_rebalance())){
       588                AllocHolder::destroy_node(p);
       589             }
       590          }
       591       }
       592       return *this;
       593    }
       594 
       595    public:   
       596    // accessors:
       597    value_compare value_comp() const
       598    {  return this->icont().value_comp().value_comp(); }
       599    key_compare key_comp() const
       600    {  return this->icont().value_comp().value_comp().key_comp(); }
       601    allocator_type get_allocator() const
       602    {  return allocator_type(this->node_alloc()); }
       603    const stored_allocator_type &get_stored_allocator() const
       604    {  return this->node_alloc(); }
       605    stored_allocator_type &get_stored_allocator()
       606    {  return this->node_alloc(); }
       607    iterator begin()
       608    { return iterator(this->icont().begin()); }
       609    const_iterator begin() const
       610    {  return this->cbegin();  }
       611    iterator end()
       612    {  return iterator(this->icont().end());  }
       613    const_iterator end() const
       614    {  return this->cend();  }
       615    reverse_iterator rbegin()
       616    {  return reverse_iterator(end());  }
       617    const_reverse_iterator rbegin() const
       618    {  return this->crbegin();  }
       619    reverse_iterator rend()
       620    {  return reverse_iterator(begin());   }
       621    const_reverse_iterator rend() const
       622    {  return this->crend();   }
       623    const_iterator cbegin() const
       624    { return const_iterator(this->non_const_icont().begin()); }
       625    const_iterator cend() const
       626    { return const_iterator(this->non_const_icont().end()); }
       627    const_reverse_iterator crbegin() const
       628    { return const_reverse_iterator(cend()); }
       629    const_reverse_iterator crend() const
       630    { return const_reverse_iterator(cbegin()); }
       631    bool empty() const
       632    {  return !this->size();  }
       633    size_type size() const
       634    {  return this->icont().size();   }
       635    size_type max_size() const
       636    {  return AllocHolder::max_size();  }
       637    void swap(ThisType& x)
       638    {  AllocHolder::swap(x);   }
       639 
       640    public:
       641    typedef typename Icont::insert_commit_data insert_commit_data;
       642    // insert/erase
       643    std::pair<iterator,bool> insert_unique_check
       644       (const key_type& key, insert_commit_data &data)
       645    {
       646       std::pair<iiterator, bool> ret =
       647          this->icont().insert_unique_check(key, KeyNodeCompare(value_comp()), data);
       648       return std::pair<iterator, bool>(iterator(ret.first), ret.second);
       649    }
       650    std::pair<iterator,bool> insert_unique_check
       651       (const_iterator hint, const key_type& key, insert_commit_data &data)
       652    {
       653       std::pair<iiterator, bool> ret =
       654          this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
       655       return std::pair<iterator, bool>(iterator(ret.first), ret.second);
       656    }
       657    iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
       658    {
       659       NodePtr tmp = AllocHolder::create_node(v);
       660       iiterator it(this->icont().insert_unique_commit(*tmp, data));
       661       return iterator(it);
       662    }
       663    template<class MovableConvertible>
       664    iterator insert_unique_commit
       665       (BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data)
       666    {
       667       NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(mv));
       668       iiterator it(this->icont().insert_unique_commit(*tmp, data));
       669       return iterator(it);
       670    }
       671    std::pair<iterator,bool> insert_unique(const value_type& v)
       672    {
       673       insert_commit_data data;
       674       std::pair<iterator,bool> ret =
       675          this->insert_unique_check(KeyOfValue()(v), data);
       676       if(!ret.second)
       677          return ret;
       678       return std::pair<iterator,bool>
       679          (this->insert_unique_commit(v, data), true);
       680    }
       681    template<class MovableConvertible>
       682    std::pair<iterator,bool> insert_unique(BOOST_FWD_REF(MovableConvertible) mv)
       683    {
       684       insert_commit_data data;
       685       std::pair<iterator,bool> ret =
       686          this->insert_unique_check(KeyOfValue()(mv), data);
       687       if(!ret.second)
       688          return ret;
       689       return std::pair<iterator,bool>
       690          (this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data), true);
       691    }
       692    private:
       693    std::pair<iterator, bool> emplace_unique_impl(NodePtr p)
       694    {
       695       value_type &v = p->get_data();
       696       insert_commit_data data;
       697       scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(p, this->node_alloc());
       698       std::pair<iterator,bool> ret =
       699          this->insert_unique_check(KeyOfValue()(v), data);
       700       if(!ret.second){
       701          return ret;
       702       }
       703       //No throw insertion part, release rollback
       704       destroy_deallocator.release();
       705       return std::pair<iterator,bool>
       706          ( iterator(iiterator(this->icont().insert_unique_commit(*p, data)))
       707          , true );
       708    }
       709    iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
       710    {
       711       value_type &v = p->get_data();
       712       insert_commit_data data;
       713       std::pair<iterator,bool> ret =
       714          this->insert_unique_check(hint, KeyOfValue()(v), data);
       715       if(!ret.second){
       716          Destroyer(this->node_alloc())(p);
       717          return ret.first;
       718       }
       719       return iterator(iiterator(this->icont().insert_unique_commit(*p, data)));
       720    }
       721    public:
       722    #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
       723    template <class... Args>
       724    std::pair<iterator, bool> emplace_unique(Args&&... args)
       725    {  return this->emplace_unique_impl(AllocHolder::create_node(boost::forward<Args>(args)...));   }
       726 
       727    template <class... Args>
       728    iterator emplace_hint_unique(const_iterator hint, Args&&... args)
       729    {  return this->emplace_unique_hint_impl(hint, AllocHolder::create_node(boost::forward<Args>(args)...));   }
       730 
       731    template <class... Args>
       732    iterator emplace_equal(Args&&... args)
       733    {
       734       NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...));
       735       return iterator(this->icont().insert_equal(this->icont().end(), *p));
       736    }
       737 
       738    template <class... Args>
       739    iterator emplace_hint_equal(const_iterator hint, Args&&... args)
       740    {
       741       NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...));
       742       return iterator(this->icont().insert_equal(hint.get(), *p));
       743    }
       744 
       745    #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
       746 
       747    #define BOOST_PP_LOCAL_MACRO(n)                                                                          
       748    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)                   
       749    std::pair<iterator, bool> emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))             
       750    {                                                                                                        
       751       return this->emplace_unique_impl                                                                      
       752          (AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)));                 
       753    }                                                                                                        
       754                                                                                                             
       755    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)                   
       756    iterator emplace_hint_unique(const_iterator hint                                                         
       757                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                         
       758    {                                                                                                        
       759       return this->emplace_unique_hint_impl                                                                 
       760          (hint, AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)));           
       761    }                                                                                                        
       762                                                                                                             
       763    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)                   
       764    iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                               
       765    {                                                                                                        
       766       NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)));           
       767       return iterator(this->icont().insert_equal(this->icont().end(), *p));                                 
       768    }                                                                                                        
       769                                                                                                             
       770    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)                   
       771    iterator emplace_hint_equal(const_iterator hint                                                          
       772                        BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                         
       773    {                                                                                                        
       774       NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)));           
       775       return iterator(this->icont().insert_equal(hint.get(), *p));                                          
       776    }                                                                                                        
       777    //!
       778    #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
       779    #include BOOST_PP_LOCAL_ITERATE()
       780 
       781    #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
       782 
       783    iterator insert_unique(const_iterator hint, const value_type& v)
       784    {
       785       insert_commit_data data;
       786       std::pair<iterator,bool> ret = this->insert_unique_check(hint, KeyOfValue()(v), data);
       787       if(!ret.second)
       788          return ret.first;
       789       return this->insert_unique_commit(v, data);
       790    }
       791 
       792    template<class MovableConvertible>
       793    iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
       794    {
       795       insert_commit_data data;
       796       std::pair<iterator,bool> ret =
       797          this->insert_unique_check(hint, KeyOfValue()(mv), data);
       798       if(!ret.second)
       799          return ret.first;
       800       return this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data);
       801    }
       802 
       803    template <class InputIterator>
       804    void insert_unique(InputIterator first, InputIterator last)
       805    {
       806       if(this->empty()){
       807          //Insert with end hint, to achieve linear
       808          //complexity if [first, last) is ordered
       809          const_iterator hint(this->cend());
       810          for( ; first != last; ++first)
       811             hint = this->insert_unique(hint, *first);
       812       }
       813       else{
       814          for( ; first != last; ++first)
       815             this->insert_unique(*first);
       816       }
       817    }
       818 
       819    iterator insert_equal(const value_type& v)
       820    {
       821       NodePtr p(AllocHolder::create_node(v));
       822       return iterator(this->icont().insert_equal(this->icont().end(), *p));
       823    }
       824 
       825    template<class MovableConvertible>
       826    iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv)
       827    {
       828       NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
       829       return iterator(this->icont().insert_equal(this->icont().end(), *p));
       830    }
       831 
       832    iterator insert_equal(const_iterator hint, const value_type& v)
       833    {
       834       NodePtr p(AllocHolder::create_node(v));
       835       return iterator(this->icont().insert_equal(hint.get(), *p));
       836    }
       837 
       838    template<class MovableConvertible>
       839    iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
       840    {
       841       NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
       842       return iterator(this->icont().insert_equal(hint.get(), *p));
       843    }
       844 
       845    template <class InputIterator>
       846    void insert_equal(InputIterator first, InputIterator last)
       847    {
       848       //Insert with end hint, to achieve linear
       849       //complexity if [first, last) is ordered
       850       const_iterator hint(this->cend());
       851       for( ; first != last; ++first)
       852          hint = this->insert_equal(hint, *first);
       853    }
       854 
       855    iterator erase(const_iterator position)
       856    {  return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
       857 
       858    size_type erase(const key_type& k)
       859    {  return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
       860 
       861    iterator erase(const_iterator first, const_iterator last)
       862    {  return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
       863 
       864    void clear()
       865    {  AllocHolder::clear(alloc_version());  }
       866 
       867    // set operations:
       868    iterator find(const key_type& k)
       869    {  return iterator(this->icont().find(k, KeyNodeCompare(value_comp())));  }
       870 
       871    const_iterator find(const key_type& k) const
       872    {  return const_iterator(this->non_const_icont().find(k, KeyNodeCompare(value_comp())));  }
       873 
       874    size_type count(const key_type& k) const
       875    {  return size_type(this->icont().count(k, KeyNodeCompare(value_comp()))); }
       876 
       877    iterator lower_bound(const key_type& k)
       878    {  return iterator(this->icont().lower_bound(k, KeyNodeCompare(value_comp())));  }
       879 
       880    const_iterator lower_bound(const key_type& k) const
       881    {  return const_iterator(this->non_const_icont().lower_bound(k, KeyNodeCompare(value_comp())));  }
       882 
       883    iterator upper_bound(const key_type& k)
       884    {  return iterator(this->icont().upper_bound(k, KeyNodeCompare(value_comp())));   }
       885 
       886    const_iterator upper_bound(const key_type& k) const
       887    {  return const_iterator(this->non_const_icont().upper_bound(k, KeyNodeCompare(value_comp())));  }
       888 
       889    std::pair<iterator,iterator> equal_range(const key_type& k)
       890    {
       891       std::pair<iiterator, iiterator> ret =
       892          this->icont().equal_range(k, KeyNodeCompare(value_comp()));
       893       return std::pair<iterator,iterator>(iterator(ret.first), iterator(ret.second));
       894    }
       895 
       896    std::pair<const_iterator, const_iterator> equal_range(const key_type& k) const
       897    {
       898       std::pair<iiterator, iiterator> ret =
       899          this->non_const_icont().equal_range(k, KeyNodeCompare(value_comp()));
       900       return std::pair<const_iterator,const_iterator>
       901          (const_iterator(ret.first), const_iterator(ret.second));
       902    }
       903 
       904    private:
       905    class insert_equal_end_hint_functor;
       906    friend class insert_equal_end_hint_functor;
       907    class insert_equal_end_hint_functor
       908    {
       909       Icont &icont_;
       910       const iconst_iterator cend_;
       911 
       912       public:
       913       insert_equal_end_hint_functor(Icont &icont)
       914          :  icont_(icont), cend_(this->icont_.cend())
       915       {}
       916 
       917       void operator()(Node &n)
       918       {  this->icont_.insert_equal(cend_, n); }
       919    };
       920 
       921    class push_back_functor;
       922    friend class push_back_functor;
       923 
       924    class push_back_functor
       925    {
       926       Icont &icont_;
       927 
       928       public:
       929       push_back_functor(Icont &icont)
       930          :  icont_(icont)
       931       {}
       932 
       933       void operator()(Node &n)
       934       {  this->icont_.push_back(n); }
       935    };
       936 };
       937 
       938 template <class Key, class Value, class KeyOfValue,
       939           class KeyCompare, class A>
       940 inline bool operator==(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
       941            const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
       942 {
       943   return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin());
       944 }
       945 
       946 template <class Key, class Value, class KeyOfValue,
       947           class KeyCompare, class A>
       948 inline bool operator<(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
       949           const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
       950 {
       951   return std::lexicographical_compare(x.begin(), x.end(),
       952                                       y.begin(), y.end());
       953 }
       954 
       955 template <class Key, class Value, class KeyOfValue,
       956           class KeyCompare, class A>
       957 inline bool operator!=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
       958            const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
       959 {
       960   return !(x == y);
       961 }
       962 
       963 template <class Key, class Value, class KeyOfValue,
       964           class KeyCompare, class A>
       965 inline bool operator>(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
       966           const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) 
       967 {
       968   return y < x;
       969 }
       970 
       971 template <class Key, class Value, class KeyOfValue,
       972           class KeyCompare, class A>
       973 inline bool operator<=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
       974            const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) 
       975 {
       976   return !(y < x);
       977 }
       978 
       979 template <class Key, class Value, class KeyOfValue,
       980           class KeyCompare, class A>
       981 inline bool operator>=(const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
       982            const rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y) 
       983 {
       984   return !(x < y);
       985 }
       986 
       987 
       988 template <class Key, class Value, class KeyOfValue,
       989           class KeyCompare, class A>
       990 inline void swap(rbtree<Key,Value,KeyOfValue,KeyCompare,A>& x,
       991      rbtree<Key,Value,KeyOfValue,KeyCompare,A>& y)
       992 {
       993   x.swap(y);
       994 }
       995 
       996 } //namespace container_detail {
       997 } //namespace container {
       998 /*
       999 //!has_trivial_destructor_after_move<> == true_type
      1000 //!specialization for optimizations
      1001 template <class K, class V, class KOV,
      1002 class C, class A>
      1003 struct has_trivial_destructor_after_move
      1004    <boost::container::container_detail::rbtree<K, V, KOV, C, A> >
      1005 {
      1006    static const bool value = has_trivial_destructor_after_move<A>::value && has_trivial_destructor_after_move<C>::value;
      1007 };
      1008 */
      1009 } //namespace boost  {
      1010 
      1011 #include <boost/container/detail/config_end.hpp>
      1012 
      1013 #endif //BOOST_CONTAINER_TREE_HPP
      View Code

      二叉树的意思是:任何节点最多只能有两个子节点的树。二叉搜索树可提供log(N)的元素插入和访问,它的节点旋转规则是:任何节点的键值一定大于其左子节点树中的每个节点的键值,并小于其右子树中的每个节点的键值。因此,从树节点一直往左走到底,即得最小元素;从根节点一直往右走到底,却得最大元素。但是,由于插入值无规律,二叉搜索树可能失去平衡,造成搜索效率低落的情况。解决办法就是尽量使树形左右“平衡”,对于何为“平衡”,没有一个绝对的定义,大致的意思就是“没有一个节点过深”。常见的平衡二叉树有AVL-tree, RB-tree, AA-tree,它们都比上面说的一般二叉树复杂,插入节点和删除节点时要做一些额外操作来维护树形平衡,但是它们可以避免极难应付的极不平衡的情况,而且由于它们总是保持某种程度的平衡,所以元素访问时间平均而言就比较少。

    SGI STL实现的搜索树是RB-tree,它在一般二叉树的基础上增加了以下必须满足的条件:

    • 每个节点不是红色就是黑色;
    • 根节点为黑色;
    • 如果节点为红,其子节点必须为黑,如果节点为黑,则随意;
    • 任一节点到树尾端的任何路径(比如从根节点到任意一个叶节点),所含的黑节点数量必须相同。

    根据规则4,新增节点必须为红色;根据规则3,新增节点的父节点必须为黑。当新节点根据一般二叉树搜索规则到达其插入点,却未能符合上述条件时,就必须调整节点颜色和旋转树形。注意经过调整后,叶节点可能为黑色。

    Associative Container->Simple Associative Container

    1. A simple Associative Container is an Associative Container where elements are their own keys. A key in a Simple Associative Container is not associated with any additional value.
    2. Immutability of element: Every element of a Simple Associative Container is immutable. Objects may be inserted and erased, but not modified.
    3. Models: set; multiset; hash_set; hash_multiset;
    4. This is a consequence of the Immutability of Keys invariant of Associative Container. Keys may never be modified; values in a Simple Associative Container are themselves keys, so it immediately follows that values in a Simple Associative Container may not be modified.
    5. template <class _Key, class _Value, class _KeyOfValue, class _Compare, class _Alloc = _BP_STL_DEFAULT_ALLOCATOR(_Value) >76. class _Rb_tree : protected _Rb_tree_base<_Value, _Alloc> 
    6. With concept of composition, template class _Rb_tree is regarded as a type of a member within template class set or hash_set and so on.
    7.   1 //! A set is a kind of associative container that supports unique keys (contains at
        2 //! most one of each key value) and provides for fast retrieval of the keys themselves.
        3 //! Class set supports bidirectional iterators.
        4 //! 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
        5 //! for unique keys.
        6 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
        7 template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> >
        8 #else
        9 template <class Key, class Compare, class Allocator>
       10 #endif
       11 class set
       12 {
       13    private:
       14    BOOST_COPYABLE_AND_MOVABLE(set)
       15    typedef container_detail::rbtree<Key, Key,
       16                      container_detail::identity<Key>, Compare, Allocator> tree_t;
       17    tree_t m_tree;  // red-black tree representing set
       18    public:
       19    typedef Key                                                                         key_type;
       20    typedef Key                                                                         value_type;
       21    typedef Compare                                                                     key_compare;
       22    typedef Compare                                                                     value_compare;
       23    typedef typename ::boost::container::allocator_traits<Allocator>::pointer           pointer;
       24    typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer     const_pointer;
       25    typedef typename ::boost::container::allocator_traits<Allocator>::reference         reference;
       26    typedef typename ::boost::container::allocator_traits<Allocator>::const_reference   const_reference;
       27    typedef typename ::boost::container::allocator_traits<Allocator>::size_type         size_type;
       28    typedef typename ::boost::container::allocator_traits<Allocator>::difference_type   difference_type;
       29    typedef Allocator                                                                   allocator_type;
       30    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type)              stored_allocator_type;
       31    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator)                           iterator;
       32    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator)                     const_iterator;
       33    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator)                   reverse_iterator;
       34    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator)             const_reverse_iterator;
       35    set(): m_tree(){}
       36    explicit set(const Compare& comp,const allocator_type& a = allocator_type()): m_tree(comp, a){}
       37 
       38    template <class InputIterator>
       39    set(InputIterator first, InputIterator last, const Compare& comp = Compare(),
       40        const allocator_type& a = allocator_type()): m_tree(true, first, last, comp, a)
       41    {}
       42    template <class InputIterator>
       43    set( ordered_unique_range_t, InputIterator first, InputIterator last
       44       , const Compare& comp = Compare(), const allocator_type& a = allocator_type())
       45       : m_tree(ordered_range, first, last, comp, a)
       46    {}
       47    set(const set& x): m_tree(x.m_tree)
       48    {}
       49    set(BOOST_RV_REF(set) x): m_tree(boost::move(x.m_tree))
       50    {}  
       51    set(const set& x, const allocator_type &a): m_tree(x.m_tree, a)
       52    {}
       53    set(BOOST_RV_REF(set) x, const allocator_type &a): m_tree(boost::move(x.m_tree), a)
       54    {}
       55    set& operator=(BOOST_COPY_ASSIGN_REF(set) x)
       56    {  
       57       m_tree = x.m_tree;   return *this;  
       58    }
       59    set& operator=(BOOST_RV_REF(set) x)
       60    {  
       61       m_tree = boost::move(x.m_tree);   return *this;  
       62    }
       63    allocator_type get_allocator() const
       64    { 
       65       return m_tree.get_allocator(); 
       66    }
       67    const stored_allocator_type &get_stored_allocator() const
       68    { 
       69       return m_tree.get_stored_allocator(); 
       70    }
       71    stored_allocator_type &get_stored_allocator()
       72    { return m_tree.get_stored_allocator(); }
       73 
       74    iterator begin()
       75    { return m_tree.begin(); }
       76 
       77    const_iterator begin() const
       78    { return m_tree.begin(); }
       79 
       80    iterator end()
       81    { return m_tree.end(); }
       82 
       83    const_iterator end() const
       84    { return m_tree.end(); }
       85 
       86    reverse_iterator rbegin()
       87    { return m_tree.rbegin(); }
       88 
       89    const_reverse_iterator rbegin() const
       90    { return m_tree.rbegin(); }
       91 
       92    reverse_iterator rend()
       93    { return m_tree.rend(); }
       94 
       95    const_reverse_iterator rend() const
       96    { return m_tree.rend(); }
       97 
       98    const_iterator cbegin() const
       99    { return m_tree.cbegin(); }
      100 
      101    const_iterator cend() const
      102    { return m_tree.cend(); }
      103 
      104    const_reverse_iterator crbegin() const
      105    { return m_tree.crbegin(); }
      106 
      107    const_reverse_iterator crend() const
      108    { return m_tree.crend(); }
      109 
      110    bool empty() const
      111    { return m_tree.empty(); }
      112 
      113    size_type size() const
      114    { return m_tree.size(); }
      115 
      116    size_type max_size() const
      117    { return m_tree.max_size(); }
      118 
      119    #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
      120 
      121    template <class... Args>
      122    std::pair<iterator,bool> emplace(Args&&... args)
      123    {  return m_tree.emplace_unique(boost::forward<Args>(args)...); }
      124 
      125    template <class... Args>
      126    iterator emplace_hint(const_iterator hint, Args&&... args)
      127    {  return m_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); }
      128 
      129    #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
      130 
      131    #define BOOST_PP_LOCAL_MACRO(n)                                                                 
      132    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          
      133    std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))            
      134    {  return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }       
      135                                                                                                    
      136    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          
      137    iterator emplace_hint(const_iterator hint                                                       
      138                          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              
      139    {  return m_tree.emplace_hint_unique(hint                                                       
      140                                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));}   
      141    //!
      142    #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
      143    #include BOOST_PP_LOCAL_ITERATE()
      144    #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
      145    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
      146  
      147    std::pair<iterator, bool> insert(const value_type &x);
      148 
      149    std::pair<iterator, bool> insert(value_type &&x);
      150    #else
      151    private:
      152    typedef std::pair<iterator, bool> insert_return_pair;
      153    public:
      154    BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, insert_return_pair, this->priv_insert)
      155    #endif
      156 
      157    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
      158    iterator insert(const_iterator p, const value_type &x);
      159    iterator insert(const_iterator position, value_type &&x);
      160    #else
      161    BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator)
      162    #endif
      163 
      164    template <class InputIterator>
      165    void insert(InputIterator first, InputIterator last)
      166    {  m_tree.insert_unique(first, last);  }
      167 
      168    iterator erase(const_iterator p)
      169    {  return m_tree.erase(p); }
      170 
      171    size_type erase(const key_type& x)
      172    {  return m_tree.erase(x); }
      173 
      174    iterator erase(const_iterator first, const_iterator last)
      175    {  return m_tree.erase(first, last);  }
      176 
      177    void swap(set& x)
      178    { m_tree.swap(x.m_tree); }
      179 
      180    void clear()
      181    { m_tree.clear(); }
      182 
      183    key_compare key_comp() const
      184    { return m_tree.key_comp(); }
      185 
      186    value_compare value_comp() const
      187    { return m_tree.key_comp(); }
      188 
      189    iterator find(const key_type& x)
      190    { return m_tree.find(x); }
      191 
      192    const_iterator find(const key_type& x) const
      193    { return m_tree.find(x); }
      194 
      195    size_type count(const key_type& x) const
      196    {  return m_tree.find(x) == m_tree.end() ? 0 : 1;  }
      197 
      198    iterator lower_bound(const key_type& x)
      199    {  return m_tree.lower_bound(x); }
      200 
      201    const_iterator lower_bound(const key_type& x) const
      202    {  return m_tree.lower_bound(x); }
      203  
      204    iterator upper_bound(const key_type& x)
      205    {  return m_tree.upper_bound(x);    }
      206 
      207    const_iterator upper_bound(const key_type& x) const
      208    {  return m_tree.upper_bound(x);    }
      209 
      210    std::pair<iterator,iterator> equal_range(const key_type& x)
      211    {  return m_tree.equal_range(x); }
      212 
      213    std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
      214    {  return m_tree.equal_range(x); }
      215 
      216    /// @cond
      217    template <class K1, class C1, class A1>
      218    friend bool operator== (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
      219 
      220    template <class K1, class C1, class A1>
      221    friend bool operator< (const set<K1,C1,A1>&, const set<K1,C1,A1>&);
      222 
      223    private:
      224    template <class KeyType>
      225    std::pair<iterator, bool> priv_insert(BOOST_FWD_REF(KeyType) x)
      226    {  return m_tree.insert_unique(::boost::forward<KeyType>(x));  }
      227 
      228    template <class KeyType>
      229    iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
      230    {  return m_tree.insert_unique(p, ::boost::forward<KeyType>(x)); }
      231    /// @endcond
      232 };
      233 template <class Key, class Compare, class Allocator>
      234 inline bool operator==(const set<Key,Compare,Allocator>& x,const set<Key,Compare,Allocator>& y)
      235 {  return x.m_tree == y.m_tree;  }
      236 template <class Key, class Compare, class Allocator>
      237 inline bool operator<(const set<Key,Compare,Allocator>& x,const set<Key,Compare,Allocator>& y)
      238 {  return x.m_tree < y.m_tree;   }
      239 template <class Key, class Compare, class Allocator>
      240 inline bool operator!=(const set<Key,Compare,Allocator>& x,const set<Key,Compare,Allocator>& y)
      241 {  return !(x == y);   }
      242 template <class Key, class Compare, class Allocator>
      243 inline bool operator>(const set<Key,Compare,Allocator>& x,const set<Key,Compare,Allocator>& y)
      244 {  return y < x; }
      245 template <class Key, class Compare, class Allocator>
      246 inline bool operator<=(const set<Key,Compare,Allocator>& x,const set<Key,Compare,Allocator>& y)
      247 {  return !(y < x); }
      248 template <class Key, class Compare, class Allocator>
      249 inline bool operator>=(const set<Key,Compare,Allocator>& x,const set<Key,Compare,Allocator>& y)
      250 {  return !(x < y);  }
      251 template <class Key, class Compare, class Allocator>
      252 inline void swap(set<Key,Compare,Allocator>& x, set<Key,Compare,Allocator>& y)
      253 {  x.swap(y);  }
      254 /// @cond
      255 
      256 } 
      257 template <class Key, class C, class Allocator>
      258 struct has_trivial_destructor_after_move<boost::container::set<Key, C, Allocator> >
      259 {
      260    static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
      261 };
      View Code
        1 //! A multiset is a kind of associative container that supports equivalent keys
        2 //! (possibly contains multiple copies of the same key value) and provides for
        3 //! fast retrieval of the keys themselves. Class multiset supports bidirectional iterators.
        4 //!
        5 //! A multiset satisfies all of the requirements of a container and of a reversible
        6 //! container, and of an associative container). multiset also provides most operations
        7 //! described for duplicate keys.
        8 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
        9 template <class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key> >
       10 #else
       11 template <class Key, class Compare, class Allocator>
       12 #endif
       13 class multiset
       14 {
       15    private:
       16    BOOST_COPYABLE_AND_MOVABLE(multiset)
       17    typedef container_detail::rbtree<Key, Key,
       18                      container_detail::identity<Key>, Compare, Allocator> tree_t;
       19    tree_t m_tree;  // red-black tree representing multiset
       20 
       21    public:
       22 
       23    typedef Key                                                                         key_type;
       24    typedef Key                                                                         value_type;
       25    typedef Compare                                                                     key_compare;
       26    typedef Compare                                                                     value_compare;
       27    typedef typename ::boost::container::allocator_traits<Allocator>::pointer           pointer;
       28    typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer     const_pointer;
       29    typedef typename ::boost::container::allocator_traits<Allocator>::reference         reference;
       30    typedef typename ::boost::container::allocator_traits<Allocator>::const_reference   const_reference;
       31    typedef typename ::boost::container::allocator_traits<Allocator>::size_type         size_type;
       32    typedef typename ::boost::container::allocator_traits<Allocator>::difference_type   difference_type;
       33    typedef Allocator                                                                   allocator_type;
       34    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type)              stored_allocator_type;
       35    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator)                           iterator;
       36    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator)                     const_iterator;
       37    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator)                   reverse_iterator;
       38    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator)             const_reverse_iterator;
       39 
       40 
       41    multiset(): m_tree()
       42    {}
       43  
       44    explicit multiset(const Compare& comp,
       45                      const allocator_type& a = allocator_type())
       46       : m_tree(comp, a)
       47    {}
       48 
       49    template <class InputIterator>
       50    multiset(InputIterator first, InputIterator last,
       51             const Compare& comp = Compare(),
       52             const allocator_type& a = allocator_type())
       53       : m_tree(false, first, last, comp, a)
       54    {}
       55 
       56    template <class InputIterator>
       57    multiset( ordered_range_t, InputIterator first, InputIterator last
       58            , const Compare& comp = Compare()
       59            , const allocator_type& a = allocator_type())
       60       : m_tree(ordered_range, first, last, comp, a)
       61    {}
       62 
       63    multiset(const multiset& x)
       64       : m_tree(x.m_tree)
       65    {}
       66 
       67    multiset(BOOST_RV_REF(multiset) x)
       68       : m_tree(boost::move(x.m_tree))
       69    {}
       70 
       71    multiset(const multiset& x, const allocator_type &a)
       72       : m_tree(x.m_tree, a)
       73    {}
       74 
       75    multiset(BOOST_RV_REF(multiset) x, const allocator_type &a)
       76       : m_tree(boost::move(x.m_tree), a)
       77    {}
       78 
       79  
       80    multiset& operator=(BOOST_COPY_ASSIGN_REF(multiset) x)
       81    {  m_tree = x.m_tree;   return *this;  }
       82 
       83    multiset& operator=(BOOST_RV_REF(multiset) x)
       84    {  m_tree = boost::move(x.m_tree);   return *this;  }
       85 
       86    allocator_type get_allocator() const
       87    { return m_tree.get_allocator(); }
       88 
       89     stored_allocator_type &get_stored_allocator()
       90    { return m_tree.get_stored_allocator(); }
       91 
       92    const stored_allocator_type &get_stored_allocator() const
       93    { return m_tree.get_stored_allocator(); }
       94 
       95    iterator begin()
       96    { return m_tree.begin(); }
       97 
       98    const_iterator begin() const
       99    { return m_tree.begin(); }
      100 
      101    iterator end()
      102    { return m_tree.end(); }
      103 
      104    const_iterator end() const
      105    { return m_tree.end(); }
      106 
      107    reverse_iterator rbegin()
      108    { return m_tree.rbegin(); }
      109 
      110    const_reverse_iterator rbegin() const
      111    { return m_tree.rbegin(); }
      112 
      113    reverse_iterator rend()
      114    { return m_tree.rend(); }
      115 
      116    const_reverse_iterator rend() const
      117    { return m_tree.rend(); }
      118 
      119    const_iterator cbegin() const
      120    { return m_tree.cbegin(); }
      121 
      122    const_iterator cend() const
      123    { return m_tree.cend(); }
      124 
      125    const_reverse_iterator crbegin() const
      126    { return m_tree.crbegin(); }
      127 
      128    const_reverse_iterator crend() const
      129    { return m_tree.crend(); }
      130 
      131    bool empty() const
      132    { return m_tree.empty(); }
      133 
      134    size_type size() const
      135    { return m_tree.size(); }
      136 
      137    size_type max_size() const
      138    { return m_tree.max_size(); }
      139 
      140    #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
      141 
      142    template <class... Args>
      143    iterator emplace(Args&&... args)
      144    {  return m_tree.emplace_equal(boost::forward<Args>(args)...); }
      145 
      146    template <class... Args>
      147    iterator emplace_hint(const_iterator hint, Args&&... args)
      148    {  return m_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); }
      149 
      150    #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
      151 
      152    #define BOOST_PP_LOCAL_MACRO(n)                                                                 
      153    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          
      154    iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                            
      155    {  return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }        
      156                                                                                                    
      157    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          
      158    iterator emplace_hint(const_iterator hint                                                       
      159                          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              
      160    {  return m_tree.emplace_hint_equal(hint                                                        
      161                                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));}   
      162    //!
      163    #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
      164    #include BOOST_PP_LOCAL_ITERATE()
      165 
      166    #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
      167 
      168    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
      169 
      170    iterator insert(const value_type &x);
      171    iterator insert(value_type &&x);
      172    #else
      173    BOOST_MOVE_CONVERSION_AWARE_CATCH(insert, value_type, iterator, this->priv_insert)
      174    #endif
      175 
      176    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
      177 
      178    iterator insert(const_iterator p, const value_type &x);
      179 
      180    iterator insert(const_iterator position, value_type &&x);
      181    #else
      182    BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, value_type, iterator, this->priv_insert, const_iterator)
      183    #endif
      184 
      185    template <class InputIterator>
      186    void insert(InputIterator first, InputIterator last)
      187    {  m_tree.insert_equal(first, last);  }
      188 
      189    iterator erase(const_iterator p)
      190    {  return m_tree.erase(p); }
      191 
      192    size_type erase(const key_type& x)
      193    {  return m_tree.erase(x); }
      194 
      195    iterator erase(const_iterator first, const_iterator last)
      196    {  return m_tree.erase(first, last); }
      197 
      198    void swap(multiset& x)
      199    { m_tree.swap(x.m_tree); }
      200 
      201    void clear()
      202    { m_tree.clear(); }
      203  
      204    key_compare key_comp() const
      205    { return m_tree.key_comp(); }
      206 
      207    value_compare value_comp() const
      208    { return m_tree.key_comp(); }
      209 
      210    iterator find(const key_type& x)
      211    { return m_tree.find(x); }
      212 
      213    const_iterator find(const key_type& x) const
      214    { return m_tree.find(x); }
      215 
      216    size_type count(const key_type& x) const
      217    {  return m_tree.count(x);  }
      218 
      219    iterator lower_bound(const key_type& x)
      220    {  return m_tree.lower_bound(x); }
      221 
      222    const_iterator lower_bound(const key_type& x) const
      223    {  return m_tree.lower_bound(x); }
      224 
      225    iterator upper_bound(const key_type& x)
      226    {  return m_tree.upper_bound(x);    }
      227 
      228    const_iterator upper_bound(const key_type& x) const
      229    {  return m_tree.upper_bound(x);    }
      230 
      231    std::pair<iterator,iterator> equal_range(const key_type& x)
      232    {  return m_tree.equal_range(x); }
      233 
      234    std::pair<const_iterator, const_iterator> equal_range(const key_type& x) const
      235    {  return m_tree.equal_range(x); }
      236 
      237    /// @cond
      238    template <class K1, class C1, class A1>
      239    friend bool operator== (const multiset<K1,C1,A1>&,
      240                            const multiset<K1,C1,A1>&);
      241    template <class K1, class C1, class A1>
      242    friend bool operator< (const multiset<K1,C1,A1>&,
      243                           const multiset<K1,C1,A1>&);
      244    private:
      245    template <class KeyType>
      246    iterator priv_insert(BOOST_FWD_REF(KeyType) x)
      247    {  return m_tree.insert_equal(::boost::forward<KeyType>(x));  }
      248 
      249    template <class KeyType>
      250    iterator priv_insert(const_iterator p, BOOST_FWD_REF(KeyType) x)
      251    {  return m_tree.insert_equal(p, ::boost::forward<KeyType>(x)); }
      252 
      253    /// @endcond
      254 };
      255 
      256 template <class Key, class Compare, class Allocator>
      257 inline bool operator==(const multiset<Key,Compare,Allocator>& x,
      258                        const multiset<Key,Compare,Allocator>& y)
      259 {  return x.m_tree == y.m_tree;  }
      260 
      261 template <class Key, class Compare, class Allocator>
      262 inline bool operator<(const multiset<Key,Compare,Allocator>& x,
      263                       const multiset<Key,Compare,Allocator>& y)
      264 {  return x.m_tree < y.m_tree;   }
      265 
      266 template <class Key, class Compare, class Allocator>
      267 inline bool operator!=(const multiset<Key,Compare,Allocator>& x,
      268                        const multiset<Key,Compare,Allocator>& y)
      269 {  return !(x == y);  }
      270 
      271 template <class Key, class Compare, class Allocator>
      272 inline bool operator>(const multiset<Key,Compare,Allocator>& x,
      273                       const multiset<Key,Compare,Allocator>& y)
      274 {  return y < x;  }
      275 
      276 template <class Key, class Compare, class Allocator>
      277 inline bool operator<=(const multiset<Key,Compare,Allocator>& x,
      278                        const multiset<Key,Compare,Allocator>& y)
      279 {  return !(y < x);  }
      280 
      281 template <class Key, class Compare, class Allocator>
      282 inline bool operator>=(const multiset<Key,Compare,Allocator>& x,const multiset<Key,Compare,Allocator>& y)
      283 {  return !(x < y);  }
      284 
      285 template <class Key, class Compare, class Allocator>
      286 inline void swap(multiset<Key,Compare,Allocator>& x, multiset<Key,Compare,Allocator>& y)
      287 {  x.swap(y);  }
      288 
      289 /// @cond
      290 
      291 } 
      View Code

    Associative Container->Pair Associative Container

      1 //////////////////////////////////////////////////////////////////////////////
      2 //
      3 // (C) Copyright Ion Gaztanaga 2005-2012.
      4 //
      5 // Distributed under the Boost Software License, Version 1.0.
      6 // (See accompanying file LICENSE_1_0.txt or copy at
      7 // http://www.boost.org/LICENSE_1_0.txt)
      8 //
      9 // See http://www.boost.org/libs/container for documentation.
     10 //
     11 //////////////////////////////////////////////////////////////////////////////
     12 #ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
     13 #define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
     14 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
     15 #  pragma once
     16 #endif
     17 #include "config_begin.hpp"
     18 #include <boost/container/detail/workaround.hpp>
     19 #include <boost/container/detail/mpl.hpp>
     20 #include <boost/container/detail/type_traits.hpp>
     21 #include <boost/container/detail/mpl.hpp>
     22 #include <boost/container/detail/type_traits.hpp>
     23 #include <utility>   //std::pair
     24 #include <algorithm> //std::swap
     25 #include <boost/move/utility.hpp>
     26 #include <boost/type_traits/is_class.hpp>
     27 #ifndef BOOST_CONTAINER_PERFECT_FORWARDING
     28 #include <boost/container/detail/preprocessor.hpp>
     29 #endif
     30 
     31 namespace boost {
     32 namespace container {
     33 namespace container_detail {
     34 
     35 template <class T1, class T2>
     36 struct pair;
     37 template <class T>
     38 struct is_pair
     39 {
     40    static const bool value = false;
     41 };
     42 
     43 template <class T1, class T2>
     44 struct is_pair< pair<T1, T2> >
     45 {
     46    static const bool value = true;
     47 };
     48 
     49 template <class T1, class T2>
     50 struct is_pair< std::pair<T1, T2> >
     51 {
     52    static const bool value = true;
     53 };
     54 
     55 struct pair_nat;
     56 struct piecewise_construct_t { };
     57 static const piecewise_construct_t piecewise_construct = piecewise_construct_t();
     58 
     59 template <class T1, class T2>
     60 struct pair
     61 {
     62    private:
     63    BOOST_COPYABLE_AND_MOVABLE(pair)
     64 
     65    public:
     66    typedef T1 first_type;
     67    typedef T2 second_type;
     68 
     69    T1 first;
     70    T2 second;
     71 
     72    //Default constructor
     73    pair(): first(), second()
     74    {}
     75 
     76    //pair copy assignment
     77    pair(const pair& x): first(x.first), second(x.second)
     78    {}
     79 
     80    //pair move constructor
     81    pair(BOOST_RV_REF(pair) p): first(::boost::move(p.first)), second(::boost::move(p.second))
     82    {}
     83 
     84    template <class D, class S>
     85    pair(const pair<D, S> &p): first(p.first), second(p.second)
     86    {}
     87 
     88    template <class D, class S>
     89    pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p): first(::boost::move(p.first)), second(::boost::move(p.second))
     90    {}
     91 
     92    //pair from two values
     93    pair(const T1 &t1, const T2 &t2): first(t1), second(t2)
     94    {}
     95 
     96    template<class U, class V>
     97    pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v): first(::boost::forward<U>(u)), second(::boost::forward<V>(v))
     98    {}
     99 
    100    //And now compatibility with std::pair
    101    pair(const std::pair<T1, T2>& x): first(x.first), second(x.second)
    102    {}
    103 
    104    template <class D, class S>
    105    pair(const std::pair<D, S>& p): first(p.first), second(p.second)
    106    {}
    107 
    108    pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p): first(::boost::move(p.first)), second(::boost::move(p.second))
    109    {}
    110 
    111    template <class D, class S>
    112    pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p): first(::boost::move(p.first)), second(::boost::move(p.second))
    113    {}
    114 
    115    //piecewise_construct missing
    116    //template <class U, class V> pair(pair<U, V>&& p);
    117    //template <class... Args1, class... Args2>
    118    //   pair(piecewise_construct_t, tuple<Args1...> first_args,
    119    //        tuple<Args2...> second_args);
    120 
    121    //pair copy assignment
    122    pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p)
    123    {
    124       first  = p.first;
    125       second = p.second;
    126       return *this;
    127    }
    128 
    129    //pair move assignment
    130    pair& operator=(BOOST_RV_REF(pair) p)
    131    {
    132       first  = ::boost::move(p.first);
    133       second = ::boost::move(p.second);
    134       return *this;
    135    }
    136 
    137    template <class D, class S>
    138    typename ::boost::container::container_detail::enable_if_c
    139       < !(::boost::container::container_detail::is_same<T1, D>::value &&
    140           ::boost::container::container_detail::is_same<T2, S>::value)
    141       , pair &>::type  operator=(const pair<D, S>&p)
    142    {
    143       first  = p.first;
    144       second = p.second;
    145       return *this;
    146    }
    147    template <class D, class S>
    148    typename ::boost::container::container_detail::enable_if_c
    149       < !(::boost::container::container_detail::is_same<T1, D>::value &&
    150           ::boost::container::container_detail::is_same<T2, S>::value)
    151       , pair &>::type  operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p)
    152    {
    153       first  = ::boost::move(p.first);
    154       second = ::boost::move(p.second);
    155       return *this;
    156    }
    157    //std::pair copy assignment
    158    pair& operator=(const std::pair<T1, T2> &p)
    159    {
    160       first  = p.first;
    161       second = p.second;
    162       return *this;
    163    }
    164    template <class D, class S>
    165    pair& operator=(const std::pair<D, S> &p)
    166    {
    167       first  = ::boost::move(p.first);
    168       second = ::boost::move(p.second);
    169       return *this;
    170    }
    171    //std::pair move assignment
    172    pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p)
    173    {
    174       first  = ::boost::move(p.first);
    175       second = ::boost::move(p.second);
    176       return *this;
    177    }
    178    template <class D, class S>
    179    pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p)
    180    {
    181       first  = ::boost::move(p.first);
    182       second = ::boost::move(p.second);
    183       return *this;
    184    }
    185    //swap
    186    void swap(pair& p)
    187    {
    188       using std::swap;
    189       swap(this->first, p.first);
    190       swap(this->second, p.second);
    191    }
    192 };
    193 
    194 template <class T1, class T2>
    195 inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y)
    196 {  return static_cast<bool>(x.first == y.first && x.second == y.second);  }
    197 
    198 template <class T1, class T2>
    199 inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y)
    200 {  return static_cast<bool>(x.first < y.first || (!(y.first < x.first) && x.second < y.second)); }
    201 
    202 template <class T1, class T2>
    203 inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y)
    204 {  return static_cast<bool>(!(x == y));  }
    205 
    206 template <class T1, class T2>
    207 inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y)
    208 {  return y < x;  }
    209 
    210 template <class T1, class T2>
    211 inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y)
    212 {  return static_cast<bool>(!(x < y)); }
    213 
    214 template <class T1, class T2>
    215 inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y)
    216 {  return static_cast<bool>(!(y < x)); }
    217 
    218 template <class T1, class T2>
    219 inline pair<T1, T2> make_pair(T1 x, T2 y)
    220 {  return pair<T1, T2>(x, y); }
    221 
    222 template <class T1, class T2>
    223 inline void swap(pair<T1, T2>& x, pair<T1, T2>& y)
    224 {
    225    swap(x.first, y.first);
    226    swap(x.second, y.second);
    227 }
    228 }  //namespace container_detail {
    229 }  //namespace container {
    230 
    231 //Without this specialization recursive flat_(multi)map instantiation fails
    232 //because is_enum needs to instantiate the recursive pair, leading to a compilation error).
    233 //This breaks the cycle clearly stating that pair is not an enum avoiding any instantiation.
    234 template<class T>
    235 struct is_enum;
    236 template<class T, class U>
    237 struct is_enum< ::boost::container::container_detail::pair<T, U> >
    238 {
    239    static const bool value = false;
    240 };
    241 //This specialization is needed to avoid instantiation of pair in
    242 //is_class, and allow recursive maps.
    243 template <class T1, class T2>
    244 struct is_class< ::boost::container::container_detail::pair<T1, T2> >: public ::boost::true_type
    245 {};
    246 
    247 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
    248 
    249 template<class T1, class T2>
    250 struct has_move_emulation_enabled< ::boost::container::container_detail::pair<T1, T2> >
    251    : ::boost::true_type
    252 {};
    253 
    254 #endif
    255 
    256 
    257 }  //namespace boost {
    258 
    259 #include <boost/container/detail/config_end.hpp>
    260 
    261 #endif   //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP
    View Code

     

      1 //////////////////////////////////////////////////////////////////////////////
      2 //
      3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
      4 // Software License, Version 1.0. (See accompanying file
      5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
      6 //
      7 // See http://www.boost.org/libs/container for documentation.
      8 //
      9 //////////////////////////////////////////////////////////////////////////////
     10 
     11 #ifndef BOOST_CONTAINER_MAP_HPP
     12 #define BOOST_CONTAINER_MAP_HPP
     13 
     14 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
     15 #  pragma once
     16 #endif
     17 
     18 #include <boost/container/detail/config_begin.hpp>
     19 #include <boost/container/detail/workaround.hpp>
     20 #include <boost/container/container_fwd.hpp>
     21 #include <utility>
     22 #include <functional>
     23 #include <memory>
     24 #include <boost/container/detail/tree.hpp>
     25 #include <boost/container/detail/value_init.hpp>
     26 #include <boost/type_traits/has_trivial_destructor.hpp>
     27 #include <boost/container/detail/mpl.hpp>
     28 #include <boost/container/detail/utilities.hpp>
     29 #include <boost/container/detail/pair.hpp>
     30 #include <boost/container/detail/type_traits.hpp>
     31 #include <boost/container/throw_exception.hpp>
     32 #include <boost/move/utility.hpp>
     33 #include <boost/move/detail/move_helpers.hpp>
     34 #include <boost/static_assert.hpp>
     35 #include <boost/container/detail/value_init.hpp>
     36 #include <boost/detail/no_exceptions_support.hpp>
     37 
     38 namespace boost {
     39 namespace container {
     40 
     41 /// @cond
     42 // Forward declarations of operators == and <, needed for friend declarations.
     43 template <class Key, class T, class Compare, class Allocator>
     44 inline bool operator==(const map<Key,T,Compare,Allocator>& x,
     45                        const map<Key,T,Compare,Allocator>& y);
     46 
     47 template <class Key, class T, class Compare, class Allocator>
     48 inline bool operator<(const map<Key,T,Compare,Allocator>& x,
     49                       const map<Key,T,Compare,Allocator>& y);
     50 
     51 //! A map is a kind of associative container that supports unique keys (contains at
     52 //! most one of each key value) and provides for fast retrieval of values of another
     53 //! type T based on the keys. The map class supports bidirectional iterators.
     54 //! A map satisfies all of the requirements of a container and of a reversible
     55 //! container and of an associative container. For a
     56 //! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
     57 //! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
     58 //! Allocator is the allocator to allocate the value_types
     59 //! (e.g. <i>allocator< std::pair<const Key, T> > </i>).
     60 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
     61 template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< const Key, T> > >
     62 #else
     63 template <class Key, class T, class Compare, class Allocator>
     64 #endif
     65 class map
     66 {
     67    /// @cond
     68    private:
     69    BOOST_COPYABLE_AND_MOVABLE(map)
     70 
     71    typedef std::pair<const Key, T>  value_type_impl;
     72    typedef container_detail::rbtree
     73       <Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator> tree_t;
     74    typedef container_detail::pair <Key, T> movable_value_type_impl;
     75    typedef container_detail::tree_value_compare
     76       < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl>
     77       >  value_compare_impl;
     78    tree_t m_tree;  // red-black tree representing map
     79    /// @endcond
     80 
     81    public:
     82    typedef Key                                                                      key_type;
     83    typedef T                                                                        mapped_type;
     84    typedef std::pair<const Key, T>                                                  value_type;
     85    typedef typename boost::container::allocator_traits<Allocator>::pointer          pointer;
     86    typedef typename boost::container::allocator_traits<Allocator>::const_pointer    const_pointer;
     87    typedef typename boost::container::allocator_traits<Allocator>::reference        reference;
     88    typedef typename boost::container::allocator_traits<Allocator>::const_reference  const_reference;
     89    typedef typename boost::container::allocator_traits<Allocator>::size_type        size_type;
     90    typedef typename boost::container::allocator_traits<Allocator>::difference_type  difference_type;
     91    typedef Allocator                                                                allocator_type;
     92    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type)           stored_allocator_type;
     93    typedef BOOST_CONTAINER_IMPDEF(value_compare_impl)                               value_compare;
     94    typedef Compare                                                                  key_compare;
     95    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator)                        iterator;
     96    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator)                  const_iterator;
     97    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator)                reverse_iterator;
     98    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator)          const_reverse_iterator;
     99    typedef std::pair<key_type, mapped_type>                                         nonconst_value_type;
    100    typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl)                          movable_value_type;
    101 
    102    map(): m_tree()
    103    {
    104       //Allocator type must be std::pair<CONST Key, T>
    105       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    106    }
    107    
    108    explicit map(const Compare& comp,const allocator_type& a = allocator_type()): m_tree(comp, a)
    109    {
    110       //Allocator type must be std::pair<CONST Key, T>
    111       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    112    }
    113 
    114    template <class InputIterator>
    115    map(InputIterator first, InputIterator last, const Compare& comp = Compare(),const allocator_type& a = allocator_type())
    116       : m_tree(true, first, last, comp, a)
    117    {
    118       //Allocator type must be std::pair<CONST Key, T>
    119       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    120    }
    121 
    122    template <class InputIterator>
    123    map( ordered_unique_range_t, InputIterator first, InputIterator last
    124       , const Compare& comp = Compare(), const allocator_type& a = allocator_type())
    125       : m_tree(ordered_range, first, last, comp, a)
    126    {
    127       //Allocator type must be std::pair<CONST Key, T>
    128       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    129    }
    130    map(const map& x): m_tree(x.m_tree)
    131    {
    132       //Allocator type must be std::pair<CONST Key, T>
    133       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    134    }
    135 
    136    map(BOOST_RV_REF(map) x): m_tree(boost::move(x.m_tree))
    137    {
    138       //Allocator type must be std::pair<CONST Key, T>
    139       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    140    }
    141 
    142    map(const map& x, const allocator_type &a): m_tree(x.m_tree, a)
    143    {
    144       //Allocator type must be std::pair<CONST Key, T>
    145       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    146    }
    147 
    148    map(BOOST_RV_REF(map) x, const allocator_type &a): m_tree(boost::move(x.m_tree), a)
    149    {
    150       //Allocator type must be std::pair<CONST Key, T>
    151       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    152    }
    153    map& operator=(BOOST_COPY_ASSIGN_REF(map) x)
    154    {  m_tree = x.m_tree;   return *this;  }
    155 
    156    map& operator=(BOOST_RV_REF(map) x)
    157    {  m_tree = boost::move(x.m_tree);   return *this;  }
    158 
    159    allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
    160    { return m_tree.get_allocator(); }
    161 
    162 
    163    stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
    164    { return m_tree.get_stored_allocator(); }
    165 
    166    const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
    167    { return m_tree.get_stored_allocator(); }
    168 
    169    iterator begin() BOOST_CONTAINER_NOEXCEPT
    170    { return m_tree.begin(); }
    171 
    172    const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
    173    { return this->cbegin(); }
    174 
    175    iterator end() BOOST_CONTAINER_NOEXCEPT
    176    { return m_tree.end(); }
    177 
    178    const_iterator end() const BOOST_CONTAINER_NOEXCEPT
    179    { return this->cend(); }
    180 
    181    reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
    182    { return m_tree.rbegin(); }
    183 
    184    const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
    185    { return this->crbegin(); }
    186 
    187    reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
    188    { return m_tree.rend(); }
    189 
    190    const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
    191    { return this->crend(); }
    192 
    193    const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
    194    { return m_tree.begin(); }
    195 
    196    const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
    197    { return m_tree.end(); }
    198 
    199    const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
    200    { return m_tree.rbegin(); }
    201 
    202    const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
    203    { return m_tree.rend(); }
    204 
    205    bool empty() const BOOST_CONTAINER_NOEXCEPT
    206    { return m_tree.empty(); }
    207 
    208    size_type size() const BOOST_CONTAINER_NOEXCEPT
    209    { return m_tree.size(); }
    210 
    211    size_type max_size() const BOOST_CONTAINER_NOEXCEPT
    212    { return m_tree.max_size(); }
    213 
    214    #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
    215   
    216    mapped_type& operator[](const key_type &k);
    217 
    218    mapped_type& operator[](key_type &&k);
    219    #else
    220    BOOST_MOVE_CONVERSION_AWARE_CATCH( operator[] , key_type, mapped_type&, this->priv_subscript)
    221    #endif
    222 
    223    T& at(const key_type& k)
    224    {
    225       iterator i = this->find(k);
    226       if(i == this->end()){
    227          throw_out_of_range("map::at key not found");
    228       }
    229       return i->second;
    230    }
    231 
    232    const T& at(const key_type& k) const
    233    {
    234       const_iterator i = this->find(k);
    235       if(i == this->end()){
    236          throw_out_of_range("map::at key not found");
    237       }
    238       return i->second;
    239    }
    240 
    241    std::pair<iterator,bool> insert(const value_type& x)
    242    { return m_tree.insert_unique(x); }
    243 
    244    std::pair<iterator,bool> insert(const nonconst_value_type& x)
    245    { return m_tree.insert_unique(x); }
    246 
    247    std::pair<iterator,bool> insert(BOOST_RV_REF(nonconst_value_type) x)
    248    { return m_tree.insert_unique(boost::move(x)); }
    249 
    250    std::pair<iterator,bool> insert(BOOST_RV_REF(movable_value_type) x)
    251    { return m_tree.insert_unique(boost::move(x)); }
    252 
    253    std::pair<iterator,bool> insert(BOOST_RV_REF(value_type) x)
    254    { return m_tree.insert_unique(boost::move(x)); }
    255 
    256    iterator insert(const_iterator position, const value_type& x)
    257    { return m_tree.insert_unique(position, x); }
    258 
    259    iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x)
    260    { return m_tree.insert_unique(position, boost::move(x)); }
    261 
    262    iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x)
    263    { return m_tree.insert_unique(position, boost::move(x)); }
    264 
    265    iterator insert(const_iterator position, const nonconst_value_type& x)
    266    { return m_tree.insert_unique(position, x); }
    267 
    268    iterator insert(const_iterator position, BOOST_RV_REF(value_type) x)
    269    { return m_tree.insert_unique(position, boost::move(x)); }
    270 
    271    template <class InputIterator>
    272    void insert(InputIterator first, InputIterator last)
    273    {  m_tree.insert_unique(first, last);  }
    274 
    275    #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
    276 
    277    template <class... Args>
    278    std::pair<iterator,bool> emplace(Args&&... args)
    279    {  return m_tree.emplace_unique(boost::forward<Args>(args)...); }
    280 
    281    template <class... Args>
    282    iterator emplace_hint(const_iterator hint, Args&&... args)
    283    {  return m_tree.emplace_hint_unique(hint, boost::forward<Args>(args)...); }
    284 
    285    #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
    286 
    287    #define BOOST_PP_LOCAL_MACRO(n)                                                                 
    288    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          
    289    std::pair<iterator,bool> emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))            
    290    {  return m_tree.emplace_unique(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }       
    291                                                                                                    
    292    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          
    293    iterator emplace_hint(const_iterator hint                                                       
    294                          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              
    295    {  return m_tree.emplace_hint_unique(hint                                                       
    296                                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));}   
    297    //!
    298    #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
    299    #include BOOST_PP_LOCAL_ITERATE()
    300 
    301    #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
    302 
    303    iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT
    304    { return m_tree.erase(position); }
    305 
    306    size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT
    307    { return m_tree.erase(x); }
    308 
    309    iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    310    { return m_tree.erase(first, last); }
    311 
    312    void swap(map& x)
    313    { m_tree.swap(x.m_tree); }
    314 
    315    void clear() BOOST_CONTAINER_NOEXCEPT
    316    { m_tree.clear(); }
    317 
    318    key_compare key_comp() const
    319    { return m_tree.key_comp(); }
    320 
    321    value_compare value_comp() const
    322    { return value_compare(m_tree.key_comp()); }
    323 
    324    iterator find(const key_type& x)
    325    { return m_tree.find(x); }
    326 
    327    const_iterator find(const key_type& x) const
    328    { return m_tree.find(x); }
    329 
    330    size_type count(const key_type& x) const
    331    {  return m_tree.find(x) == m_tree.end() ? 0 : 1;  }
    332 
    333    iterator lower_bound(const key_type& x)
    334    {  return m_tree.lower_bound(x); }
    335 
    336    const_iterator lower_bound(const key_type& x) const
    337    {  return m_tree.lower_bound(x); }
    338 
    339    iterator upper_bound(const key_type& x)
    340    {  return m_tree.upper_bound(x); }
    341 
    342    const_iterator upper_bound(const key_type& x) const
    343    {  return m_tree.upper_bound(x); }
    344 
    345    std::pair<iterator,iterator> equal_range(const key_type& x)
    346    {  return m_tree.equal_range(x); }
    347 
    348    std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
    349    {  return m_tree.equal_range(x); }
    350 
    351    template <class K1, class T1, class C1, class A1>
    352    friend bool operator== (const map<K1, T1, C1, A1>&,
    353                            const map<K1, T1, C1, A1>&);
    354    template <class K1, class T1, class C1, class A1>
    355    friend bool operator< (const map<K1, T1, C1, A1>&,
    356                           const map<K1, T1, C1, A1>&);
    357    private:
    358    mapped_type& priv_subscript(const key_type &k)
    359    {
    360       //we can optimize this
    361       iterator i = lower_bound(k);
    362       // i->first is greater than or equivalent to k.
    363       if (i == end() || key_comp()(k, (*i).first)){
    364          container_detail::value_init<mapped_type> m;
    365          movable_value_type val(k, boost::move(m.m_t));
    366          i = insert(i, boost::move(val));
    367       }
    368       return (*i).second;
    369    }
    370 
    371    mapped_type& priv_subscript(BOOST_RV_REF(key_type) mk)
    372    {
    373       key_type &k = mk;
    374       //we can optimize this
    375       iterator i = lower_bound(k);
    376       // i->first is greater than or equivalent to k.
    377       if (i == end() || key_comp()(k, (*i).first)){
    378          container_detail::value_init<mapped_type> m;
    379          movable_value_type val(boost::move(k), boost::move(m.m_t));
    380          i = insert(i, boost::move(val));
    381       }
    382       return (*i).second;
    383    }
    384 
    385    /// @endcond
    386 };
    387 
    388 template <class Key, class T, class Compare, class Allocator>
    389 inline bool operator==(const map<Key,T,Compare,Allocator>& x,
    390                        const map<Key,T,Compare,Allocator>& y)
    391    {  return x.m_tree == y.m_tree;  }
    392 template <class Key, class T, class Compare, class Allocator>
    393 inline bool operator<(const map<Key,T,Compare,Allocator>& x,
    394                       const map<Key,T,Compare,Allocator>& y)
    395    {  return x.m_tree < y.m_tree;   }
    396 template <class Key, class T, class Compare, class Allocator>
    397 inline bool operator!=(const map<Key,T,Compare,Allocator>& x,
    398                        const map<Key,T,Compare,Allocator>& y)
    399    {  return !(x == y); }
    400 template <class Key, class T, class Compare, class Allocator>
    401 inline bool operator>(const map<Key,T,Compare,Allocator>& x,
    402                       const map<Key,T,Compare,Allocator>& y)
    403    {  return y < x;  }
    404 template <class Key, class T, class Compare, class Allocator>
    405 inline bool operator<=(const map<Key,T,Compare,Allocator>& x,
    406                        const map<Key,T,Compare,Allocator>& y)
    407    {  return !(y < x);  }
    408 template <class Key, class T, class Compare, class Allocator>
    409 inline bool operator>=(const map<Key,T,Compare,Allocator>& x,
    410                        const map<Key,T,Compare,Allocator>& y)
    411    {  return !(x < y);  }
    412 template <class Key, class T, class Compare, class Allocator>
    413 inline void swap(map<Key,T,Compare,Allocator>& x, map<Key,T,Compare,Allocator>& y)
    414    {  x.swap(y);  }
    415 /// @cond
    416 
    417 // Forward declaration of operators < and ==, needed for friend declaration.
    418 
    419 template <class Key, class T, class Compare, class Allocator>
    420 inline bool operator==(const multimap<Key,T,Compare,Allocator>& x,
    421                        const multimap<Key,T,Compare,Allocator>& y);
    422 
    423 template <class Key, class T, class Compare, class Allocator>
    424 inline bool operator<(const multimap<Key,T,Compare,Allocator>& x,
    425                       const multimap<Key,T,Compare,Allocator>& y);
    426 
    427 }  //namespace container {
    428 
    429 template <class K, class T, class C, class Allocator>
    430 struct has_trivial_destructor_after_move<boost::container::map<K, T, C, Allocator> >
    431 {
    432    static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
    433 };
    434 
    435 namespace container {
    436 
    437 
    438 //! A multimap is a kind of associative container that supports equivalent keys
    439 //! (possibly containing multiple copies of the same key value) and provides for
    440 //! fast retrieval of values of another type T based on the keys. The multimap class
    441 //! supports bidirectional iterators.
    442 //!
    443 //! A multimap satisfies all of the requirements of a container and of a reversible
    444 //! container and of an associative container. For a
    445 //! map<Key,T> the key_type is Key and the value_type is std::pair<const Key,T>.
    446 //!
    447 //! Compare is the ordering function for Keys (e.g. <i>std::less<Key></i>).
    448 //!
    449 //! Allocator is the allocator to allocate the value_types
    450 //!(e.g. <i>allocator< std::pair<<b>const</b> Key, T> ></i>).
    451 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
    452 template <class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator< std::pair< const Key, T> > >
    453 #else
    454 template <class Key, class T, class Compare, class Allocator>
    455 #endif
    456 class multimap
    457 {
    458    /// @cond
    459    private:
    460    BOOST_COPYABLE_AND_MOVABLE(multimap)
    461 
    462    typedef std::pair<const Key, T>  value_type_impl;
    463    typedef container_detail::rbtree
    464       <Key, value_type_impl, container_detail::select1st<value_type_impl>, Compare, Allocator> tree_t;
    465    typedef container_detail::pair <Key, T> movable_value_type_impl;
    466    typedef container_detail::tree_value_compare
    467       < Key, value_type_impl, Compare, container_detail::select1st<value_type_impl>
    468       >  value_compare_impl;
    469    tree_t m_tree;  // red-black tree representing map
    470    /// @endcond
    471 
    472    public:
    473    typedef Key                                                                      key_type;
    474    typedef T                                                                        mapped_type;
    475    typedef std::pair<const Key, T>                                                  value_type;
    476    typedef typename boost::container::allocator_traits<Allocator>::pointer          pointer;
    477    typedef typename boost::container::allocator_traits<Allocator>::const_pointer    const_pointer;
    478    typedef typename boost::container::allocator_traits<Allocator>::reference        reference;
    479    typedef typename boost::container::allocator_traits<Allocator>::const_reference  const_reference;
    480    typedef typename boost::container::allocator_traits<Allocator>::size_type        size_type;
    481    typedef typename boost::container::allocator_traits<Allocator>::difference_type  difference_type;
    482    typedef Allocator                                                                allocator_type;
    483    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::stored_allocator_type)           stored_allocator_type;
    484    typedef BOOST_CONTAINER_IMPDEF(value_compare_impl)                               value_compare;
    485    typedef Compare                                                                  key_compare;
    486    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::iterator)                        iterator;
    487    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_iterator)                  const_iterator;
    488    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::reverse_iterator)                reverse_iterator;
    489    typedef typename BOOST_CONTAINER_IMPDEF(tree_t::const_reverse_iterator)          const_reverse_iterator;
    490    typedef std::pair<key_type, mapped_type>                                         nonconst_value_type;
    491    typedef BOOST_CONTAINER_IMPDEF(movable_value_type_impl)                          movable_value_type;
    492 
    493    multimap(): m_tree()
    494    {
    495       //Allocator type must be std::pair<CONST Key, T>
    496       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    497    }
    498 
    499    explicit multimap(const Compare& comp, const allocator_type& a = allocator_type()): m_tree(comp, a)
    500    {
    501       //Allocator type must be std::pair<CONST Key, T>
    502       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    503    }
    504    
    505    template <class InputIterator>
    506    multimap(InputIterator first, InputIterator last,
    507             const Compare& comp = Compare(),
    508             const allocator_type& a = allocator_type())
    509       : m_tree(false, first, last, comp, a)
    510    {
    511       //Allocator type must be std::pair<CONST Key, T>
    512       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    513    }
    514 
    515    template <class InputIterator>
    516    multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
    517          const allocator_type& a = allocator_type())
    518       : m_tree(ordered_range, first, last, comp, a)
    519    {}
    520 
    521    multimap(const multimap& x): m_tree(x.m_tree)
    522    {
    523       //Allocator type must be std::pair<CONST Key, T>
    524       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    525    }
    526 
    527    multimap(BOOST_RV_REF(multimap) x): m_tree(boost::move(x.m_tree))
    528    {
    529       //Allocator type must be std::pair<CONST Key, T>
    530       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    531    }
    532 
    533    multimap(const multimap& x, const allocator_type &a): m_tree(x.m_tree, a)
    534    {
    535       //Allocator type must be std::pair<CONST Key, T>
    536       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    537    }
    538    multimap(BOOST_RV_REF(multimap) x, const allocator_type &a): m_tree(boost::move(x.m_tree), a)
    539    {
    540       //Allocator type must be std::pair<CONST Key, T>
    541       BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
    542    }
    543 
    544    multimap& operator=(BOOST_COPY_ASSIGN_REF(multimap) x)
    545    {  m_tree = x.m_tree;   return *this;  }
    546 
    547    multimap& operator=(BOOST_RV_REF(multimap) x)
    548    {  m_tree = boost::move(x.m_tree);   return *this;  }
    549 
    550    allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT
    551    { return m_tree.get_allocator(); }
    552 
    553    stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT
    554    { return m_tree.get_stored_allocator(); }
    555 
    556    const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT
    557    { return m_tree.get_stored_allocator(); }
    558 
    559    iterator begin() BOOST_CONTAINER_NOEXCEPT
    560    { return m_tree.begin(); }
    561 
    562    const_iterator begin() const BOOST_CONTAINER_NOEXCEPT
    563    { return this->cbegin(); }
    564 
    565    iterator end() BOOST_CONTAINER_NOEXCEPT
    566    { return m_tree.end(); }
    567 
    568    const_iterator end() const BOOST_CONTAINER_NOEXCEPT
    569    { return this->cend(); }
    570 
    571    reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT
    572    { return m_tree.rbegin(); }
    573 
    574    const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT
    575    { return this->crbegin(); }
    576 
    577    reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT
    578    { return m_tree.rend(); }
    579 
    580    const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT
    581    { return this->crend(); }
    582 
    583    const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT
    584    { return m_tree.begin(); }
    585 
    586    const_iterator cend() const BOOST_CONTAINER_NOEXCEPT
    587    { return m_tree.end(); }
    588 
    589    const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT
    590    { return m_tree.rbegin(); }
    591 
    592    const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT
    593    { return m_tree.rend(); }
    594 
    595    bool empty() const BOOST_CONTAINER_NOEXCEPT
    596    { return m_tree.empty(); }
    597 
    598    size_type size() const BOOST_CONTAINER_NOEXCEPT
    599    { return m_tree.size(); }
    600 
    601    size_type max_size() const BOOST_CONTAINER_NOEXCEPT
    602    { return m_tree.max_size(); }  
    603 
    604    #if defined(BOOST_CONTAINER_PERFECT_FORWARDING) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
    605 
    606    template <class... Args>
    607    iterator emplace(Args&&... args)
    608    {  return m_tree.emplace_equal(boost::forward<Args>(args)...); }
    609 
    610    template <class... Args>
    611    iterator emplace_hint(const_iterator hint, Args&&... args)
    612    {  return m_tree.emplace_hint_equal(hint, boost::forward<Args>(args)...); }
    613 
    614    #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
    615 
    616    #define BOOST_PP_LOCAL_MACRO(n)                                                                 
    617    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          
    618    iterator emplace(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _))                            
    619    {  return m_tree.emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); }        
    620                                                                                                    
    621    BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >)          
    622    iterator emplace_hint(const_iterator hint                                                       
    623                          BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _))              
    624    {  return m_tree.emplace_hint_equal(hint                                                        
    625                                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _));}   
    626    //!
    627    #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
    628    #include BOOST_PP_LOCAL_ITERATE()
    629 
    630    #endif   //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
    631 
    632    iterator insert(const value_type& x)
    633    { return m_tree.insert_equal(x); }
    634 
    635    iterator insert(const nonconst_value_type& x)
    636    { return m_tree.insert_equal(x); }
    637 
    638    iterator insert(BOOST_RV_REF(nonconst_value_type) x)
    639    { return m_tree.insert_equal(boost::move(x)); }
    640 
    641    iterator insert(BOOST_RV_REF(movable_value_type) x)
    642    { return m_tree.insert_equal(boost::move(x)); }
    643 
    644    iterator insert(const_iterator position, const value_type& x)
    645    { return m_tree.insert_equal(position, x); }
    646 
    647    iterator insert(const_iterator position, const nonconst_value_type& x)
    648    { return m_tree.insert_equal(position, x); }
    649 
    650    iterator insert(const_iterator position, BOOST_RV_REF(nonconst_value_type) x)
    651    { return m_tree.insert_equal(position, boost::move(x)); }
    652 
    653     iterator insert(const_iterator position, BOOST_RV_REF(movable_value_type) x)
    654    { return m_tree.insert_equal(position, boost::move(x)); }
    655 
    656    template <class InputIterator>
    657    void insert(InputIterator first, InputIterator last)
    658    {  m_tree.insert_equal(first, last); }
    659 
    660    iterator erase(const_iterator position) BOOST_CONTAINER_NOEXCEPT
    661    { return m_tree.erase(position); }
    662 
    663    size_type erase(const key_type& x) BOOST_CONTAINER_NOEXCEPT
    664    { return m_tree.erase(x); }
    665 
    666    iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT
    667    { return m_tree.erase(first, last); }
    668 
    669    void swap(multimap& x)
    670    { m_tree.swap(x.m_tree); }
    671 
    672    void clear() BOOST_CONTAINER_NOEXCEPT
    673    { m_tree.clear(); }
    674 
    675    key_compare key_comp() const
    676    { return m_tree.key_comp(); }
    677 
    678    value_compare value_comp() const
    679    { return value_compare(m_tree.key_comp()); }
    680 
    681    iterator find(const key_type& x)
    682    { return m_tree.find(x); }
    683 
    684    const_iterator find(const key_type& x) const
    685    { return m_tree.find(x); }
    686 
    687    size_type count(const key_type& x) const
    688    { return m_tree.count(x); }
    689 
    690    iterator lower_bound(const key_type& x)
    691    {return m_tree.lower_bound(x); }
    692 
    693    const_iterator lower_bound(const key_type& x) const
    694    {  return m_tree.lower_bound(x);  }
    695 
    696    iterator upper_bound(const key_type& x)
    697    {  return m_tree.upper_bound(x); }
    698 
    699    const_iterator upper_bound(const key_type& x) const
    700    {  return m_tree.upper_bound(x); }
    701 
    702    std::pair<iterator,iterator> equal_range(const key_type& x)
    703    {  return m_tree.equal_range(x);   }
    704 
    705    std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const
    706    {  return m_tree.equal_range(x);   }
    707 
    708    /// @cond
    709    template <class K1, class T1, class C1, class A1>
    710    friend bool operator== (const multimap<K1, T1, C1, A1>& x,
    711                            const multimap<K1, T1, C1, A1>& y);
    712 
    713    template <class K1, class T1, class C1, class A1>
    714    friend bool operator< (const multimap<K1, T1, C1, A1>& x,
    715                           const multimap<K1, T1, C1, A1>& y);
    716    /// @endcond
    717 };
    718 
    719 template <class Key, class T, class Compare, class Allocator>
    720 inline bool operator==(const multimap<Key,T,Compare,Allocator>& x,
    721                        const multimap<Key,T,Compare,Allocator>& y)
    722 {  return x.m_tree == y.m_tree;  }
    723 
    724 template <class Key, class T, class Compare, class Allocator>
    725 inline bool operator<(const multimap<Key,T,Compare,Allocator>& x,
    726                       const multimap<Key,T,Compare,Allocator>& y)
    727 {  return x.m_tree < y.m_tree;   }
    728 
    729 template <class Key, class T, class Compare, class Allocator>
    730 inline bool operator!=(const multimap<Key,T,Compare,Allocator>& x,
    731                        const multimap<Key,T,Compare,Allocator>& y)
    732 {  return !(x == y);  }
    733 
    734 template <class Key, class T, class Compare, class Allocator>
    735 inline bool operator>(const multimap<Key,T,Compare,Allocator>& x,
    736                       const multimap<Key,T,Compare,Allocator>& y)
    737 {  return y < x;  }
    738 
    739 template <class Key, class T, class Compare, class Allocator>
    740 inline bool operator<=(const multimap<Key,T,Compare,Allocator>& x,
    741                        const multimap<Key,T,Compare,Allocator>& y)
    742 {  return !(y < x);  }
    743 
    744 template <class Key, class T, class Compare, class Allocator>
    745 inline bool operator>=(const multimap<Key,T,Compare,Allocator>& x,
    746                        const multimap<Key,T,Compare,Allocator>& y)
    747 {  return !(x < y);  }
    748 
    749 template <class Key, class T, class Compare, class Allocator>
    750 inline void swap(multimap<Key,T,Compare,Allocator>& x, multimap<Key,T,Compare,Allocator>& y)
    751 {  x.swap(y);  }
    752 
    753 /// @cond
    754 
    755 }  //namespace container {
    756 
    757 //!has_trivial_destructor_after_move<> == true_type
    758 //!specialization for optimizations
    759 template <class K, class T, class C, class Allocator>
    760 struct has_trivial_destructor_after_move<boost::container::multimap<K, T, C, Allocator> >
    761 {
    762    static const bool value = has_trivial_destructor_after_move<Allocator>::value && has_trivial_destructor_after_move<C>::value;
    763 };
    764 
    765 namespace container {
    766 
    767 /// @endcond
    768 
    769 }}
    770 #include <boost/container/detail/config_end.hpp>
    771 #endif /* BOOST_CONTAINER_MAP_HPP */
    View Code

     

    1. A pair Associative Container is an Associative Container that associates a key with some other object. The value type of a Pair Associative Container is pair<const key_type, data_type>.
    2. Models: map; multimap; hash_map; hash_multimap
    3. The value type must be pair<const key_type, data_type>, rather than pair<key_type, data_type>, because of the Associative Container invariant of key immutability. The data_type part of an object in a Pair Associative Container may be modified, but the key_type part may not be. Note the implication of this fact: a Pair Associative Container can not provide mutable iterators (as defined in the Trivial Iterator requirements), because the value type of a mutable iterator must be Assignable, and pair<const key_type,data_type> is not Assignable. However, a Pair Associative Container can provide iteratoers that are not completely constant: iterators such that the expression (*i).second = d is valid.
    4. Key type: X::key_type The type of the key associated with X::value_type.
    5. Data type: X::data_type The type of the data associated with X::value_type. A Pair Associative Container can be thought of as a mapping from key_type to data_type.
    6. Value type: X::value_type The type of object stored in the container. The value type is required to be pair<const key_type, data_type>.

    Associative Container->Sorted Associative Container

    1. A Sorted Associative Container is a type of Associative Container. Sorted Associative Containers use an ordering relation on their keys; two keys are considered to be equivalent if neither one is less than the other. (If the ordering relation is case-insensitive string comparison, for example, then the keys “abcde” and “aBCde” are equivalent.)
    2. Sorted Associative Containers guarantee that the complexity for most operations is never worse than logarithmic(对数), and they also guarantee that their elements are always sorted in ascending order by key. (descending order)
    3. Two new types are introduced, in addition to the types defined in the Associative Container and Reversible Container requirements.
    4.  X::key_compare The type of a Strict Weak Ordering used to compare keys. Its argument type must be X::key_type.
    5.  X::value_compare The type of a Strict Weak Ordering used to compare values. Its argument type must be X::value_type, and it compares two objects of value_type by passing the keys associated with those objects to a function object of type key_compare.
    6. Complexity guarantees: key_comp() and value_comp() are constant time. Erase element is constant time. Erase key is O (log(size()) + count (k) ). Erase range is O (log (size() ) + N ), where N is the length of the range. Find is logarithmic. Count is O (log (size() ) + count (k). Lower bound, upper bound, and equal range are logarithmic.
    7. Definition of value_comp: If t1 and t2 are objects of type X:: value_type and k1 and k2 are the keys associated with those objects, then a,value_comp() returns a function object such that a.value_com() (t1, t2) is equivalent to a.key_comp(k1,k2).
    8. Ascending order: The elements in a Sorted Associative Container are always arranged in ascending order by key. That is, if a is a Sorted Associative Container, then is_sorted( a.begin(), a.end() ), a.value_comp() ) is always true.
    9. Models: set; multiset; map; multimap
    10. This is a much stronger guarantee than the one provided by Associative Container. The guarantees in Associative Container only apply to average complexity; worst case complexity is allowed to be greater. Sorted Associative Container, however, provides an upper limit on worst case complexity.
    11. This definition is consistent with the semantics described in Associative Container. It is stronger condition, though: if a contains no elements with the key k, then a.equal_range (k) returns an empty range that indicates the position where those elements would be if they did exist. The Associative Container requirements, however, merely state that the return value is an arbitrary( 1. determined by changce, whim or impulse, and not by necessity ,reason, or principle; 2. Based on or subject to individual judgment or preference) empty range.

    Associative Container->Hashed Associative Container

    1. A Hashed Associative Container is an Associative Container whose implementation is a hash table. The elements of a Hashed Associative Container are not guaranteed to be in any meaningful order, in particular, they are not sorted. The worst case complexity of most operations on Hashed Associative is linear in the size of the container, but the average case complexity is constant time; this means that for applications where values are simply stored and retrieved, and where ordering is unimportant, Hashed Associative Containers are usually much faster than Sorted Associative Containers.
    2. Hash function X::hasher A type that is a model of Hash Function X::hasher’s argument type must be X::key_type.
    3. Key equal X::key_equal A Binary_Predicate whose argument type is X::key_type. An object of type key_equal returns true if its arguments are the same key, and false otherwise, X::key_equal must be an equivalence relation.
    4. A hash function for a Hased Associative Container X is a Unary Function with argument X::key_type and whose return type is size_t. A hash function must be deterministic ( that is, it must always return the same value whenever it is called with the same argument), but return values of the hash function should be as uniform as possible: ideally, no two keys will hash to the same value.
    5. Elements in a Hashed Associative Container are organized into buckets. A Hashed Associative Container uses the value of the hash function to determine which bucket an element is assigned to.
    6. The number of elements in a Hashed Associative Container divided by the number of buckets is called the load factor. A Hashed Associative Container with a small load factor is faster than one with a large load factor.
    7. The default constructor, constructor with bucket count, constructor with hash function, and constructor with key equal, are all amortized constant time.
    8. Hash Function and Key Equal are amortized constant time.
    9. Average complexity for Erase key is O(count(k). Worst case is linear in the size of the container.
    10. Erase Element is amortized constant time. Average complexity for Erase Range is O(N), where N is the length of the range being erased. Worse case is linear in the size of the container.
    11. Average complexity for Find is constant time. Worst case is linear in the size of the container. Resize is linear in the size of the container.
    12. Models: hash_set; hash_map; hash_multiset; hash_multimap.
    13. There is an extensive literature dealing with hash tables. If the hash function is poor( that is, if many different keys hash to the same value) then this will hurt performance. The worst case is where every key hashes to the same value, in this case, run-time complexity of most Hashed Associative Container operations will be liner in the size of the container.
    14. Resizing does not invalidate iterators; however, it does not necessarily preserve the ordering relation between iterators. That is, if I and j are iterators that point into a Hashed Associative Container such that I comes immediately before j, then there is no guarantee that I will still come immediately before j after the container is resized. The only guarantee about the ordering of elements is the contiguous storage invariant: elements with the same key are always adjacent to each other.

    Sequences->Vector

    1. 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. Vector is the simplest of the STL container classes, and in many cases the most efficient.
    2. This member function relies on member template functions, which at present are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input_iterator. If your compiler does not yet supports member templates, though, then the arguments must be of type const value_type*
    3. Memory will be reallocated automatically if more than capacity() – size() elements are inserted into the vector. Reallocation does not change size(), nor does it change the values of any elements of the vector. It does, however, increase capacity(), and it invalidates any iterators that point into the vector.
    4. When it is necessary to increase capacity(), vector usually increases it by a factor of two. It is crucial that the amount of growth is proportional to the current capacity(), rather than a fixed constant: in the former case inserting a series of elements into a vector is a linear time operation, and in the latter case it is quadratic (of, relating to or containing quantities of the second degree).
    5. Reserve() causes a reallocation manually. The main reason for using reserve() is efficiency. If you know the capacity to which your vector must eventually grow, then it is usually more efficient to allocate that memory all at once rather than relying on the automatic reallocation scheme. The other reason for using reserve() is so that you can control the invalidation of iterator.
    6. A vector’s iterators are invalidated when its memory is reallocated. Additionally, inserting or deleting an element in the middle of a vector invalidates all iterators that point to elements following the insertion or deletion point. It follows that you can prevent a vector’s iterators from being invalidates if you use reserve() to preallocate as much memory as vector will ever use, and if all insertions and deletions are at the vector’s end.

    Sequences->deque

    1. A deque is very much like a vector, it is a sequence that supports random access to elements, constant time insertion and removal of elements at the end of the sequence, and linear time insertion and removal of elements in the middle.
    2. The main way in which differs from vector is that deque also supports constant time insertion and removal of element at the beginning of the sequence. Additionally, deque does not have any member functions analogous/similar to vector’s capacity() and reserve(), and does not provide any of the guarantees on iterator validity that are associated with those member functions.
    3. The name deque is pronounced “deck”, and stands for “double-ended queue.”
    4. Inserting an element at the beginning or end of a deque takes amortized constant time. Inserting an element in the middle is linear in n, where n is the smaller of the number of elements from the insertion point to the beginning and the number of elements from the insertion point to the end.
    5. The semantics of iterator invalidation for deque is as follows. Insert(including push_front and push_back) invalidates all iterators that refer to a deque. Erase in the middle /midst of a deque invalidates all iterators that refer to the deque. Erase at the beginning or end of a deque (including pop_front and pop_back() )invalidates an iterator only if it points to the erased element.
    6. This member function relies on member template functions, which at present are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of input_iterator. If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type * or of type deque::const_iterator.

    Sequences->list<T, Alloc>

    1. A list is a doubly linked list. That is, That is to say, Namely, it is a Sequence that supports both forward and backward traversal, and 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 interators to list elements, and that even removal invalidates only the iterators that point to the elements that are removed.
    2. The ordering of iterators may be changed (that is, list<T>::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.
    3. Note that singly linked lists, which only support forward traversal, are also sometimes useful. If you do not need backward traversal, then slist may be more efficient than list.
    4. A comparison with vector is instructive. Suppose that I is a valid vector<T>::iterator. If an element is inserted or removed in a position that precedes I, then this operation will either result in I pointing to a different element than it did before, or else it will invalidate I entirely. 
    5. A vector<T>::iterator will be invalidated if an insertion requires a reallocation. 
    6. However, suppose that I and j are both iterators into a vector, and there exists some integer n such that I == j + n. In that case, even if elements are inserted into to vector and I and j point to different elements, the relation between iterators will still hold.
    7. A list is exactly the opposite: iterators predecessor/successor relationship is not invariant.
    8. A similar property holds for all version of insert() and erase(). List <T, Alloc>:: insert never invalidates any iterator, and erase() only invalidates iterators pointing to the elements that are actually being erased.
    9. If L is a list, note that L.reverse() and reverse(L.begin(), L.end() ) are both correct ways of reversing the list. They differ in that L.reverse() will preserve the values that each iterator into L points to but will not preserve the iterators’ predecessor/successor relationships, while reverse (L.begin(), L.end() ) will not preserve the value that each iterator points to but will preserve the iterators’ predecessor /successor relationships. Note also that algorithm reverse (L.begin(), L.end() ) will use T’s assignment operator, while the member function L.reverse() will not.
    10. The sort algorithm works only for random access iterators. In principle, however, it would be possible to write a sort algorithm that also accepted bidirectional iterators. Even if there were such a version of sort. It would still be useful for list to have a sort member function. That is, sort is provided as a member function not only for the sake of efficiency, but also because of the property that it preserves the values that list iterators point to.

    Associative Container->set<Key, Compare, Alloc>

    1. Set is a Sorted Associative Container that stores objects of type Key. 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.
    2. Set and multiset are particular well suited to the set algorithm includes, set_union, set_intersection, set_difference, and set_symetric_difference. The reason for this is twofold/diplex/diploid/double/dual/duple. First, the set algorithms require their arguments to be sorted ranges, and, since set and multiset are Sorted Associative Containers, their elements are always sorted in ascending order. Second, the output range of these algorithms is always sorted, and inserting a sorted range into a set or multiset is a fast operation: the Unique Sorted Associative Container and Multiple Sorted Associative Container requirements guarantee that inserting a range takes only linear time if the range is already sorted.
    3. Set has the important property that inserting a new element into a set does not invalidate iterators that point to existing element. Erasing an element from a set also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being removed /deleted /cut off /eliminated/got rod of.
    4. Key: The set’s key type and value type. This is also defined as set::key_type and set::value_type.
    5. Compare: The Key comparison function, a Strict Weak Ordering whose argument type is key_type; it returns ture if its first argument is less than its second argument, and false otherwise. This is also defined as set::key_compare and set::value_compare.
    6. Alloc: The set’s allocator, used for all internal memory management.

    Associative Container-->map<Key,Data, Compare, Alloc>

    1. Map is a Sorted Associative Container that associates objects of type Key with objects of type Data. Map is a Pair Associative Container, meaning that its value type is pair<const Key, Data>. It is also a Unique Associative Container, meaning that no two elements have the same key.
    2. Map has the important property that inserting a new element into a map does not invalidate iterators that point to existing element. Erasing an element from a set also does not invalidate any interators, except, of course, for iterators that actually point to the element that is being erased.
    3. Compare has the default implementation which is less<key>; less is a template function, just like template <class _Tp>struct less : public binary_function<_Tp,_Tp,tBool> { tBool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y? TRUE:FALSE; }};
    4. Type requirements: Data is Assignable; Compare is a Strict Weak Ordering whose argument type is key to be as template less argument type. Alloc is an Allocator.
    5. New members: data_type & operator[ ] (const key_type &k) Returns a reference to the object that is associated with a particular key. If the map does not already contain such an object, operator[ ] inserts the default object data_type().
    6. Map::iterator is not a mutable iterator, because map::value_type is not Assignable. That is, if I is of type map::iterator and p is of type map::value_type, then *I = p is not valid expression. However, map::iterator is not a constant iterator either, because it can be used to modify the object that it points to. Using the same notation as above, (*i) . second = p is a valid expression. The same point applies to map::reverse_iterator.
    7. Since operator[ ] might insert a new element into the map, it can’t possibly be a const member function. Note that the definition of operator [ ] is extremely simple: m[k] is equivalent to (* (( m.insert (value_type (k, data_type() ) ) ).first )) . second. Strictly speaking, this member function is unnecessary, it exists only for convenience.

     AutoPtr 

      1 //Forward declaretion, TEMPLATE CLASS auto_ptr
      2 template<class _Ty>
      3 class auto_ptr;
      4 
      5 template<class _Ty>
      6 struct auto_ptr_ref
      7 {    // proxy reference for auto_ptr copying
      8    explicit auto_ptr_ref(_Ty *_Right): _Ref(_Right)
      9    {    // construct from generic pointer to auto_ptr ptr
     10    }
     11   _Ty *_Ref;    // generic pointer to auto_ptr ptr
     12 };
     13 
     14 template<class _Ty>
     15 class auto_ptr
     16 {    // wrap an object pointer to ensure destruction
     17 public:
     18     typedef auto_ptr<_Ty> _Myt;
     19     typedef _Ty element_type;
     20     explicit auto_ptr(_Ty *_Ptr = 0) _THROW0(): _Myptr(_Ptr)
     21     {    // construct from object pointer
     22     }
     23     auto_ptr(_Myt& _Right) _THROW0(): _Myptr(_Right.release())
     24     {    // construct by assuming pointer from _Right auto_ptr
     25     }
     26     auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()
     27     {    // construct by assuming pointer from _Right auto_ptr_ref
     28         _Ty *_Ptr = _Right._Ref;
     29         _Right._Ref = 0;    // release old
     30         _Myptr = _Ptr;    // reset this
     31     }
     32 
     33     template<class _Other>
     34     operator auto_ptr<_Other>() _THROW0()
     35     {    // convert to compatible auto_ptr
     36          return (auto_ptr<_Other>(*this));
     37     }
     38 
     39     template<class _Other>
     40         operator auto_ptr_ref<_Other>() _THROW0()
     41         {    // convert to compatible auto_ptr_ref
     42         _Other *_Cvtptr = _Myptr;    // test implicit conversion
     43         auto_ptr_ref<_Other> _Ans(_Cvtptr);
     44         _Myptr = 0;    // pass ownership to auto_ptr_ref
     45         return (_Ans);
     46         }
     47 
     48     template<class _Other>
     49         _Myt& operator=(auto_ptr<_Other>& _Right) _THROW0()
     50         {    // assign compatible _Right (assume pointer)
     51         reset(_Right.release());
     52         return (*this);
     53         }
     54 
     55     template<class _Other>
     56         auto_ptr(auto_ptr<_Other>& _Right) _THROW0()
     57         : _Myptr(_Right.release())
     58         {    // construct by assuming pointer from _Right
     59         }
     60 
     61     _Myt& operator=(_Myt& _Right) _THROW0()
     62         {    // assign compatible _Right (assume pointer)
     63         reset(_Right.release());
     64         return (*this);
     65         }
     66 
     67     _Myt& operator=(auto_ptr_ref<_Ty> _Right) _THROW0()
     68         {    // assign compatible _Right._Ref (assume pointer)
     69         _Ty *_Ptr = _Right._Ref;
     70         _Right._Ref = 0;    // release old
     71         reset(_Ptr);    // set new
     72         return (*this);
     73         }
     74 
     75     ~auto_ptr()
     76     {    // destroy the object
     77         delete _Myptr;
     78     }
     79 
     80     _Ty& operator*() const _THROW0()
     81     {    // return designated value
     82  #if _ITERATOR_DEBUG_LEVEL == 2
     83         if (_Myptr == 0)
     84             _DEBUG_ERROR("auto_ptr not dereferencable");
     85  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
     86 
     87         return (*get());
     88     }
     89 
     90     _Ty *operator->() const _THROW0()
     91     {    // return pointer to class object
     92  #if _ITERATOR_DEBUG_LEVEL == 2
     93         if (_Myptr == 0)
     94             _DEBUG_ERROR("auto_ptr not dereferencable");
     95  #endif /* _ITERATOR_DEBUG_LEVEL == 2 */
     96 
     97         return (get());
     98     }
     99 
    100     _Ty *get() const _THROW0()
    101     {    // return wrapped pointer
    102         return (_Myptr);
    103     }
    104     _Ty *release() _THROW0()
    105     {    // return wrapped pointer and give up ownership
    106         _Ty *_Tmp = _Myptr;
    107         _Myptr = 0;
    108         return (_Tmp);
    109     }
    110 
    111     void reset(_Ty *_Ptr = 0)
    112     {    // destroy designated object and store new pointer
    113         if (_Ptr != _Myptr)
    114             delete _Myptr;
    115         _Myptr = _Ptr;
    116     }
    117 private:
    118     _Ty *_Myptr;    // the wrapped object pointer
    119     };
    120 _STD_END
    View Code

    Allocator 

      1 // xmemory internal header (from <memory>)
      2 #pragma once
      3 #ifndef _XMEMORY_
      4 #define _XMEMORY_
      5 #ifndef RC_INVOKED
      6 #include <cstdlib>
      7 #include <new>
      8 #include <xutility>
      9 
     10 #pragma pack(push,_CRT_PACKING)
     11 #pragma warning(push,3)
     12 
     13 
     14 #pragma push_macro("new")
     15 #undef new
     16 
     17 #pragma warning(disable: 4100)
     18 
     19 #ifndef _FARQ    /* specify standard memory model */
     20 #define _FARQ
     21 #define _PDFT    ptrdiff_t
     22 #define _SIZT    size_t
     23 #endif /* _FARQ */
     24 
     25 _STD_BEGIN
     26 // TEMPLATE FUNCTION _Allocate
     27 template<class _Ty> inline    _Ty _FARQ *_Allocate(_SIZT _Count, _Ty _FARQ *)
     28 {    // allocate storage for _Count elements of type _Ty
     29     void *_Ptr = 0;
     30     if (_Count <= 0)
     31         _Count = 0;
     32     else if (((_SIZT)(-1) / sizeof (_Ty) < _Count)
     33         || (_Ptr = ::operator new(_Count * sizeof (_Ty))) == 0)
     34         _THROW_NCEE(bad_alloc, 0);
     35     return ((_Ty _FARQ *)_Ptr);
     36 }
     37 
     38 // TEMPLATE FUNCTION _Construct
     39 template<class _Ty1,
     40 class _Ty2> inline
     41 void _Construct(_Ty1 _FARQ *_Ptr, _Ty2&& _Val)
     42 {    // construct object at _Ptr with value _Val
     43     void _FARQ *_Vptr = _Ptr;
     44     ::new (_Vptr) _Ty1(_STD forward<_Ty2>(_Val));
     45 }
     46 
     47 template<class _Ty1> inline
     48 void _Construct(_Ty1 _FARQ *_Ptr)
     49 {    // construct object at _Ptr with default value
     50     void _FARQ *_Vptr = _Ptr;
     51     ::new (_Vptr) _Ty1();
     52 }
     53 
     54 // TEMPLATE FUNCTION _Destroy
     55 template<class _Ty> inline
     56 void _Destroy(_Ty _FARQ *_Ptr)
     57 {    // destroy object at _Ptr
     58     _Ptr->~_Ty();
     59 }
     60 
     61 template<> inline
     62 void _Destroy(char _FARQ *)
     63 {    // destroy a char (do nothing)
     64 }
     65 
     66 template<> inline
     67 void _Destroy(wchar_t _FARQ *)
     68 {    // destroy a wchar_t (do nothing)
     69 }
     70 
     71 #ifdef _NATIVE_WCHAR_T_DEFINED
     72 template<> inline
     73 void _Destroy(unsigned short _FARQ *)
     74 {    // destroy a unsigned short (do nothing)
     75 }
     76 #endif /* _NATIVE_WCHAR_T_DEFINED */
     77 
     78     // TEMPLATE FUNCTION _Destroy_range
     79 template<class _Alloc> inline
     80 void _Destroy_range(typename _Alloc::pointer _First,typename _Alloc::pointer _Last, _Alloc& _Al)
     81 {    // destroy [_First, _Last)
     82     _Destroy_range(_First, _Last, _Al, _Ptr_cat(_First, _Last));
     83 }
     84 
     85 template<class _Alloc> inline
     86 void _Destroy_range(typename _Alloc::pointer _First,typename _Alloc::pointer _Last, _Alloc& _Al,
     87     _Nonscalar_ptr_iterator_tag)
     88 {    // destroy [_First, _Last), arbitrary type
     89     for (; _First != _Last; ++_First)
     90         _Dest_val(_Al, _First);
     91 }
     92 
     93 template<class _Alloc> inline
     94 void _Destroy_range(typename _Alloc::pointer _First,typename _Alloc::pointer _Last, _Alloc& _Al,
     95     _Scalar_ptr_iterator_tag)
     96 {    // destroy [_First, _Last), scalar type (do nothing)
     97 }
     98 
     99     // TEMPLATE FUNCTION addressof
    100 template<class _Ty> inline
    101 _Ty * addressof(_Ty& _Val)
    102 {    // return address of _Val
    103      ((_Ty *) &(char&)_Val);
    104 }
    105 
    106     // TEMPLATE CLASS _Allocator_base
    107 template<class _Ty>
    108 struct _Allocator_base
    109 {    // base class for generic allocators
    110    typedef _Ty value_type;
    111 };
    112 
    113     // TEMPLATE CLASS _Allocator_base<const _Ty>
    114 template<class _Ty>
    115 struct _Allocator_base<const _Ty>
    116 {    // base class for generic allocators for const _Ty
    117    typedef _Ty value_type;
    118 };
    119 
    120     // TEMPLATE CLASS allocator
    121 template<class _Ty>
    122 class allocator: public _Allocator_base<_Ty>
    123 {    // generic allocator for objects of class _Ty
    124     public:
    125     typedef _Allocator_base<_Ty> _Mybase;
    126     typedef typename _Mybase::value_type value_type;
    127 
    128     typedef value_type _FARQ *pointer;
    129     typedef value_type _FARQ& reference;
    130     typedef const value_type _FARQ *const_pointer;
    131     typedef const value_type _FARQ& const_reference;
    132 
    133     typedef _SIZT size_type;
    134     typedef _PDFT difference_type;
    135 
    136     template<class _Other>
    137     struct rebind
    138     {    // convert this type to allocator<_Other>
    139        typedef allocator<_Other> other;
    140     };
    141 
    142     pointer address(reference _Val) const
    143     {    // return address of mutable _Val
    144        return ((pointer) &(char&)_Val);
    145     }
    146     const_pointer address(const_reference _Val) const
    147     {    // return address of nonmutable _Val
    148        return ((const_pointer) &(char&)_Val);
    149     }
    150     allocator() _THROW0()
    151     {    // construct default allocator (do nothing)
    152     }
    153 
    154    allocator(const allocator<_Ty>&) _THROW0()
    155     {    // construct by copying (do nothing)
    156     }
    157 
    158     template<class _Other>
    159     allocator(const allocator<_Other>&) _THROW0()
    160     {    // construct from a related allocator (do nothing)
    161     }
    162 
    163     template<class _Other>
    164     allocator<_Ty>& operator=(const allocator<_Other>&)
    165     {    // assign from a related allocator (do nothing)
    166        return (*this);
    167     }
    168 
    169     void deallocate(pointer _Ptr, size_type)
    170     {    // deallocate object at _Ptr, ignore size
    171        ::operator delete(_Ptr);
    172     }
    173     pointer allocate(size_type _Count)
    174     {    // allocate array of _Count elements
    175        return (_Allocate(_Count, (pointer)0));
    176     }
    177     pointer allocate(size_type _Count, const void _FARQ *)
    178     {    // allocate array of _Count elements, ignore hint
    179        return (allocate(_Count));
    180     }
    181     void construct(pointer _Ptr, const _Ty& _Val)
    182     {    // construct object at _Ptr with value _Val
    183        _Construct(_Ptr, _Val);
    184     }
    185     void construct(pointer _Ptr, _Ty&& _Val)
    186     {    // construct object at _Ptr with value _Val
    187        ::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Ty>(_Val));
    188     }
    189 
    190     template<class _Other>
    191     void construct(pointer _Ptr, _Other&& _Val)
    192     {    // construct object at _Ptr with value _Val
    193        ::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Other>(_Val));
    194     }
    195 
    196     void destroy(pointer _Ptr)
    197     {    // destroy object at _Ptr
    198         _Destroy(_Ptr);
    199     }
    200 
    201     _SIZT max_size() const _THROW0()
    202     {    // estimate maximum array size
    203         _SIZT _Count = (_SIZT)(-1) / sizeof (_Ty);
    204         return (0 < _Count ? _Count : 1);
    205     }
    206 };
    207 
    208     // CLASS allocator<void>
    209 template<> class allocator<void>
    210 {    // generic allocator for type void
    211     public:
    212     typedef void _Ty;
    213     typedef _Ty _FARQ *pointer;
    214     typedef const _Ty _FARQ *const_pointer;
    215     typedef _Ty value_type;
    216 
    217     template<class _Other>
    218     struct rebind
    219     {    // convert this type to an allocator<_Other>
    220         typedef allocator<_Other> other;
    221     };
    222 
    223     allocator() _THROW0()
    224     {    // construct default allocator (do nothing)
    225     }
    226 
    227     allocator(const allocator<_Ty>&) _THROW0()
    228     {    // construct by copying (do nothing)
    229     }
    230 
    231     template<class _Other>
    232     allocator(const allocator<_Other>&) _THROW0()
    233     {    // construct from related allocator (do nothing)
    234     }
    235 
    236     template<class _Other>
    237     allocator<_Ty>& operator=(const allocator<_Other>&)
    238     {    // assign from a related allocator (do nothing)
    239         return (*this);
    240     }
    241 };
    242 
    243 template<class _Ty,class _Other> inline
    244 bool operator==(const allocator<_Ty>&,const allocator<_Other>&) _THROW0()
    245 {    // test for allocator equality
    246     return (true);
    247 }
    248 template<class _Ty,class _Other> 
    249 inline bool operator!=(const allocator<_Ty>& _Left,const allocator<_Other>& _Right) _THROW0()
    250 {    // test for allocator inequality
    251     return (!(_Left == _Right));
    252 }
    253 
    254     // TEMPLATE FUNCTIONS _Cons_val AND _Dest_val
    255 template<class _Alloc,class _Ty1,class _Ty2>
    256 void _Cons_val(_Alloc& _Alval, _Ty1 *_Pdest, _Ty2&& _Src)
    257 {    // construct using allocator
    258     _Alval.construct(_Pdest, _STD forward<_Ty2>(_Src));
    259 }
    260 
    261 template<class _Alloc,class _Ty1>
    262 void _Dest_val(_Alloc& _Alval, _Ty1 *_Pdest)
    263 {    // destroy using allocator
    264     _Alval.destroy(_Pdest);
    265 }
    266 _STD_END
    267 
    268 #pragma pop_macro("new")
    269 
    270 #pragma warning(pop)
    271 #pragma pack(pop)
    272 
    273 #endif /* RC_INVOKED */
    274 #endif /* _XMEMORY_ */
    View Code

     PtrBase      

      1 // TEMPLATE CLASS _Ptr_base
      2 template<class _Ty> class _Ptr_base
      3 {    // base class for shared_ptr and weak_ptr
      4     public:
      5     typedef _Ptr_base<_Ty> _Myt;
      6     typedef _Ty _Elem;
      7     typedef _Elem element_type;
      8 
      9     _Ptr_base(): _Ptr(0), _Rep(0)
     10     {    // construct
     11     }
     12 
     13     _Ptr_base(_Myt&& _Right): _Ptr(0), _Rep(0)
     14     {    // construct _Ptr_base object that takes resource from _Right
     15     _Assign_rv(_STD forward<_Myt>(_Right));
     16     }
     17 
     18     template<class _Ty2> _Ptr_base(_Ptr_base<_Ty2>&& _Right): _Ptr(_Right._Ptr), _Rep(_Right._Rep)
     19     {    // construct _Ptr_base object that takes resource from _Right
     20     _Right._Ptr = 0;
     21     _Right._Rep = 0;
     22     }
     23 
     24     _Myt& operator=(_Myt&& _Right)
     25     {    // construct _Ptr_base object that takes resource from _Right
     26     _Assign_rv(_STD forward<_Myt>(_Right));
     27     return (*this);
     28     }
     29 
     30     void _Assign_rv(_Myt&& _Right)
     31     {    // assign by moving _Right
     32     if (this != &_Right)
     33         _Swap(_Right);
     34     }
     35 
     36     long use_count() const
     37     {    // return use count
     38     return (_Rep ? _Rep->_Use_count() : 0);
     39     }
     40 
     41     void _Swap(_Ptr_base& _Right)
     42     {    // swap pointers
     43     _STD swap(_Rep, _Right._Rep);
     44     _STD swap(_Ptr, _Right._Ptr);
     45     }
     46 
     47     template<class _Ty2>
     48     bool owner_before(const _Ptr_base<_Ty2>& _Right) const
     49     {    // compare addresses of manager objects
     50     return (_Rep < _Right._Rep);
     51     }
     52 
     53     void *_Get_deleter(const _XSTD2 type_info& _Type) const
     54     {    // return pointer to deleter object if its type is _Type
     55     return (_Rep ? _Rep->_Get_deleter(_Type) : 0);
     56     }
     57 
     58     _Ty *_Get() const
     59     {    // return pointer to resource
     60     return (_Ptr);
     61     }
     62 
     63     bool _Expired() const
     64     {    // test if expired
     65     return (!_Rep || _Rep->_Expired());
     66     }
     67 
     68     void _Decref()
     69     {    // decrement reference count
     70     if (_Rep != 0)
     71         _Rep->_Decref();
     72     }
     73 
     74     void _Reset()
     75     {    // release resource
     76     _Reset(0, 0);
     77     }
     78 
     79     template<class _Ty2>
     80     void _Reset(const _Ptr_base<_Ty2>& _Other)
     81     {    // release resource and take ownership of _Other._Ptr
     82     _Reset(_Other._Ptr, _Other._Rep, false);
     83     }
     84 
     85     template<class _Ty2>
     86     void _Reset(const _Ptr_base<_Ty2>& _Other, bool _Throw)
     87     {    // release resource and take ownership from weak_ptr _Other._Ptr
     88     _Reset(_Other._Ptr, _Other._Rep, _Throw);
     89     }
     90 
     91     template<class _Ty2>
     92     void _Reset(const _Ptr_base<_Ty2>& _Other, const _Static_tag&)
     93     {    // release resource and take ownership of _Other._Ptr
     94     _Reset(static_cast<_Elem *>(_Other._Ptr), _Other._Rep);
     95     }
     96 
     97     template<class _Ty2>
     98     void _Reset(const _Ptr_base<_Ty2>& _Other, const _Const_tag&)
     99     {    // release resource and take ownership of _Other._Ptr
    100         _Reset(const_cast<_Elem *>(_Other._Ptr), _Other._Rep);
    101     }
    102 
    103     template<class _Ty2>
    104     void _Reset(const _Ptr_base<_Ty2>& _Other, const _Dynamic_tag&)
    105     {    // release resource and take ownership of _Other._Ptr
    106         _Elem *_Ptr = dynamic_cast<_Elem *>(_Other._Ptr);
    107         if (_Ptr)
    108             _Reset(_Ptr, _Other._Rep);
    109         else
    110             _Reset();
    111     }
    112     template<class _Ty2>
    113     void _Reset(auto_ptr<_Ty2>& _Other)
    114     {    // release resource and take _Other.get()
    115         _Ty2 *_Px = _Other.get();
    116         _Reset0(_Px, new _Ref_count<_Elem>(_Px));
    117         _Other.release();
    118         _Enable_shared(_Px, _Rep);
    119     }
    120     void _Reset(_Ty *_Other_ptr, _Ref_count_base *_Other_rep)
    121     {    // release resource and take _Other_ptr through _Other_rep
    122         if (_Other_rep)
    123             _Other_rep->_Incref();
    124         _Reset0(_Other_ptr, _Other_rep);
    125     }
    126     void _Reset(_Ty *_Other_ptr, _Ref_count_base *_Other_rep, bool _Throw)
    127     {    // take _Other_ptr through _Other_rep from weak_ptr if not expired
    128             // otherwise, leave in default state if !_Throw,
    129             // otherwise throw exception
    130         if (_Other_rep && _Other_rep->_Incref_nz())
    131             _Reset0(_Other_ptr, _Other_rep);
    132         else if (_Throw)
    133             _THROW_NCEE(bad_weak_ptr, 0);
    134     }
    135     void _Reset0(_Ty *_Other_ptr, _Ref_count_base *_Other_rep)
    136     {    // release resource and take new resource
    137         if (_Rep != 0)
    138             _Rep->_Decref();
    139         _Rep = _Other_rep;
    140         _Ptr = _Other_ptr;
    141     }
    142     void _Decwref()
    143     {    // decrement weak reference count
    144         if (_Rep != 0)
    145             _Rep->_Decwref();
    146     }
    147     void _Resetw()
    148     {    // release weak reference to resource
    149         _Resetw((_Elem *)0, 0);
    150     }
    151     template<class _Ty2>
    152     void _Resetw(const _Ptr_base<_Ty2>& _Other)
    153     {    // release weak reference to resource and take _Other._Ptr
    154         _Resetw(_Other._Ptr, _Other._Rep);
    155     }
    156     template<class _Ty2>
    157     void _Resetw(const _Ty2 *_Other_ptr, _Ref_count_base *_Other_rep)
    158     {    // point to _Other_ptr through _Other_rep
    159         _Resetw(const_cast<_Ty2*>(_Other_ptr), _Other_rep);
    160     }
    161     template<class _Ty2>
    162     void _Resetw(_Ty2 *_Other_ptr, _Ref_count_base *_Other_rep)
    163     {    // point to _Other_ptr through _Other_rep
    164         if (_Other_rep)
    165             _Other_rep->_Incwref();
    166         if (_Rep != 0)
    167             _Rep->_Decwref();
    168         _Rep = _Other_rep;
    169         _Ptr = _Other_ptr;
    170     }
    171     private:
    172         _Ty *_Ptr;
    173         _Ref_count_base *_Rep;
    174         template<class _Ty0> friend class _Ptr_base;
    175 };
    View Code

    SharedPtr     

      1 // TEMPLATE CLASS shared_ptr
      2 template<class _Ty> class shared_ptr: public _Ptr_base<_Ty>
      3 {    // class for reference counted resource management
      4     public:
      5     typedef shared_ptr<_Ty> _Myt;
      6     typedef _Ptr_base<_Ty> _Mybase;
      7 
      8     shared_ptr()
      9     {    // construct empty shared_ptr object
     10     }
     11     template<class _Ux>
     12     explicit shared_ptr(_Ux *_Px)
     13     {    // construct shared_ptr object that owns _Px
     14         _Resetp(_Px);
     15     }
     16     template<class _Ux,class _Dx>
     17     shared_ptr(_Ux *_Px, _Dx _Dt)
     18     {    // construct with _Px, deleter
     19         _Resetp(_Px, _Dt);
     20     }
     21     shared_ptr(_STD nullptr_t)
     22     {    // construct with nullptr
     23         _Resetp((_Ty *)0);
     24     }
     25     template<class _Dx>
     26     shared_ptr(_STD nullptr_t, _Dx _Dt)
     27     {    // construct with nullptr, deleter
     28         _Resetp((_Ty *)0, _Dt);
     29     }
     30     template<class _Dx,class _Alloc>
     31     shared_ptr(_STD nullptr_t, _Dx _Dt, _Alloc _Ax)
     32     {    // construct with nullptr, deleter, allocator
     33         _Resetp((_Ty *)0, _Dt, _Ax);
     34     }
     35     template<class _Ux,class _Dx,class _Alloc>
     36     shared_ptr(_Ux *_Px, _Dx _Dt, _Alloc _Ax)
     37     {    // construct with _Px, deleter, allocator
     38         _Resetp(_Px, _Dt, _Ax);
     39     }
     40     shared_ptr(const _Myt& _Other)
     41     {    // construct shared_ptr object that owns same resource as _Other
     42         this->_Reset(_Other);
     43     }
     44     template<class _Ty2>
     45     shared_ptr(const shared_ptr<_Ty2>& _Other,typename enable_if<is_convertible<_Ty2 *, _Ty *>::value,
     46                void *>::type * = 0)
     47     {    // construct shared_ptr object that owns same resource as _Other
     48         this->_Reset(_Other);
     49     }
     50     template<class _Ty2>
     51     explicit shared_ptr(const weak_ptr<_Ty2>& _Other,bool _Throw = true)
     52     {    // construct shared_ptr object that owns resource *_Other
     53         this->_Reset(_Other, _Throw);
     54     }
     55     template<class _Ty2>
     56     shared_ptr(auto_ptr<_Ty2>& _Other)
     57     {    // construct shared_ptr object that owns *_Other.get()
     58         this->_Reset(_Other);
     59     }
     60     template<class _Ty2>
     61     shared_ptr(const shared_ptr<_Ty2>& _Other, const _Static_tag& _Tag)
     62     {    // construct shared_ptr object for static_pointer_cast
     63         this->_Reset(_Other, _Tag);
     64     }
     65     template<class _Ty2>
     66     shared_ptr(const shared_ptr<_Ty2>& _Other, const _Const_tag& _Tag)
     67     {    // construct shared_ptr object for const_pointer_cast
     68         this->_Reset(_Other, _Tag);
     69     }
     70     template<class _Ty2>
     71     shared_ptr(const shared_ptr<_Ty2>& _Other, const _Dynamic_tag& _Tag)
     72     {    // construct shared_ptr object for dynamic_pointer_cast
     73         this->_Reset(_Other, _Tag);
     74     }
     75     shared_ptr(_Myt&& _Right): _Mybase(_STD forward<_Myt>(_Right))
     76     {    // construct shared_ptr object that takes resource from _Right
     77     }
     78     template<class _Ty2>
     79     shared_ptr(shared_ptr<_Ty2>&& _Right,typename enable_if<is_convertible<_Ty2 *, _Ty *>::value,
     80               void *>::type * = 0): _Mybase(_STD forward<shared_ptr<_Ty2> >(_Right))
     81     {    // construct shared_ptr object that takes resource from _Right
     82     }
     83     _Myt& operator=(_Myt&& _Right)
     84     {    // construct shared_ptr object that takes resource from _Right
     85         shared_ptr(_STD move(_Right)).swap(*this);
     86         return (*this);
     87     }
     88     template<class _Ty2>
     89     _Myt& operator=(shared_ptr<_Ty2>&& _Right)
     90     {    // construct shared_ptr object that takes resource from _Right
     91         shared_ptr(_STD move(_Right)).swap(*this);
     92         return (*this);
     93     }
     94     void swap(_Myt&& _Right)
     95     {    // exchange contents with movable _Right
     96         _Mybase::swap(_STD move(_Right));
     97     }
     98     ~shared_ptr()
     99     {    // release resource
    100         this->_Decref();
    101     }
    102     _Myt& operator=(const _Myt& _Right)
    103     {    // assign shared ownership of resource owned by _Right
    104         shared_ptr(_Right).swap(*this);
    105         return (*this);
    106     }
    107     template<class _Ty2>
    108     _Myt& operator=(const shared_ptr<_Ty2>& _Right)
    109     {    // assign shared ownership of resource owned by _Right
    110         shared_ptr(_Right).swap(*this);
    111         return (*this);
    112     }
    113     template<class _Ty2>
    114     _Myt& operator=(auto_ptr<_Ty2>& _Right)
    115     {    // assign ownership of resource pointed to by _Right
    116         shared_ptr(_Right).swap(*this);
    117         return (*this);
    118     }
    119     void reset()
    120     {    // release resource and convert to empty shared_ptr object
    121         shared_ptr().swap(*this);
    122     }
    123     template<class _Ux>
    124     void reset(_Ux *_Px)
    125     {    // release, take ownership of _Px
    126         shared_ptr(_Px).swap(*this);
    127     }
    128     template<class _Ux,class _Dx>
    129     void reset(_Ux *_Px, _Dx _Dt)
    130     {    // release, take ownership of _Px, with deleter _Dt
    131         shared_ptr(_Px, _Dt).swap(*this);
    132     }
    133     //#if _HAS_CPP0X
    134     template<class _Ux,    class _Dx,    class _Alloc>
    135     void reset(_Ux *_Px, _Dx _Dt, _Alloc _Ax)
    136     {    // release, take ownership of _Px, with deleter _Dt, allocator _Ax
    137         shared_ptr(_Px, _Dt, _Ax).swap(*this);
    138     }
    139     //#endif /* _HAS_CPP0X */
    140     void swap(_Myt& _Other)
    141     {    // swap pointers
    142         this->_Swap(_Other);
    143     }
    144     _Ty *get() const
    145     {    // return pointer to resource
    146         return (this->_Get());
    147     }
    148     typename tr1::add_reference<_Ty>::type operator*() const
    149     {    // return reference to resource
    150         return (*this->_Get());
    151     }
    152     _Ty *operator->() const
    153     {    // return pointer to resource
    154         return (this->_Get());
    155     }
    156     bool unique() const
    157     {    // return true if no other shared_ptr object owns this resource
    158         return (this->use_count() == 1);
    159     }    
    160     _OPERATOR_BOOL() const
    161     {    // test if shared_ptr object owns no resource
    162         return (this->_Get() != 0 ? _CONVERTIBLE_TO_TRUE : 0);
    163     }
    164 private:
    165     template<class _Ux>
    166     void _Resetp(_Ux *_Px)
    167     {    // release, take ownership of _Px
    168         _TRY_BEGIN    // allocate control block and reset
    169         _Resetp0(_Px, new _Ref_count<_Ux>(_Px));
    170         _CATCH_ALL    // allocation failed, delete resource
    171         delete _Px;
    172         _RERAISE;
    173         _CATCH_END
    174     }
    175     template<class _Ux,class _Dx>
    176     void _Resetp(_Ux *_Px, _Dx _Dt)
    177     {    // release, take ownership of _Px, deleter _Dt
    178         _TRY_BEGIN    // allocate control block and reset
    179         _Resetp0(_Px, new _Ref_count_del<_Ux, _Dx>(_Px, _Dt));
    180         _CATCH_ALL    // allocation failed, delete resource
    181         _Dt(_Px);
    182         _RERAISE;
    183         _CATCH_END
    184     }
    185     //#if _HAS_CPP0X
    186     template<class _Ux,class _Dx,class _Alloc>
    187     void _Resetp(_Ux *_Px, _Dx _Dt, _Alloc _Ax)
    188     {    // release, take ownership of _Px, deleter _Dt, allocator _Ax
    189         typedef _Ref_count_del_alloc<_Ux, _Dx, _Alloc> _Refd;
    190         typename _Alloc::template rebind<_Refd>::other _Al = _Ax;
    191 
    192         _TRY_BEGIN    // allocate control block and reset
    193         _Refd *_Ptr = _Al.allocate(1);
    194         new (_Ptr) _Refd(_Px, _Dt, _Al);
    195         _Resetp0(_Px, _Ptr);
    196         _CATCH_ALL    // allocation failed, delete resource
    197         _Dt(_Px);
    198         _RERAISE;
    199         _CATCH_END
    200     }
    201     //#endif /* _HAS_CPP0X */
    202     public:
    203     template<class _Ux>
    204     void _Resetp0(_Ux *_Px, _Ref_count_base *_Rx)
    205     {    // release resource and take ownership of _Px
    206         this->_Reset0(_Px, _Rx);
    207         _Enable_shared(_Px, _Rx);
    208     }
    209 };
    210 template<class _Ty1,class _Ty2>
    211 bool operator==(const shared_ptr<_Ty1>& _S1,const shared_ptr<_Ty2>& _S2)
    212 {    // test if shared_ptr == shared_ptr
    213     return (_S1.get() == _S2.get());
    214 }
    215 template<class _Ty1,class _Ty2>
    216 bool operator!=(const shared_ptr<_Ty1>& _S1,const shared_ptr<_Ty2>& _S2)
    217 {    // test if shared_ptr != shared_ptr
    218     return (!(_S1 == _S2));
    219 }
    220 template<class _Ty1,class _Ty2>
    221 bool operator<(const shared_ptr<_Ty1>& _S1,const shared_ptr<_Ty2>& _S2)
    222 {    // test if shared_ptr < shared_ptr
    223     return (_S1.get() < _S2.get());
    224 }
    225 template<class _Ty1,class _Ty2>
    226 bool operator>=(const shared_ptr<_Ty1>& _S1,const shared_ptr<_Ty2>& _S2)
    227 {    // shared_ptr >= shared_ptr
    228     return (!(_S1 < _S2));
    229 }
    230 template<class _Ty1,class _Ty2>
    231 bool operator>(const shared_ptr<_Ty1>& _S1,const shared_ptr<_Ty2>& _S2)
    232 {    // test if shared_ptr > shared_ptr
    233     return (_S2 < _S1);
    234 }
    235 template<class _Ty1,class _Ty2>
    236 bool operator<=(const shared_ptr<_Ty1>& _S1,const shared_ptr<_Ty2>& _S2)
    237 {    // test if shared_ptr <= shared_ptr
    238     return (!(_S2 < _S1));
    239 }
    240 template<class _Elem,class _Traits,class _Ty>
    241 basic_ostream<_Elem, _Traits>& operator<<(basic_ostream<_Elem, _Traits>& _Out,const shared_ptr<_Ty>& _Px)
    242 {    // write contained pointer to stream
    243     return (_Out << _Px.get());
    244 }
    245 template<class _Ty>
    246 void swap(shared_ptr<_Ty>& _Left,shared_ptr<_Ty>& _Right)
    247 {    // swap _Left and _Right shared_ptrs
    248     _Left.swap(_Right);
    249 }
    250 template<class _Ty>
    251 void swap(shared_ptr<_Ty>& _Left,shared_ptr<_Ty>&& _Right)
    252 {    // swap _Left and _Right shared_ptrs
    253     _Left.swap(_Right);
    254 }
    255 template<class _Ty>
    256 void swap(shared_ptr<_Ty>&& _Left,shared_ptr<_Ty>& _Right)
    257 {    // swap _Left and _Right shared_ptrs
    258     _Right.swap(_Left);
    259 }
    260 template<class _Ty1,class _Ty2>
    261 shared_ptr<_Ty1> static_pointer_cast(const shared_ptr<_Ty2>& _Other)
    262 {    // return shared_ptr object holding static_cast<_Ty1 *>(_Other.get())
    263     return (shared_ptr<_Ty1>(_Other, _Static_tag()));
    264 }
    265 template<class _Ty1,class _Ty2>
    266 shared_ptr<_Ty1> const_pointer_cast(const shared_ptr<_Ty2>& _Other)
    267 {    // return shared_ptr object holding const_cast<_Ty1 *>(_Other.get())
    268     return (shared_ptr<_Ty1>(_Other, _Const_tag()));
    269 }
    270 template<class _Ty1,class _Ty2>
    271 shared_ptr<_Ty1> dynamic_pointer_cast(const shared_ptr<_Ty2>& _Other)
    272 {    // return shared_ptr object holding dynamic_cast<_Ty1 *>(_Other.get())
    273     return (shared_ptr<_Ty1>(_Other, _Dynamic_tag()));
    274 }
    275 template<class _Dx,class _Ty>
    276 _Dx *get_deleter(const shared_ptr<_Ty>& _Sx)
    277 {    // return pointer to shared_ptr's deleter object if its type is _Ty
    278     return ((_Dx *)_Sx._Get_deleter(typeid(_Dx)));
    279 }
    280 
    281 #if _HAS_CPP0X
    282 
    283 // TEMPLATE CLASS _Ref_count_obj
    284 template<class _Ty>
    285 class _Ref_count_obj: public _Ref_count_base
    286 {    // handle reference counting for object in control block, no allocator
    287     public:
    288     #define _REF_COUNT_OBJ_CTOR
    289     #define _INCL_FILE_xxshared
    290     #include <xfwrap>
    291     #undef _REF_COUNT_OBJ_CTOR
    292     _Ty *_Getptr() const
    293     {    // get pointer
    294         return ((_Ty *)&_Storage);
    295     }
    296     private:
    297     virtual void _Destroy()
    298     {    // destroy managed resource
    299         _Getptr()->~_Ty();
    300     }
    301     virtual void _Delete_this()
    302     {    // destroy self
    303         delete this;
    304     }
    305     typename aligned_storage<sizeof(_Ty),alignment_of<_Ty>::value>::type _Storage;
    306 };
    307 // TEMPLATE CLASS _Ref_count_obj_alloc
    308 template<class _Ty,class _Alloc>
    309 class _Ref_count_obj_alloc: public _Ref_count_base
    310 {    // handle reference counting for object in control block, allocator
    311     public:
    312     typedef _Ref_count_obj_alloc<_Ty, _Alloc> _Myty;
    313     typedef typename _Alloc::template rebind<_Myty>::other _Myalty;
    314 
    315     #define _REF_COUNT_OBJ_ALLOC_CTOR
    316     #define _INCL_FILE_xxshared
    317     #include <xfwrap>
    318     #undef _REF_COUNT_OBJ_ALLOC_CTOR
    319 
    320     _Ty *_Getptr() const
    321     {    // get pointer
    322         return ((_Ty *)&_Storage);
    323     }
    324 
    325 private:
    326     virtual void _Destroy()
    327     {    // destroy managed resource
    328         _Getptr()->~_Ty();
    329     }
    330     virtual void _Delete_this()
    331     {    // destroy self
    332         _Myalty _Al = _Myal;
    333         _Dest_val(_Al, this);
    334         _Al.deallocate(this, 1);
    335     }
    336     typename aligned_storage<sizeof (_Ty),alignment_of<_Ty>::value>::type _Storage;
    337     _Myalty _Myal;    // the stored allocator for this
    338 };
    View Code
  • 相关阅读:
    网络安全从入门到精通 (第五章-3) MSSQL反弹注入
    网络安全从入门到精通 (第五章-2) MySQL注入 — Dns 注入
    网络安全从入门到精通 (第五章-1 )Access注入 — Cookie注入&偏移注入
    网络安全从入门到精通 (第四章-3) 注入之全方位利用-盲注
    网络安全从入门到精通(第四章-2)GET&POST&HEAD注入
    网络安全从入门到精通(第四章-1)SQL注入的原理分析&工具的介绍
    Educational Codeforces Round 85 (Rated for Div. 2)(A,B,C,D)
    1.1整除
    POJ
    Graph HDU
  • 原文地址:https://www.cnblogs.com/iiiDragon/p/3259809.html
Copyright © 2020-2023  润新知