Lumiera  0.pre.03
»edit your freedom«
microbenchmark-adaptor.hpp
Go to the documentation of this file.
1 /*
2  MICROBENCHMARK-ADAPTOR.hpp - helper to support microbenchmarks
3 
4  Copyright (C)
5  2023, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
30 #ifndef LIB_TEST_MICROBENCHMARK_ADAPTOR_H
31 #define LIB_TEST_MICROBENCHMARK_ADAPTOR_H
32 
33 
34 #include "lib/meta/function.hpp"
35 #include "lib/meta/util.hpp"
36 
37 namespace lib {
38 namespace test{
39 namespace microbenchmark {
40 
42  using std::is_arithmetic;
43  using std::is_same;
44  using std::__and_;
45  using std::__not_;
46 
47 
52  template<class SIG, typename SEL=void>
53  struct Adaptor
54  {
55  static_assert (not sizeof(SIG), "Unable to adapt given functor.");
56  };
57 
58  template<>
59  struct Adaptor<size_t(size_t)>
60  {
61  template<typename FUN>
62  static decltype(auto)
63  wrap (FUN&& fun)
64  {
65  return std::forward<FUN>(fun);
66  }
67  };
68 
69  template<>
70  struct Adaptor<void(void)>
71  {
72  template<typename FUN>
73  static auto
74  wrap (FUN&& fun)
75  {
76  return [functor=std::forward<FUN>(fun)]
77  (size_t) mutable
78  {
79  functor();
80  return size_t(1);
81  };
82  }
83  };
84 
85  template<typename ON, typename IN>
86  struct Adaptor<ON(IN), enable_if<__and_<is_arithmetic<IN>, __not_<is_same<IN,size_t>>
87  ,is_arithmetic<ON>, __not_<is_same<ON,size_t>>
88  >>>
89  {
90  template<typename FUN>
91  static auto
92  wrap (FUN&& fun)
93  {
94  return [functor=std::forward<FUN>(fun)]
95  (size_t i) mutable
96  {
97  return size_t(functor(i));
98  };
99  }
100  };
101 
102  template<typename ON>
103  struct Adaptor<ON(void), enable_if<__and_<is_arithmetic<ON>, __not_<is_same<ON,size_t>>
104  >>>
105  {
106  template<typename FUN>
107  static auto
108  wrap (FUN&& fun)
109  {
110  return [functor=std::forward<FUN>(fun)]
111  (size_t) mutable
112  {
113  return size_t(functor());
114  };
115  }
116  };
117 
118  template<typename IN>
119  struct Adaptor<void(IN), enable_if<__and_<is_arithmetic<IN>, __not_<is_same<IN,size_t>>
120  >>>
121  {
122  template<typename FUN>
123  static auto
124  wrap (FUN&& fun)
125  {
126  return [functor=std::forward<FUN>(fun)]
127  (size_t i) mutable
128  {
129  functor(i);
130  return size_t(1);
131  };
132  }
133  };
134 
135 
136 
147  template<typename FUN>
148  inline decltype(auto)
149  adapted4benchmark (FUN&& fun)
150  {
151  static_assert (lib::meta::_Fun<FUN>(), "Need something function-like.");
152  static_assert (lib::meta::_Fun<FUN>::ARITY <=1, "Function with zero or one argument required.");
153 
154  using Sig = typename lib::meta::_Fun<FUN>::Sig;
155 
156  return Adaptor<Sig>::wrap (std::forward<FUN> (fun));
157  }
158 
159 
160 
161 }}} // namespace lib::test::microbenchmark
162 #endif /*LIB_TEST_MICROBENCHMARK_ADAPTOR_H*/
Definition: run.hpp:40
Simple and lightweight helpers for metaprogramming and type detection.
Implementation namespace for support and library code.
typename enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition: meta/util.hpp:83
Metaprogramming tools for transforming functor types.