569 lines
18 KiB
C++
Executable File
569 lines
18 KiB
C++
Executable File
/*-----------------------------------------------------------------------------+
|
|
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
|
|
|
|
|