2
0
mirror of https://github.com/boostorg/lambda2.git synced 2026-01-20 04:32:44 +00:00

Compare commits

...

17 Commits

Author SHA1 Message Date
Peter Dimov
fd1a3e4543 Remove msvc-14.1 from GHA, add clang-win 2022-04-14 16:15:13 +03:00
Peter Dimov
8c6c1166c4 Update ci.yml 2022-04-14 14:21:41 +03:00
Peter Dimov
c618d6902b Re-enable VS2017 2022-04-14 14:02:35 +03:00
Peter Dimov
ae42ebda76 Update version 2022-04-14 13:41:49 +03:00
Peter Dimov
3ccd5c251b Add msvc-14.0 to GHA 2021-12-09 04:11:57 +02:00
Peter Dimov
132db3b09a Update version 2021-12-09 04:10:29 +02:00
Peter Dimov
253aef863f Enable syntax highlighting 2021-10-28 23:13:48 +03:00
Peter Dimov
a593616a98 Add msvc-14.3 to ci.yml 2021-10-28 23:13:17 +03:00
Peter Dimov
2ff3fef3d1 Update documentation 2021-10-18 21:33:52 +03:00
Peter Dimov
0572e42219 Work around libc++ issue (again.) 2021-10-18 21:20:14 +03:00
Peter Dimov
7c39436198 Add first, second function objects. Fixes #5. 2021-10-18 20:57:25 +03:00
Peter Dimov
f8b3099259 Fix placeholder types in the synopsis 2021-09-05 19:01:20 +03:00
Peter Dimov
a666ac4fb6 Update revision history 2021-09-05 18:46:17 +03:00
Peter Dimov
d57e7e1618 Document operator->* 2021-09-05 07:05:49 +03:00
Peter Dimov
d7a1fccc89 Work around libc++ issue (https://bugs.llvm.org/show_bug.cgi?id=51753) 2021-09-05 06:54:38 +03:00
Peter Dimov
0c1898100a Add operator->* 2021-09-05 05:26:32 +03:00
Peter Dimov
e6a538a98e Remove superfluous backslashes 2021-09-05 05:26:15 +03:00
7 changed files with 177 additions and 18 deletions

View File

@@ -139,14 +139,22 @@ jobs:
fail-fast: false
matrix:
include:
- toolset: msvc-14.1
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2016
- toolset: msvc-14.2
cxxstd: "14,17,latest"
- toolset: msvc-14.0
cxxstd: "14"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
@@ -183,4 +191,4 @@ jobs:
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker

View File

@@ -9,7 +9,10 @@ Peter Dimov
:toc: left
:toclevels: 4
:idprefix:
:listing-caption: Code Example
:docinfo: private-footer
:source-highlighter: rouge
:source-language: c++
:leveloffset: +1

View File

@@ -12,3 +12,5 @@ https://www.boost.org/LICENSE_1_0.txt
* Added special cases in `operator<<` and `operator>>` when
the first argument is a stream, to allow `std::cout << _1`.
* Added `operator\->*`.
* Added `first`, `second`.

View File

@@ -21,14 +21,14 @@ namespace lambda2 {
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{};
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
@@ -86,6 +86,15 @@ 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
```
@@ -388,3 +397,39 @@ template<class A, class B> auto operator@=( A && a, B && b );
+
Returns: :: `std::bind( fn, std::forward<A>(a), std::forward<B>(b) );`,
where `fn` is a function object such that `fn(x, y)` returns `x @= y`.
### Additional Binary Operators
```
template<class A, class B> auto operator->*( A && a, B && b );
```
[none]
* {blank}
+
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::m` or `_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)`.
.Using first and second to print out a map
```
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' );
}
```

View File

@@ -14,7 +14,7 @@
// Same format as BOOST_VERSION:
// major * 100000 + minor * 100 + patch
#define BOOST_LAMBDA2_VERSION 107800
#define BOOST_LAMBDA2_VERSION 108000
namespace boost
{
@@ -32,6 +32,14 @@ struct subscript
}
};
template<int I> struct get
{
template<class T> decltype(auto) operator()( T&& t ) const
{
return std::get<I>( std::forward<T>(t) );
}
};
} // namespace lambda2_detail
// placeholders
@@ -65,6 +73,11 @@ BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<7> _7{};
BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<8> _8{};
BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_arg<9> _9{};
// first, second
BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_detail::get<0> first{};
BOOST_LAMBDA2_INLINE_VAR constexpr lambda2_detail::get<1> second{};
#undef BOOST_LAMBDA2_INLINE_VAR
} // namespace lambda2
@@ -232,7 +245,7 @@ template<class A, class = std::enable_if_t<!lambda2_detail::is_stream<A>::value>
class B, class = lambda2_detail::enable_binary_lambda<A, B>>
auto operator<<( A&& a, B&& b )
{
return std::bind( lambda2_detail::left_shift(), std::forward<A>(a), std::forward<B>(b) ); \
return std::bind( lambda2_detail::left_shift(), std::forward<A>(a), std::forward<B>(b) );
}
template<class A, class = std::enable_if_t<lambda2_detail::is_stream<A>::value>,
@@ -248,7 +261,7 @@ template<class A, class = std::enable_if_t<!lambda2_detail::is_stream<A>::value>
class B, class = lambda2_detail::enable_binary_lambda<A, B>>
auto operator>>( A&& a, B&& b )
{
return std::bind( lambda2_detail::right_shift(), std::forward<A>(a), std::forward<B>(b) ); \
return std::bind( lambda2_detail::right_shift(), std::forward<A>(a), std::forward<B>(b) );
}
template<class A, class = std::enable_if_t<lambda2_detail::is_stream<A>::value>,
@@ -258,6 +271,14 @@ auto operator>>( A& a, B&& b )
return std::bind( lambda2_detail::right_shift(), std::ref(a), std::forward<B>(b) );
}
// operator->*
template<class A, class B, class = lambda2_detail::enable_unary_lambda<A>>
auto operator->*( A&& a, B&& b )
{
return std::bind( std::forward<B>(b), std::forward<A>(a) );
}
} // namespace lambda2
} // namespace boost

