2
0
mirror of https://github.com/boostorg/lambda.git synced 2026-01-21 04:52:25 +00:00

Compare commits

..

44 Commits

Author SHA1 Message Date
Vladimir Prus
811939f4f3 Create branch to keep WIP patch for modular build.
[SVN r85883]
2013-09-25 08:12:19 +00:00
Steven Watanabe
4545234f94 Handle const lambda functors for nullary result_of. Fixes #6914.
[SVN r83020]
2013-02-19 19:52:03 +00:00
Steven Watanabe
657a0b9dd7 Handle nullary result_of. Fixes #6914.
[SVN r82935]
2013-02-16 20:26:34 +00:00
Steven Watanabe
fab5a8041b Remove name of unused parameter. Fixes #8033.
[SVN r82932]
2013-02-16 20:01:07 +00:00
Marshall Clow
9c376db7e5 Fixed 'the the' in comments; Refs #7714
[SVN r82235]
2012-12-28 16:51:09 +00:00
Steven Watanabe
2ed8d7f4df Fix return type deduction for pointers to data members. Fixes #4962. Fixes #4566.
[SVN r67640]
2011-01-03 22:31:21 +00:00
Daniel Walker
4091f55a4b removed arity detection from has_xxx_template
[SVN r63726]
2010-07-07 20:44:59 +00:00
Daniel James
45c6ba535c Update various libraries' documentation build.
Mostly to use the images and css files under doc/src instead of
doc/html, usually be deleting the settings in order to use the defaults.
Also add 'boost.root' to some builds in order to fix links which rely on
it.

[SVN r63146]
2010-06-20 18:00:48 +00:00
Steven Watanabe
57a605d7cc Revert [62617], since there is already a Jamfile for Lambda's tests
[SVN r62628]
2010-06-09 02:10:06 +00:00
Steven Watanabe
fcfcc42baf Enable using result_of with Boost.Lambda. Fixes #426. Fixes #864
[SVN r62627]
2010-06-09 01:39:48 +00:00
Jeremiah Willcock
c516504670 Changed compound assignment (and actually all binary operators) to copy their RHS arguments like the documentation said; added a test for this; fixes #4043
[SVN r62620]
2010-06-09 00:33:25 +00:00
Jeremiah Willcock
c479b3b7b7 Fixed warning
[SVN r62619]
2010-06-09 00:31:02 +00:00
Jeremiah Willcock
269ac93b1b Added Jamfile.v2 from Daniel Walker; refs #864
[SVN r62617]
2010-06-09 00:16:43 +00:00
Steven Watanabe
15d4e6ab79 Make sure that all top level headers in Lambda include their dependencies. Fixes #4203
[SVN r61881]
2010-05-09 20:07:07 +00:00
Steven Watanabe
77495bb7e1 Deal with warnings with /Za. Fixes #3485
[SVN r57479]
2009-11-08 04:11:21 +00:00
Troy D. Straszheim
c183b699bc rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
Troy D. Straszheim
3d4a3e7050 Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
Steven Watanabe
c14095472e Don't propagate constness from pointer to pointee. Fixes #1572
[SVN r53651]
2009-06-05 02:43:54 +00:00
Steven Watanabe
1afc4b6779 Use boost/detail/container_fwd.hpp. Fixes #2601
[SVN r53649]
2009-06-05 01:43:39 +00:00
Steven Watanabe
41eb864595 Add result_type to lambda::ret. Fixes #1222
[SVN r53648]
2009-06-05 01:20:06 +00:00
Jeremiah Willcock
0f60055086 Fixed tabs
[SVN r53343]
2009-05-28 14:49:25 +00:00
Steven Watanabe
9a8e5d7784 Fix lambda regression with msvc 7.1
[SVN r53261]
2009-05-25 21:52:12 +00:00
Steven Watanabe
6985fca6ee Avoid ambiguities between boost::lambda::bind and std::bind with VC10. Fixes #3075
[SVN r53233]
2009-05-24 22:58:52 +00:00
Steven Watanabe
04ae944c3c Avoid using namespace std; to prevent ambiguity between boost and std components. Fixes #3025
[SVN r53061]
2009-05-17 00:25:06 +00:00
Steven Watanabe
0c4e251ebe Supress warnings on gcc and msvc. Fixes #1515
[SVN r51448]
2009-02-26 02:33:15 +00:00
John Maddock
0faeb3f19e Add Jamfile to build PDF versions of all the docs.
Tweaked some existing Jamfiles so that PDF build finds all the necessary image files etc.
Tweaked fo.xsl to provide more options by default, and improve formatting.

