Support for Borland C++

[SVN r29520]
This commit is contained in:
Dave Abrahams
2005-06-11 06:46:03 +00:00
parent 70762057b3
commit 74a5d3372b
13 changed files with 229 additions and 81 deletions

View File

@@ -136,6 +136,7 @@ struct arg_list : Next
{
typedef typename TaggedArg::key_type key_type;
typedef typename TaggedArg::value_type value_type;
typedef typename TaggedArg::reference reference;
TaggedArg arg; // Stores the argument
@@ -172,7 +173,7 @@ struct arg_list : Next
{
typedef typename mpl::eval_if<
boost::is_same<KW, key_type>
, add_reference<value_type>
, mpl::identity<reference>
, mpl::apply_wrap2<typename Next::binding, KW, Default>
>::type type;
};
@@ -239,38 +240,38 @@ struct arg_list : Next
// reached, indicating no matching argument was passed, the
// default is returned, or if no default_ or lazy_default was
// passed, compilation fails.
value_type& get(keyword<key_type> x) const
reference get(keyword<key_type> x) const
{
return arg.value;
}
template <class Default>
value_type& get(default_<key_type,Default> x) const
reference get(default_<key_type,Default> x) const
{
return arg.value;
}
template <class Default>
value_type& get(lazy_default<key_type, Default> x) const
reference get(lazy_default<key_type, Default> x) const
{
return arg.value;
}
#else
value_type& operator[](keyword<key_type> x) const
reference operator[](keyword<key_type> x) const
{
return arg.value;
}
template <class Default>
value_type& operator[](default_<key_type, Default> x) const
reference operator[](default_<key_type, Default> x) const
{
return arg.value;
}
template <class Default>
value_type& operator[](lazy_default<key_type, Default> x) const
reference operator[](lazy_default<key_type, Default> x) const
{
return arg.value;
}

View File

@@ -0,0 +1,40 @@
// Copyright David Abrahams 2005. Distributed under 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)
#ifndef BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP
# define BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP
# include <boost/parameter/aux_/unwrap_cv_reference.hpp>
namespace boost { namespace parameter { namespace aux {
template <class Keyword, class Arg>
struct tagged_argument;
template <class Keyword, class ActualArg
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, class = typename is_cv_reference_wrapper<ActualArg>::type
#endif
>
struct tag
{
typedef tagged_argument<
Keyword
, typename unwrap_cv_reference<ActualArg>::type
> type;
};
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Keyword, class ActualArg>
struct tag<Keyword,ActualArg,mpl::false_>
{
typedef tagged_argument<
Keyword
, ActualArg
> type;
};
#endif
}}} // namespace boost::parameter::aux_
#endif // BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP

View File

@@ -19,8 +19,9 @@ struct tagged_argument
{
typedef Keyword key_type;
typedef Arg value_type;
typedef Arg& reference;
tagged_argument(Arg& x) : value(x) {}
tagged_argument(reference x) : value(x) {}
// Comma operator to compose argument list without using parameters<>.
// Useful for argument lists with undetermined length.
@@ -39,8 +40,8 @@ struct tagged_argument
, arg_list<tagged_argument<Keyword2, Arg2> >(x, empty_arg_list())
);
}
Arg& value;
reference value;
};
// Defines a metafunction, is_tagged_argument, that identifies

View File

@@ -37,9 +37,19 @@ struct is_cv_reference_wrapper
)
);
typedef mpl::bool_<is_cv_reference_wrapper::value> type;
typedef mpl::bool_<
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
is_cv_reference_wrapper::
#endif
value> type;
};
#if BOOST_WORKAROUND(MSVC, == 1200)
template <>
struct is_cv_reference_wrapper<int>
: mpl::false_ {};
#endif
// Needed for unwrap_cv_reference below. T might be const, so
// eval_if might fail because of deriving from T const on EDG.
template <class T>
@@ -48,6 +58,25 @@ struct get_type
typedef typename T::type type;
};
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class T, class is_reference_wrapper = typename is_cv_reference_wrapper<T>::type>
struct unwrap_cv_reference
{
typedef T type;
};
template <class T>
struct unwrap_cv_reference<T const, mpl::false_>
{
typedef T const type;
};
template <class T>
struct unwrap_cv_reference<T, mpl::true_>
: T
{};
#else
// Produces the unwrapped type to hold a reference to in named<>
// Can't use boost::unwrap_reference<> here because it
// doesn't handle the case where T = reference_wrapper<U> cv
@@ -60,6 +89,7 @@ struct unwrap_cv_reference
, mpl::identity<T>
>::type type;
};
#endif
}}} // namespace boost::parameter::aux

View File

