|
Boost : |
From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2004-09-19 06:17:47
Tobias Schwinger wrote:
> I attached some experimental source code
Hrm... Did I ? ;+)
Here's the missing attachment
#include <boost/config.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/config.hpp>
#include <boost/type_traits/add_reference.hpp>
using namespace boost;
/////////////////////////////////////////////////////////////////////////////
// Type categories
struct integral
{
integral(char);
integral(short);
integral(int);
integral(long);
};
struct real
{
real(float);
real(double);
};
struct pointer
{
template <typename T>
pointer(T*);
};
/////////////////////////////////////////////////////////////////////////////
// States of the filter
enum { pass = 1, filter_true = 2, filter_false = 3 };
typedef char (& pass_type ) [pass];
typedef char (& filter_true_type ) [filter_true];
typedef char (& filter_false_type ) [filter_false];
/////////////////////////////////////////////////////////////////////////////
// Filtering rule set
pass_type BOOST_TT_DECL filter(...);
// type combinations matching builtin types
filter_true_type filter(integral,integral);
filter_true_type filter(integral,pointer);
filter_true_type filter(integral,real);
filter_true_type filter(real,integral);
filter_true_type filter(real,real);
filter_true_type filter(pointer,integral);
// impossible type combinations
filter_false_type filter(real,pointer);
filter_false_type filter(pointer,real);
filter_false_type filter(pointer,pointer);
/////////////////////////////////////////////////////////////////////////////
// The filter implementation
template <typename T1, typename T2, typename Operation>
struct op_test_input_filter
{
private:
static typename add_reference<T1>::type arg1;
static typename add_reference<T2>::type arg2;
BOOST_STATIC_CONSTANT(int, state = ( sizeof(filter(arg1, arg2)) ));
public:
typedef typename mpl::eval_if_c< (state == pass)
, typename Operation::apply<T1,T2>
, mpl::bool_<state == filter_true>
>::type type;
BOOST_STATIC_CONSTANT(bool, value = ( type::value ));
};
// Specializations for void arguments could come here.
/////////////////////////////////////////////////////////////////////////////
// Test for the filter implementation above
// These are used in place of a "real" operator checker to test the filtering
// behaviour.
struct always // ::type is always mpl::bool_<true> regardless of the argumetns
{
template <typename T1, typename T2>
struct apply
{
typedef mpl::bool_<true> type;
};
};
struct never // ::type is always mpl::bool_<false> regardless of the arguments
{
template <typename T1, typename T2>
struct apply
{
typedef mpl::bool_<false> type;
};
};
struct illegal // is not instantiatable
{
template <typename T1, typename T2>
struct apply
{
BOOST_STATIC_ASSERT(false);
};
};
// If the combination of type arguments is matched by the filter, the result
// must not depend on the specified operation.
#define ASSERT_FILTER(type1,type2) \
BOOST_STATIC_ASSERT(( op_test_input_filter<type1,type2,always>::value \
== op_test_input_filter<type1,type2,never>::value ))
// The combination of type arguments is matched by the filter and the result
// is "true". The operation passed results in an error when instantiated.
#define ASSERT_FILTER_TRUE_RESULT(type1,type2) \
ASSERT_FILTER(type1,type2); \
BOOST_STATIC_ASSERT(( op_test_input_filter<type1,type2,illegal>::value ))
// The combination of type arguments is matched by the filter and the result
// is "false". The operation passed results in an error when instantiated.
#define ASSERT_FILTER_FALSE_RESULT(type1,type2) \
ASSERT_FILTER(type1,type2); \
BOOST_STATIC_ASSERT(!( op_test_input_filter<type1,type2,illegal>::value ))
// If the combination of type arguments is unmatched by the filter, the
// result must only depend on the specified operation.
#define ASSERT_PASS(type1,type2) \
BOOST_STATIC_ASSERT(( op_test_input_filter<type1,type2,always>::value \
!= op_test_input_filter<type1,type2,never>::value ))
struct foo { };
struct bar { };
int main()
{
ASSERT_PASS(foo,bar);
ASSERT_PASS(foo,foo);
ASSERT_FILTER_TRUE_RESULT(int,int);
ASSERT_FILTER_TRUE_RESULT(char,int);
ASSERT_FILTER_TRUE_RESULT(char,char);
ASSERT_FILTER_TRUE_RESULT(int,int*);
ASSERT_FILTER_FALSE_RESULT(int*,float);
ASSERT_FILTER_FALSE_RESULT(int*,int*);
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk