api.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /**
  2. * @file
  3. * @author Caleb Fangmeier <caleb@fangmeier.tech>
  4. * @version 0.1
  5. *
  6. * @section LICENSE
  7. *
  8. *
  9. * MIT License
  10. *
  11. * Copyright (c) 2017 Caleb Fangmeier
  12. *
  13. * Permission is hereby granted, free of charge, to any person obtaining a copy
  14. * of this software and associated documentation files (the "Software"), to deal
  15. * in the Software without restriction, including without limitation the rights
  16. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  17. * copies of the Software, and to permit persons to whom the Software is
  18. * furnished to do so, subject to the following conditions:
  19. *
  20. * The above copyright notice and this permission notice shall be included in all
  21. * copies or substantial portions of the Software.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  24. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  26. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  27. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  28. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  29. * SOFTWARE.
  30. *
  31. * @section DESCRIPTION
  32. * This is the main api for FilVal. Users should try to avoid instantiating
  33. * Value objects directly, but rather use these functions. There are multiple
  34. * reasons for this. First of all, these functions do the extra work of making
  35. * sure that an identical Value doesn't already exist. If one does, it returns
  36. * the old Value object rather than creating a new one. The second reason is
  37. * that C++ allows type deduction for functions so one can often leave out the
  38. * type definitions to produce shorter, more readable, code. This cannot be
  39. * done when creating templated objects directly.
  40. */
  41. #ifndef API_HPP
  42. #define API_HPP
  43. #include <string>
  44. #include <vector>
  45. #include "filval/value.hpp"
  46. namespace fv{
  47. template<typename T>
  48. Value<T>* lookup(const std::string& name){
  49. Value<T>* tv = GenValue::get_value<T>(name);
  50. if (tv == nullptr){
  51. CRITICAL("Could not find alias or value \"" << name << "\"."
  52. <<" I'll tell you the ones I know about." << std::endl
  53. << GenValue::summary(), -1);
  54. }
  55. return tv;
  56. }
  57. template<typename T>
  58. bool check_exists(const std::string name){
  59. Value<T>* tv = GenValue::get_value<T>(name);
  60. return tv != nullptr;
  61. }
  62. ObsFilter* lookup_obs_filter(const std::string& name){
  63. ObsFilter* f = dynamic_cast<ObsFilter*>(GenValue::get_value<bool>(name));
  64. if(f == nullptr){
  65. CRITICAL("ObsFilter: "+f->get_name() + "has improper type.",-1);
  66. }
  67. return f;
  68. }
  69. template <typename T>
  70. decltype(auto)
  71. wrapper_vector(Value<int>* size, Value<T*>* data, const std::string& alias=""){
  72. typedef std::vector<T> type;
  73. const std::string& name = WrapperVector<T>::fmt_name(size, data);
  74. if (check_exists<type>(name))
  75. return lookup<type>(name);
  76. else
  77. return (Value<type>*)new WrapperVector<T>(size, data, alias);
  78. }
  79. template <typename... ArgTypes>
  80. decltype(auto)
  81. zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias=""){
  82. typedef std::vector<std::tuple<ArgTypes...>> type;
  83. std::string& name = Zip<ArgTypes...>::fmt_name(args...);
  84. if (check_exists<type>(name))
  85. return lookup<type>(name);
  86. else
  87. return (Value<type>*)new Zip<ArgTypes...>(args..., alias);
  88. }
  89. template <typename Ret, typename... ArgTypes>
  90. decltype(auto)
  91. map(Function<Ret(ArgTypes...)>& fn, Value<std::vector<std::tuple<ArgTypes...>>>* arg, const std::string& alias=""){
  92. typedef std::vector<Ret> type;
  93. const std::string& name = Map<Ret(ArgTypes...)>::fmt_name(fn, arg);
  94. if (check_exists<type>(name))
  95. return lookup<type>(name);
  96. else
  97. return (Value<type>*)new Map<Ret(ArgTypes...)>(fn, arg, alias);
  98. }
  99. template <typename... ArgTypes>
  100. decltype(auto)
  101. tuple(Value<ArgTypes>*... args){
  102. typedef std::tuple<ArgTypes...> type;
  103. const std::string& name = Tuple<ArgTypes...>::fmt_name(args...);
  104. if (check_exists<type>(name))
  105. return lookup<type>(name);
  106. else
  107. return (Value<type>*)new Tuple<ArgTypes...>(args..., "");
  108. }
  109. template <size_t N, typename... ArgTypes>
  110. decltype(auto)
  111. detup(Value<std::tuple<ArgTypes...>>* tup, const std::string& alias=""){
  112. typedef typename std::tuple_element<N, std::tuple<ArgTypes...>>::type type;
  113. const std::string& name = DeTup<N, ArgTypes...>::fmt_name(tup);
  114. if (check_exists<type>(name))
  115. return lookup<type>(name);
  116. else
  117. return (Value<type>*)new DeTup<N, ArgTypes...>(tup, alias);
  118. }
  119. template <size_t N, typename... ArgTypes>
  120. decltype(auto)
  121. detup_vec(Value<std::vector<std::tuple<ArgTypes...>>>* tup, const std::string& alias=""){
  122. typedef std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type> type;
  123. const std::string& name = DeTupVector<N, ArgTypes...>::fmt_name(tup);
  124. if (check_exists<type>(name))
  125. return lookup<type>(name);
  126. else
  127. return (Value<type>*)new DeTupVector<N, ArgTypes...>(tup, alias);
  128. }
  129. template <typename Ret, typename... ArgTypes>
  130. decltype(auto)
  131. apply(Function<Ret(ArgTypes...)>& fn, Value<std::tuple<ArgTypes...>>* arg, const std::string& alias=""){
  132. typedef Ret type;
  133. const std::string& name = Apply<Ret(ArgTypes...)>::fmt_name(fn, arg);
  134. if (check_exists<type>(name))
  135. return lookup<type>(name);
  136. else
  137. return (Value<type>*)new Apply<Ret(ArgTypes...)>(fn, arg, alias);
  138. }
  139. template <typename T1, typename T2>
  140. decltype(auto)
  141. pair(Value<T1>* val1, Value<T2>* val2, const std::string& alias=""){
  142. typedef std::pair<T1,T2> type;
  143. const std::string& name = Pair<T1,T2>::fmt_name(val1, val2);
  144. if (check_exists<type>(name))
  145. return lookup<type>(name);
  146. else
  147. return (Value<type>*)new Pair<T1,T2>(val1, val2, alias);
  148. }
  149. template <typename T1, typename T2>
  150. decltype(auto)
  151. pair(const std::string& name1, const std::string& name2, const std::string& alias=""){
  152. return pair<T1,T2>(lookup<T1>(name1), lookup<T2>(name2), alias);
  153. }
  154. template <typename T>
  155. decltype(auto)
  156. max(Value<std::vector<T>>* v, const std::string& alias=""){
  157. typedef T type;
  158. const std::string& name = Max<T>::fmt_name(v);
  159. if (check_exists<type>(name))
  160. return lookup<type>(name);
  161. else
  162. return (Value<type>*)new Max<T>(v, alias);
  163. }
  164. template <typename T>
  165. decltype(auto)
  166. max(const std::string& v_name, const std::string& alias=""){
  167. return max(lookup<std::vector<T>>(v_name), alias);
  168. }
  169. template <typename T>
  170. decltype(auto)
  171. min(Value<std::vector<T>>* v, const std::string& alias=""){
  172. typedef T type;
  173. const std::string& name = Min<T>::fmt_name(v);
  174. if (check_exists<type>(name))
  175. return lookup<type>(name);
  176. else
  177. return (Value<type>*)new Min<T>(v, alias);
  178. }
  179. template <typename T>
  180. decltype(auto)
  181. min(const std::string& v_name, const std::string& alias=""){
  182. return min(lookup<std::vector<T>>(v_name), alias);
  183. }
  184. template <typename T>
  185. decltype(auto)
  186. range(Value<std::vector<T>>* v, const std::string& alias=""){
  187. typedef T type;
  188. const std::string& name = Range<T>::fmt_name(v);
  189. if (check_exists<type>(name))
  190. return lookup<type>(name);
  191. else
  192. return (Value<type>*)new Range<T>(v, alias);
  193. }
  194. template <typename T>
  195. decltype(auto)
  196. range(const std::string& v_name, const std::string& alias=""){
  197. return range(lookup<std::vector<T>>(v_name), alias);
  198. }
  199. template <typename T>
  200. decltype(auto)
  201. mean(Value<std::vector<T>>* v, const std::string& alias=""){
  202. typedef T type;
  203. const std::string& name = Mean<T>::fmt_name(v);
  204. if (check_exists<type>(name))
  205. return lookup<type>(name);
  206. else
  207. return (Value<type>*)new Mean<T>(v, alias);
  208. }
  209. template <typename T>
  210. decltype(auto)
  211. mean(const std::string& v_name, const std::string& alias=""){
  212. return mean(lookup<std::vector<T>>(v_name), alias);
  213. }
  214. template <typename T>
  215. decltype(auto)
  216. count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string& alias=""){
  217. typedef int type;
  218. const std::string& name = Count<T>::fmt_name(selector, v);
  219. if (check_exists<type>(name))
  220. return lookup<type>(name);
  221. else
  222. return (Value<type>*)new Count<T>(selector, v, alias);
  223. }
  224. template <typename T>
  225. decltype(auto)
  226. count(Function<bool(T)>& selector, const std::string& v_name, const std::string& alias=""){
  227. return count<T>(selector, lookup<std::vector<T>>(v_name), alias);
  228. }
  229. template <typename FST, typename SND>
  230. decltype(auto)
  231. cart_product(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string& alias=""){
  232. typedef std::vector<std::tuple<FST,SND>> type;
  233. const std::string& name = CartProduct<FST, SND>::fmt_name(val1, val2);
  234. if (check_exists<type>(name))
  235. return lookup<type>(name);
  236. else
  237. return (Value<type>*)new CartProduct<FST, SND>(val1, val2, alias);
  238. }
  239. template <typename FST, typename SND>
  240. decltype(auto)
  241. cart_product(const std::string& val1_name, const std::string& val2_name, const std::string& alias=""){
  242. return cart_product<FST,SND>(lookup<std::vector<FST>>(val1_name), lookup<std::vector<SND>>(val2_name), alias);
  243. }
  244. template <typename T, int Size>
  245. decltype(auto)
  246. combinations(Value<std::vector<T>>* val, const std::string& alias=""){
  247. typedef std::vector<typename HomoTuple<T,Size>::type> type;
  248. const std::string& name = Combinations<T, Size>::fmt_name(val);
  249. if (check_exists<type>(name))
  250. return lookup<type>(name);
  251. else
  252. return (Value<type>*)new Combinations<T, Size>(val, alias);
  253. }
  254. template <typename T, int Size>
  255. decltype(auto)
  256. combinations(const std::string& val_name, const std::string alias = ""){
  257. return combinations<T, Size>(lookup<std::vector<T>>(val_name), alias);
  258. }
  259. template < typename T>
  260. decltype(auto)
  261. constant(const std::string name, T const_value, const std::string alias=""){
  262. typedef T type;
  263. const std::string& val_name = ConstantValue<T>::fmt_name(name);
  264. if (check_exists<type>(val_name))
  265. return lookup<type>(val_name);
  266. else
  267. return (Value<type>*)new ConstantValue<T>(val_name, const_value, alias);
  268. }
  269. template <typename T>
  270. decltype(auto)
  271. bound(Function<T()>& f, const std::string alias=""){
  272. typedef T type;
  273. const std::string& name = BoundValue<T>::fmt_name(f);
  274. if (check_exists<type>(name))
  275. return lookup<type>(name);
  276. else
  277. return (Value<type>*)new BoundValue<T>(f, alias);
  278. }
  279. template <typename T>
  280. decltype(auto)
  281. filter(Function<bool(T)>& filter, Value<std::vector<T>>* val, const std::string alias=""){
  282. typedef std::vector<T> type;
  283. const std::string& name = Filter<T>::fmt_name(filter, val);
  284. if (check_exists<type>(name))
  285. return lookup<type>(name);
  286. else
  287. return (Value<type>*)new Filter<T>(filter, val, alias);
  288. }
  289. template <typename T>
  290. decltype(auto)
  291. filter(Function<bool(T)>& filter_func, const std::string& val_name, const std::string alias=""){
  292. return filter<T>(filter_func, lookup<std::vector<T>>(val_name), alias);
  293. }
  294. template <typename... ArgTypes>
  295. decltype(auto)
  296. tup_filter(Function<bool(ArgTypes...)>& filter, Value<std::vector<std::tuple<ArgTypes...>>>* val, const std::string alias=""){
  297. typedef std::vector<std::tuple<ArgTypes...>> type;
  298. const std::string& name = TupFilter<ArgTypes...>::fmt_name(filter, val);
  299. if (check_exists<type>(name))
  300. return lookup<type>(name);
  301. else
  302. return (Value<type>*)new TupFilter<ArgTypes...>(filter, val, alias);
  303. }
  304. template <typename... ArgTypes>
  305. decltype(auto)
  306. tup_filter(Function<bool(ArgTypes...)>& filter, const std::string& val_name, const std::string alias=""){
  307. return tup_filter<ArgTypes...>(filter, lookup<std::vector<std::tuple<ArgTypes...>>>(val_name), alias);
  308. }
  309. ObsFilter* obs_filter(const std::string& name, std::function<bool()> filter_function, const std::string& impl=""){
  310. return new ObsFilter(name, filter_function, impl);
  311. }
  312. }
  313. #endif // API_HPP