element_set.hpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*-----------------------------------------------------------------------------+
  2. Copyright (c) 2010-2010: Joachim Faulhaber
  3. +------------------------------------------------------------------------------+
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENCE.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. +-----------------------------------------------------------------------------*/
  8. #ifndef BOOST_ICL_CONCEPT_ELEMENT_SET_HPP_JOFA_100921
  9. #define BOOST_ICL_CONCEPT_ELEMENT_SET_HPP_JOFA_100921
  10. #include <boost/icl/type_traits/is_combinable.hpp>
  11. #include <boost/icl/concept/set_value.hpp>
  12. #include <boost/icl/detail/std_set.hpp>
  13. #include <boost/icl/detail/set_algo.hpp>
  14. namespace boost{ namespace icl
  15. {
  16. //==============================================================================
  17. //= Addition<ElementSet>
  18. //==============================================================================
  19. /** \c add inserts \c operand into the map if it's key does
  20. not exist in the map.
  21. If \c operands's key value exists in the map, it's data
  22. value is added to the data value already found in the map. */
  23. template <class Type>
  24. typename enable_if<is_element_set<Type>, Type>::type&
  25. add(Type& object, const typename Type::value_type& operand)
  26. {
  27. object.insert(operand);
  28. return object;
  29. }
  30. /** \c add add \c operand into the map using \c prior as a hint to
  31. insert \c operand after the position \c prior is pointing to. */
  32. template <class Type>
  33. typename enable_if<is_element_set<Type>, typename Type::iterator>::type
  34. add(Type& object, typename Type::iterator prior,
  35. const typename Type::value_type& operand)
  36. {
  37. return object.insert(prior, operand);
  38. }
  39. //==============================================================================
  40. //= Subtraction
  41. //==============================================================================
  42. /** If the \c operand's key value is in the map, it's data value is
  43. subtraced from the data value stored in the map. */
  44. template<class Type>
  45. typename enable_if<is_element_set<Type>, Type>::type&
  46. subtract(Type& object, const typename Type::value_type& operand)
  47. {
  48. object.erase(operand);
  49. return object;
  50. }
  51. //==============================================================================
  52. //= Intersection
  53. //==============================================================================
  54. template<class Type>
  55. inline typename enable_if<is_element_set<Type>, bool>::type
  56. intersects(const Type& object, const typename Type::key_type& operand)
  57. {
  58. return !(object.find(operand) == object.end());
  59. }
  60. template<class Type>
  61. inline typename enable_if<is_element_set<Type>, bool>::type
  62. intersects(const Type& object, const Type& operand)
  63. {
  64. if(iterative_size(object) < iterative_size(operand))
  65. return Set::intersects(object, operand);
  66. else
  67. return Set::intersects(operand, object);
  68. }
  69. //==============================================================================
  70. //= Symmetric difference
  71. //==============================================================================
  72. template<class Type>
  73. inline typename enable_if<is_element_set<Type>, Type>::type&
  74. flip(Type& object, const typename Type::value_type& operand)
  75. {
  76. typedef typename Type::iterator iterator;
  77. std::pair<iterator,bool> insertion = object.insert(operand);
  78. if(!insertion.second)
  79. object.erase(insertion.first);
  80. return object;
  81. }
  82. template<class Type>
  83. inline typename enable_if<is_element_set<Type>, Type>::type&
  84. operator ^= (Type& object, const typename Type::element_type& operand)
  85. {
  86. return icl::flip(object, operand);
  87. }
  88. /** Symmetric subtract map \c x2 and \c *this.
  89. So \c *this becomes the symmetric difference of \c *this and \c x2 */
  90. template<class Type>
  91. inline typename enable_if<is_element_set<Type>, Type>::type&
  92. operator ^= (Type& object, const Type& operand)
  93. {
  94. typedef typename Type::const_iterator const_iterator;
  95. const_iterator it_ = operand.begin();
  96. while(it_ != operand.end())
  97. icl::flip(object, *it_++);
  98. return object;
  99. }
  100. //==============================================================================
  101. //= Streaming<ElementSet>
  102. //==============================================================================
  103. template<class CharType, class CharTraits, class Type>
  104. inline typename enable_if<is_element_set<Type>, std::basic_ostream<CharType, CharTraits> >::type&
  105. operator << (std::basic_ostream<CharType, CharTraits>& stream, const Type& object)
  106. {
  107. stream << "{";
  108. ICL_const_FORALL(typename Type, it, object)
  109. stream << (*it) << " ";
  110. return stream << "}";
  111. }
  112. }} // namespace boost icl
  113. #endif