blob: a00b2d6ea858693f39460463064eb1658b35dc9a [file] [log] [blame]
/*-----------------------------------------------------------------------------+
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