]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
11 | #include <boost/icl/type_traits/is_combinable.hpp> | |
12 | #include <boost/icl/concept/set_value.hpp> | |
13 | #include <boost/icl/detail/std_set.hpp> | |
14 | #include <boost/icl/detail/set_algo.hpp> | |
15 | ||
16 | ||
17 | namespace boost{ namespace icl | |
18 | { | |
19 | ||
20 | //============================================================================== | |
21 | //= Addition<ElementSet> | |
22 | //============================================================================== | |
23 | /** \c add inserts \c operand into the map if it's key does | |
24 | not exist in the map. | |
25 | If \c operands's key value exists in the map, it's data | |
26 | value is added to the data value already found in the map. */ | |
27 | template <class Type> | |
28 | typename enable_if<is_element_set<Type>, Type>::type& | |
29 | add(Type& object, const typename Type::value_type& operand) | |
30 | { | |
31 | object.insert(operand); | |
32 | return object; | |
33 | } | |
34 | ||
35 | /** \c add add \c operand into the map using \c prior as a hint to | |
36 | insert \c operand after the position \c prior is pointing to. */ | |
37 | template <class Type> | |
38 | typename enable_if<is_element_set<Type>, typename Type::iterator>::type | |
39 | add(Type& object, typename Type::iterator prior, | |
40 | const typename Type::value_type& operand) | |
41 | { | |
42 | return object.insert(prior, operand); | |
43 | } | |
44 | ||
45 | //============================================================================== | |
46 | //= Subtraction | |
47 | //============================================================================== | |
48 | /** If the \c operand's key value is in the map, it's data value is | |
49 | subtraced from the data value stored in the map. */ | |
50 | template<class Type> | |
51 | typename enable_if<is_element_set<Type>, Type>::type& | |
52 | subtract(Type& object, const typename Type::value_type& operand) | |
53 | { | |
54 | object.erase(operand); | |
55 | return object; | |
56 | } | |
57 | ||
58 | ||
59 | //============================================================================== | |
60 | //= Intersection | |
61 | //============================================================================== | |
62 | template<class Type> | |
63 | inline typename enable_if<is_element_set<Type>, bool>::type | |
64 | intersects(const Type& object, const typename Type::key_type& operand) | |
65 | { | |
66 | return !(object.find(operand) == object.end()); | |
67 | } | |
68 | ||
69 | template<class Type> | |
70 | inline typename enable_if<is_element_set<Type>, bool>::type | |
71 | intersects(const Type& object, const Type& operand) | |
72 | { | |
73 | if(iterative_size(object) < iterative_size(operand)) | |
74 | return Set::intersects(object, operand); | |
75 | else | |
76 | return Set::intersects(operand, object); | |
77 | } | |
78 | ||
79 | //============================================================================== | |
80 | //= Symmetric difference | |
81 | //============================================================================== | |
82 | template<class Type> | |
83 | inline typename enable_if<is_element_set<Type>, Type>::type& | |
84 | flip(Type& object, const typename Type::value_type& operand) | |
85 | { | |
86 | typedef typename Type::iterator iterator; | |
87 | std::pair<iterator,bool> insertion = object.insert(operand); | |
88 | if(!insertion.second) | |
89 | object.erase(insertion.first); | |
90 | ||
91 | return object; | |
92 | } | |
93 | ||
94 | template<class Type> | |
95 | inline typename enable_if<is_element_set<Type>, Type>::type& | |
96 | operator ^= (Type& object, const typename Type::element_type& operand) | |
97 | { | |
98 | return icl::flip(object, operand); | |
99 | } | |
100 | ||
101 | /** Symmetric subtract map \c x2 and \c *this. | |
102 | So \c *this becomes the symmetric difference of \c *this and \c x2 */ | |
103 | template<class Type> | |
104 | inline typename enable_if<is_element_set<Type>, Type>::type& | |
105 | operator ^= (Type& object, const Type& operand) | |
106 | { | |
107 | typedef typename Type::const_iterator const_iterator; | |
108 | const_iterator it_ = operand.begin(); | |
109 | while(it_ != operand.end()) | |
110 | icl::flip(object, *it_++); | |
111 | ||
112 | return object; | |
113 | } | |
114 | ||
115 | //============================================================================== | |
116 | //= Streaming<ElementSet> | |
117 | //============================================================================== | |
118 | template<class CharType, class CharTraits, class Type> | |
119 | inline typename enable_if<is_element_set<Type>, std::basic_ostream<CharType, CharTraits> >::type& | |
120 | operator << (std::basic_ostream<CharType, CharTraits>& stream, const Type& object) | |
121 | { | |
122 | stream << "{"; | |
123 | ICL_const_FORALL(typename Type, it, object) | |
124 | stream << (*it) << " "; | |
125 | ||
126 | return stream << "}"; | |
127 | } | |
128 | ||
129 | ||
130 | }} // namespace boost icl | |
131 | ||
132 | #endif | |
133 | ||
134 |