#include <vector>
#include <deque>
#include <array>

//#include <boost/container/vector.hpp>
//#include <boost/container/deque.hpp>

#include <boost/double_ended/devector.hpp>
#include <boost/double_ended/batch_deque.hpp>
#include <boost/double_ended/serialize_devector.hpp>
#include <boost/double_ended/serialize_batch_deque.hpp>

#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/null.hpp>

#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/deque.hpp>

#include <benchmark/benchmark.h>

namespace {

template <typename Container>
void serialize_container(benchmark::State& state)
{
  while (state.KeepRunning()) {
    state.PauseTiming();

    boost::iostreams::stream<boost::iostreams::null_sink> stream;

    Container c(state.range(0));

    state.ResumeTiming();
    {
      boost::archive::binary_oarchive out(stream);
      out << c;
    }
  }
}

BENCHMARK_TEMPLATE(serialize_container, boost::double_ended::devector<char>)->Range(8, 8 << 12);
BENCHMARK_TEMPLATE(serialize_container, boost::double_ended::devector<int>)->Range(8, 8 << 12);
BENCHMARK_TEMPLATE(serialize_container, boost::double_ended::devector<std::array<char, 32>>)->Range(8, 8 << 12);

BENCHMARK_TEMPLATE(serialize_container, boost::double_ended::batch_deque<char>)->Range(8, 8 << 12);
BENCHMARK_TEMPLATE(serialize_container, boost::double_ended::batch_deque<int>)->Range(8, 8 << 12);
BENCHMARK_TEMPLATE(serialize_container, boost::double_ended::batch_deque<std::array<char, 32>>)->Range(8, 8 << 12);

BENCHMARK_TEMPLATE(serialize_container, std::vector<char>)->Range(8, 8 << 12);
BENCHMARK_TEMPLATE(serialize_container, std::vector<int>)->Range(8, 8 << 12);
BENCHMARK_TEMPLATE(serialize_container, std::vector<std::array<char, 32>>)->Range(8, 8 << 12);

BENCHMARK_TEMPLATE(serialize_container, std::deque<char>)->Range(8, 8 << 12);
BENCHMARK_TEMPLATE(serialize_container, std::deque<int>)->Range(8, 8 << 12);
BENCHMARK_TEMPLATE(serialize_container, std::deque<std::array<char, 32>>)->Range(8, 8 << 12);

} // namespace

BENCHMARK_MAIN();