[SVN r51104]
2009-02-08 16:59:14 +00:00
Steven Watanabe
150736273e Add <async-exceptions>on. Fixes #2446
[SVN r50999]
2009-02-03 21:47:58 +00:00
Steven Watanabe
d5a98758fa Add specializations of plain_return_type_2 for std::string. Fixes #781
[SVN r50516]
2009-01-08 16:58:48 +00:00
Marshall Clow
cd3d5fd03a Typo: fixes bug #2583
[SVN r50413]
2008-12-30 18:27:43 +00:00
Michael A. Jackson
48a89b7705 Updating dependency information for modularized libraries.
[SVN r49628]
2008-11-07 17:05:27 +00:00
Michael A. Jackson
ec350abf06 Updating CMake files to latest trunk. Added dependency information for regression tests and a few new macros for internal use.
[SVN r49627]
2008-11-07 17:02:56 +00:00
Michael A. Jackson
d56abd61ce Continuing merge of CMake build system files into trunk with the encouragement of Doug Gregor
[SVN r49510]
2008-11-01 13:15:41 +00:00
Beman Dawes
2788ede42a With his kind permission, change Jaakko "Järvi" to "Jarvi"
[SVN r46808]
2008-06-28 13:45:21 +00:00
Marshall Clow
1c953ed38c Updated docs re bug #1855
[SVN r45097]
2008-05-03 23:45:30 +00:00
Marshall Clow
b2dc95bb18 Applied patch (fixes bug #1307)
[SVN r43113]
2008-02-05 16:15:35 +00:00
Vladimir Prus
797b5756cf Update for V2
[SVN r38520]
2007-08-08 19:16:43 +00:00
Peter Dimov
bd4da55f0f Rvalue support
[SVN r38299]
2007-07-29 20:33:46 +00:00
Daniel James
47bf3df0ae Merge fixed links from RC_1_34_0.
[SVN r36660]
2007-01-07 23:50:56 +00:00
Jaakko Järvi
ff0929e6e3 fixed bug 1444052
[SVN r36200]
2006-11-29 19:21:46 +00:00
Jaakko Järvi
9b925abaff added ->* to the table of actions for return types deduction
[SVN r36199]
2006-11-29 18:54:18 +00:00
Beman Dawes
bf50f2fe7f Add copyright, license
[SVN r35905]
2006-11-07 19:11:57 +00:00
Daryle Walker
85630d55a6 Correct placement of base class declaration
[SVN r34533]
2006-07-14 08:04:08 +00:00
Peter Dimov
2e8c4eb8f3 is_placeholder, is_bind_expression added.
[SVN r34468]
2006-07-06 13:47:26 +00:00
Jaakko Järvi
24e8602cf1 typo
[SVN r31518]
2005-10-31 20:11:23 +00:00
64 changed files with 11724 additions and 687 deletions

12
doc/Jamfile.v2 Normal file
View File

@@ -0,0 +1,12 @@
project boost/doc ;
import boostbook : boostbook ;
# Are these really the correct images??
path-constant images : ../../spirit/phoenix/doc/html ;
boostbook lambda-doc : lambda.xml
:
<xsl:param>boost.root=../../../..
<format>pdf:<xsl:param>img.src.path=$(images)/
;

7
doc/detail/README Normal file
View File

@@ -0,0 +1,7 @@
- lambda_doc.xml is a DocBook xml file from which the lambda docs are
generated
- lambda_doc_chunks.xsl loads the stylesheets that generate a separate
html-file for each section
- lambda_doc.xsl loads stylesheets that generate one big html-file
(you need to edit the paths in these files to make them work)

3456
doc/detail/lambda_doc.xml Normal file

File diff suppressed because it is too large Load Diff

19
doc/detail/lambda_doc.xsl Normal file
View File

@@ -0,0 +1,19 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'
xmlns="http://www.w3.org/TR/xhtml1/transitional"
exclude-result-prefixes="#default">
<xsl:import href="/u/jajarvi/dtd/docbook-xsl/html/docbook.xsl"/>
<!-- Add other variable definitions here -->
<xsl:variable name="shade.verbatim">0</xsl:variable>
<xsl:variable name="section.autolabel">1</xsl:variable>
<xsl:variable name="bibliography.collection">lambda_bib.xml</xsl:variable>
</xsl:stylesheet>

View File

@@ -0,0 +1,19 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version='1.0'
xmlns="http://www.w3.org/TR/xhtml1/transitional"
exclude-result-prefixes="#default">
<xsl:import href="/u/jajarvi/dtd/docbook-xsl/html/chunk.xsl"/>
<!-- Add other variable definitions here -->
<xsl:variable name="shade.verbatim">0</xsl:variable>
<xsl:variable name="section.autolabel">1</xsl:variable>
<xsl:variable name="bibliography.collection">lambda_bib.xml</xsl:variable>
</xsl:stylesheet>

12
doc/index.html Normal file
View File

@@ -0,0 +1,12 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=../../../doc/html/lambda.html">
</head>
<body>
Automatic redirection failed, please go to <a href="../../../doc/html/lambda.html">www.boost.org/doc/html/lambda.html</a>&nbsp;<hr>
<p>© Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

3452
doc/lambda.xml Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
// -- algorithm.hpp -- Boost Lambda Library -----------------------------------
// Copyright (C) 2002 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2002 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2002 Gary Powell (gwpowell@hotmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See

View File

@@ -1,6 +1,6 @@
// -- bind.hpp -- Boost Lambda Library --------------------------------------
// Copyright (C) 1999-2001 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999-2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Gary Powell (gwpowell@hotmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See

View File

@@ -1,7 +1,7 @@
// - casts.hpp -- BLambda Library -------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -14,11 +14,17 @@
#if !defined(BOOST_LAMBDA_CASTS_HPP)
#define BOOST_LAMBDA_CASTS_HPP
#include "boost/lambda/detail/suppress_unused.hpp"
#include "boost/lambda/core.hpp"
#include <typeinfo>
namespace boost {
namespace lambda {
template<class Act, class Args>
struct return_type_N;
template<class T> class cast_action;
template<class T> class static_cast_action;
@@ -64,11 +70,12 @@ public:
}
};
// typedid action
// typeid action
class typeid_action {
public:
template<class RET, class Arg1>
static RET apply(Arg1 &a1) {
detail::suppress_unused_variable_warnings(a1);
return typeid(a1);
}
};

View File

@@ -251,7 +251,7 @@ private:
closure& operator=(closure const&); // no assign
template <int N, typename ClosureT>
friend struct closure_member;
friend class closure_member;
template <typename ClosureT>
friend class closure_frame;

View File

@@ -1,7 +1,7 @@
// - construct.hpp -- Lambda Library -------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -14,6 +14,9 @@
#if !defined(BOOST_LAMBDA_CONSTRUCT_HPP)
#define BOOST_LAMBDA_CONSTRUCT_HPP
#include "boost/type_traits/remove_cv.hpp"
#include "boost/type_traits/is_pointer.hpp"
namespace boost {
namespace lambda {

View File

@@ -1,5 +1,5 @@
// -- control_structures.hpp -- Boost Lambda Library --------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -17,6 +17,7 @@
#include "boost/lambda/detail/operator_actions.hpp"
#include "boost/lambda/detail/operator_return_type_traits.hpp"
#include "boost/lambda/detail/control_structures_impl.hpp"
#include "boost/lambda/if.hpp"
#include "boost/lambda/loops.hpp"
#endif

View File

@@ -1,7 +1,7 @@
// -- core.hpp -- Boost Lambda Library -------------------------------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
// -- Boost Lambda Library - actions.hpp ----------------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
// -- Boost Lambda Library -------------------------------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
// -- bind_functions.hpp -- Boost Lambda Library
//
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library -- control_constructs_common.hpp -------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
//
// Distributed under the Boost Software License, Version 1.0. (See

View File

@@ -1,550 +0,0 @@
// Boost Lambda Library -- control_structures_impl.hpp ---------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// --------------------------------------------------------------------------
#if !defined(BOOST_LAMBDA_CONTROL_CONSTRUCTS_HPP)
#define BOOST_LAMBDA_CONTROL_CONSTRUCTS_HPP
namespace boost {
namespace lambda {
// -- void return control actions ----------------------
class forloop_action {};
class forloop_no_body_action {};
class ifthen_action {};
class ifthenelse_action {};
class whileloop_action {};
class whileloop_no_body_action {};
class dowhileloop_action {};
class dowhileloop_no_body_action {};
// -- nonvoid return control actions ----------------------
class ifthenelsereturn_action {};
// For loop
template <class Arg1, class Arg2, class Arg3, class Arg4>
inline const
lambda_functor<
lambda_functor_base<
forloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3>, lambda_functor<Arg4> >
>
>
for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
const lambda_functor<Arg3>& a3, const lambda_functor<Arg4>& a4) {
return
lambda_functor_base<
forloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3>, lambda_functor<Arg4> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3>, lambda_functor<Arg4> >(a1, a2, a3, a4)
);
}
// No body case.
template <class Arg1, class Arg2, class Arg3>
inline const
lambda_functor<
lambda_functor_base<
forloop_no_body_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
>
>
for_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
const lambda_functor<Arg3>& a3) {
return
lambda_functor_base<
forloop_no_body_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2>,
lambda_functor<Arg3> >(a1, a2, a3) );
}
// While loop
template <class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
whileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
>
while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
return
lambda_functor_base<
whileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
}
// No body case.
template <class Arg1>
inline const
lambda_functor<
lambda_functor_base<
whileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
>
while_loop(const lambda_functor<Arg1>& a1) {
return
lambda_functor_base<
whileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
( tuple<lambda_functor<Arg1> >(a1) );
}
// Do While loop
template <class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
dowhileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
>
do_while_loop(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
return
lambda_functor_base<
dowhileloop_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2));
}
// No body case.
template <class Arg1>
inline const
lambda_functor<
lambda_functor_base<
dowhileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
>
do_while_loop(const lambda_functor<Arg1>& a1) {
return
lambda_functor_base<
dowhileloop_no_body_action,
tuple<lambda_functor<Arg1> >
>
( tuple<lambda_functor<Arg1> >(a1));
}
// If Then
template <class Arg1, class Arg2>
inline const
lambda_functor<
lambda_functor_base<
ifthen_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
>
if_then(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2) {
return
lambda_functor_base<
ifthen_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >
>
( tuple<lambda_functor<Arg1>, lambda_functor<Arg2> >(a1, a2) );
}
// If then else
template <class Arg1, class Arg2, class Arg3>
inline const
lambda_functor<
lambda_functor_base<
ifthenelse_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
>
>
if_then_else(const lambda_functor<Arg1>& a1, const lambda_functor<Arg2>& a2,
const lambda_functor<Arg3>& a3) {
return
lambda_functor_base<
ifthenelse_action,
tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
>
(tuple<lambda_functor<Arg1>, lambda_functor<Arg2>, lambda_functor<Arg3> >
(a1, a2, a3) );
}
// Our version of operator?:()
template <class Arg1, class Arg2, class Arg3>
inline const
lambda_functor<
lambda_functor_base<
other_action<ifthenelsereturn_action>,
tuple<lambda_functor<Arg1>,
typename const_copy_argument<Arg2>::type,
typename const_copy_argument<Arg3>::type>
>
>
if_then_else_return(const lambda_functor<Arg1>& a1,
const Arg2 & a2,
const Arg3 & a3) {
return
lambda_functor_base<
other_action<ifthenelsereturn_action>,
tuple<lambda_functor<Arg1>,
typename const_copy_argument<Arg2>::type,
typename const_copy_argument<Arg3>::type>
> ( tuple<lambda_functor<Arg1>,
typename const_copy_argument<Arg2>::type,
typename const_copy_argument<Arg3>::type> (a1, a2, a3) );
}
namespace detail {
// return type specialization for conditional expression begins -----------
// start reading below and move upwards
// PHASE 6:1
// check if A is conbertible to B and B to A
template<int Phase, bool AtoB, bool BtoA, bool SameType, class A, class B>
struct return_type_2_ifthenelsereturn;
// if A can be converted to B and vice versa -> ambiguous
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, true, true, false, A, B> {
typedef
detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
// ambiguous type in conditional expression
};
// if A can be converted to B and vice versa and are of same type
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, true, true, true, A, B> {
typedef A type;
};
// A can be converted to B
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, true, false, false, A, B> {
typedef B type;
};
// B can be converted to A
template<int Phase, class A, class B>
struct return_type_2_ifthenelsereturn<Phase, false, true, false, A, B> {
typedef A type;
};
// neither can be converted. Then we drop the potential references, and
// try again
template<class A, class B>
struct return_type_2_ifthenelsereturn<1, false, false, false, A, B> {
// it is safe to add const, since the result will be an rvalue and thus
// const anyway. The const are needed eg. if the types
// are 'const int*' and 'void *'. The remaining type should be 'const void*'
typedef const typename boost::remove_reference<A>::type plainA;
typedef const typename boost::remove_reference<B>::type plainB;
// TODO: Add support for volatile ?
typedef typename
return_type_2_ifthenelsereturn<
2,
boost::is_convertible<plainA,plainB>::value,
boost::is_convertible<plainB,plainA>::value,
boost::is_same<plainA,plainB>::value,
plainA,
plainB>::type type;
};
// PHASE 6:2
template<class A, class B>
struct return_type_2_ifthenelsereturn<2, false, false, false, A, B> {
typedef
detail::return_type_deduction_failure<return_type_2_ifthenelsereturn> type;
// types_do_not_match_in_conditional_expression
};
// PHASE 5: now we know that types are not arithmetic.
template<class A, class B>
struct non_numeric_types {
typedef typename
return_type_2_ifthenelsereturn<
1, // phase 1
is_convertible<A,B>::value,
is_convertible<B,A>::value,
is_same<A,B>::value,
A,
B>::type type;
};
// PHASE 4 :
// the base case covers arithmetic types with differing promote codes
// use the type deduction of arithmetic_actions
template<int CodeA, int CodeB, class A, class B>
struct arithmetic_or_not {
typedef typename
return_type_2<arithmetic_action<plus_action>, A, B>::type type;
// plus_action is just a random pick, has to be a concrete instance
};
// this case covers the case of artihmetic types with the same promote codes.
// non numeric deduction is used since e.g. integral promotion is not
// performed with operator ?:
template<int CodeA, class A, class B>
struct arithmetic_or_not<CodeA, CodeA, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
// if either A or B has promote code -1 it is not an arithmetic type
template<class A, class B>
struct arithmetic_or_not <-1, -1, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
template<int CodeB, class A, class B>
struct arithmetic_or_not <-1, CodeB, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
template<int CodeA, class A, class B>
struct arithmetic_or_not <CodeA, -1, A, B> {
typedef typename non_numeric_types<A, B>::type type;
};
// PHASE 3 : Are the types same?
// No, check if they are arithmetic or not
template <class A, class B>
struct same_or_not {
typedef typename detail::remove_reference_and_cv<A>::type plainA;
typedef typename detail::remove_reference_and_cv<B>::type plainB;
typedef typename
arithmetic_or_not<
detail::promote_code<plainA>::value,
detail::promote_code<plainB>::value,
A,
B>::type type;
};
// Yes, clear.
template <class A> struct same_or_not<A, A> {
typedef A type;
};
} // detail
// PHASE 2 : Perform first the potential array_to_pointer conversion
template<class A, class B>
struct return_type_2<other_action<ifthenelsereturn_action>, A, B> {
typedef typename detail::array_to_pointer<A>::type A1;
typedef typename detail::array_to_pointer<B>::type B1;
typedef typename
boost::add_const<typename detail::same_or_not<A1, B1>::type>::type type;
};
// PHASE 1 : Deduction is based on the second and third operand
// return type specialization for conditional expression ends -----------
// Control loop lambda_functor_base specializations.
// Specialization for for_loop.
template<class Args>
class
lambda_functor_base<forloop_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS))
detail::select(boost::tuples::get<3>(args), CALL_ACTUAL_ARGS);
}
};
// No body case
template<class Args>
class
lambda_functor_base<forloop_no_body_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
for(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS)) {}
}
};
// Specialization for while_loop.
template<class Args>
class
lambda_functor_base<whileloop_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
}
};
// No body case
template<class Args>
class
lambda_functor_base<whileloop_no_body_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
while(detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) {}
}
};
// Specialization for do_while_loop.
// Note that the first argument is the condition.
template<class Args>
class
lambda_functor_base<dowhileloop_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
do {
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
}
};
// No body case
template<class Args>
class
lambda_functor_base<dowhileloop_no_body_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
do {} while (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS) );
}
};
// Specialization for if_then.
template<class Args>
class
lambda_functor_base<ifthen_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
}
};
// Specialization for if_then_else.
template<class Args>
class
lambda_functor_base<ifthenelse_action, Args> {
public:
Args args;
template <class T> struct sig { typedef void type; };
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
if (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS))
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS);
else
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
}
};
// Specialization of lambda_functor_base for if_then_else_return.
template<class Args>
class
lambda_functor_base<other_action<ifthenelsereturn_action>, Args> {
public:
Args args;
template <class SigArgs> struct sig {
private:
typedef typename detail::nth_return_type_sig<1, Args, SigArgs>::type ret1;
typedef typename detail::nth_return_type_sig<2, Args, SigArgs>::type ret2;
public:
typedef typename return_type_2<
other_action<ifthenelsereturn_action>, ret1, ret2
>::type type;
};
public:
explicit lambda_functor_base(const Args& a) : args(a) {}
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const {
return (detail::select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)) ?
detail::select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS)
:
detail::select(boost::tuples::get<2>(args), CALL_ACTUAL_ARGS);
}
};
} // lambda
} // boost
#endif // BOOST_LAMBDA_CONTROL_CONSTRUCTS_HPP

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library - function_adaptors.hpp ----------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -12,25 +12,170 @@
#ifndef BOOST_LAMBDA_FUNCTION_ADAPTORS_HPP
#define BOOST_LAMBDA_FUNCTION_ADAPTORS_HPP
#include "boost/mpl/has_xxx.hpp"
#include "boost/tuple/tuple.hpp"
#include "boost/type_traits/same_traits.hpp"
#include "boost/type_traits/remove_reference.hpp"
#include "boost/type_traits/remove_cv.hpp"
#include "boost/type_traits/add_const.hpp"
#include "boost/type_traits/add_volatile.hpp"
#include "boost/utility/result_of.hpp"
namespace boost {
namespace lambda {
namespace detail {
BOOST_MPL_HAS_XXX_TEMPLATE_DEF(sig)
template<class Tuple>
struct remove_references_from_elements {
typedef typename boost::tuples::cons<
typename boost::remove_reference<typename Tuple::head_type>::type,
typename remove_references_from_elements<typename Tuple::tail_type>::type
> type;
};
template<>
struct remove_references_from_elements<boost::tuples::null_type> {
typedef boost::tuples::null_type type;
};
}
template <class Func> struct function_adaptor {
typedef typename detail::remove_reference_and_cv<Func>::type plainF;
#if !defined(BOOST_NO_RESULT_OF)
// Support functors that use the boost::result_of return type convention.
template<class Tuple, int Length, bool HasSig>
struct result_converter;
template<class Tuple, int Length>
struct result_converter<Tuple, Length, true>
: plainF::template sig<
typename detail::remove_references_from_elements<Tuple>::type
>
{};
template<class Tuple>
struct result_converter<Tuple, 0, false>
: result_of<plainF()>
{};
template<class Tuple>
struct result_converter<Tuple, 1, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 2, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 3, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 4, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 5, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 6, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 7, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type,
typename tuples::element<7, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 8, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type,
typename tuples::element<7, Tuple>::type,
typename tuples::element<8, Tuple>::type)
>
{};
template<class Tuple>
struct result_converter<Tuple, 9, false>
: result_of<plainF(
typename tuples::element<1, Tuple>::type,
typename tuples::element<2, Tuple>::type,
typename tuples::element<3, Tuple>::type,
typename tuples::element<4, Tuple>::type,
typename tuples::element<5, Tuple>::type,
typename tuples::element<6, Tuple>::type,
typename tuples::element<7, Tuple>::type,
typename tuples::element<8, Tuple>::type,
typename tuples::element<9, Tuple>::type)
>
{};
// we do not know the return type off-hand, we must ask it from Func
template <class Args> class sig {
typedef typename Args::head_type F;
// To sig we pass a cons list, where the head is the function object type
// itself (potentially cv-qualified)
// and the tail contains the types of the actual arguments to be passed
// to the function object. The arguments can be cv qualified
// as well.
template <class Args>
struct sig
: result_converter<
Args
, tuples::length<typename Args::tail_type>::value
, detail::has_sig<plainF>::value
>
{};
#else // BOOST_NO_RESULT_OF
template <class Args> class sig {
typedef typename detail::remove_reference_and_cv<Func>::type plainF;
public:
// To sig we pass a cons list, where the head is the function object type
// itself (potentially cv-qualified)
// and the tail contains the types of the actual arguments to be passed
// to the function object. The arguments can be cv qualified
// as well.
typedef typename plainF::template sig<Args>::type type;
typedef typename plainF::template sig<
typename detail::remove_references_from_elements<Args>::type
>::type type;
};
#endif
template<class RET, class A1>
static RET apply(A1& a1) {
@@ -95,22 +240,26 @@ struct function_adaptor<T Object::*> {
// the data member is accessed is const, and finally adding a reference
template<class Args> class sig {
typedef typename boost::tuples::element<1, Args>::type argument_type;
typedef typename boost::remove_reference<
argument_type
>::type unref_type;
typedef typename detail::IF<boost::is_const<argument_type>::value,
typedef typename detail::IF<boost::is_const<unref_type>::value,
typename boost::add_const<T>::type,
T
>::RET properly_consted_return_type;
typedef typename detail::IF<
boost::is_volatile<properly_consted_return_type>::value,
typedef typename detail::IF<boost::is_volatile<unref_type>::value,
typename boost::add_volatile<properly_consted_return_type>::type,
properly_consted_return_type
>::RET properly_cvd_return_type;
public:
typedef typename
boost::add_reference<properly_cvd_return_type>::type type;
typedef typename detail::IF<boost::is_reference<argument_type>::value,
typename boost::add_reference<properly_cvd_return_type>::type,
typename boost::remove_cv<T>::type
>::RET type;
};
template <class RET>

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library - is_instance_of.hpp ---------------------
// Copyright (C) 2001 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library - lambda_config.hpp ------------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library lambda_functor_base.hpp -----------------------------
//
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,9 +13,19 @@
#ifndef BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP
#define BOOST_LAMBDA_LAMBDA_FUNCTOR_BASE_HPP
#include "boost/type_traits/add_reference.hpp"
#include "boost/type_traits/add_const.hpp"
#include "boost/type_traits/remove_const.hpp"
#include "boost/lambda/detail/lambda_fwd.hpp"
#include "boost/lambda/detail/lambda_traits.hpp"
namespace boost {
namespace lambda {
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
// for return type deductions we wrap bound argument to this class,
// which fulfils the base class contract for lambda_functors
@@ -36,12 +46,16 @@ public:
explicit identity(par_t t) : elem(t) {}
template <typename SigArgs>
struct sig { typedef element_t type; };
struct sig { typedef typename boost::remove_const<element_t>::type type; };
template<class RET, CALL_TEMPLATE_ARGS>
RET call(CALL_FORMAL_ARGS) const { CALL_USE_ARGS; return elem; }
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
template <class T>
inline lambda_functor<identity<T&> > var(T& t) { return identity<T&>(t); }
@@ -262,6 +276,8 @@ class lambda_functor_base<explicit_return_type_action<RET>, Args>
public:
Args args;
typedef RET result_type;
explicit lambda_functor_base(const Args& a) : args(a) {}
template <class SigArgs> struct sig { typedef RET type; };
@@ -337,7 +353,7 @@ class lambda_functor_base<action<0, Act>, Args>
{
public:
// Args args; not needed
explicit lambda_functor_base(const Args& a) {}
explicit lambda_functor_base(const Args& /*a*/) {}
template<class SigArgs> struct sig {
typedef typename return_type_N<Act, null_type>::type type;
@@ -367,7 +383,7 @@ public: \
\
template<class SigArgs> struct sig { \
typedef typename \
detail::deduce_non_ref_argument_types<Args, SigArgs>::type rets_t; \
detail::deduce_argument_types<Args, SigArgs>::type rets_t; \
public: \
typedef typename \
return_type_N_prot<Act, rets_t>::type type; \

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library - lambda_functors.hpp -------------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,31 @@
#ifndef BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
#define BOOST_LAMBDA_LAMBDA_FUNCTORS_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/result_of.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
#include <boost/mpl/or.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_array.hpp>
#define BOOST_LAMBDA_DISABLE_IF_ARRAY1(A1, R1)\
typename lazy_disable_if<is_array<A1>, typename R1 >::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) \
typename lazy_disable_if<mpl::or_<is_array<A1>, is_array<A2> >, typename R1, R2 >::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) \
typename lazy_disable_if<mpl::or_<is_array<A1>, is_array<A2>, is_array<A3> >, typename R1, R2, R3 >::type
#else
#define BOOST_LAMBDA_DISABLE_IF_ARRAY1(A1, R1) typename R1::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) typename R1, R2::type
#define BOOST_LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) typename R1, R2, R3::type
#endif
namespace boost {
namespace lambda {
@@ -105,7 +130,10 @@ typedef const lambda_functor<placeholder<THIRD> > placeholder3_type;
// other lambda_functors.
// -------------------------------------------------------------------
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
// -- lambda_functor NONE ------------------------------------------------
template <class T>
@@ -134,6 +162,25 @@ public:
inherited::template sig<null_type>::type
nullary_return_type;
// Support for boost::result_of.
template <class Sig> struct result;
template <class F>
struct result<F()> {
typedef nullary_return_type type;
};
template <class F, class A>
struct result<F(A)> {
typedef typename sig<tuple<F, A> >::type type;
};
template <class F, class A, class B>
struct result<F(A, B)> {
typedef typename sig<tuple<F, A, B> >::type type;
};
template <class F, class A, class B, class C>
struct result<F(A, B, C)> {
typedef typename sig<tuple<F, A, B, C> >::type type;
};
nullary_return_type operator()() const {
return inherited::template
call<nullary_return_type>
@@ -148,6 +195,14 @@ public:
>(a, cnull_type(), cnull_type(), cnull_type());
}
template<class A>
BOOST_LAMBDA_DISABLE_IF_ARRAY1(A, inherited::template sig<tuple<A const&> >)
operator()(A const& a) const {
return inherited::template call<
typename inherited::template sig<tuple<A const&> >::type
>(a, cnull_type(), cnull_type(), cnull_type());
}
template<class A, class B>
typename inherited::template sig<tuple<A&, B&> >::type
operator()(A& a, B& b) const {
@@ -156,6 +211,30 @@ public:
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B>
BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A const&, B&> >)
operator()(A const& a, B& b) const {
return inherited::template call<
typename inherited::template sig<tuple<A const&, B&> >::type
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B>
BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A&, B const&> >)
operator()(A& a, B const& b) const {
return inherited::template call<
typename inherited::template sig<tuple<A&, B const&> >::type
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B>
BOOST_LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A const&, B const&> >)
operator()(A const& a, B const& b) const {
return inherited::template call<
typename inherited::template sig<tuple<A const&, B const&> >::type
>(a, b, cnull_type(), cnull_type());
}
template<class A, class B, class C>
typename inherited::template sig<tuple<A&, B&, C&> >::type
operator()(A& a, B& b, C& c) const
@@ -165,6 +244,15 @@ public:
>(a, b, c, cnull_type());
}
template<class A, class B, class C>
BOOST_LAMBDA_DISABLE_IF_ARRAY3(A, B, C, inherited::template sig<tuple<A const&, B const&, C const&> >)
operator()(A const& a, B const& b, C const& c) const
{
return inherited::template call<
typename inherited::template sig<tuple<A const&, B const&, C const&> >::type
>(a, b, c, cnull_type());
}
// for internal calls with env
template<CALL_TEMPLATE_ARGS>
typename inherited::template sig<tuple<CALL_REFERENCE_TYPES> >::type
@@ -203,10 +291,67 @@ public:
}
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
} // namespace lambda
} // namespace boost
namespace boost {
#if !defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_NO_DECLTYPE)
template<class T>
struct result_of<boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
template<class T>
struct result_of<const boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
#endif
template<class T>
struct tr1_result_of<boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
template<class T>
struct tr1_result_of<const boost::lambda::lambda_functor<T>()>
{
typedef typename boost::lambda::lambda_functor<T>::nullary_return_type type;
};
}
// is_placeholder
#include <boost/is_placeholder.hpp>
namespace boost
{
template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::FIRST> > >
{
enum _vt { value = 1 };
};
template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::SECOND> > >
{
enum _vt { value = 2 };
};
template<> struct is_placeholder< lambda::lambda_functor< lambda::placeholder<lambda::THIRD> > >
{
enum _vt { value = 3 };
};
} // namespace boost
#endif

View File

@@ -1,6 +1,6 @@
// lambda_fwd.hpp - Boost Lambda Library -------------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
// - lambda_traits.hpp --- Boost Lambda Library ----------------------------
//
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -16,6 +16,7 @@
#include "boost/type_traits/cv_traits.hpp"
#include "boost/type_traits/function_traits.hpp"
#include "boost/type_traits/object_traits.hpp"
#include "boost/tuple/tuple.hpp"
namespace boost {
namespace lambda {
@@ -430,6 +431,56 @@ struct bind_traits<const volatile T[n]> {
typedef const volatile T (&type)[n];
};
template<class R>
struct bind_traits<R()> {
typedef R(&type)();
};
template<class R, class Arg1>
struct bind_traits<R(Arg1)> {
typedef R(&type)(Arg1);
};
template<class R, class Arg1, class Arg2>
struct bind_traits<R(Arg1, Arg2)> {
typedef R(&type)(Arg1, Arg2);
};
template<class R, class Arg1, class Arg2, class Arg3>
struct bind_traits<R(Arg1, Arg2, Arg3)> {
typedef R(&type)(Arg1, Arg2, Arg3);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8);
};
template<class R, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6, class Arg7, class Arg8, class Arg9>
struct bind_traits<R(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)> {
typedef R(&type)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9);
};
template<class T>
struct bind_traits<reference_wrapper<T> >{
typedef T& type;

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library -- member_ptr.hpp ---------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (gary.powell@sierra.com)
//
// Distributed under the Boost Software License, Version 1.0. (See

View File

@@ -1,6 +1,6 @@
// -- operator_actions.hpp - Boost Lambda Library ----------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library - operator_lambda_func_base.hpp -----------------
//
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
// operator_return_type_traits.hpp -- Boost Lambda Library ------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -15,6 +15,7 @@
#include "boost/type_traits/same_traits.hpp"
#include "boost/indirect_reference.hpp"
#include "boost/detail/container_fwd.hpp"
#include <cstddef> // needed for the ptrdiff_t
#include <iosfwd> // for istream and ostream
@@ -58,10 +59,6 @@ template <> struct promote_code<long double> { static const int value = 700; };
} // namespace lambda
} // namespace boost
namespace std {
template<class T> class complex;
}
namespace boost {
namespace lambda {
namespace detail {
@@ -228,34 +225,15 @@ template <> struct contentsof_type<null_type> {
template <class A> struct contentsof_type<const A> {
typedef typename contentsof_type<A>::type type1;
// return a reference to the underlying const type
// the IF is because the A::reference in the primary template could
// be some class type rather than a real reference, hence
// we do not want to make it a reference here either
typedef typename detail::IF<
is_reference<type1>::value,
const typename boost::remove_reference<type1>::type &,
const type1
>::RET type;
typedef typename contentsof_type<A>::type type;
};
template <class A> struct contentsof_type<volatile A> {
typedef typename contentsof_type<A>::type type1;
typedef typename detail::IF<
is_reference<type1>::value,
volatile typename boost::remove_reference<type1>::type &,
volatile type1
>::RET type;
typedef typename contentsof_type<A>::type type;
};
template <class A> struct contentsof_type<const volatile A> {
typedef typename contentsof_type<A>::type type1;
typedef typename detail::IF<
is_reference<type1>::value,
const volatile typename boost::remove_reference<type1>::type &,
const volatile type1
>::RET type;
typedef typename contentsof_type<A>::type type;
};
// standard iterator traits should take care of the pointer types
@@ -853,44 +831,6 @@ struct return_type_2<other_action<subscript_action>, A, B> {
};
} // namespace lambda
} // namespace boost
// Forward declarations are incompatible with the libstdc++ debug mode.
#if BOOST_WORKAROUND(__GNUC__, >= 3) && _GLIBCXX_DEBUG
#include <string>
#include <vector>
#include <map>
#include <deque>
#else
// The GCC 2.95.x uses a non-conformant deque
#if BOOST_WORKAROUND(__GNUC__, == 2) && __GNUC_MINOR__ <= 96
#include <deque>
#else
namespace std {
template <class T, class Allocator> class deque;
}
#endif
namespace std {
template <class Char, class Traits, class Allocator> class basic_string;
template <class T, class Allocator> class vector;
template <class Key, class T, class Cmp, class Allocator> class map;
template <class Key, class T, class Cmp, class Allocator> class multimap;
}
#endif
namespace boost {
namespace lambda {
template<class Key, class T, class Cmp, class Allocator, class B>
struct plain_return_type_2<other_action<subscript_action>, std::map<Key, T, Cmp, Allocator>, B> {
typedef T& type;
@@ -933,6 +873,41 @@ struct plain_return_type_2<other_action<subscript_action>, const std::basic_stri
typedef typename std::basic_string<Char, Traits, Allocator>::const_reference type;
};
template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
std::basic_string<Char, Traits, Allocator>,
std::basic_string<Char, Traits, Allocator> > {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
const Char*,
std::basic_string<Char, Traits, Allocator> > {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator>
struct plain_return_type_2<arithmetic_action<plus_action>,
std::basic_string<Char, Traits, Allocator>,
const Char*> {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator, std::size_t N>
struct plain_return_type_2<arithmetic_action<plus_action>,
Char[N],
std::basic_string<Char, Traits, Allocator> > {
typedef std::basic_string<Char, Traits, Allocator> type;
};
template<class Char, class Traits, class Allocator, std::size_t N>
struct plain_return_type_2<arithmetic_action<plus_action>,
std::basic_string<Char, Traits, Allocator>,
Char[N]> {
typedef std::basic_string<Char, Traits, Allocator> type;
};
} // namespace lambda
} // namespace boost

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library - operators.hpp --------------------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -37,16 +37,16 @@ inline const \
lambda_functor< \
lambda_functor_base< \
ACTION, \
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB>::type> \
tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type> \
> \
> \
OPER_NAME (const lambda_functor<Arg>& a, CONSTB& b) { \
return \
lambda_functor_base< \
ACTION, \
tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB>::type> \
tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type>\
> \
(tuple<lambda_functor<Arg>, typename CONVERSION <CONSTB>::type>(a, b)); \
(tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type>(a, b)); \
}
@@ -258,17 +258,17 @@ operator>>(const lambda_functor<Arg>& a, Ret(&b)(ManipArg))
#error "Multiple defines of BOOST_LAMBDA_PTR_ARITHMETIC_E1"
#endif
#define BOOST_LAMBDA_PTR_ARITHMETIC_E1(OPER_NAME, ACTION, CONSTB) \
#define BOOST_LAMBDA_PTR_ARITHMETIC_E1(OPER_NAME, ACTION, CONSTB) \
template<class Arg, int N, class B> \
inline const \
lambda_functor< \
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
> \
OPER_NAME (const lambda_functor<Arg>& a, CONSTB(&b)[N]) \
OPER_NAME (const lambda_functor<Arg>& a, CONSTB(&b)[N]) \
{ \
return lambda_functor< \
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
>(tuple<lambda_functor<Arg>, CONSTB(&)[N]>(a, b)); \
return \
lambda_functor_base<ACTION, tuple<lambda_functor<Arg>, CONSTB(&)[N]> > \
(tuple<lambda_functor<Arg>, CONSTB(&)[N]>(a, b)); \
}
@@ -276,15 +276,15 @@ OPER_NAME (const lambda_functor<Arg>& a, CONSTB(&b)[N]) \
#error "Multiple defines of BOOST_LAMBDA_PTR_ARITHMETIC_E2"
#endif
#define BOOST_LAMBDA_PTR_ARITHMETIC_E2(OPER_NAME, ACTION, CONSTA) \
template<int N, class A, class Arg> \
inline const \
lambda_functor< \
#define BOOST_LAMBDA_PTR_ARITHMETIC_E2(OPER_NAME, ACTION, CONSTA) \
template<int N, class A, class Arg> \
inline const \
lambda_functor< \
lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > > \
> \
> \
OPER_NAME (CONSTA(&a)[N], const lambda_functor<Arg>& b) \
{ \
return \
{ \
return \
lambda_functor_base<ACTION, tuple<CONSTA(&)[N], lambda_functor<Arg> > > \
(tuple<CONSTA(&)[N], lambda_functor<Arg> >(a, b)); \
}

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library ret.hpp -----------------------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -284,7 +284,7 @@ inline const
lambda_functor<
lambda_functor_base<do_nothing_action, null_type>
>
make_void(const Arg1& a1) {
make_void(const Arg1&) {
return
lambda_functor_base<do_nothing_action, null_type>();
}

View File

@@ -1,6 +1,6 @@
// return_type_traits.hpp -- Boost Lambda Library ---------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -216,8 +216,6 @@ typedef typename
// currently there are no protectable actions with > 2 args
// Note, that if there will be, lambda_functor_base will have to be
// changed to not get rid of references in Args elements
template<class Act, class Args> struct return_type_N_prot {
typedef typename return_type_N<Act, Args>::type type;

View File

@@ -1,6 +1,6 @@
// -- select_functions.hpp -- Boost Lambda Library --------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -0,0 +1,27 @@
// Boost Lambda Library suppress_unused.hpp -----------------------------
//
// Copyright (C) 2009 Steven Watanabe
//
// 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)
//
// For more information, see www.boost.org
// ------------------------------------------------------------
#ifndef BOOST_LAMBDA_SUPRESS_UNUSED_HPP
#define BOOST_LAMBDA_SUPRESS_UNUSED_HPP
namespace boost {
namespace lambda {
namespace detail {
template<class T>
inline void suppress_unused_variable_warnings(const T&) {}
}
}
}
#endif

View File

@@ -1,7 +1,7 @@
// -- Boost Lambda Library -- exceptions.hpp ----------------
//
// Copyright (C) 2000 Gary Powell (gwpowell@hotmail.com)
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -14,6 +14,7 @@
#if !defined(BOOST_LAMBDA_EXCEPTIONS_HPP)
#define BOOST_LAMBDA_EXCEPTIONS_HPP
#include "boost/lambda/core.hpp"
#include "boost/lambda/detail/control_constructs_common.hpp"
namespace boost {

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library -- if.hpp ------------------------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 2001-2002 Joel de Guzman
//
@@ -345,7 +345,7 @@ public:
// is true, the true_statement (again an lambda_functor) is executed
// otherwise, the false_statement (another lambda_functor) is executed. The
// result type of this is void. Note the trailing underscore after
// if_ and the the leading dot and the trailing underscore before
// if_ and the leading dot and the trailing underscore before
// and after .else_.
//
///////////////////////////////////////////////////////////////////////////////

View File

@@ -1,5 +1,5 @@
// -- lambda.hpp -- Boost Lambda Library -----------------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at

View File

@@ -1,6 +1,6 @@
// Boost Lambda Library -- loops.hpp ----------------------------------------
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (c) 2001-2002 Joel de Guzman
//
@@ -348,7 +348,7 @@ while_(CondT const& cond)
// While the condition (an lambda_functor) evaluates to true, statement
// (another lambda_functor) is executed. The statement is executed at least
// once. The result type of this is void. Note the trailing
// underscore after do_ and the the leading dot and the trailing
// underscore after do_ and the leading dot and the trailing
// underscore before and after .while_.
//
///////////////////////////////////////////////////////////////////////////////

View File

@@ -1,5 +1,5 @@
// -- numeric.hpp -- Boost Lambda Library -----------------------------------
// Copyright (C) 2002 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2002 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2002 Gary Powell (gwpowell@hotmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See

View File

@@ -1,7 +1,7 @@
// Boost Lambda Library -- switch.hpp -----------------------------------
//
// Copyright (C) 2000 Gary Powell (powellg@amazon.com)
// Copyright (C) 1999, 2000 Jaakko Järvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -465,12 +465,18 @@ BOOST_LAMBDA_SWITCH( BOOST_PP_INC(N) )
#define BOOST_LAMBDA_SWITCH_STATEMENT_HELPER(z, N, A) \
BOOST_LAMBDA_SWITCH_STATEMENT(BOOST_PP_INC(N))
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4065)
#endif
// up to 9 cases supported (counting default:)
BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_HELPER,FOO)
BOOST_PP_REPEAT_2ND(9,BOOST_LAMBDA_SWITCH_STATEMENT_HELPER,FOO)
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
} // namespace lambda
} // namespace boost

12
index.html Normal file
View File

@@ -0,0 +1,12 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=../../doc/html/lambda.html">
</head>
<body>
Automatic redirection failed, please go to <a href="../../doc/html/lambda.html">www.boost.org/doc/html/lambda.html</a>&nbsp;<hr>
<p>© Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

35
test/Jamfile Normal file
View File

@@ -0,0 +1,35 @@
# Lambda library
# Copyright (C) 2001-2003 Jaakko Järvi
# 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)
# For more information, see http://www.boost.org/
import testing ;
project
: requirements <toolset>msvc:<asynch-exceptions>on
;
test-suite lambda
: [ run algorithm_test.cpp ]
[ run bind_tests_simple.cpp ]
[ run bind_tests_advanced.cpp ]
[ run bind_tests_simple_f_refs.cpp ]
[ run bll_and_function.cpp ]
[ run cast_test.cpp : : : : lambda_cast_test ]
[ run constructor_tests.cpp ]
[ run control_structures.cpp ]
[ run exception_test.cpp ]
[ run extending_rt_traits.cpp ]
[ run is_instance_of_test.cpp ]
[ run member_pointer_test.cpp ]
[ run operator_tests_simple.cpp ]
[ run phoenix_control_structures.cpp ]
[ run switch_construct.cpp ]
[ run result_of_tests.cpp ]
[ run ret_test.cpp ]
;

89
test/Makefile Normal file
View File

@@ -0,0 +1,89 @@
BOOST = ../../..
CXX = g++
EXTRAFLAGS = -pedantic -Wno-long-long -Wno-long-double -ftemplate-depth-50
LIBS = -lstdc++
#CXX = KCC
#EXTRAFLAGS = --strict --display_error_number --diag_suppress 450 --max_pending_instantiations 50
#LIBS =
INCLUDES = -I$(BOOST)
CXXFLAGS = $(INCLUDES) $(EXTRAFLAGS)
LIBFLAGS = $(LIBS)
AR = ar
.SUFFIXES: .cpp .o
SOURCES = \
is_instance_of_test.cpp \
operator_tests_simple.cpp \
member_pointer_test.cpp \
control_structures.cpp \
switch_construct.cpp \
bind_tests_simple.cpp \
bind_tests_advanced.cpp \
bll_and_function.cpp \
constructor_tests.cpp \
extending_rt_traits.cpp \
bind_tests_simple_f_refs.cpp \
cast_test.cpp \
phoenix_control_structures.cpp \
exception_test.cpp \
# Create lists of object files from the source file lists.
OBJECTS = ${SOURCES:.cpp=.o}
TARGETS = ${SOURCES:.cpp=.exe}
all: $(TARGETS)
%.exe: %.o
$(CXX) $(LIBFLAGS) $(CXXFLAGS) -o $@ $<
%.o: %.cpp
$(CXX) $(CXXFLAGS) -o $@ -c $<
%.dep: %.cpp
set -e; $(CXX) -M $(INCLUDES) -c $< \
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
[ -s $@ ] || rm -f $@
DEP_FILES = $(SOURCES:.cpp=.dep)
include $(DEP_FILES)
clean:
/bin/rm -rf $(TARGETS) $(OBJECTS) $(DEP_FILES)
run:
./is_instance_of_test.exe
./member_pointer_test.exe
./operator_tests_simple.exe
./control_structures.exe
./switch_construct.exe
./extending_rt_traits.exe
./constructor_tests.exe
./cast_test.exe
./bind_tests_simple.exe
./bind_tests_advanced.exe
./bll_and_function.exe
./bind_tests_simple_f_refs.exe
./phoenix_control_structures.exe
./exception_test.exe

View File

@@ -0,0 +1,6 @@
gcc 2.96
cannot compile
exception_test.cpp (internal compiler error)

60
test/algorithm_test.cpp Normal file
View File

@@ -0,0 +1,60 @@
// bll_and_function.cpp - The Boost Lambda Library -----------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// test using BLL and boost::function
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
#include "boost/lambda/algorithm.hpp"
#include <vector>
#include <map>
#include <set>
#include <string>
#include <iostream>
void test_foreach() {
using namespace boost::lambda;
int a[10][20];
int sum = 0;
std::for_each(a, a + 10,
bind(ll::for_each(), _1, _1 + 20,
protect((_1 = var(sum), ++var(sum)))));
sum = 0;
std::for_each(a, a + 10,
bind(ll::for_each(), _1, _1 + 20,
protect((sum += _1))));
BOOST_CHECK(sum == (199 + 1)/ 2 * 199);
}
// More tests needed (for all algorithms)
int test_main(int, char *[]) {
test_foreach();
return 0;
}

View File

@@ -0,0 +1,420 @@
// bind_tests_advanced.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
// Copyright (C) 2010 Steven Watanabe
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
#include "boost/any.hpp"
#include "boost/type_traits/is_reference.hpp"
#include "boost/mpl/assert.hpp"
#include "boost/mpl/if.hpp"
#include <iostream>
#include <functional>
#include <algorithm>
using namespace boost::lambda;
namespace bl = boost::lambda;
int sum_0() { return 0; }
int sum_1(int a) { return a; }
int sum_2(int a, int b) { return a+b; }
int product_2(int a, int b) { return a*b; }
// unary function that returns a pointer to a binary function
typedef int (*fptr_type)(int, int);
fptr_type sum_or_product(bool x) {
return x ? sum_2 : product_2;
}
// a nullary functor that returns a pointer to a unary function that
// returns a pointer to a binary function.
struct which_one {
typedef fptr_type (*result_type)(bool x);
template <class T> struct sig { typedef result_type type; };
result_type operator()() const { return sum_or_product; }
};
void test_nested_binds()
{
int j = 2; int k = 3;
// bind calls can be nested (the target function can be a lambda functor)
// The interpretation is, that the innermost lambda functor returns something
// that is bindable (another lambda functor, function pointer ...)
bool condition;
condition = true;
BOOST_CHECK(bind(bind(&sum_or_product, _1), 1, 2)(condition)==3);
BOOST_CHECK(bind(bind(&sum_or_product, _1), _2, _3)(condition, j, k)==5);
condition = false;
BOOST_CHECK(bind(bind(&sum_or_product, _1), 1, 2)(condition)==2);
BOOST_CHECK(bind(bind(&sum_or_product, _1), _2, _3)(condition, j, k)==6);
which_one wo;
BOOST_CHECK(bind(bind(bind(wo), _1), _2, _3)(condition, j, k)==6);
return;
}
// unlambda -------------------------------------------------
// Sometimes it may be necessary to prevent the argument substitution of
// taking place. For example, we may end up with a nested bind expression
// inadvertently when using the target function is received as a parameter
template<class F>
int call_with_100(const F& f) {
// bind(f, _1)(make_const(100));
// This would result in;
// bind(_1 + 1, _1)(make_const(100)) , which would be a compile time error
return bl::bind(unlambda(f), _1)(make_const(100));
// for other functors than lambda functors, unlambda has no effect
// (except for making them const)
}
template<class F>
int call_with_101(const F& f) {
return bind(unlambda(f), _1)(make_const(101));
}
void test_unlambda() {
int i = 1;
BOOST_CHECK(unlambda(_1 + _2)(i, i) == 2);
BOOST_CHECK(unlambda(++var(i))() == 2);
BOOST_CHECK(call_with_100(_1 + 1) == 101);
BOOST_CHECK(call_with_101(_1 + 1) == 102);
BOOST_CHECK(call_with_100(bl::bind(std_functor(std::bind1st(std::plus<int>(), 1)), _1)) == 101);
// std_functor insturcts LL that the functor defines a result_type typedef
// rather than a sig template.
bl::bind(std_functor(std::plus<int>()), _1, _2)(i, i);
}
// protect ------------------------------------------------------------
// protect protects a lambda functor from argument substitution.
// protect is useful e.g. with nested stl algorithm calls.
namespace ll {
struct for_each {
// note, std::for_each returns it's last argument
// We want the same behaviour from our ll::for_each.
// However, the functor can be called with any arguments, and
// the return type thus depends on the argument types.
// 1. Provide a sig class member template:
// The return type deduction system instantiate this class as:
// sig<Args>::type, where Args is a boost::tuples::cons-list
// The head type is the function object type itself
// cv-qualified (so it is possilbe to provide different return types
// for differently cv-qualified operator()'s.
// The tail type is the list of the types of the actual arguments the
// function was called with.
// So sig should contain a typedef type, which defines a mapping from
// the operator() arguments to its return type.
// Note, that it is possible to provide different sigs for the same functor
// if the functor has several operator()'s, even if they have different
// number of arguments.
// Note, that the argument types in Args are guaranteed to be non-reference
// types, but they can have cv-qualifiers.
template <class Args>
struct sig {
typedef typename boost::remove_const<
typename boost::tuples::element<3, Args>::type
>::type type;
};
template <class A, class B, class C>
C
operator()(const A& a, const B& b, const C& c) const
{ return std::for_each(a, b, c);}
};
} // end of ll namespace
void test_protect()
{
int i = 0;
int b[3][5];
int* a[3];
for(int j=0; j<3; ++j) a[j] = b[j];
std::for_each(a, a+3,
bind(ll::for_each(), _1, _1 + 5, protect(_1 = ++var(i))));
// This is how you could output the values (it is uncommented, no output
// from a regression test file):
// std::for_each(a, a+3,
// bind(ll::for_each(), _1, _1 + 5,
// std::cout << constant("\nLine ") << (&_1 - a) << " : "
// << protect(_1)
// )
// );
int sum = 0;
std::for_each(a, a+3,
bind(ll::for_each(), _1, _1 + 5,
protect(sum += _1))
);
BOOST_CHECK(sum == (1+15)*15/2);
sum = 0;
std::for_each(a, a+3,
bind(ll::for_each(), _1, _1 + 5,
sum += 1 + protect(_1)) // add element count
);
BOOST_CHECK(sum == (1+15)*15/2 + 15);
(1 + protect(_1))(sum);
int k = 0;
((k += constant(1)) += protect(constant(2)))();
BOOST_CHECK(k==1);
k = 0;
((k += constant(1)) += protect(constant(2)))()();
BOOST_CHECK(k==3);
// note, the following doesn't work:
// ((var(k) = constant(1)) = protect(constant(2)))();
// (var(k) = constant(1))() returns int& and thus the
// second assignment fails.
// We should have something like:
// bind(var, var(k) = constant(1)) = protect(constant(2)))();
// But currently var is not bindable.
// The same goes with ret. A bindable ret could be handy sometimes as well
// (protect(std::cout << _1), std::cout << _1)(i)(j); does not work
// because the comma operator tries to store the result of the evaluation
// of std::cout << _1 as a copy (and you can't copy std::ostream).
// something like this:
// (protect(std::cout << _1), bind(ref, std::cout << _1))(i)(j);
// the stuff below works, but we do not want extra output to
// cout, must be changed to stringstreams but stringstreams do not
// work due to a bug in the type deduction. Will be fixed...
#if 0
// But for now, ref is not bindable. There are other ways around this:
int x = 1, y = 2;
(protect(std::cout << _1), (std::cout << _1, 0))(x)(y);
// added one dummy value to make the argument to comma an int
// instead of ostream&
// Note, the same problem is more apparent without protect
// (std::cout << 1, std::cout << constant(2))(); // does not work
(boost::ref(std::cout << 1), std::cout << constant(2))(); // this does
#endif
}
void test_lambda_functors_as_arguments_to_lambda_functors() {
// lambda functor is a function object, and can therefore be used
// as an argument to another lambda functors function call object.
// Note however, that the argument/type substitution is not entered again.
// This means, that something like this will not work:
(_1 + _2)(_1, make_const(7));
(_1 + _2)(bind(&sum_0), make_const(7));
// or it does work, but the effect is not to call
// sum_0() + 7, but rather
// bind(sum_0) + 7, which results in another lambda functor
// (lambda functor + int) and can be called again
BOOST_CHECK((_1 + _2)(bind(&sum_0), make_const(7))() == 7);
int i = 3, j = 12;
BOOST_CHECK((_1 - _2)(_2, _1)(i, j) == j - i);
// also, note that lambda functor are no special case for bind if received
// as a parameter. In oder to be bindable, the functor must
// defint the sig template, or then
// the return type must be defined within the bind call. Lambda functors
// do define the sig template, so if the return type deduction system
// covers the case, there is no need to specify the return type
// explicitly.
int a = 5, b = 6;
// Let type deduction find out the return type
BOOST_CHECK(bind(_1, _2, _3)(unlambda(_1 + _2), a, b) == 11);
//specify it yourself:
BOOST_CHECK(bind(_1, _2, _3)(ret<int>(_1 + _2), a, b) == 11);
BOOST_CHECK(ret<int>(bind(_1, _2, _3))(_1 + _2, a, b) == 11);
BOOST_CHECK(bind<int>(_1, _2, _3)(_1 + _2, a, b) == 11);
bind(_1,1.0)(_1+_1);
return;
}
void test_const_parameters() {
// (_1 + _2)(1, 2); // this would fail,
// Either make arguments const:
BOOST_CHECK((_1 + _2)(make_const(1), make_const(2)) == 3);
// Or use const_parameters:
BOOST_CHECK(const_parameters(_1 + _2)(1, 2) == 3);
}
void test_rvalue_arguments()
{
// Not quite working yet.
// Problems with visual 7.1
// BOOST_CHECK((_1 + _2)(1, 2) == 3);
}
void test_break_const()
{
// break_const is currently unnecessary, as LL supports perfect forwarding
// for up to there argument lambda functors, and LL does not support
// lambda functors with more than 3 args.
// I'll keep the test case around anyway, if more arguments will be supported
// in the future.
// break_const breaks constness! Be careful!
// You need this only if you need to have side effects on some argument(s)
// and some arguments are non-const rvalues and your lambda functors
// take more than 3 arguments.
int i = 1;
// OLD COMMENT: (_1 += _2)(i, 2) // fails, 2 is a non-const rvalue
// OLD COMMENT: const_parameters(_1 += _2)(i, 2) // fails, side-effect to i
break_const(_1 += _2)(i, 2); // ok
BOOST_CHECK(i == 3);
}
template<class T>
struct func {
template<class Args>
struct sig {
typedef typename boost::tuples::element<1, Args>::type arg1;
// If the argument type is not the same as the expected type,
// return void, which will cause an error. Note that we
// can't just assert that the types are the same, because
// both const and non-const versions can be instantiated
// even though only one is ultimately used.
typedef typename boost::mpl::if_<boost::is_same<arg1, T>,
typename boost::remove_const<arg1>::type,
void
>::type type;
};
template<class U>
U operator()(const U& arg) const {
return arg;
}
};
void test_sig()
{
int i = 1;
BOOST_CHECK(bind(func<int>(), 1)() == 1);
BOOST_CHECK(bind(func<const int>(), _1)(static_cast<const int&>(i)) == 1);
BOOST_CHECK(bind(func<int>(), _1)(i) == 1);
}
class base {
public:
virtual int foo() = 0;
};
class derived : public base {
public:
virtual int foo() {
return 1;
}
};
void test_abstract()
{
derived d;
base& b = d;
BOOST_CHECK(bind(&base::foo, var(b))() == 1);
BOOST_CHECK(bind(&base::foo, *_1)(&b) == 1);
}
int test_main(int, char *[]) {
test_nested_binds();
test_unlambda();
test_protect();
test_lambda_functors_as_arguments_to_lambda_functors();
test_const_parameters();
test_rvalue_arguments();
test_break_const();
test_sig();
test_abstract();
return 0;
}

187
test/bind_tests_simple.cpp Normal file
View File

@@ -0,0 +1,187 @@
// bind_tests_simple.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/bind.hpp"
#include <iostream>
using namespace boost::lambda;
int sum_of_args_0() { return 0; }
int sum_of_args_1(int a) { return a; }
int sum_of_args_2(int a, int b) { return a+b; }
int sum_of_args_3(int a, int b, int c) { return a+b+c; }
int sum_of_args_4(int a, int b, int c, int d) { return a+b+c+d; }
int sum_of_args_5(int a, int b, int c, int d, int e) { return a+b+c+d+e; }
int sum_of_args_6(int a, int b, int c, int d, int e, int f) { return a+b+c+d+e+f; }
int sum_of_args_7(int a, int b, int c, int d, int e, int f, int g) { return a+b+c+d+e+f+g; }
int sum_of_args_8(int a, int b, int c, int d, int e, int f, int g, int h) { return a+b+c+d+e+f+g+h; }
int sum_of_args_9(int a, int b, int c, int d, int e, int f, int g, int h, int i) { return a+b+c+d+e+f+g+h+i; }
// ----------------------------
class A {
int i;
public:
A(int n) : i(n) {};
int add(const int& j) { return i + j; }
int add2(int a1, int a2) { return i + a1 + a2; }
int add3(int a1, int a2, int a3) { return i + a1 + a2 + a3; }
int add4(int a1, int a2, int a3, int a4) { return i + a1 + a2 + a3 + a4; }
int add5(int a1, int a2, int a3, int a4, int a5)
{ return i + a1 + a2 + a3 + a4 + a5; }
int add6(int a1, int a2, int a3, int a4, int a5, int a6)
{ return i + a1 + a2 + a3 + a4 + a5 + a6; }
int add7(int a1, int a2, int a3, int a4, int a5, int a6, int a7)
{ return i + a1 + a2 + a3 + a4 + a5 + a6 + a7; }
int add8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
{ return i + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8; }
};
void test_member_functions()
{
using boost::ref;
A a(10);
int i = 1;
BOOST_CHECK(bind(&A::add, ref(a), _1)(i) == 11);
BOOST_CHECK(bind(&A::add, &a, _1)(i) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(a) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(make_const(&a)) == 11);
BOOST_CHECK(bind(&A::add2, _1, 1, 1)(a) == 12);
BOOST_CHECK(bind(&A::add3, _1, 1, 1, 1)(a) == 13);
BOOST_CHECK(bind(&A::add4, _1, 1, 1, 1, 1)(a) == 14);
BOOST_CHECK(bind(&A::add5, _1, 1, 1, 1, 1, 1)(a) == 15);
BOOST_CHECK(bind(&A::add6, _1, 1, 1, 1, 1, 1, 1)(a) == 16);
BOOST_CHECK(bind(&A::add7, _1, 1, 1, 1, 1, 1, 1, 1)(a) == 17);
BOOST_CHECK(bind(&A::add8, _1, 1, 1, 1, 1, 1, 1, 1, 1)(a) == 18);
// This should fail, as lambda functors store arguments as const
// bind(&A::add, a, _1);
}
struct B {
B(int n) : i(n) {};
int i;
};
void test_data_members()
{
using boost::ref;
B b(10);
BOOST_CHECK(bind(&B::i, ref(b))() == 10);
BOOST_CHECK(bind(&B::i, b)() == 10);
BOOST_CHECK(bind(&B::i, _1)(b) == 10);
BOOST_CHECK(bind(&B::i, _1)(B(11)) == 11);
bind(&B::i, ref(b))() = 1;
BOOST_CHECK(b.i == 1);
}
int test_main(int, char *[]) {
int i = 1; int j = 2; int k = 3;
int result;
// bind all parameters
BOOST_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, 1)()==1);
BOOST_CHECK(bind(&sum_of_args_2, 1, 2)()==3);
BOOST_CHECK(bind(&sum_of_args_3, 1, 2, 3)()==6);
BOOST_CHECK(bind(&sum_of_args_4, 1, 2, 3, 4)()==10);
BOOST_CHECK(bind(&sum_of_args_5, 1, 2, 3, 4, 5)()==15);
BOOST_CHECK(bind(&sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21);
BOOST_CHECK(bind(&sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28);
BOOST_CHECK(bind(&sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36);
BOOST_CHECK(bind(&sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45);
// first parameter open
BOOST_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(&sum_of_args_2, _1, 2)(i)==3);
BOOST_CHECK(bind(&sum_of_args_3, _1, 2, 3)(i)==6);
BOOST_CHECK(bind(&sum_of_args_4, _1, 2, 3, 4)(i)==10);
BOOST_CHECK(bind(&sum_of_args_5, _1, 2, 3, 4, 5)(i)==15);
BOOST_CHECK(bind(&sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21);
BOOST_CHECK(bind(&sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28);
BOOST_CHECK(bind(&sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36);
BOOST_CHECK(bind(&sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45);
// two open arguments
BOOST_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(&sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(&sum_of_args_3, _1, _2, 3)(i, j)==6);
BOOST_CHECK(bind(&sum_of_args_4, _1, _2, 3, 4)(i, j)==10);
BOOST_CHECK(bind(&sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15);
BOOST_CHECK(bind(&sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21);
BOOST_CHECK(bind(&sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28);
BOOST_CHECK(bind(&sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36);
BOOST_CHECK(bind(&sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45);
// three open arguments
BOOST_CHECK(bind(&sum_of_args_0)()==0);
BOOST_CHECK(bind(&sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(&sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(&sum_of_args_3, _1, _2, _3)(i, j, k)==6);
BOOST_CHECK(bind(&sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10);
BOOST_CHECK(bind(&sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15);
BOOST_CHECK(bind(&sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21);
BOOST_CHECK(bind(&sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28);
BOOST_CHECK(bind(&sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36);
BOOST_CHECK(bind(&sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45);
// function compositions with bind
BOOST_CHECK(bind(&sum_of_args_3, bind(&sum_of_args_2, _1, 2), 2, 3)(i)==8);
BOOST_CHECK(
bind(&sum_of_args_9,
bind(&sum_of_args_0), // 0
bind(&sum_of_args_1, _1), // 1
bind(&sum_of_args_2, _1, _2), // 3
bind(&sum_of_args_3, _1, _2, _3), // 6
bind(&sum_of_args_4, _1, _2, _3, 4), // 10
bind(&sum_of_args_5, _1, _2, _3, 4, 5), // 15
bind(&sum_of_args_6, _1, _2, _3, 4, 5, 6), // 21
bind(&sum_of_args_7, _1, _2, _3, 4, 5, 6, 7), // 28
bind(&sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8) // 36
)(i, j, k) == 120);
// deeper nesting
result =
bind(&sum_of_args_1, // 12
bind(&sum_of_args_4, // 12
bind(&sum_of_args_2, // 3
bind(&sum_of_args_1, // 1
bind(&sum_of_args_1, _1) // 1
),
_2),
_2,
_3,
4)
)(i, j, k);
BOOST_CHECK(result == 12);
test_member_functions();
return 0;
}

View File

@@ -0,0 +1,148 @@
// bind_tests_simple.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/bind.hpp"
#include <iostream>
using namespace boost::lambda;
int sum_of_args_0() { return 0; }
int sum_of_args_1(int a) { return a; }
int sum_of_args_2(int a, int b) { return a+b; }
int sum_of_args_3(int a, int b, int c) { return a+b+c; }
int sum_of_args_4(int a, int b, int c, int d) { return a+b+c+d; }
int sum_of_args_5(int a, int b, int c, int d, int e) { return a+b+c+d+e; }
int sum_of_args_6(int a, int b, int c, int d, int e, int f) { return a+b+c+d+e+f; }
int sum_of_args_7(int a, int b, int c, int d, int e, int f, int g) { return a+b+c+d+e+f+g; }
int sum_of_args_8(int a, int b, int c, int d, int e, int f, int g, int h) { return a+b+c+d+e+f+g+h; }
int sum_of_args_9(int a, int b, int c, int d, int e, int f, int g, int h, int i) { return a+b+c+d+e+f+g+h+i; }
// ----------------------------
class A {
int i;
public:
A(int n) : i(n) {};
int add(const int& j) { return i + j; }
};
void test_member_functions()
{
using boost::ref;
A a(10);
int i = 1;
BOOST_CHECK(bind(&A::add, ref(a), _1)(i) == 11);
BOOST_CHECK(bind(&A::add, &a, _1)(i) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(a) == 11);
BOOST_CHECK(bind(&A::add, _1, 1)(make_const(&a)) == 11);
// This should fail, as lambda functors store arguments as const
// bind(&A::add, a, _1);
}
int test_main(int, char *[]) {
int i = 1; int j = 2; int k = 3;
int result;
// bind all parameters
BOOST_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, 1)()==1);
BOOST_CHECK(bind(sum_of_args_2, 1, 2)()==3);
BOOST_CHECK(bind(sum_of_args_3, 1, 2, 3)()==6);
BOOST_CHECK(bind(sum_of_args_4, 1, 2, 3, 4)()==10);
BOOST_CHECK(bind(sum_of_args_5, 1, 2, 3, 4, 5)()==15);
BOOST_CHECK(bind(sum_of_args_6, 1, 2, 3, 4, 5, 6)()==21);
BOOST_CHECK(bind(sum_of_args_7, 1, 2, 3, 4, 5, 6, 7)()==28);
BOOST_CHECK(bind(sum_of_args_8, 1, 2, 3, 4, 5, 6, 7, 8)()==36);
BOOST_CHECK(bind(sum_of_args_9, 1, 2, 3, 4, 5, 6, 7, 8, 9)()==45);
// first parameter open
BOOST_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(sum_of_args_2, _1, 2)(i)==3);
BOOST_CHECK(bind(sum_of_args_3, _1, 2, 3)(i)==6);
BOOST_CHECK(bind(sum_of_args_4, _1, 2, 3, 4)(i)==10);
BOOST_CHECK(bind(sum_of_args_5, _1, 2, 3, 4, 5)(i)==15);
BOOST_CHECK(bind(sum_of_args_6, _1, 2, 3, 4, 5, 6)(i)==21);
BOOST_CHECK(bind(sum_of_args_7, _1, 2, 3, 4, 5, 6, 7)(i)==28);
BOOST_CHECK(bind(sum_of_args_8, _1, 2, 3, 4, 5, 6, 7, 8)(i)==36);
BOOST_CHECK(bind(sum_of_args_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i)==45);
// two open arguments
BOOST_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(sum_of_args_3, _1, _2, 3)(i, j)==6);
BOOST_CHECK(bind(sum_of_args_4, _1, _2, 3, 4)(i, j)==10);
BOOST_CHECK(bind(sum_of_args_5, _1, _2, 3, 4, 5)(i, j)==15);
BOOST_CHECK(bind(sum_of_args_6, _1, _2, 3, 4, 5, 6)(i, j)==21);
BOOST_CHECK(bind(sum_of_args_7, _1, _2, 3, 4, 5, 6, 7)(i, j)==28);
BOOST_CHECK(bind(sum_of_args_8, _1, _2, 3, 4, 5, 6, 7, 8)(i, j)==36);
BOOST_CHECK(bind(sum_of_args_9, _1, _2, 3, 4, 5, 6, 7, 8, 9)(i, j)==45);
// three open arguments
BOOST_CHECK(bind(sum_of_args_0)()==0);
BOOST_CHECK(bind(sum_of_args_1, _1)(i)==1);
BOOST_CHECK(bind(sum_of_args_2, _1, _2)(i, j)==3);
BOOST_CHECK(bind(sum_of_args_3, _1, _2, _3)(i, j, k)==6);
BOOST_CHECK(bind(sum_of_args_4, _1, _2, _3, 4)(i, j, k)==10);
BOOST_CHECK(bind(sum_of_args_5, _1, _2, _3, 4, 5)(i, j, k)==15);
BOOST_CHECK(bind(sum_of_args_6, _1, _2, _3, 4, 5, 6)(i, j, k)==21);
BOOST_CHECK(bind(sum_of_args_7, _1, _2, _3, 4, 5, 6, 7)(i, j, k)==28);
BOOST_CHECK(bind(sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8)(i, j, k)==36);
BOOST_CHECK(bind(sum_of_args_9, _1, _2, _3, 4, 5, 6, 7, 8, 9)(i, j, k)==45);
// function compositions with bind
BOOST_CHECK(bind(sum_of_args_3, bind(sum_of_args_2, _1, 2), 2, 3)(i)==8);
BOOST_CHECK(
bind(sum_of_args_9,
bind(sum_of_args_0), // 0
bind(sum_of_args_1, _1), // 1
bind(sum_of_args_2, _1, _2), // 3
bind(sum_of_args_3, _1, _2, _3), // 6
bind(sum_of_args_4, _1, _2, _3, 4), // 10
bind(sum_of_args_5, _1, _2, _3, 4, 5), // 15
bind(sum_of_args_6, _1, _2, _3, 4, 5, 6), // 21
bind(sum_of_args_7, _1, _2, _3, 4, 5, 6, 7), // 28
bind(sum_of_args_8, _1, _2, _3, 4, 5, 6, 7, 8) // 36
)(i, j, k) == 120);
// deeper nesting
result =
bind(sum_of_args_1, // 12
bind(sum_of_args_4, // 12
bind(sum_of_args_2, // 3
bind(sum_of_args_1, // 1
bind(sum_of_args_1, _1) // 1
),
_2),
_2,
_3,
4)
)(i, j, k);
BOOST_CHECK(result == 12);
test_member_functions();
return 0;
}

68
test/bll_and_function.cpp Normal file
View File

@@ -0,0 +1,68 @@
// bll_and_function.cpp - The Boost Lambda Library -----------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// test using BLL and boost::function
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/function.hpp"
#include <vector>
#include <map>
#include <set>
#include <string>
using namespace boost::lambda;
using namespace std;
void test_function() {
boost::function<int (int, int)> f;
f = _1 + _2;
BOOST_CHECK(f(1, 2)== 3);
int i=1; int j=2;
boost::function<int& (int&, int)> g = _1 += _2;
g(i, j);
BOOST_CHECK(i==3);
int* sum = new int();
*sum = 0;
boost::function<int& (int)> counter = *sum += _1;
counter(5); // ok, sum* = 5;
BOOST_CHECK(*sum == 5);
delete sum;
// The next statement would lead to a dangling reference
// counter(3); // error, *sum does not exist anymore
}
int test_main(int, char *[]) {
test_function();
return 0;
}

107
test/cast_test.cpp Normal file
View File

@@ -0,0 +1,107 @@
// cast_tests.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/casts.hpp"
#include <string>
using namespace boost::lambda;
using namespace std;
class base {
int x;
public:
virtual std::string class_name() const { return "const base"; }
virtual std::string class_name() { return "base"; }
virtual ~base() {}
};
class derived : public base {
int y[100];
public:
virtual std::string class_name() const { return "const derived"; }
virtual std::string class_name() { return "derived"; }
};
void do_test() {
derived *p_derived = new derived;
base *p_base = new base;
base *b = 0;
derived *d = 0;
(var(b) = ll_static_cast<base *>(p_derived))();
(var(d) = ll_static_cast<derived *>(b))();
BOOST_CHECK(b->class_name() == "derived");
BOOST_CHECK(d->class_name() == "derived");
(var(b) = ll_dynamic_cast<derived *>(b))();
BOOST_CHECK(b != 0);
BOOST_CHECK(b->class_name() == "derived");
(var(d) = ll_dynamic_cast<derived *>(p_base))();
BOOST_CHECK(d == 0);
const derived* p_const_derived = p_derived;
BOOST_CHECK(p_const_derived->class_name() == "const derived");
(var(d) = ll_const_cast<derived *>(p_const_derived))();
BOOST_CHECK(d->class_name() == "derived");
int i = 10;
char* cp = reinterpret_cast<char*>(&i);
int* ip;
(var(ip) = ll_reinterpret_cast<int *>(cp))();
BOOST_CHECK(*ip == 10);
// typeid
BOOST_CHECK(string(ll_typeid(d)().name()) == string(typeid(d).name()));
// sizeof
BOOST_CHECK(ll_sizeof(_1)(p_derived) == sizeof(p_derived));
BOOST_CHECK(ll_sizeof(_1)(*p_derived) == sizeof(*p_derived));
BOOST_CHECK(ll_sizeof(_1)(p_base) == sizeof(p_base));
BOOST_CHECK(ll_sizeof(_1)(*p_base) == sizeof(*p_base));
int an_array[100];
BOOST_CHECK(ll_sizeof(_1)(an_array) == 100 * sizeof(int));
delete p_derived;
delete p_base;
}
int test_main(int, char *[]) {
do_test();
return 0;
}

265
test/constructor_tests.cpp Normal file
View File

@@ -0,0 +1,265 @@
// constructor_tests.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
#include "boost/lambda/construct.hpp"
#include <iostream>
#include <algorithm>
#include <vector>
#ifdef BOOST_MSVC
#pragma warning(disable:4512)
#endif
using namespace boost::lambda;
namespace bl = boost::lambda;
template<class T>
bool check_tuple(int n, const T& t)
{
return (t.get_head() == n) && check_tuple(n+1, t.get_tail());
}
template <>
bool check_tuple(int /*n*/, const null_type& ) { return true; }
void constructor_all_lengths()
{
bool ok;
ok = check_tuple(
1,
bind(constructor<tuple<int> >(),
1)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int> >(),
1, 2)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int> >(),
1, 2, 3)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int> >(),
1, 2, 3, 4)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int> >(),
1, 2, 3, 4, 5)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8)()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
bind(constructor<tuple<int, int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8, 9)()
);
BOOST_CHECK(ok);
}
void new_ptr_all_lengths()
{
bool ok;
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int> >(),
1))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int> >(),
1, 2))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int> >(),
1, 2, 3))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int> >(),
1, 2, 3, 4))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int> >(),
1, 2, 3, 4, 5))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8))()
);
BOOST_CHECK(ok);
ok = check_tuple(
1,
*(bind(new_ptr<tuple<int, int, int, int, int, int, int, int, int> >(),
1, 2, 3, 4, 5, 6, 7, 8, 9))()
);
BOOST_CHECK(ok);
}
class is_destructor_called {
bool& b;
public:
is_destructor_called(bool& bb) : b(bb) { b = false; }
~is_destructor_called() { b = true; }
};
void test_destructor ()
{
char space[sizeof(is_destructor_called)];
bool flag = false;
is_destructor_called* idc = new(space) is_destructor_called(flag);
BOOST_CHECK(flag == false);
bind(destructor(), _1)(idc);
BOOST_CHECK(flag == true);
idc = new(space) is_destructor_called(flag);
BOOST_CHECK(flag == false);
bind(destructor(), _1)(*idc);
BOOST_CHECK(flag == true);
}
class count_deletes {
public:
static int count;
~count_deletes() { ++count; }
};
int count_deletes::count = 0;
void test_news_and_deletes ()
{
int* i[10];
std::for_each(i, i+10, _1 = bind(new_ptr<int>(), 2));
int count_errors = 0;
std::for_each(i, i+10, (*_1 == 2) || ++var(count_errors));
BOOST_CHECK(count_errors == 0);
count_deletes* ct[10];
std::for_each(ct, ct+10, _1 = bind(new_ptr<count_deletes>()));
count_deletes::count = 0;
std::for_each(ct, ct+10, bind(delete_ptr(), _1));
BOOST_CHECK(count_deletes::count == 10);
}
void test_array_new_and_delete()
{
count_deletes* c;
(_1 = bind(new_array<count_deletes>(), 5))(c);
count_deletes::count = 0;
bind(delete_array(), _1)(c);
BOOST_CHECK(count_deletes::count == 5);
}
void delayed_construction()
{
std::vector<int> x(3);
std::vector<int> y(3);
std::fill(x.begin(), x.end(), 0);
std::fill(y.begin(), y.end(), 1);
std::vector<std::pair<int, int> > v;
std::transform(x.begin(), x.end(), y.begin(), std::back_inserter(v),
bl::bind(constructor<std::pair<int, int> >(), _1, _2) );
}
int test_main(int, char *[]) {
constructor_all_lengths();
new_ptr_all_lengths();
delayed_construction();
test_destructor();
test_news_and_deletes();
test_array_new_and_delete();
return 0;
}

123
test/control_structures.cpp Normal file
View File

@@ -0,0 +1,123 @@
// -- control_structures.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/if.hpp"
#include "boost/lambda/loops.hpp"
#include <iostream>
#include <algorithm>
#include <vector>
using namespace boost;
using boost::lambda::constant;
using boost::lambda::_1;
using boost::lambda::_2;
using boost::lambda::_3;
using boost::lambda::make_const;
using boost::lambda::for_loop;
using boost::lambda::while_loop;
using boost::lambda::do_while_loop;
using boost::lambda::if_then;
using boost::lambda::if_then_else;
using boost::lambda::if_then_else_return;
// 2 container for_each
template <class InputIter1, class InputIter2, class Function>
Function for_each(InputIter1 first, InputIter1 last,
InputIter2 first2, Function f) {
for ( ; first != last; ++first, ++first2)
f(*first, *first2);
return f;
}
void simple_loops() {
// for loops ---------------------------------------------------------
int i;
int arithmetic_series = 0;
for_loop(_1 = 0, _1 < 10, _1++, arithmetic_series += _1)(i);
BOOST_CHECK(arithmetic_series == 45);
// no body case
for_loop(boost::lambda::var(i) = 0, boost::lambda::var(i) < 100, ++boost::lambda::var(i))();
BOOST_CHECK(i == 100);
// while loops -------------------------------------------------------
int a = 0, b = 0, c = 0;
while_loop((_1 + _2) >= (_1 * _2), (++_1, ++_2, ++_3))(a, b, c);
BOOST_CHECK(c == 3);
int count;
count = 0; i = 0;
while_loop(_1++ < 10, ++boost::lambda::var(count))(i);
BOOST_CHECK(count == 10);
// note that the first parameter of do_while_loop is the condition
count = 0; i = 0;
do_while_loop(_1++ < 10, ++boost::lambda::var(count))(i);
BOOST_CHECK(count == 11);
a = 0;
do_while_loop(constant(false), _1++)(a);
BOOST_CHECK(a == 1);
// no body cases
a = 40; b = 30;
while_loop(--_1 > _2)(a, b);
BOOST_CHECK(a == b);
// (the no body case for do_while_loop is pretty redundant)
a = 40; b = 30;
do_while_loop(--_1 > _2)(a, b);
BOOST_CHECK(a == b);
}
void simple_ifs () {
int value = 42;
if_then(_1 < 0, _1 = 0)(value);
BOOST_CHECK(value == 42);
value = -42;
if_then(_1 < 0, _1 = -_1)(value);
BOOST_CHECK(value == 42);
int min;
if_then_else(_1 < _2, boost::lambda::var(min) = _1, boost::lambda::var(min) = _2)
(make_const(1), make_const(2));
BOOST_CHECK(min == 1);
if_then_else(_1 < _2, boost::lambda::var(min) = _1, boost::lambda::var(min) = _2)
(make_const(5), make_const(3));
BOOST_CHECK(min == 3);
int x, y;
x = -1; y = 1;
BOOST_CHECK(if_then_else_return(_1 < _2, _2, _1)(x, y) == (std::max)(x ,y));
BOOST_CHECK(if_then_else_return(_1 < _2, _2, _1)(y, x) == (std::max)(x ,y));
}
int test_main(int, char *[])
{
simple_loops();
simple_ifs();
return 0;
}

621
test/exception_test.cpp Normal file
View File

@@ -0,0 +1,621 @@
// -- exception_test.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/exceptions.hpp"
#include "boost/lambda/bind.hpp"
#include<iostream>
#include<algorithm>
#include <cstdlib>
#include <iostream>
using namespace boost::lambda;
using namespace std;
// to prevent unused variables warnings
template <class T> void dummy(const T&) {}
void erroneous_exception_related_lambda_expressions() {
int i = 0;
dummy(i);
// Uncommenting any of the below code lines should result in a compile
// time error
// this should fail (a rethrow binder outside of catch
// rethrow()();
// this should fail too for the same reason
// try_catch(rethrow(), catch_all(cout << constant("Howdy")))();
// this fails too (_e outside of catch_exception)
// (_1 + _2 + _e)(i, i, i);
// and this (_e outside of catch_exception)
// try_catch( throw_exception(1), catch_all(cout << _e));
// and this (_3 in catch_exception
// try_catch( throw_exception(1), catch_exception<int>(cout << _3));
}
class A1 {};
class A2 {};
class A3 {};
class A4 {};
class A5 {};
class A6 {};
class A7 {};
class A8 {};
class A9 {};
void throw_AX(int j) {
int i = j;
switch(i) {
case 1: throw A1();
case 2: throw A2();
case 3: throw A3();
case 4: throw A4();
case 5: throw A5();
case 6: throw A6();
case 7: throw A7();
case 8: throw A8();
case 9: throw A9();
}
}
void test_different_number_of_catch_blocks() {
int ecount;
// no catch(...) cases
ecount = 0;
for(int i=1; i<=1; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 1);
ecount = 0;
for(int i=1; i<=2; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 2);
ecount = 0;
for(int i=1; i<=3; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 3);
ecount = 0;
for(int i=1; i<=4; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 4);
ecount = 0;
for(int i=1; i<=5; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
),
catch_exception<A5>(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 5);
ecount = 0;
for(int i=1; i<=6; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
),
catch_exception<A5>(
var(ecount)++
),
catch_exception<A6>(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 6);
ecount = 0;
for(int i=1; i<=7; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
),
catch_exception<A5>(
var(ecount)++
),
catch_exception<A6>(
var(ecount)++
),
catch_exception<A7>(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 7);
ecount = 0;
for(int i=1; i<=8; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
),
catch_exception<A5>(
var(ecount)++
),
catch_exception<A6>(
var(ecount)++
),
catch_exception<A7>(
var(ecount)++
),
catch_exception<A8>(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 8);
ecount = 0;
for(int i=1; i<=9; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
),
catch_exception<A5>(
var(ecount)++
),
catch_exception<A6>(
var(ecount)++
),
catch_exception<A7>(
var(ecount)++
),
catch_exception<A8>(
var(ecount)++
),
catch_exception<A9>(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 9);
// with catch(...) blocks
ecount = 0;
for(int i=1; i<=1; i++)
{
try_catch(
bind(throw_AX, _1),
catch_all(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 1);
ecount = 0;
for(int i=1; i<=2; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_all(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 2);
ecount = 0;
for(int i=1; i<=3; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_all(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 3);
ecount = 0;
for(int i=1; i<=4; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_all(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 4);
ecount = 0;
for(int i=1; i<=5; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
),
catch_all(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 5);
ecount = 0;
for(int i=1; i<=6; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
),
catch_exception<A5>(
var(ecount)++
),
catch_all(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 6);
ecount = 0;
for(int i=1; i<=7; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
),
catch_exception<A5>(
var(ecount)++
),
catch_exception<A6>(
var(ecount)++
),
catch_all(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 7);
ecount = 0;
for(int i=1; i<=8; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
),
catch_exception<A5>(
var(ecount)++
),
catch_exception<A6>(
var(ecount)++
),
catch_exception<A7>(
var(ecount)++
),
catch_all(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 8);
ecount = 0;
for(int i=1; i<=9; i++)
{
try_catch(
bind(throw_AX, _1),
catch_exception<A1>(
var(ecount)++
),
catch_exception<A2>(
var(ecount)++
),
catch_exception<A3>(
var(ecount)++
),
catch_exception<A4>(
var(ecount)++
),
catch_exception<A5>(
var(ecount)++
),
catch_exception<A6>(
var(ecount)++
),
catch_exception<A7>(
var(ecount)++
),
catch_exception<A8>(
var(ecount)++
),
catch_all(
var(ecount)++
)
)(i);
}
BOOST_CHECK(ecount == 9);
}
void test_empty_catch_blocks() {
try_catch(
bind(throw_AX, _1),
catch_exception<A1>()
)(make_const(1));
try_catch(
bind(throw_AX, _1),
catch_all()
)(make_const(1));
}
void return_type_matching() {
// Rules for return types of the lambda functors in try and catch parts:
// 1. The try part dictates the return type of the whole
// try_catch lambda functor
// 2. If return type of try part is void, catch parts can return anything,
// but the return types are ignored
// 3. If the return type of the try part is A, then each catch return type
// must be implicitly convertible to A, or then it must throw for sure
int i = 1;
BOOST_CHECK(
try_catch(
_1 + 1,
catch_exception<int>((&_1, rethrow())), // no match, but ok since throws
catch_exception<char>(_e) // ok, char convertible to int
)(i)
== 2
);
// note that while e.g. char is convertible to int, it is not convertible
// to int&, (some lambda functors return references)
// try_catch(
// _1 += 1,
// catch_exception<char>(_e) // NOT ok, char not convertible to int&
// )(i);
// if you don't care about the return type, you can use make_void
try_catch(
make_void(_1 += 1),
catch_exception<char>(_e) // since try is void, catch can return anything
)(i);
BOOST_CHECK(i == 2);
try_catch(
(_1 += 1, throw_exception('a')),
catch_exception<char>(_e) // since try throws, it is void,
// so catch can return anything
)(i);
BOOST_CHECK(i == 3);
char a = 'a';
try_catch(
try_catch(
throw_exception(1),
catch_exception<int>(throw_exception('b'))
),
catch_exception<char>( _1 = _e )
)(a);
BOOST_CHECK(a == 'b');
}
int test_main(int, char *[]) {
try
{
test_different_number_of_catch_blocks();
return_type_matching();
test_empty_catch_blocks();
}
catch (int)
{
BOOST_CHECK(false);
}
catch(...)
{
BOOST_CHECK(false);
}
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,394 @@
// extending_return_type_traits.cpp -- The Boost Lambda Library --------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/bind.hpp"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/detail/suppress_unused.hpp"
#include <iostream>
#include <functional>
#include <algorithm>
using boost::lambda::detail::suppress_unused_variable_warnings;
class A {};
class B {};
using namespace boost::lambda;
B operator--(const A&, int) { return B(); }
B operator--(A&) { return B(); }
B operator++(const A&, int) { return B(); }
B operator++(A&) { return B(); }
B operator-(const A&) { return B(); }
B operator+(const A&) { return B(); }
B operator!(const A&) { return B(); }
B operator&(const A&) { return B(); }
B operator*(const A&) { return B(); }
namespace boost {
namespace lambda {
// unary + and -
template<class Act>
struct plain_return_type_1<unary_arithmetic_action<Act>, A > {
typedef B type;
};
// post incr/decr
template<class Act>
struct plain_return_type_1<post_increment_decrement_action<Act>, A > {
typedef B type;
};
// pre incr/decr
template<class Act>
struct plain_return_type_1<pre_increment_decrement_action<Act>, A > {
typedef B type;
};
// !
template<>
struct plain_return_type_1<logical_action<not_action>, A> {
typedef B type;
};
// &
template<>
struct plain_return_type_1<other_action<addressof_action>, A> {
typedef B type;
};
// *
template<>
struct plain_return_type_1<other_action<contentsof_action>, A> {
typedef B type;
};
} // lambda
} // boost
void ok(B /*b*/) {}
void test_unary_operators()
{
A a; int i = 1;
ok((++_1)(a));
ok((--_1)(a));
ok((_1++)(a));
ok((_1--)(a));
ok((+_1)(a));
ok((-_1)(a));
ok((!_1)(a));
ok((&_1)(a));
ok((*_1)(a));
BOOST_CHECK((*_1)(make_const(&i)) == 1);
}
class X {};
class Y {};
class Z {};
Z operator+(const X&, const Y&) { return Z(); }
Z operator-(const X&, const Y&) { return Z(); }
X operator*(const X&, const Y&) { return X(); }
Z operator/(const X&, const Y&) { return Z(); }
Z operator%(const X&, const Y&) { return Z(); }
class XX {};
class YY {};
class ZZ {};
class VV {};
// it is possible to support differently cv-qualified versions
YY operator*(XX&, YY&) { return YY(); }
ZZ operator*(const XX&, const YY&) { return ZZ(); }
XX operator*(volatile XX&, volatile YY&) { return XX(); }
VV operator*(const volatile XX&, const volatile YY&) { return VV(); }
// the traits can be more complex:
template <class T>
class my_vector {};
template<class A, class B>
my_vector<typename return_type_2<arithmetic_action<plus_action>, A&, B&>::type>
operator+(const my_vector<A>& /*a*/, const my_vector<B>& /*b*/)
{
typedef typename
return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
return my_vector<res_type>();
}
// bitwise ops:
X operator<<(const X&, const Y&) { return X(); }
Z operator>>(const X&, const Y&) { return Z(); }
Z operator&(const X&, const Y&) { return Z(); }
Z operator|(const X&, const Y&) { return Z(); }
Z operator^(const X&, const Y&) { return Z(); }
// comparison ops:
X operator<(const X&, const Y&) { return X(); }
Z operator>(const X&, const Y&) { return Z(); }
Z operator<=(const X&, const Y&) { return Z(); }
Z operator>=(const X&, const Y&) { return Z(); }
Z operator==(const X&, const Y&) { return Z(); }
Z operator!=(const X&, const Y&) { return Z(); }
// logical
X operator&&(const X&, const Y&) { return X(); }
Z operator||(const X&, const Y&) { return Z(); }
// arithh assignment
Z operator+=( X&, const Y&) { return Z(); }
Z operator-=( X&, const Y&) { return Z(); }
Y operator*=( X&, const Y&) { return Y(); }
Z operator/=( X&, const Y&) { return Z(); }
Z operator%=( X&, const Y&) { return Z(); }
// bitwise assignment
Z operator<<=( X&, const Y&) { return Z(); }
Z operator>>=( X&, const Y&) { return Z(); }
Y operator&=( X&, const Y&) { return Y(); }
Z operator|=( X&, const Y&) { return Z(); }
Z operator^=( X&, const Y&) { return Z(); }
// assignment
class Assign {
public:
void operator=(const Assign& /*a*/) {}
X operator[](const int& /*i*/) { return X(); }
};
namespace boost {
namespace lambda {
// you can do action groups
template<class Act>
struct plain_return_type_2<arithmetic_action<Act>, X, Y> {
typedef Z type;
};
// or specialize the exact action
template<>
struct plain_return_type_2<arithmetic_action<multiply_action>, X, Y> {
typedef X type;
};
// if you want to make a distinction between differently cv-qualified
// types, you need to specialize on a different level:
template<>
struct return_type_2<arithmetic_action<multiply_action>, XX, YY> {
typedef YY type;
};
template<>
struct return_type_2<arithmetic_action<multiply_action>, const XX, const YY> {
typedef ZZ type;
};
template<>
struct return_type_2<arithmetic_action<multiply_action>, volatile XX, volatile YY> {
typedef XX type;
};
template<>
struct return_type_2<arithmetic_action<multiply_action>, volatile const XX, const volatile YY> {
typedef VV type;
};
// the mapping can be more complex:
template<class A, class B>
struct plain_return_type_2<arithmetic_action<plus_action>, my_vector<A>, my_vector<B> > {
typedef typename
return_type_2<arithmetic_action<plus_action>, A&, B&>::type res_type;
typedef my_vector<res_type> type;
};
// bitwise binary:
// you can do action groups
template<class Act>
struct plain_return_type_2<bitwise_action<Act>, X, Y> {
typedef Z type;
};
// or specialize the exact action
template<>
struct plain_return_type_2<bitwise_action<leftshift_action>, X, Y> {
typedef X type;
};
// comparison binary:
// you can do action groups
template<class Act>
struct plain_return_type_2<relational_action<Act>, X, Y> {
typedef Z type;
};
// or specialize the exact action
template<>
struct plain_return_type_2<relational_action<less_action>, X, Y> {
typedef X type;
};
// logical binary:
// you can do action groups
template<class Act>
struct plain_return_type_2<logical_action<Act>, X, Y> {
typedef Z type;
};
// or specialize the exact action
template<>
struct plain_return_type_2<logical_action<and_action>, X, Y> {
typedef X type;
};
// arithmetic assignment :
// you can do action groups
template<class Act>
struct plain_return_type_2<arithmetic_assignment_action<Act>, X, Y> {
typedef Z type;
};
// or specialize the exact action
template<>
struct plain_return_type_2<arithmetic_assignment_action<multiply_action>, X, Y> {
typedef Y type;
};
// arithmetic assignment :
// you can do action groups
template<class Act>
struct plain_return_type_2<bitwise_assignment_action<Act>, X, Y> {
typedef Z type;
};
// or specialize the exact action
template<>
struct plain_return_type_2<bitwise_assignment_action<and_action>, X, Y> {
typedef Y type;
};
// assignment
template<>
struct plain_return_type_2<other_action<assignment_action>, Assign, Assign> {
typedef void type;
};
// subscript
template<>
struct plain_return_type_2<other_action<subscript_action>, Assign, int> {
typedef X type;
};
} // end lambda
} // end boost
void test_binary_operators() {
X x; Y y;
(_1 + _2)(x, y);
(_1 - _2)(x, y);
(_1 * _2)(x, y);
(_1 / _2)(x, y);
(_1 % _2)(x, y);
// make a distinction between differently cv-qualified operators
XX xx; YY yy;
const XX& cxx = xx;
const YY& cyy = yy;
volatile XX& vxx = xx;
volatile YY& vyy = yy;
const volatile XX& cvxx = xx;
const volatile YY& cvyy = yy;
ZZ dummy1 = (_1 * _2)(cxx, cyy);
YY dummy2 = (_1 * _2)(xx, yy);
XX dummy3 = (_1 * _2)(vxx, vyy);
VV dummy4 = (_1 * _2)(cvxx, cvyy);
suppress_unused_variable_warnings(dummy1);
suppress_unused_variable_warnings(dummy2);
suppress_unused_variable_warnings(dummy3);
suppress_unused_variable_warnings(dummy4);
my_vector<int> v1; my_vector<double> v2;
my_vector<double> d = (_1 + _2)(v1, v2);
suppress_unused_variable_warnings(d);
// bitwise
(_1 << _2)(x, y);
(_1 >> _2)(x, y);
(_1 | _2)(x, y);
(_1 & _2)(x, y);
(_1 ^ _2)(x, y);
// comparison
(_1 < _2)(x, y);
(_1 > _2)(x, y);
(_1 <= _2)(x, y);
(_1 >= _2)(x, y);
(_1 == _2)(x, y);
(_1 != _2)(x, y);
// logical
(_1 || _2)(x, y);
(_1 && _2)(x, y);
// arithmetic assignment
(_1 += _2)(x, y);
(_1 -= _2)(x, y);
(_1 *= _2)(x, y);
(_1 /= _2)(x, y);
(_1 %= _2)(x, y);
// bitwise assignment
(_1 <<= _2)(x, y);
(_1 >>= _2)(x, y);
(_1 |= _2)(x, y);
(_1 &= _2)(x, y);
(_1 ^= _2)(x, y);
}
int test_main(int, char *[]) {
test_unary_operators();
test_binary_operators();
return 0;
}

View File

@@ -0,0 +1,79 @@
// is_instance_of_test.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/detail/is_instance_of.hpp"
#include <iostream>
template <class T1> struct A1 {};
template <class T1, class T2> struct A2 {};
template <class T1, class T2, class T3> struct A3 {};
template <class T1, class T2, class T3, class T4> struct A4 {};
class B1 : public A1<int> {};
class B2 : public A2<int,int> {};
class B3 : public A3<int,int,int> {};
class B4 : public A4<int,int,int,int> {};
// classes that are convertible to classes that derive from A instances
// This is not enough to make the test succeed
class C1 { public: operator A1<int>() { return A1<int>(); } };
class C2 { public: operator B2() { return B2(); } };
class C3 { public: operator B3() { return B3(); } };
class C4 { public: operator B4() { return B4(); } };
// test that the result is really a constant
// (in an alternative implementation, gcc 3.0.2. claimed that it was
// a non-constant)
template <bool b> class X {};
// this should compile
X<boost::lambda::is_instance_of_2<int, A2>::value> x;
int test_main(int, char *[]) {
using boost::lambda::is_instance_of_1;
using boost::lambda::is_instance_of_2;
using boost::lambda::is_instance_of_3;
using boost::lambda::is_instance_of_4;
BOOST_CHECK((is_instance_of_1<B1, A1>::value == true));
BOOST_CHECK((is_instance_of_1<A1<float>, A1>::value == true));
BOOST_CHECK((is_instance_of_1<int, A1>::value == false));
BOOST_CHECK((is_instance_of_1<C1, A1>::value == false));
BOOST_CHECK((is_instance_of_2<B2, A2>::value == true));
BOOST_CHECK((is_instance_of_2<A2<int, float>, A2>::value == true));
BOOST_CHECK((is_instance_of_2<int, A2>::value == false));
BOOST_CHECK((is_instance_of_2<C2, A2>::value == false));
BOOST_CHECK((is_instance_of_3<B3, A3>::value == true));
BOOST_CHECK((is_instance_of_3<A3<int, float, char>, A3>::value == true));
BOOST_CHECK((is_instance_of_3<int, A3>::value == false));
BOOST_CHECK((is_instance_of_3<C3, A3>::value == false));
BOOST_CHECK((is_instance_of_4<B4, A4>::value == true));
BOOST_CHECK((is_instance_of_4<A4<int, float, char, double>, A4>::value == true));
BOOST_CHECK((is_instance_of_4<int, A4>::value == false));
BOOST_CHECK((is_instance_of_4<C4, A4>::value == false));
return 0;
}

30
test/istreambuf_test.cpp Normal file
View File

@@ -0,0 +1,30 @@
// istreambuf_test - test lambda function objects with istreambuf_iterator
//
// Copyright (c) 2007 Peter Dimov
//
// 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/lambda/lambda.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <iterator>
#include <sstream>
#include <algorithm>
int main()
{
using namespace boost::lambda;
std::stringstream is( "ax2" );
std::istreambuf_iterator<char> b2( is );
std::istreambuf_iterator<char> e2;
std::istreambuf_iterator<char> i = std::find_if( b2, e2, _1 == 'x' );
BOOST_TEST( *i == 'x' );
BOOST_TEST( std::distance( i, e2 ) == 2 );
return boost::report_errors();
}

View File

@@ -0,0 +1,192 @@
// member_pointer_test.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
#include <string>
using namespace boost::lambda;
using namespace std;
struct my_struct {
my_struct(int x) : mem(x) {};
int mem;
int fooc() const { return mem; }
int foo() { return mem; }
int foo1c(int y) const { return y + mem; }
int foo1(int y) { return y + mem; }
int foo2c(int y, int x) const { return y + x + mem; }
int foo2(int y, int x) { return y + x + mem; }
int foo3c(int y, int x, int z) const { return y + x + z + mem; }
int foo3(int y, int x, int z ){ return y + x + z + mem; }
int foo4c(int a1, int a2, int a3, int a4) const { return a1+a2+a3+a4+mem; }
int foo4(int a1, int a2, int a3, int a4){ return a1+a2+a3+a4+mem; }
int foo3default(int y = 1, int x = 2, int z = 3) { return y + x + z + mem; }
};
my_struct x(3);
void pointer_to_data_member_tests() {
// int i = 0;
my_struct *y = &x;
BOOST_CHECK((_1 ->* &my_struct::mem)(y) == 3);
(_1 ->* &my_struct::mem)(y) = 4;
BOOST_CHECK(x.mem == 4);
((_1 ->* &my_struct::mem) = 5)(y);
BOOST_CHECK(x.mem == 5);
// &my_struct::mem is a temporary, must be constified
((y ->* _1) = 6)(make_const(&my_struct::mem));
BOOST_CHECK(x.mem == 6);
((_1 ->* _2) = 7)(y, make_const(&my_struct::mem));
BOOST_CHECK(x.mem == 7);
}
void pointer_to_member_function_tests() {
my_struct *y = new my_struct(1);
BOOST_CHECK( (_1 ->* &my_struct::foo)(y)() == (y->mem));
BOOST_CHECK( (_1 ->* &my_struct::fooc)(y)() == (y->mem));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo))() == (y->mem));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::fooc))() == (y->mem));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo))() == (y->mem));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::fooc))() == (y->mem));
BOOST_CHECK( (_1 ->* &my_struct::foo1)(y)(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* &my_struct::foo1c)(y)(1) == (y->mem+1));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo1))(1) == (y->mem+1));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo1c))(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo1))(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo1c))(1) == (y->mem+1));
BOOST_CHECK( (_1 ->* &my_struct::foo2)(y)(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* &my_struct::foo2c)(y)(1,2) == (y->mem+1+2));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo2))(1,2) == (y->mem+1+2));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo2c))(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo2))(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo2c))(1,2) == (y->mem+1+2));
BOOST_CHECK( (_1 ->* &my_struct::foo3)(y)(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* &my_struct::foo3c)(y)(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo3))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo3c))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo3))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo3c))(1,2,3) == (y->mem+1+2+3));
BOOST_CHECK( (_1 ->* &my_struct::foo4)(y)(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (_1 ->* &my_struct::foo4c)(y)(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo4))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (y ->* _1)(make_const(&my_struct::foo4c))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo4))(1,2,3,4) == (y->mem+1+2+3+4));
BOOST_CHECK( (_1 ->* _2)(y, make_const(&my_struct::foo4c))(1,2,3,4) == (y->mem+1+2+3+4));
// member functions with default values do not work (inherent language issue)
// BOOST_CHECK( (_1 ->* &my_struct::foo3default)(y)() == (y->mem+1+2+3));
}
class A {};
class B {};
class C {};
class D {};
// ->* can be overloaded to do anything
bool operator->*(A /*a*/, B /*b*/) {
return false;
}
bool operator->*(B /*b*/, A /*a*/) {
return true;
}
// let's provide specializations to take care of the return type deduction.
// Note, that you need to provide all four cases for non-const and const
// or use the plain_return_type_2 template.
namespace boost {
namespace lambda {
template <>
struct return_type_2<other_action<member_pointer_action>, B, A> {
typedef bool type;
};
template<>
struct return_type_2<other_action<member_pointer_action>, const B, A> {
typedef bool type;
};
template<>
struct return_type_2<other_action<member_pointer_action>, B, const A> {
typedef bool type;
};
template<>
struct return_type_2<other_action<member_pointer_action>, const B, const A> {
typedef bool type;
};
} // lambda
} // boost
void test_overloaded_pointer_to_member()
{
A a; B b;
// this won't work, can't deduce the return type
// BOOST_CHECK((_1->*_2)(a, b) == false);
// ret<bool> gives the return type
BOOST_CHECK(ret<bool>(_1->*_2)(a, b) == false);
BOOST_CHECK(ret<bool>(a->*_1)(b) == false);
BOOST_CHECK(ret<bool>(_1->*b)(a) == false);
BOOST_CHECK((ret<bool>((var(a))->*b))() == false);
BOOST_CHECK((ret<bool>((var(a))->*var(b)))() == false);
// this is ok without ret<bool> due to the return_type_2 spcialization above
BOOST_CHECK((_1->*_2)(b, a) == true);
BOOST_CHECK((b->*_1)(a) == true);
BOOST_CHECK((_1->*a)(b) == true);
BOOST_CHECK((var(b)->*a)() == true);
return;
}
int test_main(int, char *[]) {
pointer_to_data_member_tests();
pointer_to_member_function_tests();
test_overloaded_pointer_to_member();
return 0;
}