@@ -7,7 +7,7 @@
#define KEYWORD_050328_HPP
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
#include <boost/parameter/aux_/tagged_argument.hpp>
#include <boost/parameter/aux_/tag.hpp>
#include <boost/parameter/aux_/default.hpp>
namespace boost { namespace parameter {
@@ -31,16 +31,11 @@ template <class Tag>
struct keyword
{
template <class T>
aux::tagged_argument<
Tag
, typename aux::unwrap_cv_reference<T>::type
>
typename aux::tag<Tag, T>::type
operator=(T& x) const
{
return aux::tagged_argument<
Tag
, BOOST_DEDUCED_TYPENAME aux::unwrap_cv_reference<T>::type
>(x);
typedef typename aux::tag<Tag, T>::type result;
return result(x);
}
template <class Default>
@@ -59,16 +54,11 @@ struct keyword
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // avoid partial ordering bugs
template <class T>
aux::tagged_argument<
Tag
, typename aux::unwrap_cv_reference<T const>::type
>
typename aux::tag<Tag, T const>::type
operator=(T const& x) const
{
return aux::tagged_argument<
Tag
, BOOST_DEDUCED_TYPENAME aux::unwrap_cv_reference<T const>::type
>(x);
typedef typename aux::tag<Tag, T const>::type result;
return result(x);
}
#endif
@@ -92,7 +82,7 @@ struct keyword
{
return aux::lazy_default<Tag, Default>(default_);
}
#endif
#endif
};
}} // namespace boost::parameter

View File

@@ -21,23 +21,35 @@
#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD0(n)
#define BOOST_PARAMETER_FUN_DECL(z, n, params) \
\
BOOST_PP_CAT(BOOST_PARAMETER_FUN_TEMPLATE_HEAD, BOOST_PP_BOOL(n))(n) \
\
BOOST_PP_TUPLE_ELEM(3, 0, params) \
BOOST_PP_TUPLE_ELEM(3, 1, params)( \
BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& p) \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_EXPR_IF(n, typename) BOOST_PP_TUPLE_ELEM(3, 2, params)::restrict \
< \
BOOST_PP_ENUM_PARAMS(n, T) \
>::type kw = BOOST_PP_TUPLE_ELEM(3, 2, params)() \
) \
{ \
return BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, params), _with_named_params)( \
kw(BOOST_PP_ENUM_PARAMS(n, p)) \
); \
#ifndef BOOST_NO_SFINAE
# define BOOST_PARAMETER_RESTRICT_TYPE(n, param) \
BOOST_PP_EXPR_IF(n, typename) param::restrict \
< \
BOOST_PP_ENUM_PARAMS(n, T) \
>::type
#else
# define BOOST_PARAMETER_RESTRICT_TYPE(n, param) param
#endif
#define BOOST_PARAMETER_FUN_DECL(z, n, params) \
\
BOOST_PP_CAT(BOOST_PARAMETER_FUN_TEMPLATE_HEAD, BOOST_PP_BOOL(n))(n) \
\
BOOST_PP_TUPLE_ELEM(3, 0, params) \
BOOST_PP_TUPLE_ELEM(3, 1, params)( \
BOOST_PP_ENUM_BINARY_PARAMS(n, T, const& p) \
BOOST_PP_COMMA_IF(n) \
BOOST_PARAMETER_RESTRICT_TYPE(n,BOOST_PP_TUPLE_ELEM(3, 2, params)) \
kw = BOOST_PP_TUPLE_ELEM(3, 2, params)() \
) \
{ \
return BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, params), _with_named_params)( \
kw(BOOST_PP_ENUM_PARAMS(n, p)) \
); \
}
// Generates:

View File

@@ -15,7 +15,9 @@
#include <boost/mpl/identity.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/iterator/detail/config_def.hpp>
#include <boost/python/detail/is_xxx.hpp>
@@ -37,6 +39,7 @@
#include <boost/parameter/aux_/default.hpp>
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
#include <boost/parameter/aux_/tagged_argument.hpp>
#include <boost/parameter/aux_/tag.hpp>
#include <boost/parameter/config.hpp>
namespace boost {
@@ -179,17 +182,13 @@ namespace aux
// already a tagged_argument
template <class DefaultTag, class Arg>
struct as_tagged_argument
{
typedef typename mpl::if_<
: mpl::eval_if<
is_tagged_argument<Arg>
, Arg
, tagged_argument<
typename key_type<DefaultTag>::type
, typename unwrap_cv_reference<Arg const>::type
>
>::type type;
};
, mpl::identity<Arg>
, tag<typename key_type<DefaultTag>::type, Arg const>
>
{};
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // ETI workaround
template <>
struct as_tagged_argument<int,int>
@@ -325,15 +324,19 @@ struct parameters
{};
#endif
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// Specializations are to be used as an optional argument to
// eliminate overloads via SFINAE
template<
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// Borland simply can't handle default arguments in member
// class templates. People wishing to write portable code can
// explicitly specify BOOST_PARAMETER_MAX_ARITY arguments
BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
#else
BOOST_PP_ENUM_BINARY_PARAMS(
BOOST_PARAMETER_MAX_ARITY, class A, = aux::void_ BOOST_PP_INTERCEPT
)
)
#endif
>
struct restrict
# ifndef BOOST_NO_SFINAE
@@ -351,8 +354,6 @@ struct parameters
};
# endif
#endif
//
// The function call operator is used to build an arg_list that
// labels the positional parameters and maintains whatever other

