|
| 1 | +/* Copyright (c) 2008-2025 the MRtrix3 contributors. |
| 2 | + * |
| 3 | + * This Source Code Form is subject to the terms of the Mozilla Public |
| 4 | + * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 5 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 6 | + * |
| 7 | + * Covered Software is provided under this License on an "as is" |
| 8 | + * basis, without warranty of any kind, either expressed, implied, or |
| 9 | + * statutory, including, without limitation, warranties that the |
| 10 | + * Covered Software is free of defects, merchantable, fit for a |
| 11 | + * particular purpose or non-infringing. |
| 12 | + * See the Mozilla Public License v. 2.0 for more details. |
| 13 | + * |
| 14 | + * For more details, see http://www.mrtrix.org/. |
| 15 | + */ |
| 16 | + |
| 17 | +#pragma once |
| 18 | + |
| 19 | +#include <variant> |
| 20 | + |
| 21 | +// Utility for pattern-matching style over std::variant. |
| 22 | +// - `overload` builds an overload set from multiple lambdas (or function objects). |
| 23 | +// - `match_v` wraps std::visit, forwarding the variant and visitors. |
| 24 | +// It returns whatever the selected lambda returns. |
| 25 | +// Example: |
| 26 | +// std::variant<int, std::string> v = 42; |
| 27 | +// auto s = MR::match_v(v, |
| 28 | +// [](int i) { return std::to_string(i); }, |
| 29 | +// [](const std::string& s) { return s; }); // check_syntax off |
| 30 | +// // s == "42" |
| 31 | + |
| 32 | +namespace MR { |
| 33 | +template <class... Ts> struct overload : Ts... { |
| 34 | + using Ts::operator()...; |
| 35 | +}; |
| 36 | +template <class... Ts> overload(Ts...) -> overload<Ts...>; |
| 37 | +template <class var_t, class... Func> decltype(auto) match_v(var_t &&variant, Func &&...funcs) { |
| 38 | + return std::visit(overload{std::forward<Func>(funcs)...}, std::forward<var_t>(variant)); |
| 39 | +} |
| 40 | +} // namespace MR |
0 commit comments