Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/toolx/hdf5/ntuple

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef toolx_hdf5_ntuple
  5 #define toolx_hdf5_ntuple
  6 
  7 #include "store"
  8 
  9 #include <tools/vfind>
 10 #include <tools/vmanip>
 11 #include <tools/ntuple_binding>
 12 #include <tools/ntuple_booking>
 13 #include <tools/sout>
 14 #include <tools/scast>
 15 #include <tools/forit>
 16 #include <tools/stype>
 17 #include <tools/mnmx>
 18 #include <tools/vdata>
 19 
 20 #ifdef TOOLS_MEM
 21 #include <tools/mem>
 22 #include <tools/stype>
 23 #endif
 24 
 25 namespace toolx {
 26 namespace hdf5 {
 27 
 28 class ntuple : public store {
 29 public:
 30   class icol {
 31   public:
 32     virtual ~icol(){}
 33   public:
 34     virtual void* cast(tools::cid) const = 0;
 35     virtual tools::cid id_cls() const = 0;
 36   public:
 37     virtual bool set_basket_size(size_t a_size) = 0;
 38     virtual bool add() = 0;
 39     virtual bool fetch_entry() = 0;
 40     virtual const std::string& name() const = 0;
 41     virtual void reset() = 0;
 42   };
 43 public:
 44 
 45 
 46   template <class T>
 47   class column_ref : public virtual icol {
 48 #ifdef TOOLS_MEM
 49     static const std::string& s_class() {
 50       static const std::string s_v("toolx::hdf5::ntuple::column_ref<"+tools::stype(T())+">");
 51       return s_v;
 52     }
 53 #endif
 54   public:
 55     static tools::cid id_class() {
 56       static const T s_v = T(); //do that for T = std::string.
 57       return tools::_cid(s_v)+10000;
 58     }
 59     virtual void* cast(tools::cid a_class) const {
 60       if(void* p = tools::cmp_cast<column_ref>(this,a_class)) {return p;}
 61       else return 0;
 62     }
 63     virtual tools::cid id_cls() const {return id_class();}
 64   public: //icol
 65     virtual bool add() { //write.
 66       if(!m_write) return false;
 67       if(m_basket_pos>=m_basket_size) {
 68         if(!m_branch.write_page<T>(m_basket_size,m_basket)) {
 69           m_store.out() << "toolx::hdf5::ntuple::column_ref::add : write_page() failed." << std::endl;
 70           m_basket_pos = 0;
 71           return false;
 72   }
 73         m_basket_pos = 0;
 74   if(m_want_new_basket_size) {
 75     delete [] m_basket;
 76     m_basket = new T[m_want_new_basket_size];
 77     m_basket_pos = 0;
 78     m_basket_size = m_want_new_basket_size;
 79     m_want_new_basket_size = 0;
 80   }
 81       }
 82       m_basket[m_basket_pos] = m_ref;
 83       m_basket_pos++;
 84       return true;
 85     }
 86     virtual bool fetch_entry() { //read.
 87       if(m_write) return false;
 88       if(m_basket_pos>=m_basket_end) { //we need more data.
 89         if(m_branch.pos()>=m_branch.entries()) {
 90           m_store.out() << "toolx::hdf5::ntuple::column_ref:fetch_entry : no more data." << std::endl;
 91           m_basket_pos = 0;
 92           m_basket_end = 0;
 93           return false;
 94   }
 95   if(m_want_new_basket_size) {
 96     delete [] m_basket;
 97     m_basket = new T[m_want_new_basket_size];
 98     m_basket_pos = 0;
 99     m_basket_size = m_want_new_basket_size;
100     m_want_new_basket_size = 0;
101   }
102         tools::uint64 remain = m_branch.entries()-m_branch.pos();
103         size_t n = tools::mn<size_t>((size_t)remain,m_basket_size);
104         if(!m_branch.read_page<T>(n,m_basket)) {
105           m_store.out() << "toolx::hdf5::ntuple::column_ref:fetch_entry : read_page() failed." << std::endl;
106           m_basket_pos = 0;
107           m_basket_end = 0;
108           return false;
109         }
110         m_basket_pos = 0;
111         m_basket_end = n;
112       }
113       m_ref = m_basket[m_basket_pos];
114       m_basket_pos++;
115       return true;
116     }
117     virtual void reset() {m_branch.reset_pos();}
118     virtual const std::string& name() const {return m_name;}
119     virtual bool set_basket_size(size_t a_size) {
120       if(!a_size) return false;
121       m_want_new_basket_size = a_size;
122       return true;
123     }
124   public:
125     column_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size,T& a_ref)
126     :m_store(a_store)
127     ,m_branch(a_pages)
128     ,m_write(a_write)
129     ,m_name(a_name)
130     ,m_ref(a_ref)
131     ,m_basket_size(a_basket_size?a_basket_size:32000)
132     ,m_basket_pos(0)
133     ,m_basket_end(0) //read.
134     ,m_basket(0)
135     ,m_want_new_basket_size(0)
136     {
137 #ifdef TOOLS_MEM
138       tools::mem::increment(s_class().c_str());
139 #endif
140       m_basket = new T[m_basket_size];
141       if(m_write) {
142       } else { //read.
143         tools::uint64 _entries = m_branch.entries();
144         size_t n = tools::mn<size_t>((size_t)_entries,m_basket_size);
145         if(_entries) {
146           if(!m_branch.read_page<T>(n,m_basket)) {
147             m_store.out() << "toolx::hdf5::ntuple::column_ref:column_ref : read_page() failed." << std::endl;
148             m_basket_pos = 0;
149             m_basket_end = 0;
150             return;
151           }
152         }
153     m_basket_pos = 0;
154   m_basket_end = n;
155       }
156     }
157     virtual ~column_ref(){
158       if(m_write && m_basket_pos) {
159         if(!m_branch.write_page<T>(m_basket_pos,m_basket)) {
160           m_store.out() << "toolx::hdf5::ntuple::column_ref::~column_ref : write_page() failed." << std::endl;
161         }
162       }
163       delete [] m_basket;
164 #ifdef TOOLS_MEM
165       tools::mem::decrement(s_class().c_str());
166 #endif
167     }
168   protected:
169     column_ref(const column_ref& a_from)
170     :icol(a_from)
171     ,m_store(a_from.m_store)
172     ,m_branch(a_from.m_branch)
173     ,m_write(a_from.m_write)
174     ,m_name(a_from.m_name)
175     ,m_ref(a_from.m_ref)
176     ,m_basket_size(a_from.m_basket_size)
177     ,m_basket_pos(0)
178     ,m_basket_end(0)
179     ,m_basket(0)
180     ,m_want_new_basket_size(0)
181     {}
182     column_ref& operator=(const column_ref& a_from){
183       if(&a_from==this) return *this;
184       m_name = a_from.m_name;
185       m_basket_size = a_from.m_basket_size;
186       m_basket_pos = 0;
187       m_basket_end = 0;
188       m_want_new_basket_size = 0;
189       return *this;
190     }
191   protected:
192     store& m_store;
193     pages& m_branch;
194     bool m_write;
195     std::string m_name;
196     T& m_ref;
197     size_t m_basket_size;
198     size_t m_basket_pos;
199     size_t m_basket_end;
200     T* m_basket;
201     size_t m_want_new_basket_size;
202   };
203 
204   template <class T>
205   class column : public column_ref<T> {
206     typedef column_ref<T> parent;
207 #ifdef TOOLS_MEM
208     static const std::string& s_class() {
209       static const std::string s_v("toolx::hdf5::ntuple::column<"+tools::stype(T())+">");
210       return s_v;
211     }
212 #endif
213   public:
214     static tools::cid id_class() {
215       static const T s_v = T(); //do that for T = std::string.
216       return tools::_cid(s_v);
217     }
218     virtual void* cast(tools::cid a_class) const {
219       if(void* p = tools::cmp_cast<column>(this,a_class)) {return p;}
220       else return 0;
221     }
222     virtual tools::cid id_cls() const {return id_class();}
223   public:
224     column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size)
225     :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
226     ,m_tmp(T())
227     {
228 #ifdef TOOLS_MEM
229       tools::mem::increment(s_class().c_str());
230 #endif
231     }
232     virtual ~column(){
233 #ifdef TOOLS_MEM
234       tools::mem::decrement(s_class().c_str());
235 #endif
236     }
237   protected:
238     column(const column& a_from)
239     :icol(a_from)
240     ,parent(a_from)
241     ,m_tmp(a_from.m_tmp)
242     {}
243     column& operator=(const column& a_from){
244       if(&a_from==this) return *this;
245       parent::operator=(a_from);
246       m_tmp = a_from.m_tmp;
247       return *this;
248     }
249   public:
250     bool fill(const T& a_value) {m_tmp = a_value;return true;} //write.
251     bool get_entry(T& a_v) const {a_v = m_tmp;return true;} //read.
252   protected:
253     T m_tmp;
254   };
255 
256   TOOLS_CLASS_STRING_VALUE(vector_char,vector<char>)
257   TOOLS_CLASS_STRING_VALUE(vector_short,vector<short>)
258   TOOLS_CLASS_STRING_VALUE(vector_int,vector<int>)
259   TOOLS_CLASS_STRING_VALUE(vector_float,vector<float>)
260   TOOLS_CLASS_STRING_VALUE(vector_double,vector<double>)
261 
262   TOOLS_CLASS_STRING_VALUE(string,string)
263 
264   TOOLS_CLASS_STRING_VALUE(vector_int64,vector<tools::int64>)
265   TOOLS_CLASS_STRING_VALUE(vector_uchar,vector<tools::uchar>)
266   TOOLS_CLASS_STRING_VALUE(vector_ushort,vector<tools::ushort>)
267   TOOLS_CLASS_STRING_VALUE(vector_uint32,vector<tools::uint32>)
268   TOOLS_CLASS_STRING_VALUE(vector_uint64,vector<tools::uint64>)
269 
270   TOOLS_CLASS_STRING_VALUE(vector_string,vector<std::string>)
271 
272   template <class T>
273   class std_vector_column_ref : public virtual icol {
274 #ifdef TOOLS_MEM
275     static const std::string& s_class() {
276       static const std::string s_v("toolx::hdf5::ntuple::std_vector_column_ref<"+tools::stype(T())+">");
277       return s_v;
278     }
279 #endif
280   public:
281     static tools::cid id_class() {return tools::_cid_std_vector<T>()+10000;}
282     virtual void* cast(tools::cid a_class) const {
283       if(void* p = tools::cmp_cast<std_vector_column_ref>(this,a_class)) {return p;}
284       else return 0;
285     }
286     virtual tools::cid id_cls() const {return id_class();}
287   public: //icol
288     virtual bool add() { //write.
289       if(!m_write) return false;
290       const T* _data = tools::vec_data(m_ref);
291       return m_branch.write_vlen<T>(m_ref.size(),_data);
292     }
293     virtual bool fetch_entry() { //read.
294       if(m_write) return false;
295       size_t n;
296       T* _data;
297       if(!m_branch.read_vlen<T>(n,_data)) {
298         m_store.out() << "toolx::hdf5::ntuple::std_vector_column_ref:fetch_entry : read_page() failed." << std::endl;
299         return false;
300       }
301       m_ref.resize(n);
302       T* dpos = _data;
303       T* pos = tools::vec_data(m_ref);
304       for(size_t index=0;index<n;index++,pos++,dpos++) *pos = *dpos;
305       delete [] _data;
306       return true;
307     }
308     virtual void reset() {m_branch.reset_pos();}
309     virtual const std::string& name() const {return m_name;}
310     virtual bool set_basket_size(size_t) {return true;}
311   public:
312     std_vector_column_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,
313                           size_t /*a_basket_size*/,
314                           std::vector<T>& a_ref)
315     :m_store(a_store)
316     ,m_branch(a_pages)
317     ,m_write(a_write)
318     ,m_name(a_name)
319     ,m_ref(a_ref)
320     {
321 #ifdef TOOLS_MEM
322       tools::mem::increment(s_class().c_str());
323 #endif
324     }
325     virtual ~std_vector_column_ref(){
326 #ifdef TOOLS_MEM
327       tools::mem::decrement(s_class().c_str());
328 #endif
329     }
330   protected:
331     std_vector_column_ref(const std_vector_column_ref& a_from)
332     :icol(a_from)
333     ,m_store(a_from.m_store)
334     ,m_branch(a_from.m_branch)
335     ,m_write(a_from.m_write)
336     ,m_name(a_from.m_name)
337     ,m_ref(a_from.m_ref)
338     {}
339     std_vector_column_ref& operator=(const std_vector_column_ref& a_from){
340       if(&a_from==this) return *this;
341       m_name = a_from.m_name;
342       return *this;
343     }
344   protected:
345     store& m_store;
346     pages& m_branch;
347     bool m_write;
348     std::string m_name;
349     std::vector<T>& m_ref;
350   };
351 
352   template <class T>
353   class std_vector_column : public std_vector_column_ref<T> {
354     typedef std_vector_column_ref<T> parent;
355 #ifdef TOOLS_MEM
356     static const std::string& s_class() {
357       static const std::string s_v("toolx::hdf5::ntuple::std_vector_column<"+tools::stype(T())+">");
358       return s_v;
359     }
360 #endif
361   public:
362     static tools::cid id_class() {return tools::_cid_std_vector<T>();}
363     virtual void* cast(tools::cid a_class) const {
364       if(void* p = tools::cmp_cast<std_vector_column>(this,a_class)) {return p;}
365       else return 0;
366     }
367     virtual tools::cid id_cls() const {return id_class();}
368   public:
369     std_vector_column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size)
370     :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
371     {}
372     virtual ~std_vector_column(){}
373   protected:
374     std_vector_column(const std_vector_column& a_from)
375     :icol(a_from)
376     ,parent(a_from)
377     {}
378     std_vector_column& operator=(const std_vector_column& a_from){
379       parent::operator=(a_from);
380       return *this;
381     }
382   public:
383     const std::vector<T>& data() const {return m_tmp;}
384   protected:
385     std::vector<T> m_tmp;
386   };
387 
388   class column_string_ref : public virtual icol {
389 #ifdef TOOLS_MEM
390     TOOLS_SCLASS(toolx::hdf5::ntuple::column_string_ref)
391 #endif
392   public:
393     static tools::cid id_class() {
394       static const std::string s_v;
395       return tools::_cid(s_v)+10000;
396     }
397     virtual void* cast(tools::cid a_class) const {
398       if(void* p = tools::cmp_cast<column_string_ref>(this,a_class)) {return p;}
399       else return 0;
400     }
401     virtual tools::cid id_cls() const {return id_class();}
402   public: //icol
403     virtual bool add() { //write.
404       if(!m_write) return false;
405       return m_branch.write_string(m_ref);
406     }
407     virtual bool fetch_entry() { //read.
408       if(m_write) return false;
409       if(!m_branch.read_string(m_ref)) {
410         m_store.out() << "toolx::hdf5::ntuple::column_string_ref:fetch_entry : read_page() failed." << std::endl;
411         return false;
412       }
413       return true;
414     }
415     virtual void reset() {m_branch.reset_pos();}
416     virtual const std::string& name() const {return m_name;}
417     virtual bool set_basket_size(size_t) {return true;}
418   public:
419     column_string_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,
420                       size_t /*a_basket_size*/,
421                       std::string& a_ref)
422     :m_store(a_store)
423     ,m_branch(a_pages)
424     ,m_write(a_write)
425     ,m_name(a_name)
426     ,m_ref(a_ref)
427     {
428 #ifdef TOOLS_MEM
429       tools::mem::increment(s_class().c_str());
430 #endif
431     }
432     virtual ~column_string_ref(){
433 #ifdef TOOLS_MEM
434       tools::mem::decrement(s_class().c_str());
435 #endif
436     }
437   protected:
438     column_string_ref(const column_string_ref& a_from)
439     :icol(a_from)
440     ,m_store(a_from.m_store)
441     ,m_branch(a_from.m_branch)
442     ,m_write(a_from.m_write)
443     ,m_name(a_from.m_name)
444     ,m_ref(a_from.m_ref)
445     {}
446     column_string_ref& operator=(const column_string_ref& a_from){
447       if(&a_from==this) return *this;
448       m_name = a_from.m_name;
449       return *this;
450     }
451   protected:
452     store& m_store;
453     pages& m_branch;
454     bool m_write;
455     std::string m_name;
456     std::string& m_ref;
457   };
458 
459   class column_string : public column_string_ref {
460     typedef column_string_ref parent;
461 #ifdef TOOLS_MEM
462     TOOLS_SCLASS(toolx::hdf5::ntuple::column_string)
463 #endif
464   public:
465     static tools::cid id_class() {
466       static const std::string s_v;
467       return tools::_cid(s_v);
468     }
469     virtual void* cast(tools::cid a_class) const {
470       if(void* p = tools::cmp_cast<column_string>(this,a_class)) {return p;}
471       else return 0;
472     }
473     virtual tools::cid id_cls() const {return id_class();}
474   public:
475     column_string(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,tools::uint32 a_basket_size)
476     :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
477     {
478 #ifdef TOOLS_MEM
479       tools::mem::increment(s_class().c_str());
480 #endif
481     }
482     virtual ~column_string(){
483 #ifdef TOOLS_MEM
484       tools::mem::decrement(s_class().c_str());
485 #endif
486     }
487   protected:
488     column_string(const column_string& a_from)
489     :icol(a_from)
490     ,parent(a_from)
491     {}
492     column_string& operator=(const column_string& a_from){
493       if(&a_from==this) return *this;
494       parent::operator=(a_from);
495       return *this;
496     }
497   public:
498     bool fill(const std::string& a_value) {m_tmp = a_value;return true;}
499     bool get_entry(std::string& a_value) const {a_value = m_tmp;return true;}
500   protected:
501     std::string m_tmp;
502   };
503 
504 
505 
506   class std_vector_column_string_ref : public virtual icol {
507 #ifdef TOOLS_MEM
508     static const std::string& s_class() {
509       static const std::string s_v("toolx::hdf5::ntuple::std_vector_column_string_ref");
510       return s_v;
511     }
512 #endif
513   public:
514     static tools::cid id_class() {return tools::_cid_std_vector<std::string>()+10000;}
515     virtual void* cast(tools::cid a_class) const {
516       if(void* p = tools::cmp_cast<std_vector_column_string_ref>(this,a_class)) {return p;}
517       else return 0;
518     }
519     virtual tools::cid id_cls() const {return id_class();}
520   public: //icol
521     virtual bool add() { //write.
522       if(!m_write) return false;
523       size_t _size = 0;
524      {tools_vforcit(std::string,m_ref,it) {
525         _size += (*it).size();
526   _size++;
527       }}
528       char* _data = _size?new char[_size]:0;
529      {char* pos = _data;
530       tools_vforcit(std::string,m_ref,it) {
531         ::memcpy(pos,(*it).c_str(),(*it).size());
532   pos += (*it).size();
533   *pos = 0;
534   pos++;
535       }}
536       return m_branch.write_vlen<char>(_size,_data);
537     }
538     virtual bool fetch_entry() { //read.
539       if(m_write) return false;
540       size_t n;
541       char* _data;
542       if(!m_branch.read_vlen<char>(n,_data)) {
543         m_store.out() << "toolx::hdf5::ntuple::std_vector_column_string_ref:fetch_entry : read_page() failed." << std::endl;
544         return false;
545       }
546       m_ref.clear();
547      {char* pos = _data;
548       char* begin = _data;
549       for(size_t ichar=0;ichar<n;ichar++,pos++) {
550         if(*pos==0) {
551     m_ref.push_back(begin);
552     begin = pos+1;
553         }
554       }}
555       delete [] _data;
556       return true;
557     }
558     virtual void reset() {m_branch.reset_pos();}
559     virtual const std::string& name() const {return m_name;}
560     virtual bool set_basket_size(size_t) {return true;}
561   public:
562     std_vector_column_string_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,
563                           size_t /*a_basket_size*/,
564                           std::vector<std::string>& a_ref)
565     :m_store(a_store)
566     ,m_branch(a_pages)
567     ,m_write(a_write)
568     ,m_name(a_name)
569     ,m_ref(a_ref)
570     {
571 #ifdef TOOLS_MEM
572       tools::mem::increment(s_class().c_str());
573 #endif
574     }
575     virtual ~std_vector_column_string_ref(){
576 #ifdef TOOLS_MEM
577       tools::mem::decrement(s_class().c_str());
578 #endif
579     }
580   protected:
581     std_vector_column_string_ref(const std_vector_column_string_ref& a_from)
582     :icol(a_from)
583     ,m_store(a_from.m_store)
584     ,m_branch(a_from.m_branch)
585     ,m_write(a_from.m_write)
586     ,m_name(a_from.m_name)
587     ,m_ref(a_from.m_ref)
588     {}
589     std_vector_column_string_ref& operator=(const std_vector_column_string_ref& a_from){
590       if(&a_from==this) return *this;
591       m_name = a_from.m_name;
592       return *this;
593     }
594   protected:
595     store& m_store;
596     pages& m_branch;
597     bool m_write;
598     std::string m_name;
599     std::vector<std::string>& m_ref;
600   };
601 
602   class std_vector_column_string : public std_vector_column_string_ref {
603     typedef std_vector_column_string_ref parent;
604 #ifdef TOOLS_MEM
605     static const std::string& s_class() {
606       static const std::string s_v("toolx::hdf5::ntuple::std_vector_column_string");
607       return s_v;
608     }
609 #endif
610   public:
611     static tools::cid id_class() {return tools::_cid_std_vector<std::string>();}
612     virtual void* cast(tools::cid a_class) const {
613       if(void* p = tools::cmp_cast<std_vector_column_string>(this,a_class)) {return p;}
614       else return 0;
615     }
616     virtual tools::cid id_cls() const {return id_class();}
617   public:
618     std_vector_column_string(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size)
619     :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp)
620     {}
621     virtual ~std_vector_column_string(){}
622   protected:
623     std_vector_column_string(const std_vector_column_string& a_from)
624     :icol(a_from)
625     ,parent(a_from)
626     {}
627     std_vector_column_string& operator=(const std_vector_column_string& a_from){
628       parent::operator=(a_from);
629       return *this;
630     }
631   public:
632     //bool get_entry(std::vector<T>& a_v) const {
633     //  a_v = m_tmp;
634     //  return true;
635     //}
636     const std::vector<std::string>& data() const {return m_tmp;}
637   protected:
638     std::vector<std::string> m_tmp;
639   };
640 
641 public:
642   ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name,
643          unsigned int a_compress,size_t /*a_basket_size*//* = 32000*/)
644   :store(a_out,a_group,a_name,true,a_compress)    //true=write
645   {}
646 
647   ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name)
648   :store(a_out,a_group,a_name,false,0)  //false=read
649   {
650     tools_vforcit(pages*,m_pagess,it){
651 
652 #define TOOLX_HDF5_NTUPLE_READ_CREATE_COL(a__type) \
653       if((*it)->form()==tools::stype(a__type())) {\
654         column<a__type>* col = new column<a__type>(*this,*(*it),false,(*it)->name(),0);\
655         if(!col) {tools::safe_clear<icol>(m_cols);return;}\
656         m_cols.push_back(col);\
657       }
658 
659 #define TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(a__vec_type,a__type) \
660       if((*it)->form()==s_vector_##a__vec_type()) {\
661         std_vector_column<a__type>* col = new std_vector_column<a__type>(*this,*(*it),false,(*it)->name(),0);\
662         if(!col) {tools::safe_clear<icol>(m_cols);return;}\
663         m_cols.push_back(col);\
664       }
665 
666 #define TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL_STRING \
667       if((*it)->form()==s_vector_string()) {\
668         std_vector_column_string* col = new std_vector_column_string(*this,*(*it),false,(*it)->name(),0);\
669         if(!col) {tools::safe_clear<icol>(m_cols);return;}\
670         m_cols.push_back(col);\
671       }
672 
673            TOOLX_HDF5_NTUPLE_READ_CREATE_COL(char)
674       else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(short)
675       else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(int)
676       else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::int64)
677 
678       else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(float)
679       else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(double)
680 
681       else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::byte)
682       else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::ushort)
683       else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::uint32)
684       else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::uint64)
685 
686     //else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(bool) //use byte=uchar.
687 
688       else
689       if((*it)->form()==s_string()) {
690         column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0);
691         if(!col) {tools::safe_clear<icol>(m_cols);return;}
692         m_cols.push_back(col);
693       }
694 
695       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(char,char)
696       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(short,short)
697       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(int,int)
698       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(int64,tools::int64)
699 
700       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(float,float)
701       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(double,double)
702 
703       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uchar,tools::uchar)
704       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(ushort,tools::ushort)
705       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint32,tools::uint32)
706       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint64,tools::uint64)
707 
708       else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL_STRING
709 //    else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(bool) //use byte=uchar.
710 
711       else {
712         m_out << "toolx::hdf5::ntuple::ntuple(read) :"
713               << " for column " << tools::sout((*it)->name())
714               << ", type " << tools::sout((*it)->form()) << " not yet handled."
715               << std::endl;
716         //throw
717         tools::safe_clear<icol>(m_cols);
718         return;
719       }
720     }
721 #undef TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL
722 #undef TOOLX_HDF5_NTUPLE_READ_CREATE_COL
723   }
724 
725   ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name,const tools::ntuple_binding& a_bd)
726   :store(a_out,a_group,a_name,false,0)  //false=read
727   {
728     if(!initialize(a_out,a_bd)) {}
729   }
730 
731   ntuple(std::ostream& a_out,hid_t a_group,const tools::ntuple_booking& a_bkg,
732          unsigned int a_compress,size_t a_basket_size/* = 32000*/)
733   :store(a_out,a_group,a_bkg.name(),true,a_compress) //true=write
734   ,m_title(a_bkg.title())
735   {
736     const std::vector<tools::column_booking>& cols = a_bkg.columns();
737     tools_vforcit(tools::column_booking,cols,it){
738 
739 #define TOOLX_HDF5_NTUPLE_CREATE_COL(a__type) \
740       if((*it).cls_id()==tools::_cid(a__type())) {\
741         a__type* user = (a__type*)(*it).user_obj();\
742         if(user) {\
743           if(!create_column_ref<a__type>((*it).name(),a_basket_size,*user)) {\
744             m_out << "toolx::hdf5::ntuple :"\
745                   << " can't create column_ref " << tools::sout((*it).name()) << "."\
746                   << std::endl;\
747             tools::safe_clear<icol>(m_cols);\
748             return;\
749           }\
750         } else {\
751           if(!create_column<a__type>((*it).name(),a_basket_size)) {\
752             m_out << "toolx::hdf5::ntuple :"\
753                   << " can't create column " << tools::sout((*it).name()) << "."\
754                   << std::endl;\
755             tools::safe_clear<icol>(m_cols);\
756             return;\
757           }\
758   }\
759       }
760 
761 #define TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(a__type) \
762       if((*it).cls_id()==tools::_cid_std_vector<a__type>()) {\
763         std::vector<a__type>* vec = (std::vector<a__type>*)(*it).user_obj();\
764         if(!vec) {\
765           m_out << "toolx::hdf5::ntuple :"\
766                 << " for std::vector column " << tools::sout((*it).name())\
767                 << ", the user vector pointer is null."\
768                 << std::endl;\
769           tools::safe_clear<icol>(m_cols);\
770           return;\
771         }\
772         if(!create_std_column_ref<a__type>((*it).name(),a_basket_size,*vec)) {\
773           m_out << "toolx::hdf5::ntuple :"\
774                 << " can't create std::vector column " << tools::sout((*it).name()) << "."\
775                 << std::endl;\
776           tools::safe_clear<icol>(m_cols);\
777           return;\
778   }\
779       }
780 
781 #define TOOLX_HDF5_NTUPLE_CREATE_VEC_COL_STRING \
782       if((*it).cls_id()==tools::_cid_std_vector<std::string>()) {\
783         std::vector<std::string>* vec = (std::vector<std::string>*)(*it).user_obj();\
784         if(!vec) {\
785           m_out << "toolx::hdf5::ntuple :"\
786                 << " for std::vector column " << tools::sout((*it).name())\
787                 << ", the user vector pointer is null."\
788                 << std::endl;\
789           tools::safe_clear<icol>(m_cols);\
790           return;\
791         }\
792         if(!create_std_column_string_ref((*it).name(),a_basket_size,*vec)) {\
793           m_out << "toolx::hdf5::ntuple :"\
794                 << " can't create std::vector column " << tools::sout((*it).name()) << "."\
795                 << std::endl;\
796           tools::safe_clear<icol>(m_cols);\
797           return;\
798   }\
799       }
800 
801            TOOLX_HDF5_NTUPLE_CREATE_COL(char)
802       else TOOLX_HDF5_NTUPLE_CREATE_COL(short)
803       else TOOLX_HDF5_NTUPLE_CREATE_COL(int)
804       else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::int64)
805 
806       else TOOLX_HDF5_NTUPLE_CREATE_COL(float)
807       else TOOLX_HDF5_NTUPLE_CREATE_COL(double)
808 
809       else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::byte)
810       else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::ushort)
811       else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::uint32)
812       else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::uint64)
813 
814     //else TOOLX_HDF5_NTUPLE_CREATE_COL(bool) //use byte=uchar.
815 
816       else if((*it).cls_id()==tools::_cid(std::string())) {
817         if(!create_column_string((*it).name(),a_basket_size)) {
818           m_out << "toolx::hdf5::ntuple :"
819                 << " can't create string column " << tools::sout((*it).name()) << "."
820                 << std::endl;
821           tools::safe_clear<icol>(m_cols);
822           return;
823   }
824 
825       } else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(char)
826       else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(short)
827       else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(int)
828       else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::int64)
829 
830       else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(float)
831       else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(double)
832 
833       else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uchar)
834       else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::ushort)
835       else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint32)
836       else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint64)
837 
838       else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL_STRING
839 //    else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(std::string)
840 //    else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(bool) //use byte=uchar.
841 
842       else {
843         m_out << "toolx::hdf5::ntuple :"
844               << " for column " << tools::sout((*it).name())
845               << ", type with cid " << (*it).cls_id() << " not yet handled."
846               << std::endl;
847         tools::safe_clear<icol>(m_cols);
848         return;
849       }
850     }
851 #undef TOOLX_HDF5_NTUPLE_CREATE_COL
852 #undef TOOLX_HDF5_NTUPLE_CREATE_VEC_COL
853 
854   }
855 
856   virtual ~ntuple() {
857     tools::safe_clear<icol>(m_cols);
858   }
859 protected:
860   ntuple(const ntuple& a_from):store(a_from),m_title(a_from.m_title){}
861   ntuple& operator=(const ntuple&){return *this;}
862 public:
863   bool initialize(std::ostream& a_out,const tools::ntuple_binding& a_bd = tools::ntuple_binding()) {
864     tools::safe_clear<icol>(m_cols);
865    {tools_vforcit(pages*,m_pagess,it) (*it)->reset_pos();}
866 
867     tools_vforcit(pages*,m_pagess,it) {
868 
869 #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(a__type) \
870       if((*it)->form()==tools::stype(a__type())) {\
871         a__type* user_var = a_bd.find_variable<a__type>((*it)->name());\
872         if(user_var) {\
873           column_ref<a__type>* col = new column_ref<a__type>(*this,*(*it),false,(*it)->name(),0,*user_var);\
874           if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
875           m_cols.push_back(col);\
876   } else {\
877           column<a__type>* col = new column<a__type>(*this,*(*it),false,(*it)->name(),0);\
878           if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
879           m_cols.push_back(col);\
880   }\
881       }
882 
883 #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(a__vec_type,a__type) \
884       if((*it)->form()==s_vector_##a__vec_type()) {\
885         std::vector<a__type>* user_var = a_bd.find_variable< std::vector<a__type> >((*it)->name());\
886   if(user_var) {\
887           std_vector_column_ref<a__type>* col = \
888       new std_vector_column_ref<a__type>(*this,*(*it),false,(*it)->name(),0,*user_var);\
889           if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
890           m_cols.push_back(col);\
891   } else {\
892           std_vector_column<a__type>* col = new std_vector_column<a__type>(*this,*(*it),false,(*it)->name(),0);\
893           if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
894           m_cols.push_back(col);\
895   }\
896       }
897 
898 #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL_STRING \
899       if((*it)->form()==s_vector_string()) {\
900         std::vector<std::string>* user_var = a_bd.find_variable< std::vector<std::string> >((*it)->name());\
901   if(user_var) {\
902           std_vector_column_string_ref* col = \
903       new std_vector_column_string_ref(*this,*(*it),false,(*it)->name(),0,*user_var);\
904           if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
905           m_cols.push_back(col);\
906   } else {\
907           std_vector_column_string* col = new std_vector_column_string(*this,*(*it),false,(*it)->name(),0);\
908           if(!col) {tools::safe_clear<icol>(m_cols);return false;}\
909           m_cols.push_back(col);\
910   }\
911       }
912 
913            TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(char)
914       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(short)
915       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(int)
916       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::int64)
917 
918       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(float)
919       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(double)
920 
921       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::byte)
922       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::ushort)
923       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint32)
924       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint64)
925 
926     //else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(bool) //use byte=uchar.
927 
928       else
929       if((*it)->form()==s_string()) {
930         std::string* user_var = a_bd.find_variable<std::string>((*it)->name());
931   if(user_var) {
932           column_string_ref* col = new column_string_ref(*this,*(*it),false,(*it)->name(),0,*user_var);
933           if(!col) {tools::safe_clear<icol>(m_cols);return false;}
934           m_cols.push_back(col);
935   } else {
936           column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0);
937           if(!col) {tools::safe_clear<icol>(m_cols);return false;}
938           m_cols.push_back(col);
939         }
940       }
941 
942       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(char,char)
943       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(short,short)
944       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int,int)
945       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int64,tools::int64)
946 
947       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(float,float)
948       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(double,double)
949 
950       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uchar,tools::uchar)
951       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(ushort,tools::ushort)
952       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint32,tools::uint32)
953       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint64,tools::uint64)
954 
955       else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL_STRING
956 
957 //    else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(bool) //use byte=uchar.
958 
959       else {
960         a_out << "toolx::hdf5::ntuple::ntuple(read with binding) :"
961               << " for column " << tools::sout((*it)->name())
962               << ", type " << tools::sout((*it)->form()) << " not yet handled."
963               << std::endl;
964         tools::safe_clear<icol>(m_cols);
965         return false;
966       }
967     }
968 #undef TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL
969 #undef TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL
970     return true;
971   }
972 
973   const std::string& title() const {return m_title;}
974 
975   const std::vector<icol*>& columns() const {return m_cols;}
976   std::vector<icol*>& columns() {return m_cols;}
977 
978   template <class T>
979   column_ref<T>* create_column_ref(const std::string& a_name,size_t a_basket_size,T& a_ref) {
980     if(tools::find_named<icol>(m_cols,a_name)) return 0;
981     pages* _pages = create_pages(a_name,tools::stype(T()));
982     if(!_pages) return 0;
983     column_ref<T>* col = new column_ref<T>(*this,*_pages,true,a_name,a_basket_size,a_ref);
984     if(!col) return 0;
985     m_cols.push_back(col);
986     return col;
987   }
988 
989   template <class T>
990   column<T>* create_column(const std::string& a_name,size_t a_basket_size) {
991     if(tools::find_named<icol>(m_cols,a_name)) return 0;
992     pages* _pages = create_pages(a_name,tools::stype(T()));
993     if(!_pages) return 0;
994     column<T>* col = new column<T>(*this,*_pages,true,a_name,a_basket_size);
995     if(!col) return 0;
996     m_cols.push_back(col);
997     return col;
998   }
999 
1000   column_string* create_column_string(const std::string& a_name,size_t a_basket_size) {
1001     if(tools::find_named<icol>(m_cols,a_name)) return 0;
1002     pages* _pages = create_pages(a_name,s_string());
1003     if(!_pages) return 0;
1004     column_string* col = new column_string(*this,*_pages,true,a_name,a_basket_size);
1005     if(!col) return 0;
1006     m_cols.push_back(col);
1007     return col;
1008   }
1009 
1010   template <class T>
1011   std_vector_column_ref<T>* create_std_column_ref(const std::string& a_name,size_t a_basket_size,std::vector<T>& a_ref) {
1012     //NOTE : to optimize, we do not handle a default std::vector value logic.
1013     if(tools::find_named<icol>(m_cols,a_name)) return 0;
1014     pages* _pages = create_pages(a_name,"vector<"+tools::stype(T())+">");
1015     if(!_pages) return 0;
1016     std_vector_column_ref<T>* col = new std_vector_column_ref<T>(*this,*_pages,true,a_name,a_basket_size,a_ref);
1017     if(!col) return 0;
1018     m_cols.push_back(col);
1019     return col;
1020   }
1021 
1022   std_vector_column_string_ref* create_std_column_string_ref(const std::string& a_name,size_t a_basket_size,std::vector<std::string>& a_ref) {
1023     //NOTE : to optimize, we do not handle a default std::vector value logic.
1024     if(tools::find_named<icol>(m_cols,a_name)) return 0;
1025     pages* _pages = create_pages(a_name,"vector<std::string>");
1026     if(!_pages) return 0;
1027     std_vector_column_string_ref* col = new std_vector_column_string_ref(*this,*_pages,true,a_name,a_basket_size,a_ref);
1028     if(!col) return 0;
1029     m_cols.push_back(col);
1030     return col;
1031   }
1032 
1033   template <class T>
1034   column_ref<T>* find_column_ref(const std::string& a_name) {
1035     icol* col = tools::find_named<icol>(m_cols,a_name);
1036     if(!col) return 0;
1037     return tools::id_cast<icol, column_ref<T> >(*col);
1038   }
1039   template <class T>
1040   column<T>* find_column(const std::string& a_name) {
1041     icol* col = tools::find_named<icol>(m_cols,a_name);
1042     if(!col) return 0;
1043     return tools::id_cast<icol, column<T> >(*col);
1044   }
1045 
1046   template <class T>
1047   std_vector_column_ref<T>* find_std_vector_column_ref(const std::string& a_name) {
1048     icol* col = tools::find_named<icol>(m_cols,a_name);
1049     if(!col) return 0;
1050     return tools::id_cast<icol, std_vector_column_ref<T> >(*col);
1051   }
1052   template <class T>
1053   std_vector_column<T>* find_std_vector_column(const std::string& a_name) {
1054     icol* col = tools::find_named<icol>(m_cols,a_name);
1055     if(!col) return 0;
1056     return tools::id_cast<icol, std_vector_column<T> >(*col);
1057   }
1058 
1059   std_vector_column_string_ref* find_std_vector_column_string_ref(const std::string& a_name) {
1060     icol* col = tools::find_named<icol>(m_cols,a_name);
1061     if(!col) return 0;
1062     return tools::id_cast<icol, std_vector_column_string_ref >(*col);
1063   }
1064   std_vector_column_string* find_std_vector_column_string(const std::string& a_name) {
1065     icol* col = tools::find_named<icol>(m_cols,a_name);
1066     if(!col) return 0;
1067     return tools::id_cast<icol, std_vector_column_string >(*col);
1068   }
1069 
1070   column_string* find_column_string(const std::string& a_name) {
1071     icol* col = tools::find_named<icol>(m_cols,a_name);
1072     if(!col) return 0;
1073     return tools::id_cast<icol, column_string >(*col);
1074   }
1075 
1076   bool add_row() { //write.
1077     if(m_cols.empty()) return false;
1078     bool status = true;
1079     tools_vforit(icol*,m_cols,it) {if(!(*it)->add()) status = false;}
1080     //tools::uint32 n;
1081     //bool status = store::fill(n);
1082     //tools_vforit(icol*,m_cols,it) (*it)->set_def();
1083     return status;
1084   }
1085 
1086   bool get_row() { //read.
1087     bool status = true;
1088     tools_vforcit(icol*,m_cols,it) {
1089       if(!(*it)->fetch_entry()) status = false;
1090     }
1091     return status;
1092   }
1093 
1094   bool set_basket_size(size_t a_size) {
1095     tools_vforit(icol*,m_cols,it) {if(!(*it)->set_basket_size(a_size)) return false;}
1096     return true;
1097   }
1098 
1099   void reset() { //read.
1100     tools_vforit(icol*,m_cols,it) (*it)->reset();
1101   }
1102 
1103 protected:
1104   std::string m_title;
1105   std::vector<icol*> m_cols;
1106 };
1107 
1108 }}
1109 
1110 
1111 #endif