/Src/Dependencies/Boost/boost/multi_index/detail/copy_map.hpp

http://hadesmem.googlecode.com/ · C++ Header · 140 lines · 97 code · 25 blank · 18 comment · 4 complexity · 6b4b5c14e5c670cee60edeb07018439f MD5 · raw file

  1. /* Copyright 2003-2008 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/multi_index for library home page.
  7. */
  8. #ifndef BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP
  9. #define BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP
  10. #if defined(_MSC_VER)&&(_MSC_VER>=1200)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  14. #include <algorithm>
  15. #include <boost/detail/no_exceptions_support.hpp>
  16. #include <boost/multi_index/detail/auto_space.hpp>
  17. #include <boost/multi_index/detail/prevent_eti.hpp>
  18. #include <boost/noncopyable.hpp>
  19. #include <cstddef>
  20. #include <functional>
  21. namespace boost{
  22. namespace multi_index{
  23. namespace detail{
  24. /* copy_map is used as an auxiliary structure during copy_() operations.
  25. * When a container with n nodes is replicated, node_map holds the pairings
  26. * between original and copied nodes, and provides a fast way to find a
  27. * copied node from an original one.
  28. * The semantics of the class are not simple, and no attempt has been made
  29. * to enforce it: multi_index_container handles it right. On the other hand,
  30. * the const interface, which is the one provided to index implementations,
  31. * only allows for:
  32. * - Enumeration of pairs of (original,copied) nodes (excluding the headers),
  33. * - fast retrieval of copied nodes (including the headers.)
  34. */
  35. template <typename Node>
  36. struct copy_map_entry
  37. {
  38. copy_map_entry(Node* f,Node* s):first(f),second(s){}
  39. Node* first;
  40. Node* second;
  41. bool operator<(const copy_map_entry<Node>& x)const
  42. {
  43. return std::less<Node*>()(first,x.first);
  44. }
  45. };
  46. template <typename Node,typename Allocator>
  47. class copy_map:private noncopyable
  48. {
  49. public:
  50. typedef const copy_map_entry<Node>* const_iterator;
  51. copy_map(
  52. const Allocator& al,std::size_t size,Node* header_org,Node* header_cpy):
  53. al_(al),size_(size),spc(al_,size_),n(0),
  54. header_org_(header_org),header_cpy_(header_cpy),released(false)
  55. {}
  56. ~copy_map()
  57. {
  58. if(!released){
  59. for(std::size_t i=0;i<n;++i){
  60. boost::detail::allocator::destroy(&(spc.data()+i)->second->value());
  61. deallocate((spc.data()+i)->second);
  62. }
  63. }
  64. }
  65. const_iterator begin()const{return &*spc.data();}
  66. const_iterator end()const{return &*(spc.data()+n);}
  67. void clone(Node* node)
  68. {
  69. (spc.data()+n)->first=node;
  70. (spc.data()+n)->second=&*al_.allocate(1);
  71. BOOST_TRY{
  72. boost::detail::allocator::construct(
  73. &(spc.data()+n)->second->value(),node->value());
  74. }
  75. BOOST_CATCH(...){
  76. deallocate((spc.data()+n)->second);
  77. BOOST_RETHROW;
  78. }
  79. BOOST_CATCH_END
  80. ++n;
  81. if(n==size_)std::sort(&*spc.data(),&*spc.data()+size_);
  82. }
  83. Node* find(Node* node)const
  84. {
  85. if(node==header_org_)return header_cpy_;
  86. return std::lower_bound(
  87. begin(),end(),copy_map_entry<Node>(node,0))->second;
  88. }
  89. void release()
  90. {
  91. released=true;
  92. }
  93. private:
  94. typedef typename prevent_eti<
  95. Allocator,
  96. typename boost::detail::allocator::rebind_to<
  97. Allocator,Node>::type
  98. >::type allocator_type;
  99. typedef typename allocator_type::pointer allocator_pointer;
  100. allocator_type al_;
  101. std::size_t size_;
  102. auto_space<copy_map_entry<Node>,Allocator> spc;
  103. std::size_t n;
  104. Node* header_org_;
  105. Node* header_cpy_;
  106. bool released;
  107. void deallocate(Node* node)
  108. {
  109. al_.deallocate(static_cast<allocator_pointer>(node),1);
  110. }
  111. };
  112. } /* namespace multi_index::detail */
  113. } /* namespace multi_index */
  114. } /* namespace boost */
  115. #endif