1313#include  " utf8_string.hpp" 
1414#include  " utf8.h" 
1515
16- #include  < atomic> 
1716#include  < cstdlib> 
17+ #include  < climits> 
1818#include  < cmath> 
1919#include  < cctype> 
2020#include  < sstream> 
2929#include  " wincrypt.h" 
3030#endif 
3131
32+ #if  defined __GNUC__
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+ 
3250#define  ARG (argname, argtype ) get_arg<argtype>(argname, env, sig, pstate, backtrace)
3351#define  ARGR (argname, argtype, lo, hi ) get_arg_r(argname, env, sig, pstate, lo, hi, backtrace)
3452#define  ARGM (argname, argtype, ctx ) get_arg_m(argname, env, sig, pstate, backtrace, ctx)
@@ -211,7 +229,7 @@ namespace Sass {
211229      return  seed;
212230    }
213231    #else 
214-     static  std ::random_device rd;
232+     static  tr1ns ::random_device rd;
215233    uint64_t  GetSeed ()
216234    {
217235      return  rd ();
@@ -222,9 +240,42 @@ namespace Sass {
222240    //  random_device degrades sharply once the entropy pool
223241    //  is exhausted. For practical use, random_device is
224242    //  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 
226260
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
228279    static  std::set<std::string> features {
229280      " global-variable-shadowing"  ,
230281      " extend-selector-pseudoclass"  ,
@@ -1170,13 +1221,15 @@ namespace Sass {
11701221          err << " Expected $limit to be an integer but got `"   << v << " ` for `random`"  ;
11711222          error (err.str (), pstate);
11721223        }
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);
11761226      }
11771227      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 
11801233        return  SASS_MEMORY_NEW (ctx.mem , Number, pstate, distributed);
11811234     }
11821235    }
@@ -1906,8 +1959,11 @@ namespace Sass {
19061959    BUILT_IN (unique_id)
19071960    {
19081961      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 
19111967      ss << " u"   << std::setfill (' 0'  ) << std::setw (8 ) << std::hex << distributed;
19121968      return  SASS_MEMORY_NEW (ctx.mem , String_Quoted, pstate, ss.str ());
19131969    }
0 commit comments