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.5 or later with
-std=c++14or above -
Visual Studio 2015, 2017, 2019
Tested on Github Actions and Appveyor.
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<1> _2{};
inline constexpr lambda2_arg<1> _3{};
inline constexpr lambda2_arg<1> _4{};
inline constexpr lambda2_arg<1> _5{};
inline constexpr lambda2_arg<1> _6{};
inline constexpr lambda2_arg<1> _7{};
inline constexpr lambda2_arg<1> _8{};
inline constexpr lambda2_arg<1> _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 );
} // 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.
Copyright and License
This documentation is copyright 2020, 2021 Peter Dimov and is distributed under the Boost Software License, Version 1.0.