api.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  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. Function<T>* lookup_function(const std::string& name){
  59. return GenFunction::lookup_function<T>(name);
  60. }
  61. template<typename T>
  62. bool check_exists(const std::string name){
  63. Value<T>* tv = GenValue::get_value<T>(name);
  64. return tv != nullptr;
  65. }
  66. ObsFilter* lookup_obs_filter(const std::string& name){
  67. ObsFilter* f = dynamic_cast<ObsFilter*>(GenValue::get_value<bool>(name));
  68. if(f == nullptr){
  69. CRITICAL("ObsFilter: "+f->get_name() + "has improper type.",-1);
  70. }
  71. return f;
  72. }
  73. template <typename T>
  74. decltype(auto)
  75. wrapper_vector(Value<int>* size, Value<T*>* data, const std::string& alias=""){
  76. typedef std::vector<T> type;
  77. const std::string& name = WrapperVector<T>::fmt_name(size, data);
  78. if (check_exists<type>(name))
  79. return lookup<type>(name);
  80. else
  81. return (Value<type>*)new WrapperVector<T>(size, data, alias);
  82. }
  83. template <typename... ArgTypes>
  84. decltype(auto)
  85. zip(Value<std::vector<ArgTypes>>*... args, const std::string& alias=""){
  86. typedef std::vector<std::tuple<ArgTypes...>> type;
  87. std::string& name = Zip<ArgTypes...>::fmt_name(args...);
  88. if (check_exists<type>(name))
  89. return lookup<type>(name);
  90. else
  91. return (Value<type>*)new Zip<ArgTypes...>(args..., alias);
  92. }
  93. template <typename Ret, typename ArgType>
  94. decltype(auto)
  95. map(Function<Ret(ArgType)>* fn, Value<std::vector<ArgType>>* arg, const std::string& alias=""){
  96. typedef std::vector<Ret> type;
  97. const std::string& name = Map<Ret(ArgType)>::fmt_name(fn, arg);
  98. if (check_exists<type>(name))
  99. return lookup<type>(name);
  100. else
  101. return (Value<type>*)new Map<Ret(ArgType)>(fn, arg, alias);
  102. }
  103. template <typename Ret, typename... ArgTypes>
  104. decltype(auto)
  105. tup_map(Function<Ret(ArgTypes...)>* fn, Value<std::vector<std::tuple<ArgTypes...>>>* arg, const std::string& alias=""){
  106. typedef std::vector<Ret> type;
  107. const std::string& name = TupMap<Ret(ArgTypes...)>::fmt_name(fn, arg);
  108. if (check_exists<type>(name))
  109. return lookup<type>(name);
  110. else
  111. return (Value<type>*)new TupMap<Ret(ArgTypes...)>(fn, arg, alias);
  112. }
  113. template <typename... ArgTypes>
  114. decltype(auto)
  115. tuple(Value<ArgTypes>*... args){
  116. typedef std::tuple<ArgTypes...> type;
  117. const std::string& name = Tuple<ArgTypes...>::fmt_name(args...);
  118. if (check_exists<type>(name))
  119. return lookup<type>(name);
  120. else
  121. return (Value<type>*)new Tuple<ArgTypes...>(args..., "");
  122. }
  123. template <size_t N, typename... ArgTypes>
  124. decltype(auto)
  125. detup(Value<std::tuple<ArgTypes...>>* tup, const std::string& alias=""){
  126. typedef typename std::tuple_element<N, std::tuple<ArgTypes...>>::type type;
  127. const std::string& name = DeTup<N, ArgTypes...>::fmt_name(tup);
  128. if (check_exists<type>(name))
  129. return lookup<type>(name);
  130. else
  131. return (Value<type>*)new DeTup<N, ArgTypes...>(tup, alias);
  132. }
  133. template <size_t N, typename... ArgTypes>
  134. decltype(auto)
  135. detup_vec(Value<std::vector<std::tuple<ArgTypes...>>>* tup, const std::string& alias=""){
  136. typedef std::vector<typename std::tuple_element<N, std::tuple<ArgTypes...>>::type> type;
  137. const std::string& name = DeTupVector<N, ArgTypes...>::fmt_name(tup);
  138. if (check_exists<type>(name))
  139. return lookup<type>(name);
  140. else
  141. return (Value<type>*)new DeTupVector<N, ArgTypes...>(tup, alias);
  142. }
  143. template <typename Ret, typename ArgType>
  144. decltype(auto)
  145. apply(Function<Ret(ArgType)>* fn, Value<ArgType>* arg, const std::string& alias=""){
  146. typedef Ret type;
  147. const std::string& name = Apply<Ret(ArgType)>::fmt_name(fn, arg);
  148. if (check_exists<type>(name))
  149. return lookup<type>(name);
  150. else
  151. return (Value<type>*)new Apply<Ret(ArgType)>(fn, arg, alias);
  152. }
  153. template <typename Ret, typename... ArgTypes>
  154. decltype(auto)
  155. tup_apply(Function<Ret(ArgTypes...)>* fn, Value<std::tuple<ArgTypes...>>* arg, const std::string& alias=""){
  156. typedef Ret type;
  157. const std::string& name = TupApply<Ret(ArgTypes...)>::fmt_name(fn, arg);
  158. if (check_exists<type>(name))
  159. return lookup<type>(name);
  160. else
  161. return (Value<type>*)new TupApply<Ret(ArgTypes...)>(fn, arg, alias);
  162. }
  163. template <typename T1, typename T2>
  164. decltype(auto)
  165. pair(Value<T1>* val1, Value<T2>* val2, const std::string& alias=""){
  166. typedef std::pair<T1,T2> type;
  167. const std::string& name = Pair<T1,T2>::fmt_name(val1, val2);
  168. if (check_exists<type>(name))
  169. return lookup<type>(name);
  170. else
  171. return (Value<type>*)new Pair<T1,T2>(val1, val2, alias);
  172. }
  173. template <typename T1, typename T2>
  174. decltype(auto)
  175. pair(const std::string& name1, const std::string& name2, const std::string& alias=""){
  176. return pair<T1,T2>(lookup<T1>(name1), lookup<T2>(name2), alias);
  177. }
  178. template <typename T>
  179. decltype(auto)
  180. reduce(Function<T(std::vector<T>)>* fn, Value<std::vector<T>>* v, const std::string& alias=""){
  181. typedef T type;
  182. const std::string& name = Reduce<T>::fmt_name(fn, v);
  183. if (check_exists<type>(name))
  184. return lookup<type>(name);
  185. else
  186. return (Value<type>*)new Reduce<T>(fn, v, alias);
  187. }
  188. template <typename T>
  189. decltype(auto)
  190. max(Value<std::vector<T>>* v, const std::string& alias=""){
  191. typedef T type;
  192. const std::string& name = Max<T>::fmt_name(v);
  193. if (check_exists<type>(name))
  194. return lookup<type>(name);
  195. else
  196. return (Value<type>*)new Max<T>(v, alias);
  197. }
  198. template <typename T>
  199. decltype(auto)
  200. max(const std::string& v_name, const std::string& alias=""){
  201. return max(lookup<std::vector<T>>(v_name), alias);
  202. }
  203. template <typename T>
  204. decltype(auto)
  205. min(Value<std::vector<T>>* v, const std::string& alias=""){
  206. typedef T type;
  207. const std::string& name = Min<T>::fmt_name(v);
  208. if (check_exists<type>(name))
  209. return lookup<type>(name);
  210. else
  211. return (Value<type>*)new Min<T>(v, alias);
  212. }
  213. template <typename T>
  214. decltype(auto)
  215. min(const std::string& v_name, const std::string& alias=""){
  216. return min(lookup<std::vector<T>>(v_name), alias);
  217. }
  218. template <typename T>
  219. decltype(auto)
  220. range(Value<std::vector<T>>* v, const std::string& alias=""){
  221. typedef T type;
  222. const std::string& name = Range<T>::fmt_name(v);
  223. if (check_exists<type>(name))
  224. return lookup<type>(name);
  225. else
  226. return (Value<type>*)new Range<T>(v, alias);
  227. }
  228. template <typename T>
  229. decltype(auto)
  230. range(const std::string& v_name, const std::string& alias=""){
  231. return range(lookup<std::vector<T>>(v_name), alias);
  232. }
  233. template <typename T>
  234. decltype(auto)
  235. mean(Value<std::vector<T>>* v, const std::string& alias=""){
  236. typedef T type;
  237. const std::string& name = Mean<T>::fmt_name(v);
  238. if (check_exists<type>(name))
  239. return lookup<type>(name);
  240. else
  241. return (Value<type>*)new Mean<T>(v, alias);
  242. }
  243. template <typename T>
  244. decltype(auto)
  245. mean(const std::string& v_name, const std::string& alias=""){
  246. return mean(lookup<std::vector<T>>(v_name), alias);
  247. }
  248. template <typename T>
  249. decltype(auto)
  250. count(Function<bool(T)>* selector, Value<std::vector<T>>* v, const std::string& alias=""){
  251. typedef int type;
  252. const std::string& name = Count<T>::fmt_name(selector, v);
  253. if (check_exists<type>(name))
  254. return lookup<type>(name);
  255. else
  256. return (Value<type>*)new Count<T>(selector, v, alias);
  257. }
  258. template <typename T>
  259. decltype(auto)
  260. count(Function<bool(T)>* selector, const std::string& v_name, const std::string& alias=""){
  261. return count<T>(selector, lookup<std::vector<T>>(v_name), alias);
  262. }
  263. template <typename FST, typename SND>
  264. decltype(auto)
  265. cart_product(Value<std::vector<FST>>* val1, Value<std::vector<SND>>* val2, const std::string& alias=""){
  266. typedef std::vector<std::tuple<FST,SND>> type;
  267. const std::string& name = CartProduct<FST, SND>::fmt_name(val1, val2);
  268. if (check_exists<type>(name))
  269. return lookup<type>(name);
  270. else
  271. return (Value<type>*)new CartProduct<FST, SND>(val1, val2, alias);
  272. }
  273. template <typename FST, typename SND>
  274. decltype(auto)
  275. cart_product(const std::string& val1_name, const std::string& val2_name, const std::string& alias=""){
  276. return cart_product<FST,SND>(lookup<std::vector<FST>>(val1_name), lookup<std::vector<SND>>(val2_name), alias);
  277. }
  278. template <typename T, int Size>
  279. decltype(auto)
  280. combinations(Value<std::vector<T>>* val, const std::string& alias=""){
  281. typedef std::vector<typename HomoTuple<T,Size>::type> type;
  282. const std::string& name = Combinations<T, Size>::fmt_name(val);
  283. if (check_exists<type>(name))
  284. return lookup<type>(name);
  285. else
  286. return (Value<type>*)new Combinations<T, Size>(val, alias);
  287. }
  288. template <typename T, int Size>
  289. decltype(auto)
  290. combinations(const std::string& val_name, const std::string alias = ""){
  291. return combinations<T, Size>(lookup<std::vector<T>>(val_name), alias);
  292. }
  293. template < typename T>
  294. decltype(auto)
  295. constant(const std::string name, T const_value, const std::string alias=""){
  296. typedef T type;
  297. const std::string& val_name = ConstantValue<T>::fmt_name(name);
  298. if (check_exists<type>(val_name))
  299. return lookup<type>(val_name);
  300. else
  301. return (Value<type>*)new ConstantValue<T>(val_name, const_value, alias);
  302. }
  303. template <typename T>
  304. decltype(auto)
  305. bound(Function<T()>* f, const std::string alias=""){
  306. typedef T type;
  307. const std::string& name = BoundValue<T>::fmt_name(f);
  308. if (check_exists<type>(name))
  309. return lookup<type>(name);
  310. else
  311. return (Value<type>*)new BoundValue<T>(f, alias);
  312. }
  313. template <typename T>
  314. decltype(auto)
  315. filter(Function<bool(T)>* filter, Value<std::vector<T>>* val, const std::string alias=""){
  316. typedef std::vector<T> type;
  317. const std::string& name = Filter<T>::fmt_name(filter, val);
  318. if (check_exists<type>(name))
  319. return lookup<type>(name);
  320. else
  321. return (Value<type>*)new Filter<T>(filter, val, alias);
  322. }
  323. template <typename T>
  324. decltype(auto)
  325. filter(Function<bool(T)>* filter_func, const std::string& val_name, const std::string alias=""){
  326. return filter<T>(filter_func, lookup<std::vector<T>>(val_name), alias);
  327. }
  328. template <typename... ArgTypes>
  329. decltype(auto)
  330. tup_filter(Function<bool(ArgTypes...)>* filter, Value<std::vector<std::tuple<ArgTypes...>>>* val, const std::string alias=""){
  331. typedef std::vector<std::tuple<ArgTypes...>> type;
  332. const std::string& name = TupFilter<ArgTypes...>::fmt_name(filter, val);
  333. if (check_exists<type>(name))
  334. return lookup<type>(name);
  335. else
  336. return (Value<type>*)new TupFilter<ArgTypes...>(filter, val, alias);
  337. }
  338. template <typename... ArgTypes>
  339. decltype(auto)
  340. tup_filter(Function<bool(ArgTypes...)>* filter, const std::string& val_name, const std::string alias=""){
  341. return tup_filter<ArgTypes...>(filter, lookup<std::vector<std::tuple<ArgTypes...>>>(val_name), alias);
  342. }
  343. ObsFilter* obs_filter(const std::string& name, std::function<bool()> filter_function, const std::string& impl=""){
  344. return new ObsFilter(name, filter_function, impl);
  345. }
  346. template <typename T>
  347. static Function<T>* func(const std::string& name, std::function<T> f, const std::string& impl){
  348. return GenFunction::reg_func(name, f, impl);
  349. }
  350. template <typename Ret>
  351. decltype(auto)
  352. func_value(const std::string& name, std::function<Ret()> f, const std::string&& impl, const std::string& alias=""){
  353. typedef Ret type;
  354. const std::string& val_name = FunctionValue<Ret>::fmt_name(name);
  355. if (check_exists<type>(val_name))
  356. return lookup<type>(val_name);
  357. else {
  358. Function<Ret()>* fn = func(name, f, impl);
  359. return (Value<type>*)new FunctionValue<Ret>(name, fn, alias);
  360. }
  361. }
  362. }
  363. #endif // API_HPP