@@ -40,12 +40,10 @@ class data_frame {
4040// void from_tuples(const std::vector<std::tuple<Args...>>& t, const std::vector<std::string>& names);
4141// template<class... Args>
4242// void from_tuples(std::initializer_list<std::tuple<Args...>> t, const std::vector<std::string>& names);
43- // template<template<class...> class TypeLists, class... Args>
44- // void from_tuples(const std::vector<std::tuple<Args...>>& t, const std::vector<std::string>& names, TypeLists<Args...>);
45- // template<typename T>
46- // T& get(const std::string& col_name, size_t pos);
47- // template<typename T>
48- // const T& get_c(const std::string& col_name, size_t pos) const;
43+ template <typename T>
44+ T& get (const std::string& col_name, size_t pos);
45+ template <typename T>
46+ const T& get_c (const std::string& col_name, size_t pos) const ;
4947
5048// template<typename Col_type, typename F, template<class...> class TypeLists, class... Types>
5149// data_frame_view<TypeLists, Types...> select(const std::string& col_name, F f, TypeLists<Types...>) {
@@ -214,45 +212,31 @@ class data_frame {
214212// auto& container = col_names_map[col_name];
215213// container->initialize(std::move(f), typename type_list<Types...>::types{});
216214// }
217- // template<class... Args>
218- // void from_tuple(const std::tuple<Args...>& t, const std::vector<std::string>& names, int row) {
219- // for_each_in_tuple(t, tuple_functor(this, row), names);
220- // }
221- // template<typename T, typename F, std::size_t ... Is>
222- // void for_each(T&& t, F f, std::index_sequence<Is...>, const std::vector<std::string>& names) {
223- // auto l = { (f(std::get<Is>(t), names[Is]), 0)... };
224- // }
225- // template<typename... Ts, typename F>
226- // void for_each_in_tuple(std::tuple<Ts...> const& t, F f, const std::vector<std::string>& names) {
227- // for_each(t, f, std::index_sequence_for<Ts...>{}, names);
228- // }
229- // struct tuple_functor {
230- // tuple_functor(data_frame* df, int index): df(df), index(index) {}
231- // template<typename T>
232- // void operator () (T t, std::string name) {
233- // auto iter = df->col_names_map.find(name);
234- // if (iter == df->col_names_map.end()) return;
235- // auto& container = *(iter->second);
236- // container.at<T>(index) = t;
237- // }
238- // int index;
239- // data_frame* df;
240- // };
241- // struct tuple_create_functor {
242- // tuple_create_functor(int size, data_frame* df): size(size) ,df(df){}
243- // template<typename T>
244- // void operator () (T t, const std::string& name) {
245- // df->init_column<T>(name, size);
246- // }
247- // int size;
248- // data_frame* df;
249- // };
250- // template<typename T>
251- // bool init_column(const std::string& col_name, int size);
252- // template<class... Args>
253- // void init_columns(const std::tuple<Args...>& t, const std::vector<std::string>& names, int size) {
254- // for_each_in_tuple(t, tuple_create_functor(size, this), names);
255- // }
215+ template <class ... Args>
216+ void from_tuple (const std::tuple<Args...>& t, const std::vector<std::string>& names, int row) {
217+ for_each_in_tuple (t, [this , row](auto t, std::string name){
218+ auto iter = this ->col_names_map .find (name);
219+ if (iter == this ->col_names_map .end ()) return ;
220+ auto & container = *(iter->second );
221+ container.data_frame_col ::template at<decltype (t)>(row) = t;
222+ }, names);
223+ }
224+ template <typename T, typename F, std::size_t ... Is>
225+ void for_each (T&& t, F f, std::index_sequence<Is...>, const std::vector<std::string>& names) {
226+ auto l = { (f (std::get<Is>(t), names[Is]), 0 )... };
227+ }
228+ template <typename ... Ts, typename F>
229+ void for_each_in_tuple (std::tuple<Ts...> const & t, F f, const std::vector<std::string>& names) {
230+ for_each (t, f, std::index_sequence_for<Ts...>{}, names);
231+ }
232+ template <typename T>
233+ bool init_column (const std::string& col_name, int size);
234+ template <class ... Args>
235+ void init_columns (const std::tuple<Args...>& t, const std::vector<std::string>& names, int size) {
236+ for_each_in_tuple (t, [this , size](auto t, const std::string& cur_name) {
237+ this ->init_column <decltype (t)>(cur_name, size);
238+ }, names);
239+ }
256240 int cur_rows;
257241 store_t vals;
258242 /* col_names_map and type_map should maintain consistent */
@@ -265,29 +249,18 @@ data_frame(TypeLists<InnerTypes...>) -> data_frame<InnerTypes...>;
265249template <template <class ...> class TypeLists , class ... InnerTypes>
266250data_frame (int rows, TypeLists<InnerTypes...>) -> data_frame<InnerTypes...>;
267251
268- // template<typename T>
269- // bool data_frame::add_column(std::string col_name, std::vector<T> tmp_vec) {
270- // if (col_names_map.count(col_name)) return false;
271- // /* size check */
272- // if (cur_rows == -1) cur_rows = tmp_vec.size();
273- // if (cur_rows != tmp_vec.size()) return false;
274- // data_frame_col dfc(col_name, tmp_vec);
275- // auto iter = vals.insert(vals.end(), dfc);
276- // col_names_map.insert({col_name, iter});
277- // type_map.insert({col_name, typeid(T).name()});
278- // return true;
279- // }
280- // template<typename T>
281- // bool data_frame::init_column(const std::string& col_name, int size) {
282- // if (col_names_map.count(col_name)) return false;
283- // /* size check */
284- // if (cur_rows == -1) cur_rows = size;
285- // if (cur_rows != size) return false;
286- // auto iter = vals.insert(vals.begin(), data_frame_col(col_name, std::vector<T>(size)));
287- // col_names_map.insert({col_name, iter});
288- // type_map.insert({col_name, typeid(T).name()});
289- // return true;
290- // }
252+ template <class ... Types>
253+ template <typename T>
254+ bool data_frame<Types...>::init_column(const std::string& col_name, int size) {
255+ if (col_names_map.count (col_name)) return false ;
256+ /* size check */
257+ if (cur_rows == -1 ) cur_rows = size;
258+ if (cur_rows != size) return false ;
259+ auto iter = vals.insert (vals.begin (), data_frame_col (col_name, std::vector<T>(size)));
260+ col_names_map.insert ({col_name, iter});
261+ type_map.insert ({col_name, typeid (T).name ()});
262+ return true ;
263+ }
291264// template<class... Args>
292265// void data_frame::from_tuples(std::initializer_list<std::tuple<Args...>> t, const std::vector<std::string>& names) {
293266// std::vector<std::tuple<Args...>> vec(t);
@@ -357,34 +330,51 @@ data_frame(int rows, TypeLists<InnerTypes...>) -> data_frame<InnerTypes...>;
357330// }
358331// return tmp_index;
359332// }
360- // template<typename T>
361- // T& data_frame::get(const std::string& col_name, size_t pos) {
362- // // need to handle the case when col_name doesn't exist
363- // auto iter = col_names_map.find(col_name);
364- // auto& container = *(iter->second);
365- // auto& tmp_vector = container.get_vector<T>();
366- // return tmp_vector[pos];
367- // }
368- // template<typename T>
369- // const T& data_frame::get_c(const std::string& col_name, size_t pos) const {
370- // // need to handle the case when col_name doesn't exist
371- // auto iter = col_names_map.find(col_name);
372- // auto& container = *(iter->second);
373- // auto& tmp_vector = container.get_vector<T>();
374- // return tmp_vector[pos];
375- // }
376333template <class ... Types>
377- decltype (auto ) make_from_tuples(const std::vector<std::tuple<Types...>>& t, const std::vector<std::string>& names) {
378- using type_collection = type_list<Types...>::types;
379- assert (sizeof ...(Types) == names.size ());
380- cur_rows = t.size ();
334+ template <typename T>
335+ T& data_frame<Types...>::get(const std::string& col_name, size_t pos) {
336+ // need to handle the case when col_name doesn't exist
337+ static_assert (((std::is_same_v<T, Types> || ...)), " Type doesn't match to data_frame" );
338+ auto iter = col_names_map.find (col_name);
339+ auto & container = *(iter->second );
340+ auto & tmp_vector = container.data_frame_col ::template get_vector<T>();
341+ return tmp_vector[pos];
342+ }
343+ template <class ... Types>
344+ template <typename T>
345+ const T& data_frame<Types...>::get_c(const std::string& col_name, size_t pos) const {
346+ // need to handle the case when col_name doesn't exist
347+ static_assert (((std::is_same_v<T, Types> || ...)), " Type doesn't match to data_frame" );
348+ auto iter = col_names_map.find (col_name);
349+ auto & container = *(iter->second );
350+ auto & tmp_vector = container.data_frame_col ::template get_vector<T>();
351+ return tmp_vector[pos];
352+ }
353+ // A non-deduced context from tuple inside vector to make_from_tuples, have to provide additional parameter
354+ template <template <class ...> class TypeLists , class ... InnerTypes>
355+ decltype (auto ) make_from_tuples(const std::vector<TypeLists<InnerTypes...>>& t, const std::vector<std::string>& names) {
356+ using type_collection = typename type_list<InnerTypes...>::types;
357+ assert (sizeof ...(InnerTypes) == names.size ());
358+ int cur_rows = t.size ();
381359 data_frame df (cur_rows, type_collection{});
382360 df.init_columns (t[0 ], names, cur_rows);
383- for (int i = 0 ; i < cur_rows; i++) {
384- from_tuple (t[i], names, i);
385- }
361+ for (int i = 0 ; i < cur_rows; i++)
362+ df.from_tuple (t[i], names, i);
363+ return df;
364+ }
365+ template <template <class ...> class TypeLists , class ... InnerTypes>
366+ decltype (auto ) make_from_tuples(const std::vector<std::tuple<InnerTypes...>>& t, const std::vector<std::string>& names,
367+ TypeLists<InnerTypes...>) {
368+ using type_collection = typename type_list<InnerTypes...>::types;
369+ assert (sizeof ...(InnerTypes) == names.size ());
370+ int cur_rows = t.size ();
371+ data_frame df (cur_rows, type_collection{});
372+ df.init_columns (t[0 ], names, cur_rows);
373+ for (int i = 0 ; i < cur_rows; i++)
374+ df.from_tuple (t[i], names, i);
386375 return df;
387376}
377+
388378template <class ... Types>
389379class data_frame_view {
390380public:
0 commit comments