View File

@@ -0,0 +1,431 @@
// operator_tests_simple.cpp -- The Boost Lambda Library ---------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/detail/suppress_unused.hpp"
#include <boost/shared_ptr.hpp>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <iostream>
#ifndef BOOST_NO_STRINGSTREAM
#include <sstream>
#endif
using namespace std;
using namespace boost;
using namespace boost::lambda;
class unary_plus_tester {};
unary_plus_tester operator+(const unary_plus_tester& a) { return a; }
void cout_tests()
{
#ifndef BOOST_NO_STRINGSTREAM
using std::cout;
ostringstream os;
int i = 10;
(os << _1)(i);
(os << constant("FOO"))();
BOOST_CHECK(os.str() == std::string("10FOO"));
istringstream is("ABC 1");
std::string s;
int k;
is >> s;
is >> k;
BOOST_CHECK(s == std::string("ABC"));
BOOST_CHECK(k == 1);
// test for constant, constant_ref and var
i = 5;
constant_type<int>::type ci(constant(i));
var_type<int>::type vi(var(i));
(vi = _1)(make_const(100));
BOOST_CHECK((ci)() == 5);
BOOST_CHECK(i == 100);
int a;
constant_ref_type<int>::type cr(constant_ref(i));
(++vi, var(a) = cr)();
BOOST_CHECK(i == 101);
#endif
}
void arithmetic_operators() {
int i = 1; int j = 2; int k = 3;
using namespace std;
using namespace boost::lambda;
BOOST_CHECK((_1 + 1)(i)==2);
BOOST_CHECK(((_1 + 1) * _2)(i, j)==4);
BOOST_CHECK((_1 - 1)(i)==0);
BOOST_CHECK((_1 * 2)(j)==4);
BOOST_CHECK((_1 / 2)(j)==1);
BOOST_CHECK((_1 % 2)(k)==1);
BOOST_CHECK((-_1)(i) == -1);
BOOST_CHECK((+_1)(i) == 1);
// test that unary plus really does something
unary_plus_tester u;
unary_plus_tester up = (+_1)(u);
boost::lambda::detail::suppress_unused_variable_warnings(up);
}
void bitwise_operators() {
unsigned int ui = 2;
BOOST_CHECK((_1 << 1)(ui)==(2 << 1));
BOOST_CHECK((_1 >> 1)(ui)==(2 >> 1));
BOOST_CHECK((_1 & 1)(ui)==(2 & 1));
BOOST_CHECK((_1 | 1)(ui)==(2 | 1));
BOOST_CHECK((_1 ^ 1)(ui)==(2 ^ 1));
BOOST_CHECK((~_1)(ui)==~2u);
}
void comparison_operators() {
int i = 0, j = 1;
BOOST_CHECK((_1 < _2)(i, j) == true);
BOOST_CHECK((_1 <= _2)(i, j) == true);
BOOST_CHECK((_1 == _2)(i, j) == false);
BOOST_CHECK((_1 != _2)(i, j) == true);
BOOST_CHECK((_1 > _2)(i, j) == false);
BOOST_CHECK((_1 >= _2)(i, j) == false);
BOOST_CHECK((!(_1 < _2))(i, j) == false);
BOOST_CHECK((!(_1 <= _2))(i, j) == false);
BOOST_CHECK((!(_1 == _2))(i, j) == true);
BOOST_CHECK((!(_1 != _2))(i, j) == false);
BOOST_CHECK((!(_1 > _2))(i, j) == true);
BOOST_CHECK((!(_1 >= _2))(i, j) == true);
}
void logical_operators() {
bool t = true, f = false;
BOOST_CHECK((_1 && _2)(t, t) == true);
BOOST_CHECK((_1 && _2)(t, f) == false);
BOOST_CHECK((_1 && _2)(f, t) == false);
BOOST_CHECK((_1 && _2)(f, f) == false);
BOOST_CHECK((_1 || _2)(t, t) == true);
BOOST_CHECK((_1 || _2)(t, f) == true);
BOOST_CHECK((_1 || _2)(f, t) == true);
BOOST_CHECK((_1 || _2)(f, f) == false);
BOOST_CHECK((!_1)(t) == false);
BOOST_CHECK((!_1)(f) == true);
// test short circuiting
int i=0;
(false && ++_1)(i);
BOOST_CHECK(i==0);
i = 0;
(true && ++_1)(i);
BOOST_CHECK(i==1);
i = 0;
(false || ++_1)(i);
BOOST_CHECK(i==1);
i = 0;
(true || ++_1)(i);
BOOST_CHECK(i==0);
i = 0;
}
void unary_incs_and_decs() {
int i = 0;
BOOST_CHECK(_1++(i) == 0);
BOOST_CHECK(i == 1);
i = 0;
BOOST_CHECK(_1--(i) == 0);
BOOST_CHECK(i == -1);
i = 0;
BOOST_CHECK((++_1)(i) == 1);
BOOST_CHECK(i == 1);
i = 0;
BOOST_CHECK((--_1)(i) == -1);
BOOST_CHECK(i == -1);
i = 0;
// the result of prefix -- and ++ are lvalues
(++_1)(i) = 10;
BOOST_CHECK(i==10);
i = 0;
(--_1)(i) = 10;
BOOST_CHECK(i==10);
i = 0;
}
void compound_operators() {
int i = 1;
// normal variable as the left operand
(i += _1)(make_const(1));
BOOST_CHECK(i == 2);
(i -= _1)(make_const(1));
BOOST_CHECK(i == 1);
(i *= _1)(make_const(10));
BOOST_CHECK(i == 10);
(i /= _1)(make_const(2));
BOOST_CHECK(i == 5);
(i %= _1)(make_const(2));
BOOST_CHECK(i == 1);
// lambda expression as a left operand
(_1 += 1)(i);
BOOST_CHECK(i == 2);
(_1 -= 1)(i);
BOOST_CHECK(i == 1);
(_1 *= 10)(i);
BOOST_CHECK(i == 10);
(_1 /= 2)(i);
BOOST_CHECK(i == 5);
(_1 %= 2)(i);
BOOST_CHECK(i == 1);
// lambda expression as a left operand with rvalue on RHS
(_1 += (0 + 1))(i);
BOOST_CHECK(i == 2);
(_1 -= (0 + 1))(i);
BOOST_CHECK(i == 1);
(_1 *= (0 + 10))(i);
BOOST_CHECK(i == 10);
(_1 /= (0 + 2))(i);
BOOST_CHECK(i == 5);
(_1 %= (0 + 2))(i);
BOOST_CHECK(i == 1);
// shifts
unsigned int ui = 2;
(_1 <<= 1)(ui);
BOOST_CHECK(ui==(2 << 1));
ui = 2;
(_1 >>= 1)(ui);
BOOST_CHECK(ui==(2 >> 1));
ui = 2;
(ui <<= _1)(make_const(1));
BOOST_CHECK(ui==(2 << 1));
ui = 2;
(ui >>= _1)(make_const(1));
BOOST_CHECK(ui==(2 >> 1));
// and, or, xor
ui = 2;
(_1 &= 1)(ui);
BOOST_CHECK(ui==(2 & 1));
ui = 2;
(_1 |= 1)(ui);
BOOST_CHECK(ui==(2 | 1));
ui = 2;
(_1 ^= 1)(ui);
BOOST_CHECK(ui==(2 ^ 1));
ui = 2;
(ui &= _1)(make_const(1));
BOOST_CHECK(ui==(2 & 1));
ui = 2;
(ui |= _1)(make_const(1));
BOOST_CHECK(ui==(2 | 1));
ui = 2;
(ui ^= _1)(make_const(1));
BOOST_CHECK(ui==(2 ^ 1));
}
void assignment_and_subscript() {
// assignment and subscript need to be defined as member functions.
// Hence, if you wish to use a normal variable as the left hand argument,
// you must wrap it with var to turn it into a lambda expression
using std::string;
string s;
(_1 = "one")(s);
BOOST_CHECK(s == string("one"));
(var(s) = "two")();
BOOST_CHECK(s == string("two"));
BOOST_CHECK((var(s)[_1])(make_const(2)) == 'o');
BOOST_CHECK((_1[2])(s) == 'o');
BOOST_CHECK((_1[_2])(s, make_const(2)) == 'o');
// subscript returns lvalue
(var(s)[_1])(make_const(1)) = 'o';
BOOST_CHECK(s == "too");
(_1[1])(s) = 'a';
BOOST_CHECK(s == "tao");
(_1[_2])(s, make_const(0)) = 'm';
BOOST_CHECK(s == "mao");
// TODO: tests for vector, set, map, multimap
}
class A {};
void address_of_and_dereference() {
A a; int i = 42;
BOOST_CHECK((&_1)(a) == &a);
BOOST_CHECK((*&_1)(i) == 42);
std::vector<int> vi; vi.push_back(1);
std::vector<int>::iterator it = vi.begin();
(*_1 = 7)(it);
BOOST_CHECK(vi[0] == 7);
const std::vector<int>::iterator cit(it);
(*_1 = 8)(cit);
BOOST_CHECK(vi[0] == 8);
// TODO: Add tests for more complex iterator types
boost::shared_ptr<int> ptr(new int(0));
(*_1 = 7)(ptr);
BOOST_CHECK(*ptr == 7);
const boost::shared_ptr<int> cptr(ptr);
(*_1 = 8)(cptr);
BOOST_CHECK(*ptr == 8);
}
void comma() {
int i = 100;
BOOST_CHECK((_1 = 10, 2 * _1)(i) == 20);
// TODO: that the return type is the exact type of the right argument
// (that r/l valueness is preserved)
}
void pointer_arithmetic() {
int ia[4] = { 1, 2, 3, 4 };
int* ip = ia;
int* ia_last = &ia[3];
const int cia[4] = { 1, 2, 3, 4 };
const int* cip = cia;
const int* cia_last = &cia[3];
// non-const array
BOOST_CHECK((*(_1 + 1))(ia) == 2);
// non-const pointer
BOOST_CHECK((*(_1 + 1))(ip) == 2);
BOOST_CHECK((*(_1 - 1))(ia_last) == 3);
// const array
BOOST_CHECK((*(_1 + 1))(cia) == 2);
// const pointer
BOOST_CHECK((*(_1 + 1))(cip) == 2);
BOOST_CHECK((*(_1 - 1))(cia_last) == 3);
// pointer arithmetic should not make non-consts const
(*(_1 + 2))(ia) = 0;
(*(_1 + 3))(ip) = 0;
BOOST_CHECK(ia[2] == 0);
BOOST_CHECK(ia[3] == 0);
// pointer - pointer
BOOST_CHECK((_1 - _2)(ia_last, ia) == 3);
BOOST_CHECK((_1 - _2)(cia_last, cia) == 3);
BOOST_CHECK((ia_last - _1)(ia) == 3);
BOOST_CHECK((cia_last - _1)(cia) == 3);
BOOST_CHECK((cia_last - _1)(cip) == 3);
}
int test_main(int, char *[]) {
arithmetic_operators();
bitwise_operators();
comparison_operators();
logical_operators();
unary_incs_and_decs();
compound_operators();
assignment_and_subscript();
address_of_and_dereference();
comma();
pointer_arithmetic();
cout_tests();
return 0;
}

View File

@@ -0,0 +1,148 @@
// phoenix_style_control_structures.cpp -- The Boost Lambda Library ------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/if.hpp"
#include "boost/lambda/loops.hpp"
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <cmath>
#include <cassert>
#include <functional>
using namespace boost::lambda;
using namespace std;
// If-else, while, do-while, for statements
int test_main(int, char *[]) {
vector<int> v;
v.clear();
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.push_back(6);
v.push_back(7);
v.push_back(8);
v.push_back(9);
v.push_back(10);
int sum = 0;
//////////////////////////////////
for_each(v.begin(), v.end(),
if_(_1 > 3 && _1 <= 8)
[
sum += _1
]
);
BOOST_CHECK(sum == 4+5+6+7+8);
int gt = 0, eq = 0, lt = 0;
//////////////////////////////////
for_each(v.begin(), v.end(),
if_(_1 > 5)
[
++var(gt)
]
.else_
[
if_(_1 == 5)
[
++var(eq)
]
.else_
[
++var(lt)
]
]
);
BOOST_CHECK(lt==4);
BOOST_CHECK(eq==1);
BOOST_CHECK(gt==5);
vector<int> t = v;
int counta = 0;
int countb = 0;
//////////////////////////////////
for_each(v.begin(), v.end(),
(
while_(_1--)
[
++var(counta)
],
++var(countb)
)
);
BOOST_CHECK(counta == 55);
BOOST_CHECK(countb == 10);
v = t;
counta = 0; countb = 0;
//////////////////////////////////
for_each(v.begin(), v.end(),
(
do_
[
++var(counta)
]
.while_(_1--),
++var(countb)
)
);
BOOST_CHECK(counta == (2+11)*10/2);
BOOST_CHECK(countb == 10);
v = t;
counta = 0; countb = 0;
//////////////////////////////////
int iii;
for_each(v.begin(), v.end(),
(
for_(var(iii) = 0, var(iii) < _1, ++var(iii))
[
++var(counta)
],
++var(countb)
)
);
BOOST_CHECK(counta == (1+10)*10/2);
BOOST_CHECK(countb == 10);
v = t;
return 0;
}

