Files

182 lines
4.1 KiB
C++
Raw Permalink Normal View History

2003-10-24 09:54:09 +00:00
// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
2003-10-23 15:24:32 +00:00
#include <boost/named_params.hpp>
#include <cassert>
#include <string.h>
2004-01-17 14:15:09 +00:00
#include <boost/bind.hpp>
2004-01-14 21:22:50 +00:00
#include <boost/ref.hpp>
2004-11-05 14:09:28 +00:00
#include <boost/static_assert.hpp>
2003-10-23 15:24:32 +00:00
2003-10-23 23:13:00 +00:00
namespace test
{
2005-03-26 08:44:37 +00:00
using namespace boost::named_params;
keyword<struct name_> name;
keyword<struct value_> value;
keyword<struct index_> index;
keyword<struct tester_> tester;
2003-10-23 15:24:32 +00:00
2005-03-28 03:11:26 +00:00
struct f_parameters // vc6 is happier with inheritance than with a typedef
: parameters<
2005-03-26 08:44:37 +00:00
tester_
, name_
, value_
, index_
2003-10-23 23:13:00 +00:00
>
{};
2003-10-23 15:24:32 +00:00
2004-01-17 14:15:09 +00:00
double value_default()
2004-01-14 21:22:50 +00:00
{
2004-01-17 14:15:09 +00:00
return 666.222;
}
2003-10-23 23:13:00 +00:00
template<class Params>
int f_impl(const Params& p)
2004-01-14 21:22:50 +00:00
{
2003-10-23 23:13:00 +00:00
p[tester](
p[name]
2004-01-17 14:15:09 +00:00
, p[value || boost::bind(&value_default) ]
2005-03-26 08:44:37 +00:00
// , p[value | 666.222 ]
, p[index | 999 ]
2003-10-23 23:13:00 +00:00
);
return 1;
}
2003-10-23 15:24:32 +00:00
2003-10-23 23:13:00 +00:00
template<class Tester, class Name, class Value, class Index>
2004-01-17 14:15:09 +00:00
int f(Tester const& t, const Name& name_,
const Value& value_, const Index& index_)
2003-10-23 23:13:00 +00:00
{
2005-03-28 03:11:26 +00:00
return f_impl(f_parameters()(t, name_, value_, index_));
2003-10-23 23:13:00 +00:00
}
2003-10-23 15:24:32 +00:00
2003-10-23 23:13:00 +00:00
template<class Tester, class Name, class Value>
2004-01-17 14:15:09 +00:00
int f(Tester const& t, const Name& name_, const Value& value_)
2003-10-23 23:13:00 +00:00
{
2005-03-28 03:11:26 +00:00
return f_impl(f_parameters()(t, name_, value_));
2003-10-23 23:13:00 +00:00
}
2003-10-23 15:24:32 +00:00
2003-10-23 23:13:00 +00:00
template<class Tester, class Name>
2004-01-17 14:15:09 +00:00
int f(Tester const& t, const Name& name_)
2003-10-23 23:13:00 +00:00
{
2005-03-28 03:11:26 +00:00
return f_impl(f_parameters()(t, name_));
2003-10-23 23:13:00 +00:00
}
template<class Params>
int f_list(Params const& params)
{
return f_impl(params);
}
2003-10-23 23:13:00 +00:00
template <class T>
bool equal(T const& x, T const& y)
{
return x == y;
}
bool equal(char const* s1, char const* s2)
{
return !strcmp(s1,s2);
2003-10-23 23:13:00 +00:00
}
template <class Name, class Value, class Index>
struct values_t
{
values_t(Name const& n, Value const& v, Index const& i)
: n(n), v(v), i(i)
{}
2004-01-14 21:22:50 +00:00
2003-10-23 23:13:00 +00:00
template <class Name_, class Value_, class Index_>
void operator()(Name_ const& n_, Value_ const& v_, Index_ const& i_) const
{
2004-01-16 23:47:15 +00:00
// Only VC and its emulators fail this; they seem to have
// problems with deducing the constness of string literal
// arrays.
#if defined(_MSC_VER) \
&& (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) \
|| BOOST_WORKAROUND(BOOST_MSVC, < 1310))
# else
BOOST_STATIC_ASSERT((boost::is_same<Index,Index_>::value));
BOOST_STATIC_ASSERT((boost::is_same<Value,Value_>::value));
BOOST_STATIC_ASSERT((boost::is_same<Name,Name_>::value));
#endif
2003-10-23 23:13:00 +00:00
assert(equal(n, n_));
assert(equal(v, v_));
assert(equal(i, i_));
}
Name const& n;
Value const& v;
Index const& i;
};
template <class Name, class Value, class Index>
values_t<Name,Value,Index>
values(Name const& n, Value const& v, Index const& i)
{
return values_t<Name,Value,Index>(n,v,i);
}
2005-03-26 08:44:37 +00:00
2005-03-28 03:11:26 +00:00
typedef f_parameters g_parameters;
2005-03-26 08:44:37 +00:00
template<class Args>
int g_impl(Args const& args)
{
return f(args);
}
template<class A0>
int g(A0 const& a0)
{
2005-03-28 03:11:26 +00:00
return g_impl(g_parameters(a0));
2005-03-26 08:44:37 +00:00
}
template<class A0, class A1>
int g(A0 const& a0, A1 const& a1)
{
2005-03-28 03:11:26 +00:00
return g_impl(g_parameters(a0, a1));
2005-03-26 08:44:37 +00:00
}
2003-10-23 15:24:32 +00:00
}
2004-01-16 23:47:15 +00:00
// GCC2 has a problem with char (&)[] deduction, so we'll cast string
// literals there.
#undef S
#if BOOST_WORKAROUND(__GNUC__, == 2)
# define S(s) (char const*)s
#else
# define S(s) s
#endif
2003-10-23 15:24:32 +00:00
int main()
{
using test::f;
2004-04-20 16:18:49 +00:00
using test::f_list;
2003-10-23 15:24:32 +00:00
using test::name;
using test::value;
using test::index;
2003-10-23 23:13:00 +00:00
using test::tester;
2003-10-23 15:24:32 +00:00
2003-10-23 23:13:00 +00:00
f(
2004-01-16 23:47:15 +00:00
test::values(S("foo"), S("bar"), S("baz"))
, S("foo"), S("bar"), S("baz")
2003-10-23 23:13:00 +00:00
);
2004-01-16 23:47:15 +00:00
int x = 56;
2003-10-23 23:13:00 +00:00
f(
test::values("foo", 666.222, 56)
2004-01-16 23:47:15 +00:00
, index = boost::ref(x), name = "foo"
2003-10-23 23:13:00 +00:00
);
f_list((
tester = test::values("foo", 666.222, 56)
, index = boost::ref(x)
, name = "foo"
));
2003-10-23 23:13:00 +00:00
2003-10-23 15:24:32 +00:00
//f(index = 56, name = 55); // won't compile
2003-10-23 16:23:46 +00:00
return 0;
2003-10-23 15:24:32 +00:00
}