| /*-----------------------------------------------------------------------------+ |
| Copyright (c) 2008-2009: 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_IS_COMBINABLE_HPP_JOFA_090115 |
| #define BOOST_ICL_IS_COMBINABLE_HPP_JOFA_090115 |
| |
| #include <boost/mpl/bool.hpp> |
| #include <boost/mpl/if.hpp> |
| #include <boost/mpl/and.hpp> |
| #include <boost/mpl/or.hpp> |
| #include <boost/mpl/not.hpp> |
| #include <boost/type_traits/is_same.hpp> |
| #include <boost/icl/type_traits/is_concept_equivalent.hpp> |
| #include <boost/icl/type_traits/is_interval_container.hpp> |
| |
| namespace boost{namespace icl |
| { |
| |
| template<class Type> |
| struct is_overloadable |
| { |
| typedef is_overloadable<Type> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (boost::is_same<Type, typename Type::overloadable_type>::value) |
| ); |
| }; |
| |
| |
| //------------------------------------------------------------------------------ |
| template<class LeftT, class RightT> |
| struct is_codomain_equal |
| { |
| typedef is_codomain_equal<LeftT, RightT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (boost::is_same<typename LeftT::codomain_type, |
| typename RightT::codomain_type>::value) |
| ); |
| }; |
| |
| //NOTE: Equality of compare order implies the equality of the domain_types |
| template<class LeftT, class RightT> |
| struct is_key_compare_equal |
| { |
| typedef is_key_compare_equal<LeftT, RightT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (boost::is_same<typename LeftT::key_compare, |
| typename RightT::key_compare>::value) |
| ); |
| }; |
| |
| template<class LeftT, class RightT> |
| struct is_codomain_type_equal |
| { |
| typedef is_codomain_type_equal<LeftT, RightT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::and_<is_key_compare_equal<LeftT, RightT>, |
| is_codomain_equal<LeftT, RightT> >::value) |
| ); |
| }; |
| |
| |
| // For equal containers concepts, domain order and codomain type must match. |
| template<template<class>class IsConcept, class LeftT, class RightT> |
| struct is_concept_compatible |
| { |
| typedef is_concept_compatible<IsConcept, LeftT, RightT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::and_< |
| IsConcept<LeftT> |
| , IsConcept<RightT> |
| , is_codomain_type_equal<LeftT, RightT> |
| >::value) |
| ); |
| }; |
| |
| template<template<class>class LeftConcept, |
| template<class>class RightConcept, |
| class LeftT, class RightT> |
| struct is_concept_combinable |
| { |
| typedef is_concept_combinable<LeftConcept, RightConcept, LeftT, RightT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::and_< |
| LeftConcept<LeftT> |
| , RightConcept<RightT> |
| , is_key_compare_equal<LeftT, RightT> |
| >::value) |
| ); |
| }; |
| |
| template<class LeftT, class RightT> |
| struct is_intra_combinable |
| { |
| typedef is_intra_combinable<LeftT, RightT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_< |
| is_concept_compatible<is_interval_set, LeftT, RightT> |
| , is_concept_compatible<is_interval_map, LeftT, RightT> |
| >::value) |
| ); |
| }; |
| |
| //------------------------------------------------------------------------------ |
| |
| |
| //------------------------------------------------------------------------------ |
| template<class LeftT, class RightT> |
| struct is_cross_combinable |
| { |
| typedef is_cross_combinable<LeftT, RightT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_< |
| is_concept_combinable<is_interval_set, is_interval_map, LeftT, RightT> |
| , is_concept_combinable<is_interval_map, is_interval_set, LeftT, RightT> |
| >::value) |
| ); |
| }; |
| |
| template<class LeftT, class RightT> |
| struct is_inter_combinable |
| { |
| typedef is_inter_combinable<LeftT, RightT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_<is_intra_combinable<LeftT,RightT>, |
| is_cross_combinable<LeftT,RightT> >::value) |
| ); |
| }; |
| |
| //------------------------------------------------------------------------------ |
| // is_fragment_of |
| //------------------------------------------------------------------------------ |
| template<class FragmentT, class Type> |
| struct is_fragment_of |
| { |
| typedef is_fragment_of type; |
| BOOST_STATIC_CONSTANT(bool, value = false); |
| }; |
| |
| template<class Type> |
| struct is_fragment_of<typename Type::element_type, Type> |
| { |
| typedef is_fragment_of type; |
| BOOST_STATIC_CONSTANT(bool, value = true); |
| }; |
| |
| template<class Type> |
| struct is_fragment_of<typename Type::segment_type, Type> |
| { |
| typedef is_fragment_of type; |
| BOOST_STATIC_CONSTANT(bool, value = true); |
| }; |
| |
| //------------------------------------------------------------------------------ |
| // is_key_of |
| //------------------------------------------------------------------------------ |
| template<class KeyT, class Type> |
| struct is_key_of |
| { |
| typedef is_key_of type; |
| BOOST_STATIC_CONSTANT(bool, value = false); |
| }; |
| |
| template<class Type> |
| struct is_key_of<typename Type::domain_type, Type> |
| { |
| typedef is_key_of type; |
| BOOST_STATIC_CONSTANT(bool, value = true); |
| }; |
| |
| template<class Type> |
| struct is_key_of<typename Type::interval_type, Type> |
| { |
| typedef is_key_of type; |
| BOOST_STATIC_CONSTANT(bool, value = true); |
| }; |
| |
| //------------------------------------------------------------------------------ |
| // is_interval_set_derivative |
| //------------------------------------------------------------------------------ |
| template<class Type, class AssociateT> |
| struct is_interval_set_derivative; |
| |
| template<class Type> |
| struct is_interval_set_derivative<Type, typename Type::domain_type> |
| { |
| typedef is_interval_set_derivative type; |
| BOOST_STATIC_CONSTANT(bool, value = (is_interval_container<Type>::value)); |
| }; |
| |
| template<class Type> |
| struct is_interval_set_derivative<Type, typename Type::interval_type> |
| { |
| typedef is_interval_set_derivative type; |
| BOOST_STATIC_CONSTANT(bool, value = (is_interval_container<Type>::value)); |
| }; |
| |
| template<class Type, class AssociateT> |
| struct is_interval_set_derivative |
| { |
| typedef is_interval_set_derivative<Type, AssociateT> type; |
| BOOST_STATIC_CONSTANT(bool, value = false); |
| }; |
| |
| //------------------------------------------------------------------------------ |
| // is_interval_map_derivative |
| //------------------------------------------------------------------------------ |
| template<class Type, class AssociateT> |
| struct is_interval_map_derivative; |
| |
| template<class Type> |
| struct is_interval_map_derivative<Type, typename Type::domain_mapping_type> |
| { |
| typedef is_interval_map_derivative type; |
| BOOST_STATIC_CONSTANT(bool, value = (is_interval_container<Type>::value)); |
| }; |
| |
| template<class Type> |
| struct is_interval_map_derivative<Type, typename Type::interval_mapping_type> |
| { |
| typedef is_interval_map_derivative type; |
| BOOST_STATIC_CONSTANT(bool, value = (is_interval_container<Type>::value)); |
| }; |
| |
| template<class Type> |
| struct is_interval_map_derivative<Type, typename Type::value_type> |
| { |
| typedef is_interval_map_derivative type; |
| BOOST_STATIC_CONSTANT(bool, value = (is_interval_container<Type>::value)); |
| }; |
| |
| template<class Type, class AssociateT> |
| struct is_interval_map_derivative |
| { |
| typedef is_interval_map_derivative<Type, AssociateT> type; |
| BOOST_STATIC_CONSTANT(bool, value = false); |
| }; |
| |
| //------------------------------------------------------------------------------ |
| // is_intra_derivative |
| //------------------------------------------------------------------------------ |
| template<class Type, class AssociateT> |
| struct is_intra_derivative |
| { |
| typedef is_intra_derivative<Type, AssociateT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_ |
| < |
| mpl::and_<is_interval_set<Type>, |
| is_interval_set_derivative<Type, AssociateT> > |
| , mpl::and_<is_interval_map<Type>, |
| is_interval_map_derivative<Type, AssociateT> > |
| >::value) |
| ); |
| }; |
| |
| template<class Type, class AssociateT> |
| struct is_cross_derivative |
| { |
| typedef is_cross_derivative<Type, AssociateT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::and_< |
| is_interval_map<Type> |
| , is_interval_set_derivative<Type, AssociateT> |
| >::value) |
| ); |
| }; |
| |
| template<class Type, class AssociateT> |
| struct is_inter_derivative |
| { |
| typedef is_inter_derivative<Type, AssociateT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_< |
| is_intra_derivative<Type, AssociateT> |
| , is_cross_derivative<Type, AssociateT> |
| >::value) |
| ); |
| }; |
| |
| //------------------------------------------------------------------------------ |
| //- right combinable |
| //------------------------------------------------------------------------------ |
| |
| template<class GuideT, class CompanionT> |
| struct is_interval_set_right_combinable |
| { |
| typedef is_interval_set_right_combinable<GuideT, CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::and_ |
| < |
| is_interval_set<GuideT> |
| , mpl::or_ |
| < |
| is_interval_set_derivative<GuideT, CompanionT> |
| , is_concept_compatible<is_interval_set, GuideT, CompanionT> |
| > |
| >::value) |
| ); |
| }; |
| |
| template<class GuideT, class CompanionT> |
| struct is_interval_map_right_intra_combinable //NOTE equivalent to is_fragment_type_of |
| { |
| typedef is_interval_map_right_intra_combinable<GuideT, CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::and_ |
| < |
| is_interval_map<GuideT> |
| , mpl::or_ |
| < |
| is_interval_map_derivative<GuideT, CompanionT> |
| , is_concept_compatible<is_interval_map, GuideT, CompanionT> |
| > |
| >::value) |
| ); |
| }; |
| |
| template<class GuideT, class CompanionT> |
| struct is_interval_map_right_cross_combinable //NOTE equivalent to key_type_of<Comp, Guide> |
| { |
| typedef is_interval_map_right_cross_combinable<GuideT, CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::and_ |
| < |
| is_interval_map<GuideT> |
| , mpl::or_ |
| < |
| is_cross_derivative<GuideT, CompanionT> |
| , is_concept_combinable<is_interval_map, is_interval_set, GuideT, CompanionT> |
| > |
| >::value) |
| ); |
| }; |
| |
| template<class GuideT, class CompanionT> |
| struct is_interval_map_right_inter_combinable |
| { |
| typedef is_interval_map_right_inter_combinable<GuideT, CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_< |
| is_interval_map_right_intra_combinable<GuideT, CompanionT> |
| , is_interval_map_right_cross_combinable<GuideT, CompanionT> |
| >::value) |
| ); |
| }; |
| |
| |
| template<class GuideT, class CompanionT> |
| struct is_right_intra_combinable |
| { |
| typedef is_right_intra_combinable<GuideT, CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_ |
| < |
| is_interval_set_right_combinable<GuideT, CompanionT> |
| , is_interval_map_right_intra_combinable<GuideT, CompanionT> |
| >::value) |
| ); |
| }; |
| |
| template<class GuideT, class CompanionT> |
| struct is_right_inter_combinable |
| { |
| typedef is_right_inter_combinable<GuideT, CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_ |
| < |
| is_interval_set_right_combinable<GuideT, CompanionT> |
| , is_interval_map_right_inter_combinable<GuideT, CompanionT> |
| >::value) |
| ); |
| }; |
| |
| template<class GuideT, class IntervalSetT> |
| struct combines_right_to_interval_set |
| { |
| typedef combines_right_to_interval_set<GuideT, IntervalSetT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (is_concept_combinable<is_interval_container, is_interval_set, |
| GuideT, IntervalSetT>::value) |
| ); |
| }; |
| |
| template<class GuideT, class IntervalMapT> |
| struct combines_right_to_interval_map |
| { |
| typedef combines_right_to_interval_map<GuideT, IntervalMapT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (is_concept_compatible<is_interval_map, GuideT, IntervalMapT>::value) ); |
| }; |
| |
| template<class GuideT, class IntervalContainerT> |
| struct combines_right_to_interval_container |
| { |
| typedef combines_right_to_interval_container<GuideT, IntervalContainerT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_<combines_right_to_interval_set<GuideT, IntervalContainerT>, |
| combines_right_to_interval_map<GuideT, IntervalContainerT> >::value) |
| ); |
| }; |
| |
| |
| |
| //------------------------------------------------------------------------------ |
| //- segmentational_fineness |
| //------------------------------------------------------------------------------ |
| template<class Type> struct unknown_fineness |
| { |
| typedef unknown_fineness<Type> type; |
| static const int value = 0; |
| }; |
| |
| template<class Type> struct known_fineness |
| { |
| typedef known_fineness<Type> type; |
| static const int value = Type::fineness; |
| }; |
| |
| template<class Type>struct segmentational_fineness |
| { |
| typedef segmentational_fineness<Type> type; |
| static const int value = |
| mpl::if_<is_interval_container<Type>, |
| known_fineness<Type>, |
| unknown_fineness<Type> |
| >::type::value; |
| }; |
| |
| |
| //------------------------------------------------------------------------------ |
| // is_interval_set_companion |
| //------------------------------------------------------------------------------ |
| |
| // CompanionT is either an interval_set or a derivative of set level: |
| // element_type=domain_type, segment_type=interval_type |
| template<class GuideT, class CompanionT> struct is_interval_set_companion |
| { |
| typedef is_interval_set_companion<GuideT,CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_ |
| < |
| combines_right_to_interval_set<GuideT,CompanionT> |
| , is_interval_set_derivative<GuideT,CompanionT> |
| >::value) |
| ); |
| }; |
| |
| |
| //------------------------------------------------------------------------------ |
| // is_interval_map_companion |
| //------------------------------------------------------------------------------ |
| |
| template<class GuideT, class CompanionT> struct is_interval_map_companion |
| { |
| typedef is_interval_map_companion<GuideT,CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_ |
| < |
| combines_right_to_interval_map<GuideT,CompanionT> |
| , is_interval_map_derivative<GuideT,CompanionT> |
| >::value) |
| ); |
| }; |
| |
| |
| //------------------------------------------------------------------------------ |
| //- is_coarser_interval_{set,map}_companion |
| //------------------------------------------------------------------------------ |
| template<class GuideT, class CompanionT> |
| struct is_coarser_interval_set_companion |
| { |
| typedef is_coarser_interval_set_companion<GuideT, CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::and_ |
| < |
| is_interval_set_companion<GuideT, CompanionT> |
| , mpl::bool_<( segmentational_fineness<GuideT>::value |
| > segmentational_fineness<CompanionT>::value)> |
| >::value) |
| ); |
| }; |
| |
| template<class GuideT, class CompanionT> |
| struct is_coarser_interval_map_companion |
| { |
| typedef is_coarser_interval_map_companion<GuideT, CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::and_ |
| < |
| is_interval_map_companion<GuideT, CompanionT> |
| , mpl::bool_<( segmentational_fineness<GuideT>::value |
| > segmentational_fineness<CompanionT>::value)> |
| >::value) |
| ); |
| }; |
| |
| //------------------------------------------------------------------------------ |
| // is_binary_interval_{set,map}_combinable |
| //------------------------------------------------------------------------------ |
| template<class GuideT, class CompanionT> |
| struct is_binary_interval_set_combinable |
| { |
| typedef is_binary_interval_set_combinable<GuideT,CompanionT> type; |
| static const int value = |
| mpl::and_< is_interval_set<GuideT> |
| , is_coarser_interval_set_companion<GuideT, CompanionT> |
| >::value; |
| }; |
| |
| template<class GuideT, class CompanionT> |
| struct is_binary_interval_map_combinable |
| { |
| typedef is_binary_interval_map_combinable<GuideT,CompanionT> type; |
| static const int value = |
| mpl::and_< is_interval_map<GuideT> |
| , is_coarser_interval_map_companion<GuideT, CompanionT> |
| >::value; |
| }; |
| |
| template<class GuideT, class CompanionT> |
| struct is_binary_intra_combinable |
| { |
| typedef is_binary_intra_combinable<GuideT,CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_<is_binary_interval_set_combinable<GuideT, CompanionT>, |
| is_binary_interval_map_combinable<GuideT, CompanionT> |
| >::value) |
| ); |
| }; |
| |
| template<class GuideT, class CompanionT> |
| struct is_binary_cross_combinable |
| { |
| typedef is_binary_cross_combinable<GuideT,CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::and_ |
| < is_interval_map<GuideT> |
| , mpl::or_< is_coarser_interval_map_companion<GuideT, CompanionT> |
| , is_interval_set_companion<GuideT, CompanionT> > |
| >::value) |
| ); |
| }; |
| |
| template<class GuideT, class CompanionT> |
| struct is_binary_inter_combinable |
| { |
| typedef is_binary_inter_combinable<GuideT,CompanionT> type; |
| BOOST_STATIC_CONSTANT(bool, value = |
| (mpl::or_ |
| < |
| mpl::and_<is_interval_map<GuideT>, |
| is_binary_cross_combinable<GuideT, CompanionT> > |
| , mpl::and_<is_interval_set<GuideT>, |
| is_binary_intra_combinable<GuideT, CompanionT> > |
| >::value) |
| ); |
| }; |
| |
| |
| }} // namespace icl boost |
| |
| #endif |
| |
| |