Skip to content

Commit

Permalink
Add qxFuncAggregate, useful for std::variant overload pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
oblivioncth committed Aug 15, 2024
1 parent 06c1ffe commit 3299eff
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
39 changes: 39 additions & 0 deletions lib/utility/doc/res/snippets/qx-helpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//! [0]
#include <iostream>
#include <string>
#include <variant>
#include <vector>
#include <functional>
#include <qx/utility/qx-helpers.h>

// The variant to visit
using var_t = std::variant<int, long, double, bool, char, std::string>;

int main()
{
std::vector<var_t> vec = {10, 15l, 1.5, true, 'c', "hello"};

std::function<void(std::string)> f = [](std::string arg) { std::cout << arg << " (from string std::function)"; };

for (auto& v : vec)
{
// Visit using aggregate
std::visit(qxFuncAggregate{
[](auto arg) { std::cout << arg << " (from catch-all lambda) "; },
[](double arg) { std::cout << std::fixed << arg << " (from double lambda) "; },
[](bool arg) { std::cout << arg << " (from bool lambda) "; },
[](char arg) { std::cout << arg << " (from char lambda) "; },
f
}, v);

std::cout << std::endl;
}
}

// 10 (from catch-all lambda)
// 15 (from catch-all lambda)
// 1.500000 (from double lambda)
// 1 (from bool lambda)
// c (from char lambda)
// hello (from string std::function)
//! [0]
10 changes: 10 additions & 0 deletions lib/utility/include/qx/utility/qx-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@
// Standard Library Includes
#include <type_traits>

//Non-namespace Structs----------------------------------------------------------
/* TODO: Figure out how to constrain this to only accept functors, issue is at least as of C++20
* there doesnt seem to be a way to check if a type has an arbitrary number of operator() overloads
* with an arbitrary number of arguments.
*/
template<typename... Functors>
struct qxFuncAggregate : Functors... {
using Functors::operator()...;
};

//Non-namespace Functions----------------------------------------------------------
template <typename T>
const T qxAsConst(T&& t) { return std::move(t); }
Expand Down
14 changes: 13 additions & 1 deletion lib/utility/src/qx-helpers.dox
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@
* are designed to facilitate common fundamental tasks with as brief syntax as possible.
*/

//Non-namespace Structs----------------------------------------------------------
/*!
* @struct qxFuncAggregate
*
* A template struct that takes an arbitrary number of functors as arguments and, when
* instantiated, produces a struct with all `operator()` overloads from all provided functors.
*
* This helper struct is commonly used in the `std::variant` overload visit pattern to concisely
* implement a handler for all alternatives:
*
* @snippet qx-helpers.cpp 0
*/

//Non-namespace Functions----------------------------------------------------------
/*!
* @fn const T qxAsConst(T&& t)
Expand All @@ -26,7 +39,6 @@
* qAsConst().
*/


/*!
* @fn void qxDelete(T*& pointer)
*
Expand Down

0 comments on commit 3299eff

Please sign in to comment.