314
test/result_of_tests.cpp Normal file
View File

@@ -0,0 +1,314 @@
// result_of_tests.cpp -- The Boost Lambda Library ------------------
//
// Copyright (C) 2010 Steven Watanabe
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
struct with_result_type {
typedef int result_type;
int operator()() const { return 0; }
int operator()(int) const { return 1; }
int operator()(int, int) const { return 2; }
int operator()(int, int, int) const { return 3; }
int operator()(int, int, int, int) const { return 4; }
int operator()(int, int, int, int, int) const { return 5; }
int operator()(int, int, int, int, int, int) const { return 6; }
int operator()(int, int, int, int, int, int, int) const { return 7; }
int operator()(int, int, int, int, int, int, int, int) const { return 8; }
int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
};
struct with_result_template_value {
template<class Sig>
struct result;
template<class This>
struct result<This()> {
typedef int type;
};
template<class This, class A1>
struct result<This(A1)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
typedef int type;
};
template<class This, class A1, class A2>
struct result<This(A1, A2)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3>
struct result<This(A1, A2, A3)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4>
struct result<This(A1, A2, A3, A4)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5>
struct result<This(A1, A2, A3, A4, A5)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6>
struct result<This(A1, A2, A3, A4, A5, A6)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct result<This(A1, A2, A3, A4, A5, A6, A7)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
BOOST_MPL_ASSERT((boost::is_same<A7, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
BOOST_MPL_ASSERT((boost::is_same<A7, int>));
BOOST_MPL_ASSERT((boost::is_same<A8, int>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int>));
BOOST_MPL_ASSERT((boost::is_same<A2, int>));
BOOST_MPL_ASSERT((boost::is_same<A3, int>));
BOOST_MPL_ASSERT((boost::is_same<A4, int>));
BOOST_MPL_ASSERT((boost::is_same<A5, int>));
BOOST_MPL_ASSERT((boost::is_same<A6, int>));
BOOST_MPL_ASSERT((boost::is_same<A7, int>));
BOOST_MPL_ASSERT((boost::is_same<A8, int>));
BOOST_MPL_ASSERT((boost::is_same<A9, int>));
typedef int type;
};
int operator()() const { return 0; }
int operator()(int) const { return 1; }
int operator()(int, int) const { return 2; }
int operator()(int, int, int) const { return 3; }
int operator()(int, int, int, int) const { return 4; }
int operator()(int, int, int, int, int) const { return 5; }
int operator()(int, int, int, int, int, int) const { return 6; }
int operator()(int, int, int, int, int, int, int) const { return 7; }
int operator()(int, int, int, int, int, int, int, int) const { return 8; }
int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
};
struct with_result_template_reference {
template<class Sig>
struct result;
template<class This>
struct result<This()> {
typedef int type;
};
template<class This, class A1>
struct result<This(A1)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
typedef int type;
};
template<class This, class A1, class A2>
struct result<This(A1, A2)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3>
struct result<This(A1, A2, A3)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4>
struct result<This(A1, A2, A3, A4)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5>
struct result<This(A1, A2, A3, A4, A5)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6>
struct result<This(A1, A2, A3, A4, A5, A6)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
struct result<This(A1, A2, A3, A4, A5, A6, A7)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
BOOST_MPL_ASSERT((boost::is_same<A8, int&>));
typedef int type;
};
template<class This, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
struct result<This(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
BOOST_MPL_ASSERT((boost::is_same<A1, int&>));
BOOST_MPL_ASSERT((boost::is_same<A2, int&>));
BOOST_MPL_ASSERT((boost::is_same<A3, int&>));
BOOST_MPL_ASSERT((boost::is_same<A4, int&>));
BOOST_MPL_ASSERT((boost::is_same<A5, int&>));
BOOST_MPL_ASSERT((boost::is_same<A6, int&>));
BOOST_MPL_ASSERT((boost::is_same<A7, int&>));
BOOST_MPL_ASSERT((boost::is_same<A8, int&>));
BOOST_MPL_ASSERT((boost::is_same<A9, int&>));
typedef int type;
};
int operator()() const { return 0; }
int operator()(int) const { return 1; }
int operator()(int, int) const { return 2; }
int operator()(int, int, int) const { return 3; }
int operator()(int, int, int, int) const { return 4; }
int operator()(int, int, int, int, int) const { return 5; }
int operator()(int, int, int, int, int, int) const { return 6; }
int operator()(int, int, int, int, int, int, int) const { return 7; }
int operator()(int, int, int, int, int, int, int, int) const { return 8; }
int operator()(int, int, int, int, int, int, int, int, int) const { return 9; }
};
template<class F>
typename boost::result_of<F()>::type apply0(F f) {
return f();
}
template<class A, class F>
typename boost::result_of<F(A)>::type apply1(F f, A a) {
return f(a);
}
template<class A, class B, class F>
typename boost::result_of<F(A, B)>::type apply2(F f, A a, B b) {
return f(a, b);
}
template<class A, class B, class C, class F>
typename boost::result_of<F(A, B, C)>::type apply3(F f, A a, B b, C c) {
return f(a, b, c);
}
using namespace boost::lambda;
int test_main(int, char *[]) {
BOOST_CHECK(boost::lambda::bind(with_result_type())() == 0);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1)() == 1);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2)() == 2);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3)() == 3);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4)() == 4);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5)() == 5);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6)() == 6);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7)() == 7);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8)() == 8);
BOOST_CHECK(boost::lambda::bind(with_result_type(), 1, 2, 3, 4, 5, 6, 7, 8, 9)() == 9);
// Nullary result_of fails
//BOOST_CHECK(boost::lambda::bind(with_result_template_value())() == 0);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1)() == 1);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2)() == 2);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3)() == 3);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4)() == 4);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5)() == 5);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6)() == 6);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7)() == 7);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8)() == 8);
BOOST_CHECK(boost::lambda::bind(with_result_template_value(), 1, 2, 3, 4, 5, 6, 7, 8, 9)() == 9);
int one = 1,
two = 2,
three = 3,
four = 4,
five = 5,
six = 6,
seven = 7,
eight = 8,
nine = 9;
// Nullary result_of fails
//BOOST_CHECK(boost::lambda::bind(with_result_template_reference())() == 0);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one))() == 1);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two))() == 2);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three))() == 3);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four))() == 4);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five))() == 5);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six))() == 6);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven))() == 7);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven), var(eight))() == 8);
BOOST_CHECK(boost::lambda::bind(with_result_template_reference(), var(one), var(two), var(three), var(four), var(five), var(six), var(seven), var(eight), var(nine))() == 9);
// Check using result_of with lambda functors
BOOST_CHECK(apply0(constant(0)) == 0);
BOOST_CHECK(apply1<int>(_1, one) == 1);
BOOST_CHECK(apply1<int&>(_1, one) == 1);
BOOST_CHECK(apply1<const int&>(_1, one) == 1);
BOOST_CHECK((apply2<int, int>(_1 + _2, one, two) == 3));
BOOST_CHECK((apply2<int&, int&>(_1 + _2, one, two) == 3));
BOOST_CHECK((apply2<const int&, const int&>(_1 + _2, one, two) == 3));
BOOST_CHECK((apply3<int, int, int>(_1 + _2 + _3, one, two, three) == 6));
BOOST_CHECK((apply3<int&, int&, int&>(_1 + _2 + _3, one, two, three) == 6));
BOOST_CHECK((apply3<const int&, const int&, const int&>(_1 + _2 + _3, one, two, three) == 6));
return 0;
}

