Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef GENERS_FORWARD_LISTIO_HH_
0002 #define GENERS_FORWARD_LISTIO_HH_
0003 
0004 #include "Alignment/Geners/interface/CPP11_config.hh"
0005 #ifdef CPP11_STD_AVAILABLE
0006 
0007 #include <forward_list>
0008 #include "Alignment/Geners/interface/GenericIO.hh"
0009 
0010 // std::forward_list does not have the size() method. Because of this,
0011 // we can not use the I/O machinery developed in "GenericIO.hh" for
0012 // standard containers. Instead, we will designate std::forward_list
0013 // as an external type and will handle it separately.
0014 //
0015 gs_declare_template_external_TT(std::forward_list)
0016 gs_specialize_template_id_TT(std::forward_list, 0, 1)
0017 
0018 namespace gs {
0019     // Assuming that we want to write the list once and potentially
0020     // read it back many times, we will write it out in the reverse
0021     // order. This is because it is easy to extend the list from the
0022     // front but not from the back.
0023     //
0024     template <class Stream, class State, class T>
0025     struct GenericWriter<Stream, State, std::forward_list<T>,
0026                          Int2Type<IOTraits<int>::ISEXTERNAL> >
0027     {
0028         inline static bool process(const std::forward_list<T>& s, Stream& os,
0029                                    State* p2, const bool processClassId)
0030         {
0031             typedef typename std::forward_list<T>::const_iterator Iter;
0032 
0033             bool status = processClassId ? 
0034                 ClassId::makeId<std::forward_list<T> >().write(os) : true;
0035             if (status)
0036             {
0037                 const Iter listend = s.end();
0038                 std::size_t sz = 0;
0039                 for (Iter it=s.begin(); it!=listend; ++it, ++sz) {;}
0040                 write_pod(os, sz);
0041                 if (sz)
0042                 {
0043                     status = ClassId::makeId<T>().write(os);
0044                     std::vector<Iter> iters(sz);
0045                     sz = 0;
0046                     for (Iter it=s.begin(); it!=listend; ++it, ++sz)
0047                         iters[sz] = it;
0048                     for (long long number=sz-1; number>=0 && status; --number)
0049                         status = process_const_item<GenericWriter2>(
0050                             *iters[number], os, p2, false);
0051                 }
0052             }
0053             return status && !os.fail();
0054         }
0055     };
0056 
0057     template <class T>
0058     struct InsertContainerItem<std::forward_list<T> >
0059     {
0060         inline static void insert(std::forward_list<T>& obj, const T& item,
0061                                   const std::size_t /* itemNumber */)
0062             {obj.push_front(item);}
0063     };
0064 
0065     template <class Stream, class State, class T>
0066     struct GenericReader<Stream, State, std::forward_list<T>,
0067                          Int2Type<IOTraits<int>::ISEXTERNAL> >
0068     {
0069         inline static bool readIntoPtr(std::forward_list<T>*& ptr, Stream& is,
0070                                        State* p2, const bool processClassId)
0071         {
0072             if (processClassId)
0073             {
0074                 ClassId id(is, 1);
0075                 const ClassId& curr = ClassId::makeId<std::forward_list<T> >();
0076                 curr.ensureSameName(id);
0077             }
0078             CPP11_auto_ptr<std::forward_list<T> > myptr;
0079             if (ptr == 0)
0080                 myptr = CPP11_auto_ptr<std::forward_list<T> >(
0081                     new std::forward_list<T>());
0082             else
0083                 ptr->clear();
0084             std::size_t sz = 0;
0085             read_pod(is, &sz);
0086             bool itemStatus = true;
0087             if (sz)
0088             {
0089                 ClassId itemId(is, 1);
0090                 p2->push_back(itemId);
0091                 std::forward_list<T>* nzptr = ptr ? ptr : myptr.get();
0092                 try
0093                 {
0094                     for (std::size_t i=0; i < sz && itemStatus; ++i)
0095                         itemStatus = GenericReader<
0096                              Stream,State,std::forward_list<T>,InContainerCycle
0097                         >::process(*nzptr, is, p2, i);
0098                 }
0099                 catch (...)
0100                 {
0101                     p2->pop_back();
0102                     throw;
0103                 }
0104             }
0105             const bool success = itemStatus && !is.fail();
0106             if (success && ptr == 0)
0107                 ptr = myptr.release();
0108             return success;
0109         }
0110 
0111         inline static bool process(std::forward_list<T>& s, Stream& is,
0112                                    State* st, const bool processClassId)
0113         {
0114             std::forward_list<T>* ps = &s;
0115             return readIntoPtr(ps, is, st, processClassId);
0116         }
0117     };
0118 }
0119 
0120 #endif // CPP11_STD_AVAILABLE
0121 #endif // GENERS_FORWARD_LISTIO_HH_
0122