static_assert( __cplusplus > 2020'99 ); #pragma once #include #include #include namespace Alepha::Hydrogen::Utility ::detail:: lambaste_m { inline namespace exports { /*! * Mechanism to define lambda capture of a value. * * Sometimes it's useful or necessary to take a known value and wrap it in a function-like interface. Some * APIs let programmers provide functions which act as customization points. Sometimes the value is already * at hand, and it needs to be wrapped in a lambda. * * For example: * * ``` * auto wrapped= [myValue] { return myValue; }; * ``` * * While the above is perfectly adequate, it is a bit cumbersome. `myValue` is used twice, there's a lot of * mechanical syntax for lambda function definition, etc. `lambaste` provides a simpler alternative: * * ``` * auto wrapped= lambaste <=myValue; * ``` * * Because `lambaste <=` precedes the variable, it is clear that something is going on here. The `<=` in * this case should be thought of as a `fat left arrow` -- the value is being given to `lambaste` to be used * in constructing a function-object. * * @note Lambaste is a stupid pun -- a better name might be in order. */ inline struct lambaste_t {} lambaste; } template< typename ValueType > constexpr auto as_func( ValueType value ) noexcept( std::is_nothrow_move_constructible_v< ValueType > ) { return [value= std::move( value )]() -> std::decay_t< ValueType > { return value; }; } template< typename ValueType > constexpr decltype( auto ) operator <=( lambaste_t, ValueType value ) noexcept( noexcept( as_func( std::move( value ) ) ) ) { return as_func( std::move( value ) ); } } namespace Alepha::Hydrogen::Utility::inline exports::inline lambaste_m { using namespace detail::lambaste_m::exports; }