|
Boost : |
Subject: [boost] Fit: C++ function utility library
From: pfultz2 (pfultz2_at_[hidden])
Date: 2014-10-31 21:20:23
Hi,
I developed a library called Fit, that provides a lot of utilites for
dealing
with function objects, here:
https://github.com/pfultz2/Fit
First, it provides a mechanism to construct function objects at compile time
using lambdas, for example:
const constexpr auto sum = FIT_STATIC_LAMBDA(auto x, auto y)
{
return x + y;
};
Secondly, it provides lots of adaptors to provide "enhancements" to the
function. For example, we could make the sum function pipable:
const constexpr auto sum = pipable(FIT_STATIC_LAMBDA(auto x, auto y)
{
return x + y;
});
Then call it like this:
auto three = 1 | sum(2);
Or we could make it an infix operator:
const constexpr auto sum = infix(FIT_STATIC_LAMBDA(auto x, auto y)
{
return x + y;
});
And then use it like this:
auto three = 1 <sum> 2;
Also, it provides the basic partial application and function composition:
auto add_1 = partial(sum)(1);
auto add_2 = compose(add_1, add_1);
auto four = add_2(1);
Now, the greatest benifit is being to do better overloading and even
recursive
functions using lambdas. So, for example, if we wanted to write a more
sophisticated `print` function that iterated over ranges and fusion
sequences
recursively, and printed it all out, we can write this using the Fit
library:
// Some helpers for template constraints
#define REQUIRES(...) typename std::enable_if<(decltype(__VA_ARGS__)()),
int>::type = 0
template<template<class...> class Trait, class... Ts>
constexpr auto trait(Ts&&...)
{
return std::integral_constant<bool,
Trait<std::remove_reference_t<Ts>...>::value>();
}
const constexpr auto print = fix(conditional(
// Overload for strings
FIT_STATIC_LAMBDA(auto, const std::string& x)
{
std::cout << x << std::endl;
},
// Overload for fusion sequences
FIT_STATIC_LAMBDA(auto self, const auto& seq,
REQUIRES(trait<boost::fusion::traits::is_sequence>(seq)))
{
boost::fusion::for_each(seq, self);
},
// Overload for ranges
FIT_STATIC_LAMBDA(auto self, const auto& range,
REQUIRES(trait<boost::has_range_const_iterator>(range)))
{
for(const auto& x:range)
self(x);
},
// Overload for anything else
FIT_STATIC_LAMBDA(auto, const auto& x)
{
std::cout << x << std::endl;
}
));
The documentation for it can be found here:
http://pfultz2.github.io/Fit/doc/html/
Any feedback would be appreciated. Also, I don't know if there would be any
interest in incorporating this into boost.
Thanks,
Paul
-- View this message in context: http://boost.2283326.n4.nabble.com/Fit-C-function-utility-library-tp4668629.html Sent from the Boost - Dev mailing list archive at Nabble.com.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk