#ifndef GENERS_FORWARD_LISTIO_HH_ #define GENERS_FORWARD_LISTIO_HH_ #include "geners/CPP11_config.hh" #ifdef CPP11_STD_AVAILABLE #include #include "geners/GenericIO.hh" // std::forward_list does not have the size() method. Because of this, // we can not use the I/O machinery developed in "GenericIO.hh" for // standard containers. Instead, we will designate std::forward_list // as an external type and will handle it separately. // gs_declare_template_external_TT(std::forward_list) gs_specialize_template_id_TT(std::forward_list, 0, 1) namespace gs { // Assuming that we want to write the list once and potentially // read it back many times, we will write it out in the reverse // order. This is because it is easy to extend the list from the // front but not from the back. // template struct GenericWriter, Int2Type::ISEXTERNAL> > { inline static bool process(const std::forward_list& s, Stream& os, State* p2, const bool processClassId) { typedef typename std::forward_list::const_iterator Iter; bool status = processClassId ? ClassId::makeId >().write(os) : true; if (status) { const Iter listend = s.end(); std::size_t sz = 0; for (Iter it=s.begin(); it!=listend; ++it, ++sz) {;} write_pod(os, sz); if (sz) { status = ClassId::makeId().write(os); std::vector iters(sz); sz = 0; for (Iter it=s.begin(); it!=listend; ++it, ++sz) iters[sz] = it; for (long long number=sz-1; number>=0 && status; --number) status = process_const_item( *iters[number], os, p2, false); } } return status && !os.fail(); } }; template struct InsertContainerItem > { inline static void insert(std::forward_list& obj, const T& item, const std::size_t /* itemNumber */) {obj.push_front(item);} }; template struct GenericReader, Int2Type::ISEXTERNAL> > { inline static bool readIntoPtr(std::forward_list*& ptr, Stream& is, State* p2, const bool processClassId) { if (processClassId) { ClassId id(is, 1); const ClassId& curr = ClassId::makeId >(); curr.ensureSameName(id); } CPP11_auto_ptr > myptr; if (ptr == 0) myptr = CPP11_auto_ptr >( new std::forward_list()); else ptr->clear(); std::size_t sz = 0; read_pod(is, &sz); bool itemStatus = true; if (sz) { ClassId itemId(is, 1); p2->push_back(itemId); std::forward_list* nzptr = ptr ? ptr : myptr.get(); try { for (std::size_t i=0; i < sz && itemStatus; ++i) itemStatus = GenericReader< Stream,State,std::forward_list,InContainerCycle >::process(*nzptr, is, p2, i); } catch (...) { p2->pop_back(); throw; } } const bool success = itemStatus && !is.fail(); if (success && ptr == 0) ptr = myptr.release(); return success; } inline static bool process(std::forward_list& s, Stream& is, State* st, const bool processClassId) { std::forward_list* ps = &s; return readIntoPtr(ps, is, st, processClassId); } }; } #endif // CPP11_STD_AVAILABLE #endif // GENERS_FORWARD_LISTIO_HH_