13
13
#include " utf8_string.hpp"
14
14
#include " utf8.h"
15
15
16
- #include < atomic>
17
16
#include < cstdlib>
17
+ #include < climits>
18
18
#include < cmath>
19
19
#include < cctype>
20
20
#include < sstream>
29
29
#include " wincrypt.h"
30
30
#endif
31
31
32
+ #if defined __GNUC__ && ! defined __llvm__
33
+ #define GCC_VERSION (__GNUC__ * 10000 \
34
+ + __GNUC_MINOR__ * 100 \
35
+ + __GNUC_PATCHLEVEL__)
36
+ #if GCC_VERSION < 40500
37
+ #include < tr1/random>
38
+ #define IMPLEMENT_TR1
39
+ #define tr1ns std::tr1
40
+ #define uniform_real_distribution uniform_real
41
+ #else
42
+ #include < random>
43
+ #define tr1ns std
44
+ #endif
45
+ #else
46
+ #include < random>
47
+ #define tr1ns std
48
+ #endif
49
+
32
50
#define ARG (argname, argtype ) get_arg<argtype>(argname, env, sig, pstate, backtrace)
33
51
#define ARGR (argname, argtype, lo, hi ) get_arg_r(argname, env, sig, pstate, lo, hi, backtrace)
34
52
#define ARGM (argname, argtype, ctx ) get_arg_m(argname, env, sig, pstate, backtrace, ctx)
@@ -211,7 +229,7 @@ namespace Sass {
211
229
return seed;
212
230
}
213
231
#else
214
- static std ::random_device rd;
232
+ static tr1ns ::random_device rd;
215
233
uint64_t GetSeed ()
216
234
{
217
235
return rd ();
@@ -222,9 +240,42 @@ namespace Sass {
222
240
// random_device degrades sharply once the entropy pool
223
241
// is exhausted. For practical use, random_device is
224
242
// generally only used to seed a PRNG such as mt19937.
225
- static std::mt19937 rand (static_cast <unsigned int >(GetSeed()));
243
+ static tr1ns::mt19937 rand (static_cast <unsigned int >(GetSeed()));
244
+
245
+ tr1ns::uniform_real_distribution<> std_dist (0 , 1 );
246
+ #ifdef IMPLEMENT_TR1
247
+ tr1ns::variate_generator <
248
+ tr1ns::mt19937,
249
+ tr1ns::uniform_real_distribution <double >
250
+ > gen_std_dist (rand, std_dist);
251
+ #endif
252
+
253
+ tr1ns::uniform_real_distribution<> full_dist (0 , ULONG_MAX);
254
+ #ifdef IMPLEMENT_TR1
255
+ tr1ns::variate_generator <
256
+ tr1ns::mt19937,
257
+ tr1ns::uniform_real_distribution <double >
258
+ > gen_full_dist (rand, full_dist);
259
+ #endif
226
260
227
- // features
261
+ // helper function to retrieve a random number in interval
262
+ // works around some compiler issues with older gcc versions
263
+ static double random (double min, double max)
264
+ {
265
+ tr1ns::uniform_real_distribution<> distributor (min, max);
266
+ #ifdef IMPLEMENT_TR1
267
+ tr1ns::variate_generator <
268
+ tr1ns::mt19937,
269
+ tr1ns::uniform_real_distribution <>
270
+ > gen (rand, distributor);
271
+ distributor (rand);
272
+ return gen ();
273
+ #else
274
+ return distributor (rand);
275
+ #endif
276
+ }
277
+
278
+ // supported features lookup table
228
279
static std::set<std::string> features {
229
280
" global-variable-shadowing" ,
230
281
" extend-selector-pseudoclass" ,
@@ -1170,13 +1221,15 @@ namespace Sass {
1170
1221
err << " Expected $limit to be an integer but got `" << v << " ` for `random`" ;
1171
1222
error (err.str (), pstate);
1172
1223
}
1173
- std::uniform_real_distribution<> distributor (1 , v + 1 );
1174
- uint_fast32_t distributed = static_cast <uint_fast32_t >(distributor (rand));
1175
- return SASS_MEMORY_NEW (ctx.mem , Number, pstate, (double )distributed);
1224
+ uint_fast32_t distributed = random (1 , v + 1 );
1225
+ return SASS_MEMORY_NEW (ctx.mem , Number, pstate, distributed);
1176
1226
}
1177
1227
else {
1178
- std::uniform_real_distribution<> distributor (0 , 1 );
1179
- double distributed = static_cast <double >(distributor (rand));
1228
+ #ifdef IMPLEMENT_TR1
1229
+ double distributed = gen_std_dist ();
1230
+ #else
1231
+ double distributed = std_dist (rand);
1232
+ #endif
1180
1233
return SASS_MEMORY_NEW (ctx.mem , Number, pstate, distributed);
1181
1234
}
1182
1235
}
@@ -1906,8 +1959,11 @@ namespace Sass {
1906
1959
BUILT_IN (unique_id)
1907
1960
{
1908
1961
std::stringstream ss;
1909
- std::uniform_real_distribution<> distributor (0 , 4294967296 ); // 16^8
1910
- uint_fast32_t distributed = static_cast <uint_fast32_t >(distributor (rand));
1962
+ #ifdef IMPLEMENT_TR1
1963
+ uint_fast32_t distributed = gen_full_dist ();
1964
+ #else
1965
+ uint_fast32_t distributed = full_dist (rand);
1966
+ #endif
1911
1967
ss << " u" << std::setfill (' 0' ) << std::setw (8 ) << std::hex << distributed;
1912
1968
return SASS_MEMORY_NEW (ctx.mem , String_Quoted, pstate, ss.str ());
1913
1969
}
0 commit comments