Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
#ifndef GENERS_FORWARD_LISTIO_HH_
#define GENERS_FORWARD_LISTIO_HH_

#include "Alignment/Geners/interface/CPP11_config.hh"
#ifdef CPP11_STD_AVAILABLE

#include <forward_list>
#include "Alignment/Geners/interface/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 <class Stream, class State, class T>
  struct GenericWriter<Stream, State, std::forward_list<T>, Int2Type<IOTraits<int>::ISEXTERNAL> > {
    inline static bool process(const std::forward_list<T>& s, Stream& os, State* p2, const bool processClassId) {
      typedef typename std::forward_list<T>::const_iterator Iter;

      bool status = processClassId ? ClassId::makeId<std::forward_list<T> >().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<T>().write(os);
          std::vector<Iter> 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<GenericWriter2>(*iters[number], os, p2, false);
        }
      }
      return status && !os.fail();
    }
  };

  template <class T>
  struct InsertContainerItem<std::forward_list<T> > {
    inline static void insert(std::forward_list<T>& obj, const T& item, const std::size_t /* itemNumber */) {
      obj.push_front(item);
    }
  };

  template <class Stream, class State, class T>
  struct GenericReader<Stream, State, std::forward_list<T>, Int2Type<IOTraits<int>::ISEXTERNAL> > {
    inline static bool readIntoPtr(std::forward_list<T>*& ptr, Stream& is, State* p2, const bool processClassId) {
      if (processClassId) {
        ClassId id(is, 1);
        const ClassId& curr = ClassId::makeId<std::forward_list<T> >();
        curr.ensureSameName(id);
      }
      std::unique_ptr<std::forward_list<T> > myptr;
      if (ptr == 0)
        myptr = std::unique_ptr<std::forward_list<T> >(new std::forward_list<T>());
      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<T>* nzptr = ptr ? ptr : myptr.get();
        try {
          for (std::size_t i = 0; i < sz && itemStatus; ++i)
            itemStatus =
                GenericReader<Stream, State, std::forward_list<T>, 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<T>& s, Stream& is, State* st, const bool processClassId) {
      std::forward_list<T>* ps = &s;
      return readIntoPtr(ps, is, st, processClassId);
    }
  };
}

#endif  // CPP11_STD_AVAILABLE
#endif  // GENERS_FORWARD_LISTIO_HH_