api.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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. reduce(Function<T(std::vector<T>)>& fn, Value<std::vector<T>>* v, const std::string& alias=""){
  157. typedef T type;
  158. const std::string& name = Reduce<T>::fmt_name(fn, v);
  159. if (check_exists<type>(name))
  160. return lookup<type>(name);
  161. else
  162. return (Value<type>*)new Reduce<T>(fn, v, alias);
  163. }
  164. template <typename T>
  165. decltype(auto)
  166. max(Value<std::vector<T>>* v, const std::string& alias=""){
  167. typedef T type;
  168. const std::string& name = Max<T>::fmt_name(v);
  169. if (check_exists<type>(name))
  170. return lookup<type>(name);
  171. else
  172. return (Value<type>*)new Max<T>(v, alias);
  173. }
  174. template <typename T>
  175. decltype(auto)
  176. max(const std::string& v_name, const std::string& alias=""){
  177. return max(lookup<std::vector<T>>(v_name), alias);
  178. }
  179. template <typename T>
  180. decltype(auto)
  181. min(Value<std::vector<T>>* v, const std::string& alias=""){
  182. typedef T type;
  183. const std::string& name = Min<T>::fmt_name(v);
  184. if (check_exists<type>(name))
  185. return lookup<type>(name);
  186. else
  187. return (Value<type>*)new Min<T>(v, alias);
  188. }
  189. template <typename T>
  190. decltype(auto)
  191. min(const std::string& v_name, const std::string& alias=""){
  192. return min(lookup<std::vector<T>>(v_name), alias);
  193. }
  194. template <typename T>
  195. decltype(auto)
  196. range(Value<std::vector<T>>* v, const std::string& alias=""){
  197. typedef T type;
  198. const std::string& name = Range<T>::fmt_name(v);
  199. if (check_exists<type>(name))
  200. return lookup<type>(name);
  201. else
  202. return (Value<type>*)new Range<T>(v, alias);
  203. }
  204. template <typename T>
  205. decltype(auto)
  206. range(const std::string& v_name, const std::string& alias=""){
  207. return range(lookup<std::vector<T>>(v_name), alias);
  208. }
  209. template <typename T>
  210. decltype(auto)
  211. mean(Value<std::vector<T>>* v, const std::string& alias=""){
  212. typedef T type;
  213. const std::string& name = Mean<T>::fmt_name(v);
  214. if (check_exists<type>(name))
  215. return lookup<type>(name);
  216. else
  217. return (Value<type>*)new Mean<T>(v, alias);
  218. }
  219. template <typename T>
  220. decltype(auto)
  221. mean(const std::string& v_name, const std::string& alias=""){
  222. return mean(lookup<std::vector<T>>(v_name), alias);
  223. }
  224. template <typename T>
  225. decltype(auto)
  226. count(Function<bool(T)>& selector, Value<std::vector<T>>* v, const std::string& alias=""){
  227. typedef int type;
  228. const std::string& name = Count<T>::fmt_name(selector, v);
  229. if (check_exists<type>(name))
  230. return lookup<type>(name);
  231. else
  232. return (Value<type>*)new Count<T>(selector, v, alias);
  233. }
  234. template <typename T>
  235. decltype(auto)
  236. count(Function<bool(T)>& selector, const std::string& v_name, const std::string& alias=""){
  237. return count<T>(selector, lookup<std::vector<T>>(v_name), alias);
  238. }
  239. template <typename FST, typename SND>
  240. decltype(auto)
  241. cart_product(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string& alias=""){
  242. typedef std::vector<std::tuple<FST,SND>> type;
  243. const std::string& name = CartProduct<FST, SND>::fmt_name(val1, val2);
  244. if (check_exists<type>(name))
  245. return lookup<type>(name);
  246. else
  247. return (Value<type>*)new CartProduct<FST, SND>(val1, val2, alias);
  248. }
  249. template <typename FST, typename SND>
  250. decltype(auto)
  251. cart_product(const std::string& val1_name, const std::string& val2_name, const std::string& alias=""){
  252. return cart_product<FST,SND>(lookup<std::vector<FST>>(val1_name), lookup<std::vector<SND>>(val2_name), alias);
  253. }
  254. template <typename T, int Size>
  255. decltype(auto)
  256. combinations(Value<std::vector<T>>* val, const std::string& alias=""){
  257. typedef std::vector<typename HomoTuple<T,Size>::type> type;
  258. const std::string& name = Combinations<T, Size>::fmt_name(val);
  259. if (check_exists<type>(name))
  260. return lookup<type>(name);
  261. else
  262. return (Value<type>*)new Combinations<T, Size>(val, alias);
  263. }
  264. template <typename T, int Size>
  265. decltype(auto)
  266. combinations(const std::string& val_name, const std::string alias = ""){
  267. return combinations<T, Size>(lookup<std::vector<T>>(val_name), alias);
  268. }
  269. template < typename T>
  270. decltype(auto)
  271. constant(const std::string name, T const_value, const std::string alias=""){
  272. typedef T type;
  273. const std::string& val_name = ConstantValue<T>::fmt_name(name);
  274. if (check_exists<type>(val_name))
  275. return lookup<type>(val_name);
  276. else
  277. return (Value<type>*)new ConstantValue<T>(val_name, const_value, alias);
  278. }
  279. template <typename T>
  280. decltype(auto)
  281. bound(Function<T()>& f, const std::string alias=""){
  282. typedef T type;
  283. const std::string& name = BoundValue<T>::fmt_name(f);
  284. if (check_exists<type>(name))
  285. return lookup<type>(name);
  286. else
  287. return (Value<type>*)new BoundValue<T>(f, alias);
  288. }
  289. template <typename T>
  290. decltype(auto)
  291. filter(Function<bool(T)>& filter, Value<std::vector<T>>* val, const std::string alias=""){
  292. typedef std::vector<T> type;
  293. const std::string& name = Filter<T>::fmt_name(filter, val);
  294. if (check_exists<type>(name))
  295. return lookup<type>(name);
  296. else
  297. return (Value<type>*)new Filter<T>(filter, val, alias);
  298. }
  299. template <typename T>
  300. decltype(auto)
  301. filter(Function<bool(T)>& filter_func, const std::string& val_name, const std::string alias=""){
  302. return filter<T>(filter_func, lookup<std::vector<T>>(val_name), alias);
  303. }
  304. template <typename... ArgTypes>
  305. decltype(auto)
  306. tup_filter(Function<bool(ArgTypes...)>& filter, Value<std::vector<std::tuple<ArgTypes...>>>* val, const std::string alias=""){
  307. typedef std::vector<std::tuple<ArgTypes...>> type;
  308. const std::string& name = TupFilter<ArgTypes...>::fmt_name(filter, val);
  309. if (check_exists<type>(name))
  310. return lookup<type>(name);
  311. else
  312. return (Value<type>*)new TupFilter<ArgTypes...>(filter, val, alias);
  313. }
  314. template <typename... ArgTypes>
  315. decltype(auto)
  316. tup_filter(Function<bool(ArgTypes...)>& filter, const std::string& val_name, const std::string alias=""){
  317. return tup_filter<ArgTypes...>(filter, lookup<std::vector<std::tuple<ArgTypes...>>>(val_name), alias);
  318. }
  319. ObsFilter* obs_filter(const std::string& name, std::function<bool()> filter_function, const std::string& impl=""){
  320. return new ObsFilter(name, filter_function, impl);
  321. }
  322. }
  323. #endif // API_HPP