LocARNA-2.0.0
named_arguments.hh
1 #ifndef LOCARNA_NAMED_ARGUMENTS_HH
2 #define LOCARNA_NAMED_ARGUMENTS_HH
3 
4 #ifdef HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7 
8 #include <cassert>
9 
18 #include <tuple>
19 #include <type_traits>
20 
21 namespace LocARNA {
22 
23  // template meta program to test whether a tuple has a type
24  template <typename T, typename Tuple>
25  struct has_type;
26 
27  template <typename T>
28  struct has_type<T, std::tuple<>> : std::false_type {};
29 
30  template <typename T, typename U, typename... Ts>
31  struct has_type<T, std::tuple<U, Ts...>> : has_type<T, std::tuple<Ts...>> {
32  };
33 
34  template <typename T, typename... Ts>
35  struct has_type<T, std::tuple<T, Ts...>> : std::true_type {};
36 
37  // check whether T is contained in Us...
38  template <typename T, typename... Us>
39  struct contains;
40 
41  template <typename T>
42  struct contains<T, std::tuple<>> : std::false_type {};
43 
44  template <typename T, typename U, typename... Us>
45  struct contains<T, std::tuple<U, Us...>> : contains<T, std::tuple<Us...>> {
46  };
47 
48  template <typename T, typename... Us>
49  struct contains<T, std::tuple<T, Us...>> : std::true_type {};
50 
51  template <typename T, typename... Us>
52  using contains_t = typename contains<T, Us...>::type;
53 
54  // check that types in Ts are a subset of Us...
55  template <typename Tuple1, typename Tuple2>
57 
58  template <typename... Ts>
59  struct type_subset_of<std::tuple<Ts...>, std::tuple<>> : std::false_type {};
60 
61  template <typename... Us>
62  struct type_subset_of<std::tuple<>, std::tuple<Us...>> : std::true_type {};
63 
64  template <typename T, typename... Ts, typename... Us>
65  struct type_subset_of<std::tuple<T, Ts...>, std::tuple<Us...>> {
66  static constexpr bool value =
67  type_subset_of<std::tuple<Ts...>, std::tuple<Us...>>::value &&
68  contains<T, std::tuple<Us...>>::value;
69  };
70 
71  // get with default value
72  //
73  template <
74  typename T,
75  typename... Args,
76  std::enable_if_t<!has_type<T, std::tuple<Args...>>::value> * = nullptr>
77  constexpr T
78  get_def(const std::tuple<Args...> &t, const T &def) noexcept {
79  return def;
80  }
81 
82  template <
83  typename T,
84  typename... Args,
85  std::enable_if_t<has_type<T, std::tuple<Args...>>::value> * = nullptr>
86  constexpr const T &
87  get_def(const std::tuple<Args...> &t, const T &def) noexcept {
88  return std::get<T>(t);
89  }
90 
91  template <typename T>
92  class NamedArgument {
93  public:
94  using value_type = T;
95  NamedArgument() : value_(){};
96  NamedArgument(const value_type &value) : value_(value){};
97  NamedArgument(value_type &&value) : value_(value){};
98 
99  value_type
100  value() const {
101  return value_;
102  }
103 
104  private:
105  value_type value_;
106  };
107 
109 # define DEFINE_NAMED_ARG(name, type) \
110  struct name : public NamedArgument<type> { \
111  name(type value) : NamedArgument<type>(value) {} \
112  }
113 
115 # define DEFINE_NAMED_ARG_DEFAULT(name, type, default_value) \
116  struct name : public NamedArgument<type> { \
117  name() : NamedArgument<type>(default_value) {} \
118  name(type value) : NamedArgument<type>(value) {} \
119  }
120 
123  template <typename name, typename ArgTuple>
124  auto
125  get_named_arg(const ArgTuple &args) {
126  static_assert(has_type<name, ArgTuple>::value,
127  "Required named argument missing.");
128  return std::get<name>(args).value();
129  }
130 
131  // //! get a named argument from argument pack; return default if argument does not
132  // //! exist
133  // template <typename name, typename ValueType, typename ArgsTuple>
134  // auto
135  // get_named_arg_def(ValueType &&def, const ArgsTuple &args) {
136  // return get_def<name>(args,
137  // name(std::forward<ValueType>(def))).value();
138  // }
139 
144  template <typename name, typename ArgsTuple>
145  auto
146  get_named_arg_opt(const ArgsTuple &args) {
147  return get_def<name>(args,
148  name()).value();
149  }
150 
153 # define DEFINE_NAMED_ARG_FEATURE(name, type) \
154  type name##_; \
155  DEFINE_NAMED_ARG(name, type)
156 
159 # define DEFINE_NAMED_ARG_DEFAULT_FEATURE(name, type, default_value) \
160  type name##_; \
161  DEFINE_NAMED_ARG_DEFAULT(name, type, default_value)
162 
163 } // end namespace LocARNA
164 
165 #endif // LOCARNA_NAMED_ARGUMENTS_HH
Definition: named_arguments.hh:92
Definition: aligner.cc:15
auto get_named_arg(const ArgTuple &args)
get a mandatory named argument from argument pack; ensure that argument is given
Definition: named_arguments.hh:125
auto get_named_arg_opt(const ArgsTuple &args)
Definition: named_arguments.hh:146
Definition: named_arguments.hh:39
Definition: named_arguments.hh:25
Definition: named_arguments.hh:56