Random for modern C++ with convenient API

Overview

Random for modern C++ with convenient API

Build Status Build status Coverage Status Coverity Scan Build Status

Design goals

There are few ways to get working with random in C++:

  • C style
  srand( time(NULL) ); // seed with time since epoch
  auto random_number = (rand() % (9 - 1)) + 1; // get a pseudo-random integer between 1 and 9
  • C++11 style
  std::random_device random_device; // create object for seeding
  std::mt19937 engine{random_device()}; // create engine and seed it
  std::uniform_int_distribution<> dist(1,9); // create distribution for integers with [1; 9] range
  auto random_number = dist(engine); // finally get a pseudo-random integer number
  • Problems
    • should specify seed
    • should choose, create and use a chain of various objects like engines and distributions
    • mt19937 use 5000 bytes of memory for each creation (which is bad for performance if we create it too frequently)
    • uncomfortable and not intuitively clear usage
  • effolkronium random style
  // auto seeded
  auto random_number = Random::get(1, 9); // invoke 'get' method to generate a pseudo-random integer in [1; 9] range
  // yep, that's all.
  • Advantages
    • Intuitive syntax. You can do almost everything with random by simple 'get' method, like getting simple numbers, bools, random object from given set or using custom distribution.
    • Trivial integration. All code consists of a single header file random.hpp. That's it. No library, no subproject, no dependencies, no complex build system. The class is written in vanilla C++11. All in all, everything should require no adjustment of your compiler flags or project settings.
    • Usability. There are 3 versions of random:
      • random_static which has static methods and static internal state. It's not thread safe but more efficient
      • random_thread_local which has static methods and thread_local internal state. It's thread safe but less efficient
      • random_local which has non static methods and local internal state. It can be created on the stack at local scope

Supported compilers

  • GCC 4.9 - 8.0 (and possibly later)
  • Clang 3.7 - 8.0 (and possibly later)
  • Microsoft Visual C++ 2015 - 2019 (and possibly later)

Integration

CMake

  • As subproject
add_subdirectory(random) # path to the 'random' library root
... # create target
target_link_libraries(${TARGET} effolkronium_random) # add include path to a compiler
  • As external project

First of all, build or|and install this project:

cd "path_to_root_of_the_library"
mkdir build
cd build
cmake -G"Visual Studio 15 2017" ..
cmake --build . --target install --config Release
ctest -C Release

Then, find the package by a cmake

find_package(effolkronium_random REQUIRED)
... # create target
target_link_libraries(${TARGET} effolkronium_random)

Manually

The single required source, file random.hpp is in the include/effolkronium directory.

Then

All you need to do is add

#include "effolkronium/random.hpp"

// get base random alias which is auto seeded and has static API and internal state
using Random = effolkronium::random_static;

to the files you want to use effolkronium random class. That's it. Do not forget to set the necessary switches to enable C++11 (e.g., -std=c++11 for GCC and Clang).

Five-minute tutorial

Number range

Returns a pseudo-random number in a [first; second] range.

auto val = Random::get(-1, 1) // decltype(val) is int
// specify explicit type
auto val = Random::get<uint8_t>(-1, 1) // decltype(val) is uint8_t
// you able to use range from greater to lower
auto val = Random::get(1.l, -1.l) // decltype(val) is long double
auto val = Random::get(1.f, -1) // Error: implicit conversions are not allowed here.

Common type number range

Choose common type of two range arguments by std::common_type.

auto val = Random::get<Random::common>(1, 0.f) // decltype(val) is float
auto val = Random::get<Random::common>(0ul, 1ull) // decltype(val) is unsigned long long
auto val = Random::get<Random::common>(1.2l, 1.5f) // decltype(val) is long double
auto val = Random::get<Random::common>(1u, -1) // Error: prevent conversion from signed to unsigned.

Character range

Returns a pseudo-random character in a [first; second] range.

auto val = Random::get('a', 'z')
auto val = Random::get(L'', L'')
auto val = Random::get<wchar_t>()

Bool

Generate true with [0; 1] probability

auto val = Random::get<bool>(0.7) // true with 70% probability
auto val = Random::get<bool>() // true with 50% probability by default
auto val = Random::get<bool>(-1) // Error: assert occurred! Out of [0; 1] range

Random value from std::initializer_list