View File

@@ -26,3 +26,4 @@ run subscript.cpp ;
run compound.cpp ;
run stream_insert.cpp ;
run stream_extract.cpp ;
run project.cpp ;

79
test/project.cpp Normal file
View File

@@ -0,0 +1,79 @@
// Copyright 2021 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/lambda2.hpp>
#include <boost/core/lightweight_test.hpp>
#include <utility>
struct X
{
int m1;
int m2;
int f1() const
{
return m1;
}
int& f2()
{
return m2;
}
};
int main()
{
using namespace boost::lambda2;
{
X const x{ 1, 2 };
BOOST_TEST_EQ( (_1->*&X::m1)( x ), 1 );
BOOST_TEST_EQ( (_1->*&X::m2)( x ), 2 );
BOOST_TEST_EQ( (_1->*&X::f1)( x ), 1 );
}
{
X x{ 0, 0 };
BOOST_TEST_EQ( (_1->*&X::m1)( x ), 0 );
BOOST_TEST_EQ( (_1->*&X::m2)( x ), 0 );
BOOST_TEST_EQ( (_1->*&X::f1)( x ), 0 );
BOOST_TEST_EQ( (_1->*&X::f2)( x ), 0 );
#if defined(_LIBCPP_VERSION)
// https://bugs.llvm.org/show_bug.cgi?id=51753
using std::placeholders::_1;
#endif
BOOST_TEST_EQ( (_1->*&X::m1 += 1)( x ), 1 );
BOOST_TEST_EQ( (_1->*&X::m2 += 2)( x ), 2 );
BOOST_TEST_EQ( (_1->*&X::f1)( x ), 1 );
BOOST_TEST_EQ( (_1->*&X::f2)( x ), 2 );
BOOST_TEST_EQ( (_1->*&X::f2 += 3)( x ), 5 );
}
{
std::pair<int, int> const x( 1, 2 );
BOOST_TEST_EQ( (_1->*&std::pair<int, int>::first)( x ), 1 );
BOOST_TEST_EQ( (_1->*&std::pair<int, int>::second)( x ), 2 );
#if defined(_LIBCPP_VERSION)
// https://bugs.llvm.org/show_bug.cgi?id=51753
using std::placeholders::_1;
#endif
BOOST_TEST_EQ( (_1->*first)( x ), 1 );
BOOST_TEST_EQ( (_1->*second)( x ), 2 );
}
return boost::report_errors();
}