View File

@@ -5,11 +5,10 @@ subproject libs/parameter/test ;
# bring in rules for testing
import testing ;
{
test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
;
test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
[ compile unwrap_cv_reference.cpp ]
;
}

View File

@@ -1,7 +1,8 @@
# Boost Parameter Library test Jamfile
test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
;
test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
[ compile unwrap_cv_reference.cpp ]
;

View File

@@ -8,10 +8,10 @@
#include <string.h>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <boost/static_assert.hpp>
#include "basics.hpp"
namespace test
{
// A separate function for getting the "value" key, so we can deduce

View File

@@ -6,6 +6,8 @@
#ifndef BASICS_050424_HPP
#define BASICS_050424_HPP
#include <boost/static_assert.hpp>
namespace test {
using namespace boost::parameter;
@@ -50,6 +52,13 @@ inline bool equal(char const* s1, char const* s2)
return !strcmp(s1,s2);
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
inline bool equal(char* s1, char* s2)
{
return !strcmp(s1,s2);
}
#endif
template <class Name, class Value, class Index>
struct values_t
{
@@ -64,9 +73,10 @@ struct values_t
// 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))
#if defined(_MSC_VER) \
&& (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) \
|| BOOST_WORKAROUND(BOOST_MSVC, < 1310)) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# else
BOOST_STATIC_ASSERT((boost::is_same<Index,Index_>::value));
BOOST_STATIC_ASSERT((boost::is_same<Value,Value_>::value));
@@ -94,7 +104,7 @@ values(Name const& n, Value const& v, Index const& i)
// GCC2 has a problem with char (&)[] deduction, so we'll cast string
// literals there.
#undef S
#if BOOST_WORKAROUND(__GNUC__, == 2)
#if BOOST_WORKAROUND(__GNUC__, == 2) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# define S(s) (char const*)s
#else
# define S(s) s

View File

@@ -9,6 +9,11 @@
#include <boost/type_traits/is_convertible.hpp>
#include <iostream>
#ifndef BOOST_NO_SFINAE
# include <boost/utility/enable_if.hpp>
# include <boost/type_traits/is_same.hpp>
#endif
namespace test
{
using namespace boost::parameter;
@@ -45,21 +50,45 @@ namespace test
{
f_impl(f_parameters()());
}
using boost::parameter::aux::void_;
template<class A0>
void f(A0 const& a0
, typename f_parameters::restrict<A0>::type args = f_parameters())
, typename f_parameters::restrict<A0
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
,void_,void_,void_,void_
#endif
>::type args = f_parameters())
{
f_impl(args(a0));
}
template<class A0, class A1>
void f(A0 const& a0, A1 const& a1
, typename f_parameters::restrict<A0, A1>::type args = f_parameters())
, typename f_parameters::restrict<A0, A1
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
,void_,void_,void_
#endif
>::type args = f_parameters())
{
f_impl(args(a0, a1));
}
#ifndef BOOST_NO_SFINAE
// On compilers that actually support SFINAE, add another overload
// that is an equally good match and can only be in the overload set
// when the others are not. This tests that the SFINAE is actually
// working. On all other compilers we're just checking that
// everything about SFINAE-enabled code will work, except of course
// the SFINAE.
template<class A0, class A1>
typename boost::enable_if<boost::is_same<int,A0>, int>::type
f(A0 const& a0, A1 const& a1)
{
return 0;
}
#endif
} // namespace test
int main()
@@ -72,6 +101,10 @@ int main()
f("foo", 3.f);
f(value = 3.f, name = "foo");
#ifndef BOOST_NO_SFINAE
return f(3, 4);
#else
return 0;
#endif
}

30
test/unwrap_cv_reference.cpp Executable file
View File

@@ -0,0 +1,30 @@
// Copyright David Abrahams 2005. Distributed under 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)
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/ref.hpp>
#include <boost/type_traits/is_same.hpp>
namespace test
{
using namespace boost::parameter::aux;
using namespace boost;
struct foo {};
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int>::type,int>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int const>::type,int const>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int volatile>::type,int volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int const volatile>::type,int const volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo>::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo const>::type,foo const>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo volatile>::type,foo volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo const volatile>::type,foo const volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> >::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> const>::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> volatile>::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> const volatile>::type,foo>));
}