Apply.hpp 1.83 KB
Newer Older
1
2
3
4
5
6
#pragma once

#include <tuple>
#include <type_traits>
#include <utility>

7
8
#include <amdis/common/Index.hpp>
#include <amdis/common/StaticSize.hpp>
Praetorius, Simon's avatar
Praetorius, Simon committed
9
#include <amdis/common/TypeTraits.hpp>
10
11
12
13
14
15
16

namespace AMDiS
{
  namespace Tools
  {
    namespace Impl_
    {
17
18
      template <class Functor, class Tuple, std::size_t... I>
      constexpr decltype(auto) apply_impl(Functor&& f, Tuple&& t, std::index_sequence<I...>)
19
      {
20
21
        using std::get;
        return f(get<I>(FWD(t))...);
22
23
      }

24
25
      template <class Functor, std::size_t I0, std::size_t... I>
      constexpr decltype(auto) apply_indices_impl(Functor&& f, index_t<I0>, std::index_sequence<I...>)
26
27
28
29
30
31
32
33
      {
        return f(index_t<I0+I>{}...);
      }
    }  // namespace Impl_

    template <class F, class Tuple>
    constexpr decltype(auto) apply(F&& f, Tuple&& t)
    {
34
      return Impl_::apply_impl(FWD(f), FWD(t),
35
          std::make_index_sequence<static_size_v<Tuple>>{});
36
37
    }

38
39
    template <class Functor, class... Args>
    constexpr decltype(auto) apply_variadic(Functor&& f, Args&&... args)
40
    {
41
      return apply(FWD(f), std::forward_as_tuple(args...));
42
43
    }

44
45
46
47
48
49
50
    template <std::size_t N, class Functor>
    constexpr decltype(auto) apply_indices(Functor&& f)
    {
      return Impl_::apply_indices_impl(FWD(f), index_t<0>{},
          std::make_index_sequence<N>{});
    }

51
52
    template <class Functor, std::size_t N>
    constexpr decltype(auto) apply_indices(Functor&& f, index_t<N>)
53
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
54
      return Impl_::apply_indices_impl(FWD(f), index_t<0>{},
55
56
57
          std::make_index_sequence<N>{});
    }

58
59
    template <class Functor, std::size_t I0, std::size_t I1>
    constexpr decltype(auto) apply_indices(Functor&& f, index_t<I0>, index_t<I1>)
60
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
61
      return Impl_::apply_indices_impl(FWD(f), index_t<I0>{},
62
63
64
65
          std::make_index_sequence<I1-I0>{});
    }
  }
} // end namespace AMDiS