117 lines
2.9 KiB
C++
117 lines
2.9 KiB
C++
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// noinvoke.hpp
|
||
|
//
|
||
|
// Copyright 2008 Eric Niebler. 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/proto/core.hpp>
|
||
|
#include <boost/proto/transform/make.hpp>
|
||
|
#include <boost/type_traits/add_pointer.hpp>
|
||
|
#include <boost/type_traits/remove_pointer.hpp>
|
||
|
#include <boost/test/unit_test.hpp>
|
||
|
namespace proto=boost::proto;
|
||
|
using proto::_;
|
||
|
|
||
|
struct Test
|
||
|
: proto::when<
|
||
|
_
|
||
|
, proto::noinvoke<
|
||
|
// This remove_pointer invocation is bloked by noinvoke
|
||
|
boost::remove_pointer<
|
||
|
// This add_pointer invocation is *not* blocked by noinvoke
|
||
|
boost::add_pointer<_>
|
||
|
>
|
||
|
>()
|
||
|
>
|
||
|
{};
|
||
|
|
||
|
struct Test2
|
||
|
: proto::when<
|
||
|
_
|
||
|
// This add_pointer gets invoked because a substitution takes place
|
||
|
// within it.
|
||
|
, boost::add_pointer<
|
||
|
proto::noinvoke<
|
||
|
// This remove_pointer invocation is bloked by noinvoke
|
||
|
boost::remove_pointer<
|
||
|
// This add_pointer invocation is *not* blocked by noinvoke
|
||
|
boost::add_pointer<_>
|
||
|
>
|
||
|
>
|
||
|
>()
|
||
|
>
|
||
|
{};
|
||
|
|
||
|
template<typename T, typename U>
|
||
|
struct select2nd
|
||
|
{
|
||
|
typedef U type;
|
||
|
};
|
||
|
|
||
|
struct Test3
|
||
|
: proto::when<
|
||
|
_
|
||
|
// This add_pointer gets invoked because a substitution takes place
|
||
|
// within it.
|
||
|
, select2nd<
|
||
|
void
|
||
|
, proto::noinvoke<
|
||
|
// This remove_pointer invocation is bloked by noinvoke
|
||
|
select2nd<
|
||
|
void
|
||
|
// This add_pointer invocation is *not* blocked by noinvoke
|
||
|
, boost::add_pointer<_>
|
||
|
>
|
||
|
>
|
||
|
>()
|
||
|
>
|
||
|
{};
|
||
|
|
||
|
|
||
|
void test_noinvoke()
|
||
|
{
|
||
|
typedef proto::terminal<int>::type Int;
|
||
|
Int i = {42};
|
||
|
|
||
|
BOOST_MPL_ASSERT((
|
||
|
boost::is_same<
|
||
|
boost::result_of<Test(Int)>::type
|
||
|
, boost::remove_pointer<Int *>
|
||
|
>
|
||
|
));
|
||
|
|
||
|
boost::remove_pointer<Int *> t = Test()(i);
|
||
|
|
||
|
BOOST_MPL_ASSERT((
|
||
|
boost::is_same<
|
||
|
boost::result_of<Test2(Int)>::type
|
||
|
, boost::remove_pointer<Int *> *
|
||
|
>
|
||
|
));
|
||
|
|
||
|
boost::remove_pointer<Int *> * t2 = Test2()(i);
|
||
|
|
||
|
BOOST_MPL_ASSERT((
|
||
|
boost::is_same<
|
||
|
boost::result_of<Test3(Int)>::type
|
||
|
, select2nd<void, Int *>
|
||
|
>
|
||
|
));
|
||
|
|
||
|
select2nd<void, Int *> t3 = Test3()(i);
|
||
|
}
|
||
|
|
||
|
using namespace boost::unit_test;
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
// init_unit_test_suite
|
||
|
//
|
||
|
test_suite* init_unit_test_suite( int argc, char* argv[] )
|
||
|
{
|
||
|
test_suite *test = BOOST_TEST_SUITE("test proto::noinvoke");
|
||
|
|
||
|
test->add(BOOST_TEST_CASE(&test_noinvoke));
|
||
|
|
||
|
return test;
|
||
|
}
|