135 lines
4.7 KiB
C++
135 lines
4.7 KiB
C++
|
/*-----------------------------------------------------------------------------+
|
||
|
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
|
||
|
|
||
|
|