Return random value from values in a std::initializer_list

auto val = Random::get({1, 2, 3}) // val = 1 or 2 or 3

Random iterator

Return random iterator from iterator range or container. Iterator must be at least Input iterator. If a std::distance(first, last) == 0, return the 'last' iterator. If container is empty, return std::end(container) iterator.

std::array<int, 3> array{ {1, 2, 3} };
  • Iterator range
auto randomIt = Random::get( array.begin(), array.end() );
  • Container
auto randomIt = Random::get( array );

Random element from array

Return pointer to random element in built-in array

int array [] = {1, 2, 3};
auto randomPtr = Random::get( array );

Container of random values

Return container filled with random numbers. Any containers with "begin", "end" and "insert" methods are applicable

auto vec = Random::get<std::vector>(1, 9, 5); // decltype(vec) is std::vector<int> with size = 5
// Note: "reserve" method invokes automatically for performance

auto mset = Random::get<std::multiset>(1.0, 9.9, 10); // decltype(mset) is std::multiset<double> with size = 10

auto arr = Random::get<std::array, 5>('0', '9'); // decltype(arr) is std::array<char, 5>
// Warning: Returning arrays with large size could be ineficcient

auto vec = Random::get<std::vector>(1l, 9ll, 5); // decltype(vec) is std::vector<long long> with size = 5

template<typename T>
class MyContainer
{
    iterator begin() {...}
    iterator end() {...}
    void insert(iterator after, T value) {...}
};

auto vec = Random::get<MyContainer>(1, 9, 5); // decltype(vec) is std::MyContainer<int> with size = 5

Shuffle

Reorders the elements in a given range or in all container ref

std::array<int, 3> array{ {1, 2, 3} };
  • Iterator range
Random::shuffle( array.begin( ), array.end( ) )
  • Container
Random::shuffle( array )

Custom distribution

Return result from operator() of a distribution with internal random engine argument

  • Template argument
// 1.f and 2.f will be forwarded to std::gamma_distribution constructor
auto result = Random::get<std::gamma_distribution<>>( 1.f, 2.f );
  • Argument by reference
std::gamma_distribution<> gamma{ 1.f, 2.f };
auto result = Random::get( gamma ); // return result of gamma.operator()( engine_ )

Custom Seeder

Specify seed by which random engine will be seeded at construction time:

  • Number
struct MySeeder {
    unsigned operator() () {
        return 42u;
    }
};
    
// Seeded by 42
using Random = effolkronium::basic_random_static<std::mt19937, MySeeder>;
  • Seed sequence

Because we can't copy std::seed_seq, the 'random' library destroy seeder instance after engine seeding. So it's safe to return seed by reference.

struct MySeeder {
    // std::seed_seq isn't copyable
    std::seed_seq& operator() () {
        return seed_seq_;
    }
    std::seed_seq seed_seq_{ { 1, 2, 3, 4, 5 } };
};
    
// Seeded by seed_seq_ from MySeeder
using Random = effolkronium::basic_random_static<std::mt19937, MySeeder>;
  • Reseed

Seed an internal random engine by a newly created Seeder instance

Random::reseed( );

Thread local random

It uses static methods API and data with thread_local storage which is fully thread safe (but less perfomance)

using Random = effolkronium::random_thread_local

// use in the same way as random_static. Thread safe
std::thread first{ [ ] { Random::get( ); } };
std::thread second{ [ ] { Random::get( ); } };

Local random

It uses non static methods API and data with auto storage which can be created on the stack at local scope

#include "effolkronium/random.hpp"

using Random_t = effolkronium::random_local

int main( ) {
  Random_t localRandom{ }; // Construct on the stack
  
  // access throughout dot
  auto val = localRandom.get(-10, 10);
  
} // Destroy localRandom and free stack memory

Seeding

ref

Set new seed for an internal random engine.

Random::seed( 10 ); // 10 is new seed number

std::seed_seq sseq{ 1, 2, 3 };
Random::seed( sseq ); // use seed sequence here

Min value

ref

Returns the minimum value potentially generated by the internal random-number engine

auto minVal = Random::min( );

Max value

ref

Returns the maximum value potentially generated by the internal random-number engine

auto maxVal = Random::max( );

get without arguments

ref

Returns the random number in [ Random::min( ), Random::max ] range

auto val = Random::get( );
// val is random number in [ Random::min( ), Random::max ] range

engine

Returns reference to the internal engine.

auto& engine = Random::engine( );
std::sample(itBeg, itEnd, std::back_inserter(out), 5, Random::engine( ));

Get engine

Returns copy of internal engine.

auto engine = Random::get_engine( );

Discard

ref

Advances the internal engine's state by a specified amount. Equivalent to calling Random::get() N times and discarding the result.

Random::discard( 500 );

IsEqual

ref

Compares internal pseudo-random number engine with other pseudo-random number engine.

Random::Engine otherEngine;
bool isSame = Random::is_equal( otherEngine );

Serialize

ref

Serializes the internal state of the internal pseudo-random number engine as a sequence of decimal numbers separated by one or more spaces, and inserts it to the output stream. The fill character and the formatting flags of the stream are ignored and unaffected.

std::stringstream strStream;
Random::serialize( strStream ); // the strStream now contain internal state of the Random internal engine

Deserialize

ref

Restores the internal state of the internal pseudo-random number engine from the serialized representation, which was created by an earlier call to 'serialize' using a stream with the same imbued locale and the same CharT and Traits. If the input cannot be deserialized, internal engine is left unchanged and failbit is raised on input stream.

std::stringstream strStream;
Random::serialize( strStream );

// ...

