Example
int main() {
using std::literals::string_view_literals::operator""sv;
std::cout << "trade.price"sv.contains("order"); // prints 0
std::cout << "trade.price"sv.contains(""); // prints 1
std::cout << "trade.price"sv.contains("price"); // prints 1
}
Puzzle
- Can you implement
values
function which returns the sum of values that contains the given name?
consteval auto values(auto in, auto str); // TODO
using std::literals::string_view_literals::operator""sv;
static_assert(0 == values(std::tuple{}, ""sv));
static_assert(0 == values(std::tuple{}, "price"sv));
static_assert(0 == values(std::tuple{}, "size"sv));
constexpr auto prices = std::tuple{std::pair{"trade.price"sv, 123.456}, std::pair{"order.price"sv, 42.}};
static_assert(0. == values(prices, ""sv));
static_assert(0. == values(prices, "unknown"sv));
static_assert(0. == values(prices, "size"sv));
static_assert(123.456 + 42. == values(prices, "price"sv));
constexpr auto sizes = std::tuple{std::pair{"trade.size"sv, 42}, std::pair{"trade.id"sv, 100}, std::pair{"order.size"sv, 99}};
static_assert(0 == values(sizes, ""sv));
static_assert(0 == values(sizes, "unknown"sv));
static_assert(42 + 99 == values(sizes, "size"sv));
Solutions
consteval auto values(const auto& t, const auto str) {
const auto value_for = [&] (const auto& p) {
const auto& [name, value] = p;
return not std::empty(str) and name.contains(str) ? value : decltype(value){};
};
return std::apply([&] (auto&&... elems) {
return (value_for(elems) + ... + 0);
}, t);
}
consteval auto values(auto in, auto str)
{
return std::apply( [&str](auto ... args ){
return ( ( !str.empty() && args.first.contains(str) ? args.second : 0 ) + ... + 0) ;
}, in );
}
consteval auto values(auto in, auto str) {
return std::apply(
[&](const auto&... args) {
return (([&] {
if (const auto& [name, value] = args;
not std::empty(str) and name.contains(str))
return value;
else
return decltype(value){};
}()) +
... + 0);
},
in);
}
constexpr auto value(auto in, auto str) {
if constexpr (requires {
in.first;
in.second;
in.first.contains(str);
std::empty(str);
}) {
if (not std::empty(str) and in.first.contains(str)) {
return in.second;
} else {
return decltype(in.second){};
}
} else {
return 0;
}
};
consteval auto values(auto in, auto str) {
return std::apply(
[&str](const auto&... items) { return (value(items, str) + ... + 0); },
in);
}
consteval auto values(auto const& tuple, auto const strv) noexcept {
const auto check_pairs = [=](auto const& pair) {
if (std::empty(strv) or pair.first.find(strv) == std::string_view::npos) {
return decltype(pair.second){};
}
return pair.second;
};
return std::apply([&] (auto const&... pairs) {
return (check_pairs(pairs) + ... + 0);
}, tuple);
}
consteval auto values(auto in, auto str)
{
return std::apply([&](auto... vs) -> decltype((0 + ... + vs.second))
{
return str.empty() ? 0 : (0 + ... + (vs.first.contains(str) ? vs.second : 0));
}, in);
}
consteval auto values(auto in, auto str){
const auto value = [&](const auto& arg){
const auto [arg_str, arg_val] = arg;
const auto default_val = decltype(arg_val){};
return not std::empty(str) and arg_str.contains(str) ? arg_val : default_val;
};
return std::apply([&] (auto... args){
return (value(args) + ... + 0);
},in);
}
consteval auto values(const auto tup, const auto key){
if constexpr (std::tuple_size_v<decltype(tup)> == 0)
{
return 0.;
}
else
{
const auto get_value=[&](const auto pair)
{
const auto [name, value] = pair;
if (not std::empty(key) and name.contains(key))
{
return value;
}
else return decltype(value){};
};
return std::apply(
[get_value]( const auto... args ) {
return (get_value(args) + ... );
}
,tup);
}
}