mirror of
https://github.com/yuzu-emu/ext-boost.git
synced 2024-12-23 09:45:32 +00:00
135 lines
4.6 KiB
C++
135 lines
4.6 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
|
|
|
|
|