// Copyright (C) 2020-2021 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3.  If not see
// <http://www.gnu.org/licenses/>.


#include <random>
#include <testsuite_performance.h>

namespace counters
{
  __gnu_test::time_counter time;
  __gnu_test::resource_counter resource;
}


template<typename Dist, typename Engine>
void do_fill_with_uniform_ints(std::string name, Dist& d, Engine& e)
{
  using counters::time;
  using counters::resource;

  std::vector<typename Dist::result_type> r;
  int n = 10000000;
  {
    const auto suffix = "-e" + std::to_string((int)std::log10(n));
    r.resize(n);

    start_counters(time, resource);
    for (auto& x : r)
      x = d(e);
    stop_counters(time, resource);
    report_performance(__FILE__, name+suffix, time, resource);
    clear_counters(time, resource);

    d.reset();

    start_counters(time, resource);
    d.__generate(begin(r), end(r), e);
    stop_counters(time, resource);
    report_performance(__FILE__, name+"-range"+suffix, time, resource);
    clear_counters(time, resource);
  }
}

template<typename Engine>
void fill_with_uniform_ints(std::string name, Engine& e)
{
  using Dist = std::uniform_int_distribution<typename Engine::result_type>;
  using param_type = typename Dist::param_type;

  unsigned maxima[]{6, 10, 32, 100, 1000, 1024, (1<<16)-1, 1<<16, 1<<20, -1u};
  for (auto hi : maxima)
  {
    Dist dist(param_type{0, hi});
    std::ostringstream s;
    s << name << "-uniform_int-" << (dist.max() - dist.min());
    do_fill_with_uniform_ints(s.str(), dist, e);
  }
}

int main()
{
  using namespace std;

  std::mt19937 mt;
  fill_with_uniform_ints("mt19937", mt);
  std::mt19937_64 mt64;
  fill_with_uniform_ints("mt19937_64", mt64);

  // Same as std::mt19937 but using uint32_t not uint_fast32_t for result_type
  using mt19937_32 = std::mersenne_twister_engine<uint32_t, 32, 624, 397, 31,
                                                  0x9908b0df, 11, 0xffffffff,
                                                  7, 0x9d2c5680, 15,
                                                  0xefc60000, 18, 1812433253>;
  mt19937_32 mt32;
  fill_with_uniform_ints("mt19937_32", mt32);

  std::minstd_rand0 lcg;
  fill_with_uniform_ints("minstd_rand0", lcg);

  // Same as std::minstd_rand0 but using uint32_t not uint_fast32_t
  using minstd_rand0_32 = std::linear_congruential_engine<uint32_t, 48271, 0,
                                                          2147483647>;
  minstd_rand0_32 lcg_32;
  fill_with_uniform_ints("minstd_rand0_32", lcg_32);

  return 0;
}