Random::deserialize( strStream ); // Restore internal state of internal Random engine
Comments
  • Can't get it to work

    Can't get it to work

    #include <effolrandom.hpp> im icluding like this, i have changed to this so it doesnt get with random.hpp, but even if it used how you give us it gives me this eror error: 'Random' has not been declared image

    opened by TurgutHarunArslan 21
  • Add get() overload for built-in arrays

    Add get() overload for built-in arrays

    Hi,

    I added an overload of get() for built-in arrays. I know this isn’t completely necessary as we can already write get(std::begin(carray), std::end(carray) ) though I prefer less verbosity.

    I deliberated between returning a pointer or a reference. I decided to return a pointer for consistency with the other overloads; if we passed a built-in array as above it would return an iterator, and the container overload also returns an iterator.

    I’d be grateful for your feedback.

    If you like I’d be happy to write tests and update the documentation.

    Kind regards,

    Riccardo

    opened by ricky65 8
  • Add Visual Studio 2013 support?

    Add Visual Studio 2013 support?

    This is a long shot, so please don't hesitate to close without discussing too much, but what would be the chances this could be back-ported to Visual Studio 2013?

    I tried to hack it together myself, but I'm not familiar with constexpr enough to understand what it should be doing in the first place.

    opened by tankorsmash 6
  • seeder is created on every instance dereference

    seeder is created on every instance dereference

    Hi,

    I'm currently using your lib and overwrite the seeding function and ask myself, whether this is intended. E.g. the static engine has the following code:

            static Engine& engine_instance( ) {
                Seeder seeder{ };
                static Engine engine{ seeder( ) };
                return engine;
            }
        };
    

    this means, even if the engine is not created every time, the seeder is. I was simply confused that my seeding function was called more than once, when I debugged it. Is that intended? It might be expensive to always get data from random device, as in the default seeder

        /// Default seeder for 'random' classes
        struct seeder_default {
            /// return seed sequence
            std::seed_seq& operator() ( ) {
                // MinGW issue, std::random_device returns constant value
                // Use std::seed_seq with additional seed from C++ chrono
                return seed_seq;
            }
        private:
            std::seed_seq seed_seq{ {
                    static_cast<std::uintmax_t>( std::random_device{ }( ) ),
                    static_cast<std::uintmax_t>( std::chrono::steady_clock::now( )
                                                 .time_since_epoch( ).count( ) ),
            } };
        };
    

    Maybe the compiler is sometimes clever enough to omit the creation (as the variable is only used, when the static is initialized), but it would be the same result if the Seeder is also simply static, isn't it?

    bug 
    opened by BenjaminBeichler 5
  • support for wide characters

    support for wide characters

    I cannot use wchar_t directly, I can only cast between wchar_t and i.e. long long:

    #include <iostream>
    #include <codecvt>
    #include <locale>
    
    std::wstring ws;
    
    /* all characters from ㋐ to ㋾ */
    std::cout << "㋐㋑㋒㋓㋔㋕㋖㋗㋘㋙㋚㋛㋜㋝㋞㋟㋠㋡㋢㋣㋤㋥㋦㋧㋨㋩㋪㋫㋬㋭㋮㋯㋰㋱㋲㋳㋴㋵㋶㋷㋸㋹㋺㋻㋼㋽㋾" << std::endl;
    
    for (int i=0; i < 20; i++) {
      ws.push_back(Random::get<long long>(L'㋐', L'㋾'));
    }
    
    std::cout << std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(ws) << std::endl;
    

    In order to call Random::get<wchar_t>() I need to add wchar_t to struct is_uniform_int.

    opened by darealshinji 5
  • Update LICENSE.MIT year

    Update LICENSE.MIT year

    2020 is a bad year but this library isn't so keep with the great work dude ^^. Using this library in my CS career final project and it's pretty well done. Beautifull and easy syntax and usage

    opened by RubenRubioM 2
  • Suggestion: custom distribution for iterator

    Suggestion: custom distribution for iterator

    Right now, random iterator uses uniform distribution over container. I can imagine myself, that in some cases it might be useful to have possibility to apply custom distributions. For example, triangular distribution with the peak in the middle of array. I imagine that being used like already Random::get<std::*_distribution<>>(array.begin(), array.end()).

    enhancement 
    opened by krofik 2
  • Random iterator different behaviour with iterator range vs container

    Random iterator different behaviour with iterator range vs container

    Hi, thanks for the nice library, it's really useful I think I found a small bug though: random iterator using iterator range is non-const:

    #include "effolkronium/random.hpp"
    #include <vector>
    
    using Random = effolkronium::random_static;
    
    int main()
    {
      std::vector<int> v(10);
    
      // assign a value to a random element
      *Random::get(v.begin(), v.end()) = 1;
    }
    

    But if I get the random iterator using the "container" form, it seems to be const:

    #include "effolkronium/random.hpp"
    #include <vector>
    
    using Random = effolkronium::random_static;
    
    int main()
    {
      std::vector<int> v(10);
    
      // assign a value to a random element
      *Random::get(v) = 1; /// <<<<<<<<<< doesn't compile
    }
    

    Compiler error:

    src/Main2.cpp:11:19: error: assignment of read-only location 'effolkronium::basic_random_static<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get<std::vector<int> >(v).__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator*<const int*, std::vector<int> >()'
    
       *Random::get(v) = 1;
    

    Thanks

    opened by feedhandler 2
  • std::distance and unsigned compare

    std::distance and unsigned compare

    I'm running Ubuntu 18.04.1 LTS and gcc 7.3.0

    [email protected]:~/random/build$ cmake -DCMAKE_BUILD_TYPE=Release .. && make
    -- The CXX compiler identification is GNU 7.3.0
    -- Check for working CXX compiler: /usr/bin/c++
    -- Check for working CXX compiler: /usr/bin/c++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    -- The C compiler identification is GNU 7.3.0
    -- Check for working C compiler: /usr/bin/cc
    -- Check for working C compiler: /usr/bin/cc -- works
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Detecting C compile features
    -- Detecting C compile features - done
    -- Looking for pthread.h
    -- Looking for pthread.h - found
    -- Looking for pthread_create
    -- Looking for pthread_create - not found
    -- Looking for pthread_create in pthreads
    -- Looking for pthread_create in pthreads - not found
    -- Looking for pthread_create in pthread
    -- Looking for pthread_create in pthread - found
    -- Found Threads: TRUE
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/build/random/build
    Scanning dependencies of target random_thread_local_test
    [ 16%] Building CXX object test/CMakeFiles/random_thread_local_test.dir/random_test.cpp.o
    In file included from /home/build/random/test/current_random.hpp:1:0,
                     from /home/build/random/test/random_test.cpp:9:
    /home/build/random/test/../include/effolkronium/random.hpp: In instantiation of ‘static typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type effolkronium::basic_random_thread_local<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get(InputIt, InputIt) [with InputIt = int*; Engine = std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>; Seeder = effolkronium::seeder_default; IntegerDist = std::uniform_int_distribution; RealDist = std::uniform_real_distribution; BoolDist = std::bernoulli_distribution; typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type = int*]’:
    /home/build/random/test/random_test.cpp:622:68:   required from here
    /home/build/random/test/../include/effolkronium/random.hpp:788:20: error: conversion to ‘unsigned int’ from ‘int’ may change the sign of the result [-Werror=sign-conversion]
                 if( 0u == size ) return last;
                     ~~~^~~~~~~
    /home/build/random/test/../include/effolkronium/random.hpp: In instantiation of ‘static typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type effolkronium::basic_random_thread_local<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get(InputIt, InputIt) [with InputIt = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; Engine = std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>; Seeder = effolkronium::seeder_default; IntegerDist = std::uniform_int_distribution; RealDist = std::uniform_real_distribution; BoolDist = std::bernoulli_distribution; typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type = __gnu_cxx::__normal_iterator<int*, std::vector<int> >]’:
    /home/build/random/test/random_test.cpp:644:9:   required from here
    /home/build/random/test/../include/effolkronium/random.hpp:788:20: error: conversion to ‘unsigned int’ from ‘int’ may change the sign of the result [-Werror=sign-conversion]
    /home/build/random/test/../include/effolkronium/random.hpp: In instantiation of ‘static typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type effolkronium::basic_random_thread_local<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get(InputIt, InputIt) [with InputIt = const int*; Engine = std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>; Seeder = effolkronium::seeder_default; IntegerDist = std::uniform_int_distribution; RealDist = std::uniform_real_distribution; BoolDist = std::bernoulli_distribution; typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type = const int*]’:
    /home/build/random/test/../include/effolkronium/random.hpp:775:24:   required from ‘static T effolkronium::basic_random_thread_local<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get(std::initializer_list<T>) [with T = int; Engine = std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>; Seeder = effolkronium::seeder_default; IntegerDist = std::uniform_int_distribution; RealDist = std::uniform_real_distribution; BoolDist = std::bernoulli_distribution]’
    /home/build/random/test/random_test.cpp:337:45:   required from here
    /home/build/random/test/../include/effolkronium/random.hpp:788:20: error: conversion to ‘unsigned int’ from ‘int’ may change the sign of the result [-Werror=sign-conversion]
    /home/build/random/test/../include/effolkronium/random.hpp: In instantiation of ‘static typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type effolkronium::basic_random_thread_local<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get(InputIt, InputIt) [with InputIt = const ____C_A_T_C_H____T_E_S_T____32()::NoexceptMoveNoexceptCopy*; Engine = std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>; Seeder = effolkronium::seeder_default; IntegerDist = std::uniform_int_distribution; RealDist = std::uniform_real_distribution; BoolDist = std::bernoulli_distribution; typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type = const ____C_A_T_C_H____T_E_S_T____32()::NoexceptMoveNoexceptCopy*]’:
    /home/build/random/test/../include/effolkronium/random.hpp:775:24:   required from ‘static T effolkronium::basic_random_thread_local<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get(std::initializer_list<T>) [with T = ____C_A_T_C_H____T_E_S_T____32()::NoexceptMoveNoexceptCopy; Engine = std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>; Seeder = effolkronium::seeder_default; IntegerDist = std::uniform_int_distribution; RealDist = std::uniform_real_distribution; BoolDist = std::bernoulli_distribution]’
    /home/build/random/test/random_test.cpp:364:47:   required from here
    /home/build/random/test/../include/effolkronium/random.hpp:788:20: error: conversion to ‘unsigned int’ from ‘int’ may change the sign of the result [-Werror=sign-conversion]
    /home/build/random/test/../include/effolkronium/random.hpp: In instantiation of ‘static typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type effolkronium::basic_random_thread_local<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get(InputIt, InputIt) [with InputIt = const std::reference_wrapper<int>*; Engine = std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>; Seeder = effolkronium::seeder_default; IntegerDist = std::uniform_int_distribution; RealDist = std::uniform_real_distribution; BoolDist = std::bernoulli_distribution; typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type = const std::reference_wrapper<int>*]’:
    /home/build/random/test/../include/effolkronium/random.hpp:775:24:   required from ‘static T effolkronium::basic_random_thread_local<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get(std::initializer_list<T>) [with T = std::reference_wrapper<int>; Engine = std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>; Seeder = effolkronium::seeder_default; IntegerDist = std::uniform_int_distribution; RealDist = std::uniform_real_distribution; BoolDist = std::bernoulli_distribution]’
    /home/build/random/test/random_test.cpp:371:50:   required from here
    /home/build/random/test/../include/effolkronium/random.hpp:788:20: error: conversion to ‘unsigned int’ from ‘int’ may change the sign of the result [-Werror=sign-conversion]
    /home/build/random/test/../include/effolkronium/random.hpp: In instantiation of ‘static typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type effolkronium::basic_random_thread_local<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get(InputIt, InputIt) [with InputIt = int* const*; Engine = std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>; Seeder = effolkronium::seeder_default; IntegerDist = std::uniform_int_distribution; RealDist = std::uniform_real_distribution; BoolDist = std::bernoulli_distribution; typename std::enable_if<effolkronium::details::is_iterator<InputIt>::value, InputIt>::type = int* const*]’:
    /home/build/random/test/../include/effolkronium/random.hpp:775:24:   required from ‘static T effolkronium::basic_random_thread_local<Engine, Seeder, IntegerDist, RealDist, BoolDist>::get(std::initializer_list<T>) [with T = int*; Engine = std::mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>; Seeder = effolkronium::seeder_default; IntegerDist = std::uniform_int_distribution; RealDist = std::uniform_real_distribution; BoolDist = std::bernoulli_distribution]’
    /home/build/random/test/random_test.cpp:378:39:   required from here
    /home/build/random/test/../include/effolkronium/random.hpp:788:20: error: conversion to ‘unsigned int’ from ‘int’ may change the sign of the result [-Werror=sign-conversion]
    cc1plus: all warnings being treated as errors
    test/CMakeFiles/random_thread_local_test.dir/build.make:62: recipe for target 'test/CMakeFiles/random_thread_local_test.dir/random_test.cpp.o' failed
    make[2]: *** [test/CMakeFiles/random_thread_local_test.dir/random_test.cpp.o] Error 1
    CMakeFiles/Makefile2:89: recipe for target 'test/CMakeFiles/random_thread_local_test.dir/all' failed
    make[1]: *** [test/CMakeFiles/random_thread_local_test.dir/all] Error 2
    Makefile:140: recipe for target 'all' failed
    make: *** [all] Error 2
    

    Tests're failing because of the -Werror and signed-unsigned compare. Specifically std::distance result (can be negative) with unsigned zero in a few places.

    I also tested with older gcc 6.3.0 and there're no problems.

    https://github.com/effolkronium/random/blob/985de84de4ec891ce060c4c6579cf70d3c1c86e2/include/effolkronium/random.hpp#L418

    https://github.com/effolkronium/random/blob/985de84de4ec891ce060c4c6579cf70d3c1c86e2/include/effolkronium/random.hpp#L788

    https://github.com/effolkronium/random/blob/985de84de4ec891ce060c4c6579cf70d3c1c86e2/include/effolkronium/random.hpp#L1156

    opened by gouranga 2
  • Use Construct On First Use idiom for static and thread local randoms

    Use Construct On First Use idiom for static and thread local randoms

    This prevents static initialization order issues. Test case for such an issue:

    1.cpp

    #include <iostream>
    
    int getThatInt();
    
    int theInt = getThatInt();
    
    int main()
    {
        std::cout << theInt<< std::endl;
    }
    

    2.cpp

    #include <effolkronium/random.hpp>
    
    int getThatInt()
    {
        return effolkronium::random_static::get(1, 1000);
    }
    

    compile with

    g++ 1.cpp 2.cpp

    and run the executable.

    opened by khuttun 2
  • Typo `std::initilizer_list` instead of `std::initializer list`

    Typo `std::initilizer_list` instead of `std::initializer list`

    opened by cooky922 1
