TECA
The Toolkit for Extreme Climate Analysis
teca_table.h
1 #ifndef teca_table_h
2 #define teca_table_h
3 
4 #include "teca_config.h"
5 #include "teca_dataset.h"
6 #include "teca_variant_array.h"
7 #include "teca_array_collection.h"
8 #include "teca_shared_object.h"
9 
10 #include <map>
11 #include <vector>
12 #include <string>
13 
14 TECA_SHARED_OBJECT_FORWARD_DECL(teca_table)
15 
16 /** @brief
17  * A collection of columnar data with row based
18  * accessors and communication and I/O support.
19  */
21 {
22 public:
23  TECA_DATASET_STATIC_NEW(teca_table)
24  TECA_DATASET_NEW_INSTANCE()
25  TECA_DATASET_NEW_COPY()
26 
27  virtual ~teca_table() = default;
28 
29  // set/get metadata
30  TECA_DATASET_METADATA(calendar, std::string, 1)
31  TECA_DATASET_METADATA(time_units, std::string, 1)
32 
33  // remove all column definitions and data
34  void clear();
35 
36  // define the table columns. requires name,type pairs
37  // for ex. define("c1",int(),"c2",float()) creates a
38  // table with 2 columns the first storing int the
39  // second storing float.
40  template<typename nT, typename cT, typename... oT>
41  void declare_columns(nT &&col_name, cT col_type, oT &&...args);
42 
43  // add a column definition to the table.
44  template<typename nT, typename cT>
45  void declare_column(nT &&col_name, cT col_type);
46 
47  /// set the allocator to use with ::declare_column
48  void set_default_allocator(allocator alloc)
49  { m_impl->columns->set_default_allocator(alloc); }
50 
51  // get the number of rows/columns
52  unsigned int get_number_of_columns() const noexcept;
53  unsigned long get_number_of_rows() const noexcept;
54 
55  // get a specific column. return a nullptr if
56  // the column doesn't exist.
57  p_teca_variant_array get_column(unsigned int i);
58  p_teca_variant_array get_column(const std::string &col_name);
59 
60  const_p_teca_variant_array get_column(unsigned int i) const;
61  const_p_teca_variant_array get_column(const std::string &col_name) const;
62 
63  // test for the existence of a specific column
64  bool has_column(const std::string &col_name) const
65  { return m_impl->columns->has(col_name); }
66 
67  // get the name of the column, see also get_number_of_columns
68  std::string get_column_name(unsigned int i) const
69  { return m_impl->columns->get_name(i); }
70 
71  // add a column
72  int append_column(p_teca_variant_array array)
73  { return m_impl->columns->append(array); }
74 
75  int append_column(const std::string &name, p_teca_variant_array array)
76  { return m_impl->columns->append(name, array); }
77 
78  // remove a column
79  int remove_column(unsigned int i)
80  { return m_impl->columns->remove(i); }
81 
82  int remove_column(const std::string &name)
83  { return m_impl->columns->remove(name); }
84 
85  // get container holding columns
86  p_teca_array_collection get_columns()
87  { return m_impl->columns; }
88 
89  const_p_teca_array_collection get_columns() const
90  { return m_impl->columns; }
91 
92  // default initialize n rows of data
93  void resize(unsigned long n);
94 
95  // reserve memory for future rows
96  void reserve(unsigned long n);
97 
98  // append the collection of data in succession to
99  // each column. see also operator<< for sequential
100  // stream insertion like append.
101  template<typename cT, typename... oT>
102  void append(cT &&val, oT &&... args);
103 
104  // return a unique string identifier
105  std::string get_class_name() const override
106  { return "teca_table"; }
107 
108  // return an integer identifier uniquely naming the dataset type
109  int get_type_code() const override;
110 
111  // covert to boolean. true if the dataset is not empty.
112  // otherwise false.
113  explicit operator bool() const noexcept
114  { return !this->empty(); }
115 
116  // return true if the dataset is empty.
117  bool empty() const noexcept override;
118 
119  // serialize the dataset to/from the given stream
120  // for I/O or communication
121  int to_stream(teca_binary_stream &) const override;
122  int from_stream(teca_binary_stream &) override;
123 
124  // stream to/from human readable representation
125  int to_stream(std::ostream &) const override;
126  int from_stream(std::istream &) override;
127 
128  /// @copydoc teca_dataset::copy(const const_p_teca_dataset &,allocator)
129  void copy(const const_p_teca_dataset &other,
130  allocator alloc = allocator::malloc) override;
131 
132  /// deep copy a subset of row values.
133  void copy(const const_p_teca_table &other,
134  unsigned long first_row, unsigned long last_row,
135  allocator alloc = allocator::malloc);
136 
137  /// @copydoc teca_dataset::shallow_copy(const p_teca_dataset &)
138  void shallow_copy(const p_teca_dataset &other) override;
139 
140  // copy the column layout and types
141  void copy_structure(const const_p_teca_table &other);
142 
143  // swap internals of the two objects
144  void swap(const p_teca_dataset &other) override;
145 
146  // append rows from the passed in table which must have identical
147  // columns.
148  void concatenate_rows(const const_p_teca_table &other);
149 
150  // append columns from the passed in table which must have same
151  // number of rows. if deep flag is true a full copy of the data
152  // is made, else a shallow copy is made.
153  void concatenate_cols(const const_p_teca_table &other, bool deep=false);
154 
155 #if defined(SWIG)
156 protected:
157 #else
158 public:
159 #endif
160  // NOTE: constructors are public to enable std::make_shared. do not use.
161  teca_table();
162 
163 protected:
164  teca_table(const teca_table &other) = delete;
165  teca_table(teca_table &&other) = delete;
166  teca_table &operator=(const teca_table &other) = delete;
167 
168  void declare_columns(){}
169  void append(){}
170 
171 private:
172  struct impl_t
173  {
174  impl_t();
175  //
176  p_teca_array_collection columns;
177  unsigned int active_column;
178  };
179  std::shared_ptr<impl_t> m_impl;
180 };
181 
182 
183 
184 
185 
186 // --------------------------------------------------------------------------
187 inline
188 p_teca_variant_array teca_table::get_column(unsigned int i)
189 {
190  return m_impl->columns->get(i);
191 }
192 
193 // --------------------------------------------------------------------------
194 inline
195 const_p_teca_variant_array teca_table::get_column(unsigned int i) const
196 {
197  return m_impl->columns->get(i);
198 }
199 
200 // --------------------------------------------------------------------------
201 template<typename nT, typename cT, typename... oT>
202 void teca_table::declare_columns(nT &&col_name, cT col_type, oT &&... args)
203 {
204  m_impl->columns->declare(std::forward<nT>(col_name), col_type);
205  this->declare_columns(args...);
206 }
207 
208 // --------------------------------------------------------------------------
209 template<typename nT, typename cT>
210 void teca_table::declare_column(nT &&col_name, cT col_type)
211 {
212  m_impl->columns->declare(std::forward<nT>(col_name), col_type);
213 }
214 
215 // --------------------------------------------------------------------------
216 template<typename cT, typename... oT>
217 void teca_table::append(cT &&val, oT &&... args)
218 {
219  unsigned int col = m_impl->active_column++%this->get_number_of_columns();
220  m_impl->columns->get(col)->append(std::forward<cT>(val));
221  this->append(args...);
222 }
223 
224 template<typename T>
225 p_teca_table &operator<<(p_teca_table &t, T &&v)
226 {
227  t->append(std::forward<T>(v));
228  return t;
229 }
230 
231 #endif
teca_variant_array.h
teca_binary_stream
Serialize objects into a binary stream.
Definition: teca_binary_stream.h:16
teca_dataset
Interface for TECA datasets.
Definition: teca_dataset.h:231
operator<<
TECA_EXPORT std::ostream & operator<<(std::ostream &os, const teca_calendar_util::time_point &tpt)
send the time_point to a stream in humnan readable form
const_p_teca_variant_array
std::shared_ptr< const teca_variant_array > const_p_teca_variant_array
Definition: teca_variant_array.h:27
teca_py_array::copy
TECA_EXPORT bool copy(teca_variant_array *varr, PyObject *obj)
Copy values from the object into variant array.
Definition: teca_py_array.h:290
teca_table
A collection of columnar data with row based accessors and communication and I/O support.
Definition: teca_table.h:20
teca_table::set_default_allocator
void set_default_allocator(allocator alloc)
set the allocator to use with ::declare_column
Definition: teca_table.h:48
teca_shared_object.h
p_teca_variant_array
std::shared_ptr< teca_variant_array > p_teca_variant_array
Definition: teca_variant_array.h:27
teca_error::TECA_EXPORT
p_teca_error_handler error_handler TECA_EXPORT
The global error handler instance.
teca_py_array::append
TECA_EXPORT bool append(teca_variant_array *varr, PyObject *obj)
Append values from the object to the variant array.
Definition: teca_py_array.h:221