Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:44:54

0001 #ifndef GENERS_TUPLEIO_HH_
0002 #define GENERS_TUPLEIO_HH_
0003 
0004 #include "Alignment/Geners/interface/CPP11_config.hh"
0005 #ifdef CPP11_STD_AVAILABLE
0006 
0007 #include <tuple>
0008 #include <cassert>
0009 
0010 #include "Alignment/Geners/interface/GenericIO.hh"
0011 
0012 #define gs_specialize_template_help_tuple(qualifyer, name, version) /**/      \
0013     template<typename... Args>                                                \
0014     struct ClassIdSpecialization<qualifyer name <Args...> >                   \
0015     {inline static ClassId classId(const bool pt=false)                       \
0016     {return ClassId(tuple_class_name< name <Args...> >(#name), version, pt);}};
0017 
0018 #define gs_specialize_template_id_tuple(name, version) /**/                         \
0019 namespace gs {                                                                      \
0020     gs_specialize_template_help_tuple(GENERS_EMPTY_TYPE_QUALIFYER_, name, version)\
0021     gs_specialize_template_help_tuple(const, name, version)                         \
0022     gs_specialize_template_help_tuple(volatile, name, version)                      \
0023     gs_specialize_template_help_tuple(const volatile, name, version)                \
0024 }
0025 
0026 namespace gs {
0027     template<typename Item>
0028     Item notImplementedItemCreator();
0029 
0030     template <typename... Args>
0031     struct IOIsTuple<std::tuple<Args...> >
0032     {
0033         enum {value = 1};
0034     };
0035 
0036     namespace Private
0037     {
0038         template<typename Tuple, unsigned long N>
0039         struct TupleClassIdCycler
0040         {
0041             inline static void collectClassIds(std::string& os)
0042             {
0043                 TupleClassIdCycler<Tuple, N-1>::collectClassIds(os);
0044                 if (N > 1) os += ',';
0045                 os += ClassIdSpecialization<typename 
0046                     std::tuple_element<N-1, Tuple>::type>::classId().id();
0047             }
0048 
0049             inline static bool dumpClassIds(std::ostream& os)
0050             {
0051                 return TupleClassIdCycler<Tuple, N-1>::dumpClassIds(os) &&
0052                   ClassIdSpecialization<typename 
0053                     std::tuple_element<N-1, Tuple>::type>::classId().write(os);
0054             }
0055 
0056             inline static void fillClassIdVector(std::vector<ClassId>* vec)
0057             {
0058                 TupleClassIdCycler<Tuple, N-1>::fillClassIdVector(vec);
0059                 vec->push_back(ClassIdSpecialization<
0060                     typename std::tuple_element<N-1, Tuple>::type>::classId());
0061             }
0062         };
0063 
0064         template<typename Tuple>
0065         struct TupleClassIdCycler<Tuple, 0UL>
0066         {
0067             inline static void collectClassIds(std::string&) {}
0068             inline static bool dumpClassIds(std::ostream&) {return true;}
0069             inline static void fillClassIdVector(std::vector<ClassId>* vec)
0070             {
0071                 assert(vec);
0072                 vec->clear();
0073             }
0074         };
0075 
0076         template<typename Tuple, unsigned long N>
0077         struct TupleIOCycler
0078         {
0079             template <typename Stream, typename State>
0080             inline static bool write(const Tuple& s, Stream& os, State* st,
0081                                      const bool processClassId)
0082             {
0083                 return TupleIOCycler<Tuple, N-1>::write(
0084                     s, os, st, processClassId) &&
0085                     process_const_item<GenericWriter2>(
0086                         std::get<N-1>(s), os, st, processClassId);
0087             }
0088 
0089             template <typename Stream, typename StateVec>
0090             inline static bool read(Tuple* s, Stream& os, StateVec& st,
0091                                     const bool processClassId)
0092             {
0093                 return TupleIOCycler<Tuple, N-1>::read(
0094                     s, os, st, processClassId) &&
0095                     process_item<GenericReader2>(
0096                         std::get<N-1>(*s), os, &st[N-1], processClassId);
0097             }
0098 
0099             inline static void clearPointers(Tuple* s)
0100             {
0101                 TupleIOCycler<Tuple, N-1>::clearPointers(s);
0102                 clearIfPointer(std::get<N-1>(*s));
0103             }
0104         };
0105 
0106         template<typename Tuple>
0107         struct TupleIOCycler<Tuple, 0UL>
0108         {
0109             template <typename Stream, typename State>
0110             inline static bool write(const Tuple&, Stream&, State*, bool)
0111                 {return true;}
0112 
0113             template <typename Stream, typename StateVec>
0114             inline static bool read(Tuple*, Stream&, StateVec&, bool)
0115                 {return true;}
0116 
0117             inline static void clearPointers(Tuple*) {}
0118         };
0119 
0120         inline std::vector<std::string> make_default_tuple_columns(
0121             const unsigned long N)
0122         {
0123             std::vector<std::string> names_;
0124             names_.reserve(N);
0125             for (unsigned long i=0; i<N; ++i)
0126             {
0127                 std::ostringstream os;
0128                 os << 'c';
0129                 os << i;
0130                 names_.push_back(os.str());
0131             }
0132             return names_;
0133         }
0134     }
0135 
0136     template<class T>
0137     std::string tuple_class_name(const char* templateName)
0138     {
0139         assert(templateName);
0140         std::string os(templateName);
0141         if (std::tuple_size<T>::value)
0142         {
0143             os += '<';
0144             Private::TupleClassIdCycler<
0145                 T, std::tuple_size<T>::value>::collectClassIds(os);
0146             os += '>';
0147         }
0148         return os;
0149     }
0150 
0151     template<unsigned long N>
0152     const std::vector<std::string>& default_tuple_columns()
0153     {
0154         static const std::vector<std::string> names_(
0155             Private::make_default_tuple_columns(N));
0156         return names_;
0157     }
0158 }
0159 
0160 gs_specialize_template_id_tuple(std::tuple, 0)
0161 
0162 namespace gs {
0163     template <class Stream, class State, class T>
0164     struct GenericWriter<Stream, State, T,
0165                          Int2Type<IOTraits<int>::ISTUPLE> >
0166     {
0167         inline static bool process(const T& s, Stream& os, State* st,
0168                                    const bool processClassId)
0169         {
0170             static const ClassId current(ClassId::makeId<T>());
0171             return (processClassId ? current.write(os) : true) &&
0172                 Private::TupleIOCycler<T, std::tuple_size<T>::value>::write(
0173                     s, os, st, false);
0174         }
0175     };
0176 
0177     template <class Stream, class State, class T>
0178     struct GenericReader<Stream, State, T,
0179                          Int2Type<IOTraits<int>::ISTUPLE> >
0180     {
0181         inline static bool readIntoPtr(T*& ptr, Stream& str, State* s,
0182                                        const bool processClassId)
0183         {
0184             std::unique_ptr<T> myptr;
0185             if (ptr == 0)
0186             {
0187                 myptr = std::unique_ptr<T>(new T());
0188                 Private::TupleIOCycler<
0189                     T, std::tuple_size<T>::value>::clearPointers(myptr.get());
0190             }
0191             std::vector<std::vector<ClassId> > itemIds;
0192             if (processClassId)
0193             {
0194                 static const ClassId current(ClassId::makeId<T>());
0195                 ClassId id(str, 1);
0196                 current.ensureSameName(id);
0197                 id.templateParameters(&itemIds);
0198                 assert(itemIds.size() == std::tuple_size<T>::value);
0199             }
0200             else
0201             {
0202                 assert(!s->empty());
0203                 s->back().templateParameters(&itemIds);
0204                 if (itemIds.size() != std::tuple_size<T>::value)
0205                 {
0206                     std::string err("In gs::GenericReader::readIntoPtr: "
0207                                     "bad class id for std::tuple on the "
0208                                     "class id stack: ");
0209                     err += s->back().id();
0210                     throw IOInvalidData(err);
0211                 }
0212             }
0213             const bool status = Private::TupleIOCycler<
0214                 T, std::tuple_size<T>::value>::read(
0215                     ptr ? ptr : myptr.get(), str, itemIds, false);
0216             if (status && ptr == 0)
0217                 ptr = myptr.release();
0218             return status;
0219         }
0220 
0221         inline static bool process(T& s, Stream& os, State* st,
0222                                    const bool processClassId)
0223         {
0224             T* ps = &s;
0225             return readIntoPtr(ps, os, st, processClassId);
0226         }
0227     };
0228 }
0229 
0230 #endif // CPP11_STD_AVAILABLE
0231 #endif // GENERS_TUPLEIO_HH_
0232