Releases(v1.4.1)
Owner
Ilya Polishchuk
Hi
Ilya Polishchuk
Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)

KFR - Fast, modern C++ DSP framework Compiler support: https://www.kfr.dev KFR is an open source C++ DSP framework that focuses on high performance (s

KFR 1.3k Nov 18, 2022
A modern, C++20-native, single-file header-only dense 2D matrix library.

A modern, C++20-native, single-file header-only dense 2D matrix library. Contents Example usage creating matrices basic operations row, col, size, sha

feng wang 57 Oct 29, 2022
Kraken is an open-source modern math library that comes with a fast-fixed matrix class and math-related functions.

Kraken ?? Table of Contents Introduction Requirement Contents Installation Introduction Kraken is a modern math library written in a way that gives ac

yahya mohammed 25 Aug 26, 2022
Random for modern C++ with convenient API

Random for modern C++ with convenient API Design goals Supported compilers Integration Five-minute tutorial Number range Common type number range Char

Ilya Polishchuk 728 Nov 19, 2022
C++ networking library including UniConf and a convenient D-Bus API

This is wvstreams, a nominally platform-independent networking and utilities library for C++. Some documentation is in the Docs/ directory. If that

null 27 Dec 29, 2021
Convenient unified display of the most relevant technical and tag data for video and audio files.