53
test/ret_test.cpp Normal file
View File

@@ -0,0 +1,53 @@
// ret_test.cpp - The Boost Lambda Library -----------------------
//
// Copyright (C) 2009 Steven Watanabe
//
// 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)
//
// For more information, see www.boost.org
#include <boost/test/minimal.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
template<class R, class F>
void test_ret(R r, F f) {
typename F::result_type x = f();
BOOST_MPL_ASSERT((boost::is_same<R, typename F::result_type>));
BOOST_CHECK(x == r);
}
template<class R, class F, class T1>
void test_ret(R r, F f, T1& t1) {
typename F::result_type x = f(t1);
BOOST_MPL_ASSERT((boost::is_same<R, typename F::result_type>));
BOOST_CHECK(x == r);
}
class add_result {
public:
add_result(int i = 0) : value(i) {}
friend bool operator==(const add_result& lhs, const add_result& rhs) {
return(lhs.value == rhs.value);
}
private:
int value;
};
class addable {};
add_result operator+(addable, addable) {
return add_result(7);
}
int test_main(int, char*[]) {
addable test;
test_ret(add_result(7), boost::lambda::ret<add_result>(boost::lambda::_1 + test), test);
test_ret(8.0, boost::lambda::ret<double>(boost::lambda::constant(7) + 1));
return 0;
}

