Program Listing for File GSLrng_t.hpp

Return to documentation for file (fwdpp/GSLrng_t.hpp)

#ifndef __FWDPP_SUGAR_GSLRNG_T_HPP__
#define __FWDPP_SUGAR_GSLRNG_T_HPP__

#include <stdexcept>
//#include <cstdio>// FOR SOME POSIX ONLY FUNCTIONS!
#include <fwdpp/gsl/tags.hpp>
#include <fwdpp/gsl/deleter.hpp>

namespace fwdpp
{

    using GSL_RNG_MT19937
        = gsl::GSL_RNG_TYPE_TAG<gsl::GSL_RNG_TYPE::MT19937>;
    using GSL_RNG_TAUS2 = gsl::GSL_RNG_TYPE_TAG<gsl::GSL_RNG_TYPE::TAUS2>;

    template <typename T> class GSLrng_t
    {
      private:
        gsl::gsl_rng_ptr_t setup(GSL_RNG_MT19937)
        {
            return gsl::gsl_rng_ptr_t(gsl_rng_alloc(gsl_rng_mt19937),
                                        [](gsl_rng *r) { gsl_rng_free(r); });
        }

        gsl::gsl_rng_ptr_t setup(GSL_RNG_TAUS2)
        {
            return gsl::gsl_rng_ptr_t(gsl_rng_alloc(gsl_rng_taus2),
                                        [](gsl_rng *r) { gsl_rng_free(r); });
        }

        gsl::gsl_rng_ptr_t
        setup(const gsl_rng *r)
        {
            return gsl::gsl_rng_ptr_t(gsl_rng_clone(r),
                                        [](gsl_rng *r) { gsl_rng_free(r); });
        }

        gsl::gsl_rng_ptr_t r;

      public:
        using rngtype = T;

        GSLrng_t(const unsigned long seed) noexcept : r(setup(T()))
        {
            gsl_rng_set(r.get(), seed);
        }

        ~GSLrng_t() = default;
        GSLrng_t(const GSLrng_t &rng) = delete;
        GSLrng_t(GSLrng_t &&) = default;
        GSLrng_t &operator=(GSLrng_t &) = delete;
        GSLrng_t &operator=(GSLrng_t &&) = default;

        const gsl_rng *
        get() const
        {
            return r.get();
        }

        // /*!
        //   Write gsl_rng state to memory buffer.

        //   Throws std::runtime_error if there are problems
        // */
        // template<typename ostream_t>
        // void serialize(ostream_t & o) const
        // {
        //   /*
        //  We use C-style NULL in lieu of nullptr
        //  b/c we cannot be sure what the POSIX functions
        //  are doing...
        //   */
        //   FILE * stream = NULL;
        //   char * buf = NULL;
        //   std::size_t len;
        //   stream = open_memstream(&buf,&len);
        //   auto rv = gsl_rng_fwrite(stream,this->get());
        //   if( rv ) //gsl_rng_fwrite returns 0 upon success
        //  {
        //    fclose(stream);
        //    if(buf != NULL) free(buf);
        //    throw std::runtime_error("error calling gsl_rng_fwrite");
        //  }
        //   fclose(stream);
        //   o.write( reinterpret_cast<char*>(&len),sizeof(std::size_t) );
        //   o.write( buf, len*sizeof(char) );
        //   free(buf);
        // }

        // //! Read RNG state from a memory buffer
        // template<typename istream_t>
        // void deserialize(istream_t & i)
        // {
        //   std::size_t len;
        //   i.read(reinterpret_cast<char*>(&len),sizeof(std::size_t));
        //   std::unique_ptr<char> buffer(new char[len]);
        //   i.read(buffer.get(),len*sizeof(char));
        //   FILE * stream = fmemopen(buffer.get(),len*sizeof(char),"r");
        //   auto rv = gsl_rng_fread(stream,r.get());
        //   fclose(stream);
        // }
    };

    using GSLrng_mt = GSLrng_t<GSL_RNG_MT19937>;
}

#endif