match_eggs.hpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2014, 2015 Ableton AG, Berlin. All rights reserved.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
21 //
22 
27 #pragma once
28 
31 
32 #include <ableton/build_system/Warnings.hpp>
33 ABL_DISABLE_WARNINGS
34 #include <eggs/variant.hpp>
35 ABL_RESTORE_WARNINGS
36 #include <utility>
37 
38 namespace atria {
39 namespace variant {
40 
41 namespace detail {
42 
43 template <typename T>
44 struct is_eggs_variant : std::is_base_of<
45  meta::unpack<eggs::variant, variant_types_t<estd::decay_t<T> > >,
46  estd::decay_t<T> >
47 {};
48 
49 } // namespace detail
50 
65 template <typename VariantT, typename ...FnTs>
66 auto match(VariantT&& variant, FnTs&& ...fns)
68  detail::is_eggs_variant<estd::decay_t<VariantT> >{},
69  visitor_result_of_t<
70  detail::visitor_impl<FnTs...>,
71  variant_types_t<VariantT&&> > >
72 {
73  using result_t = visitor_result_of_t<
74  detail::visitor_impl<FnTs...>,
75  variant_types_t<VariantT&&> >;
76 
77  using eggs_t = meta::copy_decay_t<
78  VariantT,
80 
81  return eggs::variants::apply<result_t>(
82  visitor_for<VariantT>(std::forward<FnTs>(fns)...),
83  // eggs::variants::apply is too stupid to detect that a subclass
84  // of a variant can be destructured, so we cast up such that
85  // subclassing works
86  std::forward<eggs_t>(static_cast<eggs_t&&>(variant)));
87 }
88 
89 } // namespace variant
90 } // namespace atria
typename std::enable_if< X, T >::type enable_if_t
Similar to C++14 std::enable_if_t.
Definition: type_traits.hpp:84
typename detail::unpack< MF, T >::type unpack
Metafunction that given a variadic template MF and a type ArgT, returns MF, or if ArgT is of th...
Definition: pack.hpp:101
auto match(VariantT &variant, FnTs &&...fns) -> estd::enable_if_t< detail::is_boost_variant< estd::decay_t< VariantT > >
Destructure a boost::variant with a given set of functions.
Definition: match_boost.hpp:69
C++ amazing templates and reusable implementations awesomeness.
Definition: _doc.hpp:35
Fork me on GitHub