MediaInfoLib README MediaInfo(Lib) is a convenient unified display of the most relevant technical and tag data for video and audio files. MediaInfoLib

MediaArea 489 Nov 24, 2022
A computationally efficient and convenient toolkit of iterated Kalman filter.

IKFoM IKFoM (Iterated Kalman Filters on Manifolds) is a computationally efficient and convenient toolkit for deploying iterated Kalman filters on vari

HKU-Mars-Lab 204 Nov 17, 2022
Convenient generic print() for C

generic-print Convenient generic print() for C inspired by Python/JavaScript and other high-level languages. Still using printf("%i\n", result) for de

exebook 304 Nov 19, 2022
🥑 ArangoDB is a native multi-model database with flexible data models for documents, graphs, and key-values. Build high performance applications using a convenient SQL-like query language or JavaScript extensions.

?? ArangoDB is a native multi-model database with flexible data models for documents, graphs, and key-values. Build high performance applications using a convenient SQL-like query language or JavaScript extensions.

ArangoDB 12.7k Nov 28, 2022
Small and convenient C2 tool for Windows targets

Micro Backdoor for Windows Micro Backdoor is C2 tool for Windows targets with easy customizable code base and small footprint. Micro Backdoor consists

Dmytro Oleksiuk 458 Nov 24, 2022
Memory Process File System (MemProcFS) is an easy and convenient way of viewing physical memory as files in a virtual file system

