1
0
forked from Alepha/Alepha
Files
Alepha/Utility/lambaste.h

62 lines
1.8 KiB
C++

static_assert( __cplusplus > 2020'99 );
#pragma once
#include <Alepha/Alepha.h>
#include <type_traits>
#include <utility>
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;
}