You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
134 lines
4.6 KiB
134 lines
4.6 KiB
/*-----------------------------------------------------------------------------+ |
|
Copyright (c) 2010-2010: Joachim Faulhaber |
|
+------------------------------------------------------------------------------+ |
|
Distributed under the Boost Software License, Version 1.0. |
|
(See accompanying file LICENCE.txt or copy at |
|
http://www.boost.org/LICENSE_1_0.txt) |
|
+-----------------------------------------------------------------------------*/ |
|
#ifndef BOOST_ICL_CONCEPT_ELEMENT_SET_HPP_JOFA_100921 |
|
#define BOOST_ICL_CONCEPT_ELEMENT_SET_HPP_JOFA_100921 |
|
|
|
#include <boost/icl/type_traits/is_combinable.hpp> |
|
#include <boost/icl/concept/set_value.hpp> |
|
#include <boost/icl/detail/std_set.hpp> |
|
#include <boost/icl/detail/set_algo.hpp> |
|
|
|
|
|
namespace boost{ namespace icl |
|
{ |
|
|
|
//============================================================================== |
|
//= Addition<ElementSet> |
|
//============================================================================== |
|
/** \c add inserts \c operand into the map if it's key does |
|
not exist in the map. |
|
If \c operands's key value exists in the map, it's data |
|
value is added to the data value already found in the map. */ |
|
template <class Type> |
|
typename enable_if<is_element_set<Type>, Type>::type& |
|
add(Type& object, const typename Type::value_type& operand) |
|
{ |
|
object.insert(operand); |
|
return object; |
|
} |
|
|
|
/** \c add add \c operand into the map using \c prior as a hint to |
|
insert \c operand after the position \c prior is pointing to. */ |
|
template <class Type> |
|
typename enable_if<is_element_set<Type>, typename Type::iterator>::type |
|
add(Type& object, typename Type::iterator prior, |
|
const typename Type::value_type& operand) |
|
{ |
|
return object.insert(prior, operand); |
|
} |
|
|
|
//============================================================================== |
|
//= Subtraction |
|
//============================================================================== |
|
/** If the \c operand's key value is in the map, it's data value is |
|
subtraced from the data value stored in the map. */ |
|
template<class Type> |
|
typename enable_if<is_element_set<Type>, Type>::type& |
|
subtract(Type& object, const typename Type::value_type& operand) |
|
{ |
|
object.erase(operand); |
|
return object; |
|
} |
|
|
|
|
|
//============================================================================== |
|
//= Intersection |
|
//============================================================================== |
|
template<class Type> |
|
inline typename enable_if<is_element_set<Type>, bool>::type |
|
intersects(const Type& object, const typename Type::key_type& operand) |
|
{ |
|
return !(object.find(operand) == object.end()); |
|
} |
|
|
|
template<class Type> |
|
inline typename enable_if<is_element_set<Type>, bool>::type |
|
intersects(const Type& object, const Type& operand) |
|
{ |
|
if(iterative_size(object) < iterative_size(operand)) |
|
return Set::intersects(object, operand); |
|
else |
|
return Set::intersects(operand, object); |
|
} |
|
|
|
//============================================================================== |
|
//= Symmetric difference |
|
//============================================================================== |
|
template<class Type> |
|
inline typename enable_if<is_element_set<Type>, Type>::type& |
|
flip(Type& object, const typename Type::value_type& operand) |
|
{ |
|
typedef typename Type::iterator iterator; |
|
std::pair<iterator,bool> insertion = object.insert(operand); |
|
if(!insertion.second) |
|
object.erase(insertion.first); |
|
|
|
return object; |
|
} |
|
|
|
template<class Type> |
|
inline typename enable_if<is_element_set<Type>, Type>::type& |
|
operator ^= (Type& object, const typename Type::element_type& operand) |
|
{ |
|
return icl::flip(object, operand); |
|
} |
|
|
|
/** Symmetric subtract map \c x2 and \c *this. |
|
So \c *this becomes the symmetric difference of \c *this and \c x2 */ |
|
template<class Type> |
|
inline typename enable_if<is_element_set<Type>, Type>::type& |
|
operator ^= (Type& object, const Type& operand) |
|
{ |
|
typedef typename Type::const_iterator const_iterator; |
|
const_iterator it_ = operand.begin(); |
|
while(it_ != operand.end()) |
|
icl::flip(object, *it_++); |
|
|
|
return object; |
|
} |
|
|
|
//============================================================================== |
|
//= Streaming<ElementSet> |
|
//============================================================================== |
|
template<class CharType, class CharTraits, class Type> |
|
inline typename enable_if<is_element_set<Type>, std::basic_ostream<CharType, CharTraits> >::type& |
|
operator << (std::basic_ostream<CharType, CharTraits>& stream, const Type& object) |
|
{ |
|
stream << "{"; |
|
ICL_const_FORALL(typename Type, it, object) |
|
stream << (*it) << " "; |
|
|
|
return stream << "}"; |
|
} |
|
|
|
|
|
}} // namespace boost icl |
|
|
|
#endif |
|
|
|
|
|
|