#pragma once #include #include #include #include #include #include namespace rng { template inline void shuffle(R& rng, span span) { if(!span.size()) return; std::cout << " -> shuffling " << span.size() << " objects..."; for(std::size_t i=span.size()-1;i>0;i--) { auto j = rng.next_long(i); std::swap(span[i], span[j]); } std::cout << " OK" << std::endl; } namespace { extern "C" int _can_allocate(std::size_t bytes); template inline bool can_allocate(std::size_t len) { return !!_can_allocate(len*sizeof(T)); } } template inline void unshuffle(R& rng, span span) { if(!span.size()) return; #if defined(_FS_SPILL_BUFFER) && _FS_SPILL_BUFFER == DYN dynamic_spill_vector rng_values = can_allocate(span.size()) //Is there any way we can not waste this malloc() when it's valid? ? dynamic_spill_vector (span.size()) : dynamic_spill_vector (FSV_DEFAULT_SPILL_AT); #elif defined(_FS_SPILL_BUFFER) fixed_spill_vector rng_values; #else std::vector rng_values; rng_values.reserve(span.size()); #endif std::cout << " -> unshuffling " << span.size() << " objects..."; for(std::size_t i=span.size()-1;i>0;i--) rng_values.push_back(rng.next_long(i)); for(std::size_t i=1;i