57
test/rvalue_test.cpp Normal file
View File

@@ -0,0 +1,57 @@
// rvalue_test - test lambda function objects with rvalue arguments
//
// Copyright (c) 2007 Peter Dimov
//
// 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/lambda/lambda.hpp>
#include <boost/detail/lightweight_test.hpp>
int main()
{
using namespace boost::lambda;
int x = 0;
int const y = 1;
int const z = 2;
BOOST_TEST( _1( x ) == 0 );
BOOST_TEST( _1( y ) == 1 );
BOOST_TEST( _1( 2 ) == 2 );
BOOST_TEST( _2( x, x ) == 0 );
BOOST_TEST( _2( x, y ) == 1 );
BOOST_TEST( _2( x, 2 ) == 2 );
BOOST_TEST( _2( 4, x ) == 0 );
BOOST_TEST( _2( 4, y ) == 1 );
BOOST_TEST( _2( 4, 2 ) == 2 );
(_1 = _2)( x, y );
BOOST_TEST( x == y );
(_1 = _2)( x, 3 );
BOOST_TEST( x == 3 );
(_2 = _1)( z, x );
BOOST_TEST( x == z );
(_2 = _1)( 4, x );
BOOST_TEST( x == 4 );
BOOST_TEST( _3( x, x, x ) == x );
BOOST_TEST( _3( x, x, y ) == y );
BOOST_TEST( _3( x, x, 2 ) == 2 );
BOOST_TEST( _3( x, 5, x ) == x );
BOOST_TEST( _3( x, 5, y ) == y );
BOOST_TEST( _3( x, 5, 2 ) == 2 );
BOOST_TEST( _3( 9, 5, x ) == x );
BOOST_TEST( _3( 9, 5, y ) == y );
BOOST_TEST( _3( 9, 5, 2 ) == 2 );
return boost::report_errors();
}