The Memory Process File System (MemProcFS) is an easy and convenient way of viewing physical memory as files in a virtual file system.

Ulf Frisk 1.6k Nov 22, 2022
Just a repository convenient for reviewing and retrieval practice.

The-art-of-multiprocessor-programming Purpose Just a repository convenient for reviewing and retrieval practice. The architecture of this repository(H

null 1 Nov 9, 2021
Convenient, high-performance RGB color and position control for console output

Oof (omnipotent output friend) It's common for C++ programs to write output to the console. But consoles are far more capable than what they are usual

Sebastian Werhausen 770 Nov 26, 2022
A Fast and Convenient C++ Logging Library for Low-latency or Real-time Environments

xtr What is it? XTR is a C++ logging library aimed at applications with low-latency or real-time requirements. The cost of log statements is minimised

null 10 Jul 17, 2022
Arduino library for providing a convenient C++ interface for accessing UAVCAN.

107-Arduino-UAVCAN Arduino library for providing a convenient C++ interface for accessing UAVCAN (v1.0-beta) utilizing libcanard. This library works f

107-Systems 52 Nov 2, 2022
xsnip - a minimal and convenient screenshot utility for X11

xsnip - a minimal and convenient screenshot utility for X11 Most screenshot utilities compatible with X are clumsy, use bloated toolkits, and often do

null 25 Sep 8, 2022
Webdav-client-cpp - C++ WebDAV Client provides easy and convenient to work with WebDAV-servers.

WebDAV Client Package WebDAV Client provides easy and convenient to work with WebDAV-servers: Yandex.Disk Dropbox Google Drive Box 4shared ownCloud ..

Cloud Polis 102 Oct 1, 2022
DirectX 11 library that provides convenient access to compute-based triangle filtering (CTF)

AMD GeometryFX The GeometryFX library provides convenient access to compute-based triangle filtering (CTF), which improves triangle throughput by filt

GPUOpen Effects 218 Oct 6, 2022
Random access array of tightly packed unsigned integers

PackedArray: random access array of tightly packed unsigned integers TLDR PackedArray comes to the rescue when you're in a desperate need for an uint9

Gregory Pakosz 137 Nov 11, 2022