Overview
Description
This is a simple, but functional, C++14 lambda library. It takes
advantage of the fact that the standard <functional> header already
provides std::bind customization points (is_placeholder,
is_bind_expression), and function objects such as std::plus,
std::greater, std::logical_not, and std::bit_xor, corresponding
to arithmetic, relational, logical and bitwise operators.
This allows the library to provide a minimal implementation that
still lets expressions such as _1 + 5, _1 % 2 == 0, _1 > _2,
or _1 == ' ' || _1 == '\t' to be composed and used as function
objects.
For example, _1 + 5 is implemented as std::bind(std::plus<>, _1, 5).
These "lambda" expressions can also be freely combined with std::bind.
For example, std::bind( f, _1 ) == std::bind( g, _1 ) and
std::bind( f, _1 + _2 ) both work and have the expected behavior.
Usage Examples
Counting the Even Numbers
#include <boost/lambda2.hpp>
#include <algorithm>
using namespace boost::lambda2;
int count_even( int const * first, int const * last )
{
return std::count_if( first, last, _1 % 2 == 0 );
}
Finding the First Whitespace Character
#include <boost/lambda2.hpp>
#include <algorithm>
char const * find_whitespace( char const * first, char const * last )
{
using namespace boost::lambda2;
return std::find_if( first, last,
_1 == ' ' || _1 == '\t' || _1 == '\r' || _1 == '\n' );
}
Dependencies
None. A single, self-contained header.
Supported Compilers
-
GCC 5 or later with
-std=c++14or above -
Clang 3.9 or later with
-std=c++14or above -
Visual Studio 2015, 2017, 2019
Tested on Github Actions and Appveyor.
Revision History
Changes in 1.78.0
-
Added special cases in
operator<<andoperator>>when the first argument is a stream, to allowstd::cout << _1. -
Added
operator->*. -
Added
first,second.
Reference
<boost/lambda2/lambda2.hpp>
Synopsis
namespace boost {
namespace lambda2 {
// placeholders
template<int I> struct lambda2_arg;
inline constexpr lambda2_arg<1> _1{};
inline constexpr lambda2_arg<2> _2{};
inline constexpr lambda2_arg<3> _3{};
inline constexpr lambda2_arg<4> _4{};
inline constexpr lambda2_arg<5> _5{};
inline constexpr lambda2_arg<6> _6{};
inline constexpr lambda2_arg<7> _7{};
inline constexpr lambda2_arg<8> _8{};
inline constexpr lambda2_arg<9> _9{};
// arithmetic operators
template<class A, class B> auto operator+( A && a, B && b );
template<class A, class B> auto operator-( A && a, B && b );
template<class A, class B> auto operator*( A && a, B && b );
template<class A, class B> auto operator/( A && a, B && b );
template<class A, class B> auto operator%( A && a, B && b );
template<class A> auto operator-( A && a );
// relational operators
template<class A, class B> auto operator==( A && a, B && b );
template<class A, class B> auto operator!=( A && a, B && b );
template<class A, class B> auto operator>( A && a, B && b );
template<class A, class B> auto operator<( A && a, B && b );
template<class A, class B> auto operator>=( A && a, B && b );
template<class A, class B> auto operator<=( A && a, B && b );
// logical operators
template<class A, class B> auto operator&&( A && a, B && b );
template<class A, class B> auto operator||( A && a, B && b );
template<class A> auto operator!( A && a );
// bitwise operators
template<class A, class B> auto operator&( A && a, B && b );
template<class A, class B> auto operator|( A && a, B && b );
template<class A, class B> auto operator^( A && a, B && b );
template<class A> auto operator~( A && a );
template<class A, class B> auto operator<<( A && a, B && b );
template<class A, class B> auto operator>>( A && a, B && b );
// additional unary operators
template<class A> auto operator+( A && a );
template<class A> auto operator*( A && a );
template<class A> auto operator++( A && a );
template<class A> auto operator--( A && a );
template<class A> auto operator++( A && a, int );
template<class A> auto operator--( A && a, int );
// compound assignment operators
template<class A, class B> auto operator+=( A && a, B && b );
template<class A, class B> auto operator-=( A && a, B && b );
template<class A, class B> auto operator*=( A && a, B && b );
template<class A, class B> auto operator/=( A && a, B && b );
template<class A, class B> auto operator%=( A && a, B && b );
template<class A, class B> auto operator&=( A && a, B && b );
template<class A, class B> auto operator|=( A && a, B && b );
template<class A, class B> auto operator^=( A && a, B && b );
template<class A, class B> auto operator<<=( A && a, B && b );
template<class A, class B> auto operator>>=( A && a, B && b );
// additional binary operators
template<class A, class B> auto operator->*( A && a, B && b );
// projections
inline constexpr /unspecified/ first{};
inline constexpr /unspecified/ second{};
} // namespace lambda2
} // namespace boost
Placeholders
template<int I> struct lambda2_arg
{
template<class... A> decltype(auto) operator()( A&&... a ) const noexcept;
template<class T> auto operator[]( T&& t ) const;
};
lambda2_arg<I> is the type of the library-provided placeholders _I. The
standard customization point std::is_placeholder is specialized for it,
enabling the use of Lambda2’s placeholders with std::bind.
The placeholders define operator(), which permits their direct use as
function objects. E.g. _1(x, y) returns x.
operator[] is also defined to allow expressions like _1[x] or _1[_2].
template<class... A> decltype(auto) operator()( A&&... a ) const noexcept;
-
- Returns:
-
std::get<std::size_t{I-1}>( std::tuple<A&&…>( std::forward<A>(a)… ) );
template<class T> auto operator[]( T&& t ) const;
-
- Returns:
-
std::bind( fn, *this, std::forward<T>(t) );, wherefnis a function object such thatfn(x, y)returnsx[y].
Common Requirements
All operators defined in the subsequent sections only participate in
overload resolution if at least one of their operands is such that for
its unqualified type T, the expression
std::is_placeholder<T>::value || std::is_bind_expression<T>::value
is true.
Arithmetic Operators
template<class A, class B> auto operator+( A && a, B && b );
-
- Returns:
-
std::bind( std::plus<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator-( A && a, B && b );
-
- Returns:
-
std::bind( std::minus<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator*( A && a, B && b );
-
- Returns:
-
std::bind( std::multiplies<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator/( A && a, B && b );
-
- Returns:
-
std::bind( std::divides<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator%( A && a, B && b );
-
- Returns:
-
std::bind( std::modulus<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A> auto operator-( A && a );
-
- Returns:
-
std::bind( std::negate<>(), std::forward<A>(a) );
Relational Operators
template<class A, class B> auto operator==( A && a, B && b );
-
- Returns:
-
std::bind( std::equal_to<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator!=( A && a, B && b );
-
- Returns:
-
std::bind( std::not_equal_to<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator>( A && a, B && b );
-
- Returns:
-
std::bind( std::greater<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator<( A && a, B && b );
-
- Returns:
-
std::bind( std::less<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator>=( A && a, B && b );
-
- Returns:
-
std::bind( std::greater_equal<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator<=( A && a, B && b );
-
- Returns:
-
std::bind( std::less_equal<>(), std::forward<A>(a), std::forward<B>(b) );
Logical Operators
template<class A, class B> auto operator&&( A && a, B && b );
-
- Returns:
-
std::bind( std::logical_and<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator||( A && a, B && b );
-
- Returns:
-
std::bind( std::logical_or<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A> auto operator!( A && a );
-
- Returns:
-
std::bind( std::logical_not<>(), std::forward<A>(a) );
Bitwise Operators
template<class A, class B> auto operator&( A && a, B && b );
-
- Returns:
-
std::bind( std::bit_and<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator|( A && a, B && b );
-
- Returns:
-
std::bind( std::bit_or<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A, class B> auto operator^( A && a, B && b );
-
- Returns:
-
std::bind( std::bit_xor<>(), std::forward<A>(a), std::forward<B>(b) );
template<class A> auto operator~( A && a );
-
- Returns:
-
std::bind( std::bit_not<>(), std::forward<A>(a) );
template<class A, class B> auto operator<<( A && a, B && b );
-
- Returns:
-
std::bind( fn, std::forward<A>(a), std::forward<B>(b) );, wherefnis a function object such thatfn(x, y)returnsx << y.
template<class A, class B> auto operator>>( A && a, B && b );
-
- Returns:
-
std::bind( fn, std::forward<A>(a), std::forward<B>(b) );, wherefnis a function object such thatfn(x, y)returnsx >> y.
Additional Unary Operators
template<class A> auto operator+( A && a );
-
- Returns:
-
std::bind( fn, std::forward<A>(a) );, wherefnis a function object such thatfn(x)returns+x.
template<class A> auto operator*( A && a );
-
- Returns:
-
std::bind( fn, std::forward<A>(a) );, wherefnis a function object such thatfn(x)returns*x.
template<class A> auto operator++( A && a );
-
- Returns:
-
std::bind( fn, std::forward<A>(a) );, wherefnis a function object such thatfn(x)returns++x.
template<class A> auto operator--( A && a );
-
- Returns:
-
std::bind( fn, std::forward<A>(a) );, wherefnis a function object such thatfn(x)returns--x.
template<class A> auto operator++( A && a, int );
-
- Returns:
-
std::bind( fn, std::forward<A>(a) );, wherefnis a function object such thatfn(x)returnsx++.
template<class A> auto operator--( A && a, int );
-
- Returns:
-
std::bind( fn, std::forward<A>(a) );, wherefnis a function object such thatfn(x)returnsx--.
Compound Assignment Operators
template<class A, class B> auto operator@=( A && a, B && b );
-
- Returns:
-
std::bind( fn, std::forward<A>(a), std::forward<B>(b) );, wherefnis a function object such thatfn(x, y)returnsx @= y.
Additional Binary Operators
template<class A, class B> auto operator->*( A && a, B && b );
-
- Returns:
-
std::bind( std::forward<B>(b), std::forward<A>(a) ); - Notes:
-
This operator is intended to be used with "projection" function objects such as member pointers or member functions taking zero arguments, as in
_1->*&X::mor_1->*&X::f.
Projections
inline constexpr /unspecified/ first{};
A function object such that first(x) returns std::get<0>(x).
inline constexpr /unspecified/ second{};
A function object such that second(x) returns std::get<1>(x).
void print( std::map<int, std::string> const & m )
{
using namespace boost::lambda2;
std::for_each( m.begin(), m.end(), std::cout << _1->*first << ": " << _1->*second << '\n' );
}
Copyright and License
This documentation is copyright 2020, 2021 Peter Dimov and is distributed under the Boost Software License, Version 1.0.