/*-----------------------------------------------------------------------------+ 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 #include #include #include namespace boost{ namespace icl { //============================================================================== //= Addition //============================================================================== /** \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 typename enable_if, 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 typename enable_if, 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 typename enable_if, Type>::type& subtract(Type& object, const typename Type::value_type& operand) { object.erase(operand); return object; } //============================================================================== //= Intersection //============================================================================== template inline typename enable_if, bool>::type intersects(const Type& object, const typename Type::key_type& operand) { return !(object.find(operand) == object.end()); } template inline typename enable_if, 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 inline typename enable_if, Type>::type& flip(Type& object, const typename Type::value_type& operand) { typedef typename Type::iterator iterator; std::pair insertion = object.insert(operand); if(!insertion.second) object.erase(insertion.first); return object; } template inline typename enable_if, 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 inline typename enable_if, 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 //============================================================================== template inline typename enable_if, std::basic_ostream >::type& operator << (std::basic_ostream& stream, const Type& object) { stream << "{"; ICL_const_FORALL(typename Type, it, object) stream << (*it) << " "; return stream << "}"; } }} // namespace boost icl #endif