// @(#)root/mathcore:$Id$
// Author: L. Moneta Tue Aug 4 2015

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2015  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// random engines based on ROOT 

#ifndef ROOT_Math_StdEngine
#define ROOT_Math_StdEngine

#include <random>
#include <string>

namespace ROOT {

   namespace Math {


      class StdRandomEngine {};

      template<class Generator>
      struct StdEngineType {
         static std::string Name() { return "std_random_eng";}
      };
      template<>
         struct StdEngineType<std::minstd_rand> {
         static std::string Name() { return "std_minstd_rand";}
      };
      template<>
      struct StdEngineType<std::mt19937> {
         static std::string Name() { return "std_mt19937";}
      };
      template<>
      struct StdEngineType<std::mt19937_64> {
         static std::string Name() { return "std_mt19937_64";}
      };
      template<>
      struct StdEngineType<std::ranlux24> {
         static std::string Name() { return "std_ranlux24";}
      };
      template<>
      struct StdEngineType<std::ranlux48> {
         static std::string Name() { return "std_ranlux48";}
      };
      template<>
      struct StdEngineType<std::knuth_b> {
         static std::string Name() { return "std_knuth_b";}
      };
      template<>
      struct StdEngineType<std::random_device> {
         static std::string Name() { return "std_random_device";}
      };
      
      
      /** 
          Wrapper class for std::random generator to be included in ROOT 
      */
      
      template <class Generator> 
      class StdEngine {


      public:

         typedef  StdRandomEngine BaseType; 
         typedef  typename Generator::result_type Result_t;
         
         StdEngine() : fGen() {
            fCONS = 1./fGen.max(); 
         }

         
         void SetSeed(Result_t seed) { fGen.seed(seed);}
         
         double Rndm() {
            Result_t rndm = fGen(); // generate integer number according to the type
            if (rndm != 0) return  fCONS*rndm;
            return Rndm();
         }

         Result_t IntRndm() {
            return fGen();
         }

         double operator() () {
            return Rndm(); 
         }

         static std::string Name()  {
            return StdEngineType<Generator>::Name(); 
         }

         static uint64_t MaxInt() { return Generator::max(); }


      private:
         Generator fGen;
         double fCONS;   //! cached value of maximum integer value generated
      };


      extern template class StdEngine<std::mt19937_64>;
      extern template class StdEngine<std::ranlux48>;

   } // end namespace Math

} // end namespace ROOT


#endif /* ROOT_Math_StdEngine */
 StdEngine.h:1
 StdEngine.h:2
 StdEngine.h:3
 StdEngine.h:4
 StdEngine.h:5
 StdEngine.h:6
 StdEngine.h:7
 StdEngine.h:8
 StdEngine.h:9
 StdEngine.h:10
 StdEngine.h:11
 StdEngine.h:12
 StdEngine.h:13
 StdEngine.h:14
 StdEngine.h:15
 StdEngine.h:16
 StdEngine.h:17
 StdEngine.h:18
 StdEngine.h:19
 StdEngine.h:20
 StdEngine.h:21
 StdEngine.h:22
 StdEngine.h:23
 StdEngine.h:24
 StdEngine.h:25
 StdEngine.h:26
 StdEngine.h:27
 StdEngine.h:28
 StdEngine.h:29
 StdEngine.h:30
 StdEngine.h:31
 StdEngine.h:32
 StdEngine.h:33
 StdEngine.h:34
 StdEngine.h:35
 StdEngine.h:36
 StdEngine.h:37
 StdEngine.h:38
 StdEngine.h:39
 StdEngine.h:40
 StdEngine.h:41
 StdEngine.h:42
 StdEngine.h:43
 StdEngine.h:44
 StdEngine.h:45
 StdEngine.h:46
 StdEngine.h:47
 StdEngine.h:48
 StdEngine.h:49
 StdEngine.h:50
 StdEngine.h:51
 StdEngine.h:52
 StdEngine.h:53
 StdEngine.h:54
 StdEngine.h:55
 StdEngine.h:56
 StdEngine.h:57
 StdEngine.h:58
 StdEngine.h:59
 StdEngine.h:60
 StdEngine.h:61
 StdEngine.h:62
 StdEngine.h:63
 StdEngine.h:64
 StdEngine.h:65
 StdEngine.h:66
 StdEngine.h:67
 StdEngine.h:68
 StdEngine.h:69
 StdEngine.h:70
 StdEngine.h:71
 StdEngine.h:72
 StdEngine.h:73
 StdEngine.h:74
 StdEngine.h:75
 StdEngine.h:76
 StdEngine.h:77
 StdEngine.h:78
 StdEngine.h:79
 StdEngine.h:80
 StdEngine.h:81
 StdEngine.h:82
 StdEngine.h:83
 StdEngine.h:84
 StdEngine.h:85
 StdEngine.h:86
 StdEngine.h:87
 StdEngine.h:88
 StdEngine.h:89
 StdEngine.h:90
 StdEngine.h:91
 StdEngine.h:92
 StdEngine.h:93
 StdEngine.h:94
 StdEngine.h:95
 StdEngine.h:96
 StdEngine.h:97
 StdEngine.h:98
 StdEngine.h:99
 StdEngine.h:100
 StdEngine.h:101
 StdEngine.h:102
 StdEngine.h:103
 StdEngine.h:104
 StdEngine.h:105
 StdEngine.h:106
 StdEngine.h:107
 StdEngine.h:108
 StdEngine.h:109
 StdEngine.h:110
 StdEngine.h:111
 StdEngine.h:112
 StdEngine.h:113
 StdEngine.h:114
 StdEngine.h:115