#ifndef GENERS_ARRAYADAPTOR_HH_ #define GENERS_ARRAYADAPTOR_HH_ #include #include #include #include "geners/ProcessItem.hh" #include "geners/InsertContainerItem.hh" #include "geners/IOIsContiguous.hh" #include "geners/binaryIO.hh" namespace gs { template struct GenericWriter; template struct GenericReader; template class ArrayAdaptor { public: typedef T value_type; typedef const T* const_iterator; inline ArrayAdaptor(const T* indata, const std::size_t sz, const bool writeItemClassId = true) : data_(indata), size_(sz), writetemCl_(writeItemClassId) {if (sz) assert(data_);} inline std::size_t size() const {return size_;} inline const_iterator begin() const {return data_;} inline const_iterator end() const {return data_ + size_;} inline bool writeItemClassId() const {return writetemCl_;} inline const T& operator[](const std::size_t index) const {return data_[index];} inline T& operator[](const std::size_t index) {return (const_cast(data_))[index];} inline T& at(const std::size_t index) { if (index >= size_) throw std::out_of_range( "gs::ArrayAdaptor::at: index out of range"); return (const_cast(data_))[index]; } private: ArrayAdaptor(); const T* data_; std::size_t size_; bool writetemCl_; }; template struct IOIsContiguous > {enum {value = 1};}; template struct IOIsContiguous > {enum {value = 1};}; template struct IOIsContiguous > {enum {value = 1};}; template struct IOIsContiguous > {enum {value = 1};}; template struct InsertContainerItem > { typedef ArrayAdaptor A; static inline void insert(A& obj, const typename A::value_type& item, const std::size_t itemNumber) {obj.at(itemNumber) = item;} }; template struct InsertContainerItem > { typedef ArrayAdaptor A; static inline void insert(A& obj, const typename A::value_type& item, const std::size_t itemNumber) {obj.at(itemNumber) = item;} }; // Ignore array size I/O. The size is provided in the constructor. // Of course, it still has to be written somewhere, but that code // is external w.r.t. the array adaptor. template struct GenericWriter, InContainerSize> { inline static bool process(std::size_t, Stream&, State*, bool) {return true;} }; template struct GenericReader, InContainerSize> { inline static bool process(std::size_t, Stream&, State*, bool) {return true;} }; template struct GenericWriter, InPODArray> { inline static bool process(const ArrayAdaptor& a, Stream& os, State*, bool) { const std::size_t len = a.size(); if (len) write_pod_array(os, &a[0], len); return !os.fail(); } }; template struct GenericReader, InPODArray> { inline static bool process(ArrayAdaptor& a, Stream& s, State*, bool) { const std::size_t len = a.size(); if (len) read_pod_array(s, &a[0], len); return !s.fail(); } }; template struct GenericWriter, InContainerHeader> { typedef ArrayAdaptor Container; inline static bool process(const Container& c, Stream& os, State*, const bool processClassId) { bool status = processClassId ? ClassId::makeId().write(os) : true; if (status && !(IOTraits::IsPOD && IOTraits::IsContiguous) && c.writeItemClassId()) status = ClassId::makeId().write(os); return status; } }; template struct GenericReader, InContainerHeader> { typedef ArrayAdaptor Container; inline static bool process(Container& a, Stream& is, State* state, const bool processClassId) { bool status = true; if (processClassId) { ClassId id(is, 1); const ClassId& current = ClassId::makeId(); status = (id.name() == current.name()); } if (status) { if (!(IOTraits::IsPOD && IOTraits::IsContiguous)) if (a.writeItemClassId()) { ClassId id(is, 1); state->push_back(id); } } return status; } }; template struct GenericReader, InContainerFooter> { typedef ArrayAdaptor Container; inline static bool process(Container& a, Stream&, State* state, bool) { if (!(IOTraits::IsPOD && IOTraits::IsContiguous)) if (a.writeItemClassId()) state->pop_back(); return true; } }; } gs_specialize_template_id_T(gs::ArrayAdaptor, 0, 1) #endif // GENERS_ARRAYADAPTOR_HH_