Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-07-30 02:32:39

0001 #ifndef GENERS_ARRAYADAPTOR_HH_
0002 #define GENERS_ARRAYADAPTOR_HH_
0003 
0004 #include "Alignment/Geners/interface/IOException.hh"
0005 #include <cassert>
0006 #include <cstddef>
0007 
0008 #include "Alignment/Geners/interface/IOIsContiguous.hh"
0009 #include "Alignment/Geners/interface/InsertContainerItem.hh"
0010 #include "Alignment/Geners/interface/ProcessItem.hh"
0011 #include "Alignment/Geners/interface/binaryIO.hh"
0012 
0013 namespace gs {
0014   template <class Stream, class State, class Item, class Stage>
0015   struct GenericWriter;
0016 
0017   template <class Stream, class State, class Item, class Stage>
0018   struct GenericReader;
0019 
0020   template <typename T>
0021   class ArrayAdaptor {
0022   public:
0023     typedef T value_type;
0024     typedef const T *const_iterator;
0025 
0026     inline ArrayAdaptor(const T *indata, const std::size_t sz, const bool writeItemClassId = true)
0027         : data_(indata), size_(sz), writetemCl_(writeItemClassId) {
0028       if (sz)
0029         assert(data_);
0030     }
0031 
0032     inline std::size_t size() const { return size_; }
0033     inline const_iterator begin() const { return data_; }
0034     inline const_iterator end() const { return data_ + size_; }
0035     inline bool writeItemClassId() const { return writetemCl_; }
0036     inline const T &operator[](const std::size_t index) const { return data_[index]; }
0037     inline T &operator[](const std::size_t index) { return (const_cast<T *>(data_))[index]; }
0038     inline T &at(const std::size_t index) {
0039       if (index >= size_)
0040         throw gs::IOOutOfRange("gs::ArrayAdaptor::at: index out of range");
0041       return (const_cast<T *>(data_))[index];
0042     }
0043 
0044     ArrayAdaptor() = delete;
0045 
0046   private:
0047     const T *data_;
0048     std::size_t size_;
0049     bool writetemCl_;
0050   };
0051 
0052   template <class T>
0053   struct IOIsContiguous<ArrayAdaptor<T>> {
0054     enum { value = 1 };
0055   };
0056 
0057   template <class T>
0058   struct IOIsContiguous<const ArrayAdaptor<T>> {
0059     enum { value = 1 };
0060   };
0061 
0062   template <class T>
0063   struct IOIsContiguous<volatile ArrayAdaptor<T>> {
0064     enum { value = 1 };
0065   };
0066 
0067   template <class T>
0068   struct IOIsContiguous<const volatile ArrayAdaptor<T>> {
0069     enum { value = 1 };
0070   };
0071 
0072   template <class T>
0073   struct InsertContainerItem<ArrayAdaptor<T>> {
0074     typedef ArrayAdaptor<T> A;
0075     static inline void insert(A &obj, const typename A::value_type &item, const std::size_t itemNumber) {
0076       obj.at(itemNumber) = item;
0077     }
0078   };
0079 
0080   template <class T>
0081   struct InsertContainerItem<volatile ArrayAdaptor<T>> {
0082     typedef ArrayAdaptor<T> A;
0083     static inline void insert(A &obj, const typename A::value_type &item, const std::size_t itemNumber) {
0084       obj.at(itemNumber) = item;
0085     }
0086   };
0087 
0088   // Ignore array size I/O. The size is provided in the constructor.
0089   // Of course, it still has to be written somewhere, but that code
0090   // is external w.r.t. the array adaptor.
0091   template <class Stream, class State, class T>
0092   struct GenericWriter<Stream, State, ArrayAdaptor<T>, InContainerSize> {
0093     inline static bool process(std::size_t, Stream &os, State *, const bool processClassId) { return true; }
0094   };
0095 
0096   template <class Stream, class State, class T>
0097   struct GenericReader<Stream, State, ArrayAdaptor<T>, InContainerSize> {
0098     inline static bool process(std::size_t, Stream &os, State *, const bool processClassId) { return true; }
0099   };
0100 
0101   template <class Stream, class State, class T>
0102   struct GenericWriter<Stream, State, ArrayAdaptor<T>, InPODArray> {
0103     inline static bool process(const ArrayAdaptor<T> &a, Stream &os, State *, bool) {
0104       const std::size_t len = a.size();
0105       if (len)
0106         write_pod_array(os, &a[0], len);
0107       return !os.fail();
0108     }
0109   };
0110 
0111   template <class Stream, class State, class T>
0112   struct GenericReader<Stream, State, ArrayAdaptor<T>, InPODArray> {
0113     inline static bool process(ArrayAdaptor<T> &a, Stream &s, State *, bool) {
0114       const std::size_t len = a.size();
0115       if (len)
0116         read_pod_array(s, &a[0], len);
0117       return !s.fail();
0118     }
0119   };
0120 
0121   template <class Stream, class State, class T>
0122   struct GenericWriter<Stream, State, ArrayAdaptor<T>, InContainerHeader> {
0123     typedef ArrayAdaptor<T> Container;
0124 
0125     inline static bool process(const Container &c, Stream &os, State *, const bool processClassId) {
0126       bool status = processClassId ? ClassId::makeId<Container>().write(os) : true;
0127       if (status && !(IOTraits<T>::IsPOD && IOTraits<Container>::IsContiguous) && c.writeItemClassId())
0128         status = ClassId::makeId<T>().write(os);
0129       return status;
0130     }
0131   };
0132 
0133   template <class Stream, class State, class T>
0134   struct GenericReader<Stream, State, ArrayAdaptor<T>, InContainerHeader> {
0135     typedef ArrayAdaptor<T> Container;
0136 
0137     inline static bool process(Container &a, Stream &is, State *state, const bool processClassId) {
0138       bool status = true;
0139       if (processClassId) {
0140         ClassId id(is, 1);
0141         const ClassId &current = ClassId::makeId<Container>();
0142         status = (id.name() == current.name());
0143       }
0144       if (status) {
0145         if (!(IOTraits<T>::IsPOD && IOTraits<Container>::IsContiguous))
0146           if (a.writeItemClassId()) {
0147             ClassId id(is, 1);
0148             state->push_back(id);
0149           }
0150       }
0151       return status;
0152     }
0153   };
0154 
0155   template <class Stream, class State, class T>
0156   struct GenericReader<Stream, State, ArrayAdaptor<T>, InContainerFooter> {
0157     typedef ArrayAdaptor<T> Container;
0158 
0159     inline static bool process(Container &a, Stream &, State *state, bool) {
0160       if (!(IOTraits<T>::IsPOD && IOTraits<Container>::IsContiguous))
0161         if (a.writeItemClassId())
0162           state->pop_back();
0163       return true;
0164     }
0165   };
0166 }  // namespace gs
0167 
0168 gs_specialize_template_id_T(gs::ArrayAdaptor, 0, 1)
0169 
0170 #endif  // GENERS_ARRAYADAPTOR_HH_