Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:19

0001 //=========================================================================
0002 // ProcessItem.hh
0003 //
0004 // We will employ a compile-time visitor pattern. The idea
0005 // is to replace function calls (which are difficult to develop)
0006 // with partial template specializations (which are relatively
0007 // easy to develop).
0008 //
0009 // The call signature of the visitor will be
0010 //
0011 // bool InspectingVisitor<Arg1, Arg2, T, Stage>::process(
0012 //         const T&, Arg1&, Arg2*, const bool processClassId);
0013 //
0014 // or
0015 //
0016 // bool ModifyingVisitor<Arg1, Arg2, T, Stage>::process(
0017 //         T&, Arg1&, Arg2*, const bool processClassId);
0018 //
0019 // The processing will be terminated as soon as any call to
0020 // the visitor's process function returns "false".
0021 //
0022 // I. Volobouev
0023 // October 2010
0024 //=========================================================================
0025 
0026 #ifndef GENERS_PROCESSITEM_HH_
0027 #define GENERS_PROCESSITEM_HH_
0028 
0029 #include "Alignment/Geners/interface/IOTraits.hh"
0030 #include "Alignment/Geners/interface/Int2Type.hh"
0031 
0032 namespace gs {
0033   // Special types to designate stages in container processing
0034   struct InContainerHeader {
0035     static const char *stage() { return "InContainerHeader"; }
0036   };
0037 
0038   struct InContainerSize {
0039     static const char *stage() { return "InContainerSize"; }
0040   };
0041 
0042   struct InContainerFooter {
0043     static const char *stage() { return "InContainerFooter"; }
0044   };
0045 
0046   struct InContainerCycle {
0047     static const char *stage() { return "InContainerCycle"; }
0048   };
0049 
0050   struct InPODArray {
0051     static const char *stage() { return "InPODArray"; }
0052   };
0053 }  // namespace gs
0054 
0055 // I am not aware of an easy way to have both const and non-const
0056 // version of a template defined in the same code fragment. This is
0057 // why you see some preprocessor tricks below -- the alternative
0058 // of maintaining separate const and non-const codes is much worse.
0059 
0060 #ifdef GENERS_GENERATE_CONST_IO_PROCESSOR
0061 #undef GENERS_GENERATE_CONST_IO_PROCESSOR
0062 #endif
0063 
0064 //
0065 // This is an internal header. Applications should NEVER use it directly.
0066 //
0067 #ifdef GENERS_GENERATED_IO_PROCESSOR
0068 #undef GENERS_GENERATED_IO_PROCESSOR
0069 #endif
0070 
0071 #ifdef GENERS_GENERATED_IO_CONSTNESS
0072 #undef GENERS_GENERATED_IO_CONSTNESS
0073 #endif
0074 
0075 #ifdef GENERS_CONTAINER_ITERATION_PROC
0076 #undef GENERS_CONTAINER_ITERATION_PROC
0077 #endif
0078 
0079 #ifdef GENERS_GENERIC_ITEM_PROCESSOR
0080 #undef GENERS_GENERIC_ITEM_PROCESSOR
0081 #endif
0082 
0083 #ifdef GENERS_GENERATE_CONST_IO_PROCESSOR
0084 #define GENERS_GENERATED_IO_PROCESSOR ProcessItemLVL1
0085 #define GENERS_GENERATED_IO_CONSTNESS const
0086 #define GENERS_CONTAINER_ITERATION_PROC iterate_const_container
0087 #define GENERS_GENERIC_ITEM_PROCESSOR process_const_item
0088 #else
0089 #define GENERS_GENERATED_IO_PROCESSOR ProcessItemLVL2
0090 #define GENERS_GENERATED_IO_CONSTNESS
0091 #define GENERS_CONTAINER_ITERATION_PROC iterate_container
0092 #define GENERS_GENERIC_ITEM_PROCESSOR process_item
0093 #endif
0094 
0095 namespace gs {
0096   namespace Private {
0097     template <template <typename, typename, typename, typename> class Visitor,
0098               typename T,
0099               typename Arg1,
0100               typename Arg2,
0101               int Mode>
0102     struct GENERS_GENERATED_IO_PROCESSOR;
0103   }
0104 }  // namespace gs
0105 
0106 namespace gs {
0107   template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0108   bool GENERS_GENERIC_ITEM_PROCESSOR(GENERS_GENERATED_IO_CONSTNESS T &obj,
0109                                      Arg1 &a1,
0110                                      Arg2 *p2,
0111                                      const bool processClassId) {
0112     // The following works like a compile-time "switch" statement.
0113     // This switch is too high level to be implemented using types,
0114     // so we must do something like what is coded below.
0115     typedef IOTraits<T> M;
0116     return Private::GENERS_GENERATED_IO_PROCESSOR<
0117         Visitor,
0118         T,
0119         Arg1,
0120         Arg2,
0121         M::Signature &(M::ISPOD | M::ISSTDCONTAINER | M::ISWRITABLE | M::ISPOINTER | M::ISSHAREDPTR | M::ISIOPTR |
0122                        M::ISPAIR | M::ISSTRING | M::ISTUPLE | M::ISEXTERNAL)>::process(obj, a1, p2, processClassId);
0123   }
0124 }  // namespace gs
0125 
0126 namespace gs {
0127   namespace Private {
0128     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0129     struct GENERS_CONTAINER_ITERATION_PROC {
0130 #ifdef GENERS_GENERATE_CONST_IO_PROCESSOR
0131       static bool process(const T &v, Arg1 &a1, Arg2 *p2, std::size_t) {
0132         bool itemStatus = true;
0133         typename T::const_iterator end = v.end();
0134         for (typename T::const_iterator it = v.begin(); it != end && itemStatus; ++it)
0135           itemStatus = process_const_item<Visitor>(*it, a1, p2, false);
0136         return itemStatus;
0137       }
0138 #else
0139       static bool process(T &obj, Arg1 &a1, Arg2 *p2, const std::size_t newSize) {
0140         bool itemStatus = true;
0141         for (std::size_t i = 0; i < newSize && itemStatus; ++i)
0142           itemStatus = Visitor<Arg1, Arg2, T, InContainerCycle>::process(obj, a1, p2, i);
0143         return itemStatus;
0144       }
0145 #endif
0146     };
0147 
0148     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0149     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISPOD> {
0150       // POD-processing visitor
0151       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0152         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISPOD>>::process(obj, a1, p2, processClassId);
0153       }
0154     };
0155 
0156     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0157     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISWRITABLE> {
0158       // Processor of writable objects
0159       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0160         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISWRITABLE>>::process(obj, a1, p2, processClassId);
0161       }
0162     };
0163 
0164     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0165     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISPOINTER> {
0166       // There is not enough info here to decide how the pointer
0167       // should be managed. Therefore, just call the visitor.
0168       // However, turn on the class id writing because pointer
0169       // usually signifies polymorphic class.
0170       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, bool /* processClassId */) {
0171         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISPOINTER>>::process(obj, a1, p2, true);
0172       }
0173     };
0174 
0175     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0176     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISIOPTR> {
0177       // There is not enough info here to decide how the pointer
0178       // should be managed. Therefore, just call the visitor.
0179       // In this particular case, we are passing the "processClassId"
0180       // value as is.
0181       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0182         return Visitor<Arg1, Arg2, typename T::element_type *, Int2Type<IOTraits<int>::ISPOINTER>>::process(
0183             obj.getIOReference(), a1, p2, processClassId);
0184       }
0185     };
0186 
0187     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0188     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISSHAREDPTR> {
0189       // There is not enough info here to decide how the shared pointer
0190       // should be managed. Therefore, just call the visitor.
0191       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, bool /* processClassId */) {
0192         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISSHAREDPTR>>::process(obj, a1, p2, true);
0193       }
0194     };
0195 
0196     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0197     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISPAIR> {
0198       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0199         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISPAIR>>::process(obj, a1, p2, processClassId);
0200       }
0201     };
0202 
0203     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0204     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISTUPLE> {
0205       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0206         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISTUPLE>>::process(obj, a1, p2, processClassId);
0207       }
0208     };
0209 
0210     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0211     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISEXTERNAL> {
0212       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0213         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISEXTERNAL>>::process(obj, a1, p2, processClassId);
0214       }
0215     };
0216 
0217     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0218     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISSTRING> {
0219       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0220         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISSTRING>>::process(obj, a1, p2, processClassId);
0221       }
0222     };
0223 
0224     // Processing of containers which do not support "write",
0225     // "read" or "restore"
0226     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0227     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISSTDCONTAINER> {
0228     private:
0229       // The following function will be fired on containers which
0230       // store PODs contiguously
0231       static bool process2(
0232           GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId, Int2Type<true>) {
0233         return Visitor<Arg1, Arg2, T, InPODArray>::process(obj, a1, p2, processClassId);
0234       }
0235 
0236       // The following function will be fired on containers which
0237       // do not not store PODs contiguously
0238       static bool process2(
0239           GENERS_GENERATED_IO_CONSTNESS T &v, Arg1 &a1, Arg2 *p2, const bool processClassId, Int2Type<false>) {
0240         GENERS_GENERATED_IO_CONSTNESS std::size_t sz = v.size();
0241         return Visitor<Arg1, Arg2, T, InContainerSize>::process(sz, a1, p2, processClassId) &&
0242                GENERS_CONTAINER_ITERATION_PROC<Visitor, T, Arg1, Arg2>::process(v, a1, p2, sz) && sz == v.size();
0243       }
0244 
0245     public:
0246       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0247         if (Visitor<Arg1, Arg2, T, InContainerHeader>::process(obj, a1, p2, processClassId)) {
0248           // Do generic container processing in case the container
0249           // either does not have contiguous storage or its items
0250           // are non-PODs. Otherwise do fast processing.
0251           bool bodyStatus = true, footerStatus = true;
0252           try {
0253             bodyStatus = process2(obj,
0254                                   a1,
0255                                   p2,
0256                                   processClassId,
0257                                   Int2Type < IOTraits<typename T::value_type>::IsPOD && IOTraits<T>::IsContiguous > ());
0258           } catch (...) {
0259             footerStatus = Visitor<Arg1, Arg2, T, InContainerFooter>::process(obj, a1, p2, processClassId);
0260             throw;
0261           }
0262           footerStatus = Visitor<Arg1, Arg2, T, InContainerFooter>::process(obj, a1, p2, processClassId);
0263           return bodyStatus && footerStatus;
0264         } else
0265           return false;
0266       }
0267     };
0268   }  // namespace Private
0269 }  // namespace gs
0270 
0271 #undef GENERS_GENERATED_IO_PROCESSOR
0272 #undef GENERS_GENERATED_IO_CONSTNESS
0273 #undef GENERS_CONTAINER_ITERATION_PROC
0274 #undef GENERS_GENERIC_ITEM_PROCESSOR
0275 
0276 #define GENERS_GENERATE_CONST_IO_PROCESSOR
0277 
0278 //
0279 // This is an internal header. Applications should NEVER use it directly.
0280 //
0281 #ifdef GENERS_GENERATED_IO_PROCESSOR
0282 #undef GENERS_GENERATED_IO_PROCESSOR
0283 #endif
0284 
0285 #ifdef GENERS_GENERATED_IO_CONSTNESS
0286 #undef GENERS_GENERATED_IO_CONSTNESS
0287 #endif
0288 
0289 #ifdef GENERS_CONTAINER_ITERATION_PROC
0290 #undef GENERS_CONTAINER_ITERATION_PROC
0291 #endif
0292 
0293 #ifdef GENERS_GENERIC_ITEM_PROCESSOR
0294 #undef GENERS_GENERIC_ITEM_PROCESSOR
0295 #endif
0296 
0297 #ifdef GENERS_GENERATE_CONST_IO_PROCESSOR
0298 #define GENERS_GENERATED_IO_PROCESSOR ProcessItemLVL1
0299 #define GENERS_GENERATED_IO_CONSTNESS const
0300 #define GENERS_CONTAINER_ITERATION_PROC iterate_const_container
0301 #define GENERS_GENERIC_ITEM_PROCESSOR process_const_item
0302 #else
0303 #define GENERS_GENERATED_IO_PROCESSOR ProcessItemLVL2
0304 #define GENERS_GENERATED_IO_CONSTNESS
0305 #define GENERS_CONTAINER_ITERATION_PROC iterate_container
0306 #define GENERS_GENERIC_ITEM_PROCESSOR process_item
0307 #endif
0308 
0309 namespace gs {
0310   namespace Private {
0311     template <template <typename, typename, typename, typename> class Visitor,
0312               typename T,
0313               typename Arg1,
0314               typename Arg2,
0315               int Mode>
0316     struct GENERS_GENERATED_IO_PROCESSOR;
0317   }
0318 }  // namespace gs
0319 
0320 namespace gs {
0321   template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0322   bool GENERS_GENERIC_ITEM_PROCESSOR(GENERS_GENERATED_IO_CONSTNESS T &obj,
0323                                      Arg1 &a1,
0324                                      Arg2 *p2,
0325                                      const bool processClassId) {
0326     // The following works like a compile-time "switch" statement.
0327     // This switch is too high level to be implemented using types,
0328     // so we must do something like what is coded below.
0329     typedef IOTraits<T> M;
0330     return Private::GENERS_GENERATED_IO_PROCESSOR<
0331         Visitor,
0332         T,
0333         Arg1,
0334         Arg2,
0335         M::Signature &(M::ISPOD | M::ISSTDCONTAINER | M::ISWRITABLE | M::ISPOINTER | M::ISSHAREDPTR | M::ISIOPTR |
0336                        M::ISPAIR | M::ISSTRING | M::ISTUPLE | M::ISEXTERNAL)>::process(obj, a1, p2, processClassId);
0337   }
0338 }  // namespace gs
0339 
0340 namespace gs {
0341   namespace Private {
0342     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0343     struct GENERS_CONTAINER_ITERATION_PROC {
0344 #ifdef GENERS_GENERATE_CONST_IO_PROCESSOR
0345       static bool process(const T &v, Arg1 &a1, Arg2 *p2, std::size_t) {
0346         bool itemStatus = true;
0347         typename T::const_iterator end = v.end();
0348         for (typename T::const_iterator it = v.begin(); it != end && itemStatus; ++it)
0349           itemStatus = process_const_item<Visitor>(*it, a1, p2, false);
0350         return itemStatus;
0351       }
0352 #else
0353       static bool process(T &obj, Arg1 &a1, Arg2 *p2, const std::size_t newSize) {
0354         bool itemStatus = true;
0355         for (std::size_t i = 0; i < newSize && itemStatus; ++i)
0356           itemStatus = Visitor<Arg1, Arg2, T, InContainerCycle>::process(obj, a1, p2, i);
0357         return itemStatus;
0358       }
0359 #endif
0360     };
0361 
0362     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0363     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISPOD> {
0364       // POD-processing visitor
0365       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0366         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISPOD>>::process(obj, a1, p2, processClassId);
0367       }
0368     };
0369 
0370     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0371     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISWRITABLE> {
0372       // Processor of writable objects
0373       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0374         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISWRITABLE>>::process(obj, a1, p2, processClassId);
0375       }
0376     };
0377 
0378     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0379     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISPOINTER> {
0380       // There is not enough info here to decide how the pointer
0381       // should be managed. Therefore, just call the visitor.
0382       // However, turn on the class id writing because pointer
0383       // usually signifies polymorphic class.
0384       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, bool /* processClassId */) {
0385         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISPOINTER>>::process(obj, a1, p2, true);
0386       }
0387     };
0388 
0389     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0390     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISIOPTR> {
0391       // There is not enough info here to decide how the pointer
0392       // should be managed. Therefore, just call the visitor.
0393       // In this particular case, we are passing the "processClassId"
0394       // value as is.
0395       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0396         return Visitor<Arg1, Arg2, typename T::element_type *, Int2Type<IOTraits<int>::ISPOINTER>>::process(
0397             obj.getIOReference(), a1, p2, processClassId);
0398       }
0399     };
0400 
0401     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0402     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISSHAREDPTR> {
0403       // There is not enough info here to decide how the shared pointer
0404       // should be managed. Therefore, just call the visitor.
0405       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, bool /* processClassId */) {
0406         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISSHAREDPTR>>::process(obj, a1, p2, true);
0407       }
0408     };
0409 
0410     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0411     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISPAIR> {
0412       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0413         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISPAIR>>::process(obj, a1, p2, processClassId);
0414       }
0415     };
0416 
0417     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0418     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISTUPLE> {
0419       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0420         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISTUPLE>>::process(obj, a1, p2, processClassId);
0421       }
0422     };
0423 
0424     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0425     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISEXTERNAL> {
0426       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0427         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISEXTERNAL>>::process(obj, a1, p2, processClassId);
0428       }
0429     };
0430 
0431     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0432     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISSTRING> {
0433       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0434         return Visitor<Arg1, Arg2, T, Int2Type<IOTraits<int>::ISSTRING>>::process(obj, a1, p2, processClassId);
0435       }
0436     };
0437 
0438     // Processing of containers which do not support "write",
0439     // "read" or "restore"
0440     template <template <typename, typename, typename, typename> class Visitor, typename T, typename Arg1, typename Arg2>
0441     struct GENERS_GENERATED_IO_PROCESSOR<Visitor, T, Arg1, Arg2, IOTraits<int>::ISSTDCONTAINER> {
0442     private:
0443       // The following function will be fired on containers which
0444       // store PODs contiguously
0445       static bool process2(
0446           GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId, Int2Type<true>) {
0447         return Visitor<Arg1, Arg2, T, InPODArray>::process(obj, a1, p2, processClassId);
0448       }
0449 
0450       // The following function will be fired on containers which
0451       // do not not store PODs contiguously
0452       static bool process2(
0453           GENERS_GENERATED_IO_CONSTNESS T &v, Arg1 &a1, Arg2 *p2, const bool processClassId, Int2Type<false>) {
0454         GENERS_GENERATED_IO_CONSTNESS std::size_t sz = v.size();
0455         return Visitor<Arg1, Arg2, T, InContainerSize>::process(sz, a1, p2, processClassId) &&
0456                GENERS_CONTAINER_ITERATION_PROC<Visitor, T, Arg1, Arg2>::process(v, a1, p2, sz) && sz == v.size();
0457       }
0458 
0459     public:
0460       static bool process(GENERS_GENERATED_IO_CONSTNESS T &obj, Arg1 &a1, Arg2 *p2, const bool processClassId) {
0461         if (Visitor<Arg1, Arg2, T, InContainerHeader>::process(obj, a1, p2, processClassId)) {
0462           // Do generic container processing in case the container
0463           // either does not have contiguous storage or its items
0464           // are non-PODs. Otherwise do fast processing.
0465           bool bodyStatus = true, footerStatus = true;
0466           try {
0467             bodyStatus = process2(obj,
0468                                   a1,
0469                                   p2,
0470                                   processClassId,
0471                                   Int2Type < IOTraits<typename T::value_type>::IsPOD && IOTraits<T>::IsContiguous > ());
0472           } catch (...) {
0473             footerStatus = Visitor<Arg1, Arg2, T, InContainerFooter>::process(obj, a1, p2, processClassId);
0474             throw;
0475           }
0476           footerStatus = Visitor<Arg1, Arg2, T, InContainerFooter>::process(obj, a1, p2, processClassId);
0477           return bodyStatus && footerStatus;
0478         } else
0479           return false;
0480       }
0481     };
0482   }  // namespace Private
0483 }  // namespace gs
0484 
0485 #undef GENERS_GENERATED_IO_PROCESSOR
0486 #undef GENERS_GENERATED_IO_CONSTNESS
0487 #undef GENERS_CONTAINER_ITERATION_PROC
0488 #undef GENERS_GENERIC_ITEM_PROCESSOR
0489 
0490 #undef GENERS_GENERATE_CONST_IO_PROCESSOR
0491 
0492 #endif  // GENERS_PROCESSITEM_HH_