File indexing completed on 2024-04-06 11:56:20
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
0231 #endif
0232