392
test/switch_construct.cpp Normal file
View File

@@ -0,0 +1,392 @@
// switch_test.cpp -- The Boost Lambda Library --------------------------
//
// Copyright (C) 2000-2003 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
// Copyright (C) 2000-2003 Gary Powell (powellg@amazon.com)
//
// 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)
//
// For more information, see www.boost.org
// -----------------------------------------------------------------------
#include <boost/test/minimal.hpp> // see "Header Implementation Option"
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/if.hpp"
#include "boost/lambda/switch.hpp"
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
// Check that elements 0 -- index are 1, and the rest are 0
bool check(const std::vector<int>& v, int index) {
using namespace boost::lambda;
int counter = 0;
std::vector<int>::const_iterator
result = std::find_if(v.begin(), v.end(),
! if_then_else_return(
var(counter)++ <= index,
_1 == 1,
_1 == 0)
);
return result == v.end();
}
void do_switch_no_defaults_tests() {
using namespace boost::lambda;
int i = 0;
std::vector<int> v,w;
// elements from 0 to 9
std::generate_n(std::back_inserter(v),
10,
var(i)++);
std::fill_n(std::back_inserter(w), 10, 0);
// ---
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0]))
)
);
BOOST_CHECK(check(w, 0));
std::fill_n(w.begin(), 10, 0);
// ---
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1]))
)
);
BOOST_CHECK(check(w, 1));
std::fill_n(w.begin(), 10, 0);
// ---
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2]))
)
);
BOOST_CHECK(check(w, 2));
std::fill_n(w.begin(), 10, 0);
// ---
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3]))
)
);
BOOST_CHECK(check(w, 3));
std::fill_n(w.begin(), 10, 0);
// ---
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3])),
case_statement<4>(++var(w[4]))
)
);
BOOST_CHECK(check(w, 4));
std::fill_n(w.begin(), 10, 0);
// ---
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3])),
case_statement<4>(++var(w[4])),
case_statement<5>(++var(w[5]))
)
);
BOOST_CHECK(check(w, 5));
std::fill_n(w.begin(), 10, 0);
// ---
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3])),
case_statement<4>(++var(w[4])),
case_statement<5>(++var(w[5])),
case_statement<6>(++var(w[6]))
)
);
BOOST_CHECK(check(w, 6));
std::fill_n(w.begin(), 10, 0);
// ---
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3])),
case_statement<4>(++var(w[4])),
case_statement<5>(++var(w[5])),
case_statement<6>(++var(w[6])),
case_statement<7>(++var(w[7]))
)
);
BOOST_CHECK(check(w, 7));
std::fill_n(w.begin(), 10, 0);
// ---
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3])),
case_statement<4>(++var(w[4])),
case_statement<5>(++var(w[5])),
case_statement<6>(++var(w[6])),
case_statement<7>(++var(w[7])),
case_statement<8>(++var(w[8]))
)
);
BOOST_CHECK(check(w, 8));
std::fill_n(w.begin(), 10, 0);
}
void do_switch_yes_defaults_tests() {
using namespace boost::lambda;
int i = 0;
std::vector<int> v,w;
// elements from 0 to 9
std::generate_n(std::back_inserter(v),
10,
var(i)++);
std::fill_n(std::back_inserter(w), 10, 0);
int default_count;
// ---
default_count = 0;
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
default_statement(++var(default_count))
)
);
BOOST_CHECK(check(w, -1));
BOOST_CHECK(default_count == 10);
std::fill_n(w.begin(), 10, 0);
// ---
default_count = 0;
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
default_statement(++var(default_count))
)
);
BOOST_CHECK(check(w, 0));
BOOST_CHECK(default_count == 9);
std::fill_n(w.begin(), 10, 0);
// ---
default_count = 0;
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
default_statement(++var(default_count))
)
);
BOOST_CHECK(check(w, 1));
BOOST_CHECK(default_count == 8);
std::fill_n(w.begin(), 10, 0);
// ---
default_count = 0;
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
default_statement(++var(default_count))
)
);
BOOST_CHECK(check(w, 2));
BOOST_CHECK(default_count == 7);
std::fill_n(w.begin(), 10, 0);
// ---
default_count = 0;
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3])),
default_statement(++var(default_count))
)
);
BOOST_CHECK(check(w, 3));
BOOST_CHECK(default_count == 6);
std::fill_n(w.begin(), 10, 0);
// ---
default_count = 0;
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3])),
case_statement<4>(++var(w[4])),
default_statement(++var(default_count))
)
);
BOOST_CHECK(check(w, 4));
BOOST_CHECK(default_count == 5);
std::fill_n(w.begin(), 10, 0);
// ---
default_count = 0;
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3])),
case_statement<4>(++var(w[4])),
case_statement<5>(++var(w[5])),
default_statement(++var(default_count))
)
);
BOOST_CHECK(check(w, 5));
BOOST_CHECK(default_count == 4);
std::fill_n(w.begin(), 10, 0);
// ---
default_count = 0;
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3])),
case_statement<4>(++var(w[4])),
case_statement<5>(++var(w[5])),
case_statement<6>(++var(w[6])),
default_statement(++var(default_count))
)
);
BOOST_CHECK(check(w, 6));
BOOST_CHECK(default_count == 3);
std::fill_n(w.begin(), 10, 0);
// ---
default_count = 0;
std::for_each(v.begin(), v.end(),
switch_statement(
_1,
case_statement<0>(++var(w[0])),
case_statement<1>(++var(w[1])),
case_statement<2>(++var(w[2])),
case_statement<3>(++var(w[3])),
case_statement<4>(++var(w[4])),
case_statement<5>(++var(w[5])),
case_statement<6>(++var(w[6])),
case_statement<7>(++var(w[7])),
default_statement(++var(default_count))
)
);
BOOST_CHECK(check(w, 7));
BOOST_CHECK(default_count == 2);
std::fill_n(w.begin(), 10, 0);
}
void test_empty_cases() {
using namespace boost::lambda;
// ---
switch_statement(
_1,
default_statement()
)(make_const(1));
switch_statement(
_1,
case_statement<1>()
)(make_const(1));
}
int test_main(int, char* []) {
do_switch_no_defaults_tests();
do_switch_yes_defaults_tests();
test_empty_cases();
return EXIT_SUCCESS;
}