// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef toolx_hdf5_ntuple #define toolx_hdf5_ntuple #include "store" #include #include #include #include #include #include #include #include namespace toolx { namespace hdf5 { class ntuple : public store { public: class icol { public: virtual ~icol(){} public: virtual void* cast(tools::cid) const = 0; virtual tools::cid id_cls() const = 0; public: virtual bool set_basket_size(size_t a_size) = 0; virtual bool add() = 0; virtual bool fetch_entry() = 0; virtual const std::string& name() const = 0; virtual void reset() = 0; }; public: template class column_ref : public virtual icol { public: static tools::cid id_class() { static const T s_v = T(); //do that for T = std::string. return tools::_cid(s_v)+10000; } virtual void* cast(tools::cid a_class) const { if(void* p = tools::cmp_cast(this,a_class)) {return p;} else return 0; } virtual tools::cid id_cls() const {return id_class();} public: //icol virtual bool add() { //write. if(!m_write) return false; if(m_basket_pos>=m_basket_size) { if(!m_branch.write_page(m_basket_size,m_basket)) { m_store.out() << "toolx::hdf5::ntuple::column_ref::add : write_page() failed." << std::endl; m_basket_pos = 0; return false; } m_basket_pos = 0; if(m_want_new_basket_size) { delete [] m_basket; m_basket = new T[m_want_new_basket_size]; m_basket_pos = 0; m_basket_size = m_want_new_basket_size; m_want_new_basket_size = 0; } } m_basket[m_basket_pos] = m_ref; m_basket_pos++; return true; } virtual bool fetch_entry() { //read. if(m_write) return false; if(m_basket_pos>=m_basket_end) { //we need more data. if(m_branch.pos()>=m_branch.entries()) { m_store.out() << "toolx::hdf5::ntuple::column_ref:fetch_entry : no more data." << std::endl; m_basket_pos = 0; m_basket_end = 0; return false; } if(m_want_new_basket_size) { delete [] m_basket; m_basket = new T[m_want_new_basket_size]; m_basket_pos = 0; m_basket_size = m_want_new_basket_size; m_want_new_basket_size = 0; } tools::uint64 remain = m_branch.entries()-m_branch.pos(); size_t n = tools::min_of((size_t)remain,m_basket_size); if(!m_branch.read_page(n,m_basket)) { m_store.out() << "toolx::hdf5::ntuple::column_ref:fetch_entry : read_page() failed." << std::endl; m_basket_pos = 0; m_basket_end = 0; return false; } m_basket_pos = 0; m_basket_end = n; } m_ref = m_basket[m_basket_pos]; m_basket_pos++; return true; } virtual void reset() {m_branch.reset_pos();} virtual const std::string& name() const {return m_name;} virtual bool set_basket_size(size_t a_size) { if(!a_size) return false; m_want_new_basket_size = a_size; return true; } public: column_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size,T& a_ref) :m_store(a_store) ,m_branch(a_pages) ,m_write(a_write) ,m_name(a_name) ,m_ref(a_ref) ,m_basket_size(a_basket_size?a_basket_size:32000) ,m_basket_pos(0) ,m_basket_end(0) //read. ,m_basket(0) ,m_want_new_basket_size(0) { m_basket = new T[m_basket_size]; if(m_write) { } else { //read. tools::uint64 _entries = m_branch.entries(); size_t n = tools::min_of((size_t)_entries,m_basket_size); if(_entries) { if(!m_branch.read_page(n,m_basket)) { m_store.out() << "toolx::hdf5::ntuple::column_ref:column_ref : read_page() failed." << std::endl; m_basket_pos = 0; m_basket_end = 0; return; } } m_basket_pos = 0; m_basket_end = n; } } virtual ~column_ref(){ if(m_write && m_basket_pos) { if(!m_branch.write_page(m_basket_pos,m_basket)) { m_store.out() << "toolx::hdf5::ntuple::column_ref::~column_ref : write_page() failed." << std::endl; } } delete [] m_basket; } protected: column_ref(const column_ref& a_from) :icol(a_from) ,m_store(a_from.m_store) ,m_branch(a_from.m_branch) ,m_write(a_from.m_write) ,m_name(a_from.m_name) ,m_ref(a_from.m_ref) ,m_basket_size(a_from.m_basket_size) ,m_basket_pos(0) ,m_basket_end(0) ,m_basket(0) ,m_want_new_basket_size(0) {} column_ref& operator=(const column_ref& a_from){ if(&a_from==this) return *this; m_name = a_from.m_name; m_basket_size = a_from.m_basket_size; m_basket_pos = 0; m_basket_end = 0; m_want_new_basket_size = 0; return *this; } protected: store& m_store; pages& m_branch; bool m_write; std::string m_name; T& m_ref; size_t m_basket_size; size_t m_basket_pos; size_t m_basket_end; T* m_basket; size_t m_want_new_basket_size; }; template class column : public column_ref { typedef column_ref parent; public: static tools::cid id_class() { static const T s_v = T(); //do that for T = std::string. return tools::_cid(s_v); } virtual void* cast(tools::cid a_class) const { if(void* p = tools::cmp_cast(this,a_class)) {return p;} else return 0; } virtual tools::cid id_cls() const {return id_class();} public: column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size) :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp) ,m_tmp(T()) { } virtual ~column(){ } protected: column(const column& a_from) :icol(a_from) ,parent(a_from) ,m_tmp(a_from.m_tmp) {} column& operator=(const column& a_from){ if(&a_from==this) return *this; parent::operator=(a_from); m_tmp = a_from.m_tmp; return *this; } public: bool fill(const T& a_value) {m_tmp = a_value;return true;} //write. bool get_entry(T& a_v) const {a_v = m_tmp;return true;} //read. protected: T m_tmp; }; TOOLS_CLASS_STRING_VALUE(vector_char,vector) TOOLS_CLASS_STRING_VALUE(vector_short,vector) TOOLS_CLASS_STRING_VALUE(vector_int,vector) TOOLS_CLASS_STRING_VALUE(vector_float,vector) TOOLS_CLASS_STRING_VALUE(vector_double,vector) TOOLS_CLASS_STRING_VALUE(string,string) TOOLS_CLASS_STRING_VALUE(vector_int64,vector) TOOLS_CLASS_STRING_VALUE(vector_uchar,vector) TOOLS_CLASS_STRING_VALUE(vector_ushort,vector) TOOLS_CLASS_STRING_VALUE(vector_uint32,vector) TOOLS_CLASS_STRING_VALUE(vector_uint64,vector) TOOLS_CLASS_STRING_VALUE(vector_string,vector) template class std_vector_column_ref : public virtual icol { public: static tools::cid id_class() {return tools::_cid_std_vector()+10000;} virtual void* cast(tools::cid a_class) const { if(void* p = tools::cmp_cast(this,a_class)) {return p;} else return 0; } virtual tools::cid id_cls() const {return id_class();} public: //icol virtual bool add() { //write. if(!m_write) return false; const T* _data = m_ref.data(); return m_branch.write_vlen(m_ref.size(),_data); } virtual bool fetch_entry() { //read. if(m_write) return false; size_t n; T* _data; if(!m_branch.read_vlen(n,_data)) { m_store.out() << "toolx::hdf5::ntuple::std_vector_column_ref:fetch_entry : read_page() failed." << std::endl; return false; } m_ref.resize(n); T* dpos = _data; T* pos = m_ref.data(); for(size_t index=0;index& a_ref) :m_store(a_store) ,m_branch(a_pages) ,m_write(a_write) ,m_name(a_name) ,m_ref(a_ref) { } virtual ~std_vector_column_ref(){ } protected: std_vector_column_ref(const std_vector_column_ref& a_from) :icol(a_from) ,m_store(a_from.m_store) ,m_branch(a_from.m_branch) ,m_write(a_from.m_write) ,m_name(a_from.m_name) ,m_ref(a_from.m_ref) {} std_vector_column_ref& operator=(const std_vector_column_ref& a_from){ if(&a_from==this) return *this; m_name = a_from.m_name; return *this; } protected: store& m_store; pages& m_branch; bool m_write; std::string m_name; std::vector& m_ref; }; template class std_vector_column : public std_vector_column_ref { typedef std_vector_column_ref parent; public: static tools::cid id_class() {return tools::_cid_std_vector();} virtual void* cast(tools::cid a_class) const { if(void* p = tools::cmp_cast(this,a_class)) {return p;} else return 0; } virtual tools::cid id_cls() const {return id_class();} public: std_vector_column(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size) :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp) {} virtual ~std_vector_column(){} protected: std_vector_column(const std_vector_column& a_from) :icol(a_from) ,parent(a_from) {} std_vector_column& operator=(const std_vector_column& a_from){ parent::operator=(a_from); return *this; } public: const std::vector& data() const {return m_tmp;} protected: std::vector m_tmp; }; class column_string_ref : public virtual icol { public: static tools::cid id_class() { static const std::string s_v; return tools::_cid(s_v)+10000; } virtual void* cast(tools::cid a_class) const { if(void* p = tools::cmp_cast(this,a_class)) {return p;} else return 0; } virtual tools::cid id_cls() const {return id_class();} public: //icol virtual bool add() { //write. if(!m_write) return false; return m_branch.write_string(m_ref); } virtual bool fetch_entry() { //read. if(m_write) return false; if(!m_branch.read_string(m_ref)) { m_store.out() << "toolx::hdf5::ntuple::column_string_ref:fetch_entry : read_page() failed." << std::endl; return false; } return true; } virtual void reset() {m_branch.reset_pos();} virtual const std::string& name() const {return m_name;} virtual bool set_basket_size(size_t) {return true;} public: column_string_ref(store& a_store,pages& a_pages,bool a_write,const std::string& a_name, size_t /*a_basket_size*/, std::string& a_ref) :m_store(a_store) ,m_branch(a_pages) ,m_write(a_write) ,m_name(a_name) ,m_ref(a_ref) { } virtual ~column_string_ref(){ } protected: column_string_ref(const column_string_ref& a_from) :icol(a_from) ,m_store(a_from.m_store) ,m_branch(a_from.m_branch) ,m_write(a_from.m_write) ,m_name(a_from.m_name) ,m_ref(a_from.m_ref) {} column_string_ref& operator=(const column_string_ref& a_from){ if(&a_from==this) return *this; m_name = a_from.m_name; return *this; } protected: store& m_store; pages& m_branch; bool m_write; std::string m_name; std::string& m_ref; }; class column_string : public column_string_ref { typedef column_string_ref parent; public: static tools::cid id_class() { static const std::string s_v; return tools::_cid(s_v); } virtual void* cast(tools::cid a_class) const { if(void* p = tools::cmp_cast(this,a_class)) {return p;} else return 0; } virtual tools::cid id_cls() const {return id_class();} public: column_string(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,tools::uint32 a_basket_size) :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp) { } virtual ~column_string(){ } protected: column_string(const column_string& a_from) :icol(a_from) ,parent(a_from) {} column_string& operator=(const column_string& a_from){ if(&a_from==this) return *this; parent::operator=(a_from); return *this; } public: bool fill(const std::string& a_value) {m_tmp = a_value;return true;} bool get_entry(std::string& a_value) const {a_value = m_tmp;return true;} protected: std::string m_tmp; }; class std_vector_column_string_ref : public virtual icol { public: static tools::cid id_class() {return tools::_cid_std_vector()+10000;} virtual void* cast(tools::cid a_class) const { if(void* p = tools::cmp_cast(this,a_class)) {return p;} else return 0; } virtual tools::cid id_cls() const {return id_class();} public: //icol virtual bool add() { //write. if(!m_write) return false; size_t _size = 0; {tools_vforcit(std::string,m_ref,it) { _size += (*it).size(); _size++; }} char* _data = _size?new char[_size]:0; {char* pos = _data; tools_vforcit(std::string,m_ref,it) { ::memcpy(pos,(*it).c_str(),(*it).size()); pos += (*it).size(); *pos = 0; pos++; }} return m_branch.write_vlen(_size,_data); } virtual bool fetch_entry() { //read. if(m_write) return false; size_t n; char* _data; if(!m_branch.read_vlen(n,_data)) { m_store.out() << "toolx::hdf5::ntuple::std_vector_column_string_ref:fetch_entry : read_page() failed." << std::endl; return false; } m_ref.clear(); {char* pos = _data; char* begin = _data; for(size_t ichar=0;ichar& a_ref) :m_store(a_store) ,m_branch(a_pages) ,m_write(a_write) ,m_name(a_name) ,m_ref(a_ref) { } virtual ~std_vector_column_string_ref(){ } protected: std_vector_column_string_ref(const std_vector_column_string_ref& a_from) :icol(a_from) ,m_store(a_from.m_store) ,m_branch(a_from.m_branch) ,m_write(a_from.m_write) ,m_name(a_from.m_name) ,m_ref(a_from.m_ref) {} std_vector_column_string_ref& operator=(const std_vector_column_string_ref& a_from){ if(&a_from==this) return *this; m_name = a_from.m_name; return *this; } protected: store& m_store; pages& m_branch; bool m_write; std::string m_name; std::vector& m_ref; }; class std_vector_column_string : public std_vector_column_string_ref { typedef std_vector_column_string_ref parent; public: static tools::cid id_class() {return tools::_cid_std_vector();} virtual void* cast(tools::cid a_class) const { if(void* p = tools::cmp_cast(this,a_class)) {return p;} else return 0; } virtual tools::cid id_cls() const {return id_class();} public: std_vector_column_string(store& a_store,pages& a_pages,bool a_write,const std::string& a_name,size_t a_basket_size) :parent(a_store,a_pages,a_write,a_name,a_basket_size,m_tmp) {} virtual ~std_vector_column_string(){} protected: std_vector_column_string(const std_vector_column_string& a_from) :icol(a_from) ,parent(a_from) {} std_vector_column_string& operator=(const std_vector_column_string& a_from){ parent::operator=(a_from); return *this; } public: const std::vector& data() const {return m_tmp;} protected: std::vector m_tmp; }; public: ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name, unsigned int a_compress,size_t /*a_basket_size*//* = 32000*/) :store(a_out,a_group,a_name,true,a_compress) //true=write {} ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name) :store(a_out,a_group,a_name,false,0) //false=read { tools_vforcit(pages*,m_pagess,it){ #define TOOLX_HDF5_NTUPLE_READ_CREATE_COL(a__type) \ if((*it)->form()==tools::stype(a__type())) {\ column* col = new column(*this,*(*it),false,(*it)->name(),0);\ if(!col) {tools::safe_clear(m_cols);return;}\ m_cols.push_back(col);\ } #define TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(a__vec_type,a__type) \ if((*it)->form()==s_vector_##a__vec_type()) {\ std_vector_column* col = new std_vector_column(*this,*(*it),false,(*it)->name(),0);\ if(!col) {tools::safe_clear(m_cols);return;}\ m_cols.push_back(col);\ } #define TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL_STRING \ if((*it)->form()==s_vector_string()) {\ std_vector_column_string* col = new std_vector_column_string(*this,*(*it),false,(*it)->name(),0);\ if(!col) {tools::safe_clear(m_cols);return;}\ m_cols.push_back(col);\ } TOOLX_HDF5_NTUPLE_READ_CREATE_COL(char) else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(short) else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(int) else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::int64) else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(float) else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(double) else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::byte) else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::ushort) else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::uint32) else TOOLX_HDF5_NTUPLE_READ_CREATE_COL(tools::uint64) else if((*it)->form()==s_string()) { column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0); if(!col) {tools::safe_clear(m_cols);return;} m_cols.push_back(col); } else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(char,char) else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(short,short) else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(int,int) else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(int64,tools::int64) else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(float,float) else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(double,double) else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uchar,tools::uchar) else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(ushort,tools::ushort) else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint32,tools::uint32) else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL(uint64,tools::uint64) else TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL_STRING else { m_out << "toolx::hdf5::ntuple::ntuple(read) :" << " for column " << tools::sout((*it)->name()) << ", type " << tools::sout((*it)->form()) << " not yet handled." << std::endl; //throw tools::safe_clear(m_cols); return; } } #undef TOOLX_HDF5_NTUPLE_READ_CREATE_VEC_COL #undef TOOLX_HDF5_NTUPLE_READ_CREATE_COL } ntuple(std::ostream& a_out,hid_t a_group,const std::string& a_name,const tools::ntuple_binding& a_bd) :store(a_out,a_group,a_name,false,0) //false=read { if(!initialize(a_out,a_bd)) {} } ntuple(std::ostream& a_out,hid_t a_group,const tools::ntuple_booking& a_bkg, unsigned int a_compress,size_t a_basket_size/* = 32000*/) :store(a_out,a_group,a_bkg.name(),true,a_compress) //true=write ,m_title(a_bkg.title()) { const std::vector& cols = a_bkg.columns(); tools_vforcit(tools::column_booking,cols,it){ #define TOOLX_HDF5_NTUPLE_CREATE_COL(a__type) \ if((*it).cls_id()==tools::_cid(a__type())) {\ a__type* user = (a__type*)(*it).user_obj();\ if(user) {\ if(!create_column_ref((*it).name(),a_basket_size,*user)) {\ m_out << "toolx::hdf5::ntuple :"\ << " can't create column_ref " << tools::sout((*it).name()) << "."\ << std::endl;\ tools::safe_clear(m_cols);\ return;\ }\ } else {\ if(!create_column((*it).name(),a_basket_size)) {\ m_out << "toolx::hdf5::ntuple :"\ << " can't create column " << tools::sout((*it).name()) << "."\ << std::endl;\ tools::safe_clear(m_cols);\ return;\ }\ }\ } #define TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(a__type) \ if((*it).cls_id()==tools::_cid_std_vector()) {\ std::vector* vec = (std::vector*)(*it).user_obj();\ if(!vec) {\ m_out << "toolx::hdf5::ntuple :"\ << " for std::vector column " << tools::sout((*it).name())\ << ", the user vector pointer is null."\ << std::endl;\ tools::safe_clear(m_cols);\ return;\ }\ if(!create_std_column_ref((*it).name(),a_basket_size,*vec)) {\ m_out << "toolx::hdf5::ntuple :"\ << " can't create std::vector column " << tools::sout((*it).name()) << "."\ << std::endl;\ tools::safe_clear(m_cols);\ return;\ }\ } #define TOOLX_HDF5_NTUPLE_CREATE_VEC_COL_STRING \ if((*it).cls_id()==tools::_cid_std_vector()) {\ std::vector* vec = (std::vector*)(*it).user_obj();\ if(!vec) {\ m_out << "toolx::hdf5::ntuple :"\ << " for std::vector column " << tools::sout((*it).name())\ << ", the user vector pointer is null."\ << std::endl;\ tools::safe_clear(m_cols);\ return;\ }\ if(!create_std_column_string_ref((*it).name(),a_basket_size,*vec)) {\ m_out << "toolx::hdf5::ntuple :"\ << " can't create std::vector column " << tools::sout((*it).name()) << "."\ << std::endl;\ tools::safe_clear(m_cols);\ return;\ }\ } TOOLX_HDF5_NTUPLE_CREATE_COL(char) else TOOLX_HDF5_NTUPLE_CREATE_COL(short) else TOOLX_HDF5_NTUPLE_CREATE_COL(int) else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::int64) else TOOLX_HDF5_NTUPLE_CREATE_COL(float) else TOOLX_HDF5_NTUPLE_CREATE_COL(double) else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::byte) else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::ushort) else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::uint32) else TOOLX_HDF5_NTUPLE_CREATE_COL(tools::uint64) else if((*it).cls_id()==tools::_cid(std::string())) { if(!create_column_string((*it).name(),a_basket_size)) { m_out << "toolx::hdf5::ntuple :" << " can't create string column " << tools::sout((*it).name()) << "." << std::endl; tools::safe_clear(m_cols); return; } } else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(char) else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(short) else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(int) else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::int64) else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(float) else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(double) else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uchar) else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::ushort) else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint32) else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL(tools::uint64) else TOOLX_HDF5_NTUPLE_CREATE_VEC_COL_STRING else { m_out << "toolx::hdf5::ntuple :" << " for column " << tools::sout((*it).name()) << ", type with cid " << (*it).cls_id() << " not yet handled." << std::endl; tools::safe_clear(m_cols); return; } } #undef TOOLX_HDF5_NTUPLE_CREATE_COL #undef TOOLX_HDF5_NTUPLE_CREATE_VEC_COL } virtual ~ntuple() { tools::safe_clear(m_cols); } protected: ntuple(const ntuple& a_from):store(a_from),m_title(a_from.m_title){} ntuple& operator=(const ntuple&){return *this;} public: bool initialize(std::ostream& a_out,const tools::ntuple_binding& a_bd = tools::ntuple_binding()) { tools::safe_clear(m_cols); {tools_vforcit(pages*,m_pagess,it) (*it)->reset_pos();} tools_vforcit(pages*,m_pagess,it) { #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(a__type) \ if((*it)->form()==tools::stype(a__type())) {\ a__type* user_var = a_bd.find_variable((*it)->name());\ if(user_var) {\ column_ref* col = new column_ref(*this,*(*it),false,(*it)->name(),0,*user_var);\ if(!col) {tools::safe_clear(m_cols);return false;}\ m_cols.push_back(col);\ } else {\ column* col = new column(*this,*(*it),false,(*it)->name(),0);\ if(!col) {tools::safe_clear(m_cols);return false;}\ m_cols.push_back(col);\ }\ } #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(a__vec_type,a__type) \ if((*it)->form()==s_vector_##a__vec_type()) {\ std::vector* user_var = a_bd.find_variable< std::vector >((*it)->name());\ if(user_var) {\ std_vector_column_ref* col = \ new std_vector_column_ref(*this,*(*it),false,(*it)->name(),0,*user_var);\ if(!col) {tools::safe_clear(m_cols);return false;}\ m_cols.push_back(col);\ } else {\ std_vector_column* col = new std_vector_column(*this,*(*it),false,(*it)->name(),0);\ if(!col) {tools::safe_clear(m_cols);return false;}\ m_cols.push_back(col);\ }\ } #define TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL_STRING \ if((*it)->form()==s_vector_string()) {\ std::vector* user_var = a_bd.find_variable< std::vector >((*it)->name());\ if(user_var) {\ std_vector_column_string_ref* col = \ new std_vector_column_string_ref(*this,*(*it),false,(*it)->name(),0,*user_var);\ if(!col) {tools::safe_clear(m_cols);return false;}\ m_cols.push_back(col);\ } else {\ std_vector_column_string* col = new std_vector_column_string(*this,*(*it),false,(*it)->name(),0);\ if(!col) {tools::safe_clear(m_cols);return false;}\ m_cols.push_back(col);\ }\ } TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(char) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(short) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(int) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::int64) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(float) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(double) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::byte) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::ushort) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint32) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL(tools::uint64) else if((*it)->form()==s_string()) { std::string* user_var = a_bd.find_variable((*it)->name()); if(user_var) { column_string_ref* col = new column_string_ref(*this,*(*it),false,(*it)->name(),0,*user_var); if(!col) {tools::safe_clear(m_cols);return false;} m_cols.push_back(col); } else { column_string* col = new column_string(*this,*(*it),false,(*it)->name(),0); if(!col) {tools::safe_clear(m_cols);return false;} m_cols.push_back(col); } } else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(char,char) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(short,short) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int,int) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(int64,tools::int64) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(float,float) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(double,double) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uchar,tools::uchar) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(ushort,tools::ushort) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint32,tools::uint32) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL(uint64,tools::uint64) else TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL_STRING else { a_out << "toolx::hdf5::ntuple::ntuple(read with binding) :" << " for column " << tools::sout((*it)->name()) << ", type " << tools::sout((*it)->form()) << " not yet handled." << std::endl; tools::safe_clear(m_cols); return false; } } #undef TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_COL #undef TOOLX_HDF5_NTUPLE_READ_BINDING_CREATE_VEC_COL size_t num = m_cols.size(); if(!num) { a_out << "toolx::hdf5::ntuple::ntuple(read with binding) :" << " zero columns." << std::endl; return false; } {tools_vforcit(tools::column_binding,a_bd.columns(),it) { if(!tools::find_named(m_cols,(*it).name())) { a_out << "toolx::hdf5::ntuple::ntuple(read with binding) :" << " error : for column binding with name " << tools::sout((*it).name()) << ", no ntuple column found." << std::endl; tools::safe_clear(m_cols); return false; } }} return true; } const std::string& title() const {return m_title;} const std::vector& columns() const {return m_cols;} std::vector& columns() {return m_cols;} template column_ref* create_column_ref(const std::string& a_name,size_t a_basket_size,T& a_ref) { if(tools::find_named(m_cols,a_name)) return 0; pages* _pages = create_pages(a_name,tools::stype(T())); if(!_pages) return 0; column_ref* col = new column_ref(*this,*_pages,true,a_name,a_basket_size,a_ref); if(!col) return 0; m_cols.push_back(col); return col; } template column* create_column(const std::string& a_name,size_t a_basket_size) { if(tools::find_named(m_cols,a_name)) return 0; pages* _pages = create_pages(a_name,tools::stype(T())); if(!_pages) return 0; column* col = new column(*this,*_pages,true,a_name,a_basket_size); if(!col) return 0; m_cols.push_back(col); return col; } column_string* create_column_string(const std::string& a_name,size_t a_basket_size) { if(tools::find_named(m_cols,a_name)) return 0; pages* _pages = create_pages(a_name,s_string()); if(!_pages) return 0; column_string* col = new column_string(*this,*_pages,true,a_name,a_basket_size); if(!col) return 0; m_cols.push_back(col); return col; } template std_vector_column_ref* create_std_column_ref(const std::string& a_name,size_t a_basket_size,std::vector& a_ref) { //NOTE : to optimize, we do not handle a default std::vector value logic. if(tools::find_named(m_cols,a_name)) return 0; pages* _pages = create_pages(a_name,"vector<"+tools::stype(T())+">"); if(!_pages) return 0; std_vector_column_ref* col = new std_vector_column_ref(*this,*_pages,true,a_name,a_basket_size,a_ref); if(!col) return 0; m_cols.push_back(col); return col; } std_vector_column_string_ref* create_std_column_string_ref(const std::string& a_name,size_t a_basket_size,std::vector& a_ref) { //NOTE : to optimize, we do not handle a default std::vector value logic. if(tools::find_named(m_cols,a_name)) return 0; pages* _pages = create_pages(a_name,"vector"); if(!_pages) return 0; std_vector_column_string_ref* col = new std_vector_column_string_ref(*this,*_pages,true,a_name,a_basket_size,a_ref); if(!col) return 0; m_cols.push_back(col); return col; } template column_ref* find_column_ref(const std::string& a_name) { icol* col = tools::find_named(m_cols,a_name); if(!col) return 0; return tools::id_cast >(*col); } template column* find_column(const std::string& a_name) { icol* col = tools::find_named(m_cols,a_name); if(!col) return 0; return tools::id_cast >(*col); } template std_vector_column_ref* find_std_vector_column_ref(const std::string& a_name) { icol* col = tools::find_named(m_cols,a_name); if(!col) return 0; return tools::id_cast >(*col); } template std_vector_column* find_std_vector_column(const std::string& a_name) { icol* col = tools::find_named(m_cols,a_name); if(!col) return 0; return tools::id_cast >(*col); } std_vector_column_string_ref* find_std_vector_column_string_ref(const std::string& a_name) { icol* col = tools::find_named(m_cols,a_name); if(!col) return 0; return tools::id_cast(*col); } std_vector_column_string* find_std_vector_column_string(const std::string& a_name) { icol* col = tools::find_named(m_cols,a_name); if(!col) return 0; return tools::id_cast(*col); } column_string* find_column_string(const std::string& a_name) { icol* col = tools::find_named(m_cols,a_name); if(!col) return 0; return tools::id_cast(*col); } bool add_row() { //write. if(m_cols.empty()) return false; bool status = true; tools_vforit(icol*,m_cols,it) {if(!(*it)->add()) status = false;} return status; } bool get_row() { //read. bool status = true; tools_vforcit(icol*,m_cols,it) { if(!(*it)->fetch_entry()) status = false; } return status; } bool set_basket_size(size_t a_size) { tools_vforit(icol*,m_cols,it) {if(!(*it)->set_basket_size(a_size)) return false;} return true; } void reset() { //read. tools_vforit(icol*,m_cols,it) (*it)->reset(); } protected: std::string m_title; std::vector m_cols; }; }} #endif