Added user authentication and management.

This commit is contained in:
Daniel Önnerby 2008-09-08 21:37:49 +00:00
parent 31e7c6daa7
commit 31d932112a
70 changed files with 7350 additions and 45 deletions

View File

@ -39,7 +39,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./include/;./include/sqlite/;./include/expat"
AdditionalIncludeDirectories="./include/;./include/sqlite/;./include/expat;./include/md5"
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;SQLITE_THREADSAFE;COMPILED_FROM_DSP;XML_STATIC"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@ -105,7 +105,7 @@
Optimization="2"
InlineFunctionExpansion="0"
FavorSizeOrSpeed="0"
AdditionalIncludeDirectories="./include/;./include/sqlite/;./include/expat"
AdditionalIncludeDirectories="./include/;./include/sqlite/;./include/expat;./include/md5"
PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;SQLITE_THREADSAFE;COMPILED_FROM_DSP;XML_STATIC"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
@ -260,6 +260,18 @@
>
</File>
</Filter>
<Filter
Name="md5"
>
<File
RelativePath=".\src\md5\md5.c"
>
</File>
<File
RelativePath=".\include\md5\md5.h"
>
</File>
</Filter>
</Filter>
</Files>
<Globals>

72
src/3rdparty/include/boost/random.hpp vendored Normal file
View File

@ -0,0 +1,72 @@
/* boost random.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org/libs/random for documentation.
*
* $Id: random.hpp 24096 2004-07-27 03:43:34Z dgregor $
*
* Revision history
* 2000-02-18 portability fixes (thanks to Beman Dawes)
* 2000-02-21 shuffle_output, inversive_congruential_schrage,
* generator_iterator, uniform_smallint
* 2000-02-23 generic modulus arithmetic helper, removed *_schrage classes,
* implemented Streamable and EqualityComparable concepts for
* generators, added Bernoulli distribution and Box-Muller
* transform
* 2000-03-01 cauchy, lognormal, triangle distributions; fixed
* uniform_smallint; renamed gaussian to normal distribution
* 2000-03-05 implemented iterator syntax for distribution functions
* 2000-04-21 removed some optimizations for better BCC/MSVC compatibility
* 2000-05-10 adapted to BCC and MSVC
* 2000-06-13 incorporated review results
* 2000-07-06 moved basic templates from namespace detail to random
* 2000-09-23 warning removals and int64 fixes (Ed Brey)
* 2000-09-24 added lagged_fibonacci generator (Matthias Troyer)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_HPP
#define BOOST_RANDOM_HPP
// generators
#include <boost/random/linear_congruential.hpp>
#include <boost/random/additive_combine.hpp>
#include <boost/random/inversive_congruential.hpp>
#include <boost/random/shuffle_output.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/lagged_fibonacci.hpp>
#include <boost/random/ranlux.hpp>
#include <boost/random/linear_feedback_shift.hpp>
#include <boost/random/xor_combine.hpp>
namespace boost {
typedef random::xor_combine<random::xor_combine<random::linear_feedback_shift<uint32_t, 32, 31, 13, 12, 0>, 0,
random::linear_feedback_shift<uint32_t, 32, 29, 2, 4, 0>, 0, 0>, 0,
random::linear_feedback_shift<uint32_t, 32, 28, 3, 17, 0>, 0, 0> taus88;
} // namespace boost
// misc
#include <boost/random/random_number_generator.hpp>
// distributions
#include <boost/random/uniform_smallint.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/triangle_distribution.hpp>
#include <boost/random/bernoulli_distribution.hpp>
#include <boost/random/cauchy_distribution.hpp>
#include <boost/random/exponential_distribution.hpp>
#include <boost/random/geometric_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/lognormal_distribution.hpp>
#include <boost/random/poisson_distribution.hpp>
#include <boost/random/gamma_distribution.hpp>
#include <boost/random/binomial_distribution.hpp>
#include <boost/random/uniform_on_sphere.hpp>
#endif // BOOST_RANDOM_HPP

View File

@ -0,0 +1,125 @@
/* boost random/additive_combine.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: additive_combine.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_ADDITIVE_COMBINE_HPP
#define BOOST_RANDOM_ADDITIVE_COMBINE_HPP
#include <iostream>
#include <algorithm> // for std::min and std::max
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/random/linear_congruential.hpp>
namespace boost {
namespace random {
// L'Ecuyer 1988
template<class MLCG1, class MLCG2,
#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
typename MLCG1::result_type
#else
int32_t
#endif
val>
class additive_combine
{
public:
typedef MLCG1 first_base;
typedef MLCG2 second_base;
typedef typename MLCG1::result_type result_type;
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
static const bool has_fixed_range = true;
static const result_type min_value = 1;
static const result_type max_value = MLCG1::max_value-1;
#else
enum { has_fixed_range = false };
#endif
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 1; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_mlcg1.max)()-1; }
additive_combine() : _mlcg1(), _mlcg2() { }
additive_combine(typename MLCG1::result_type seed1,
typename MLCG2::result_type seed2)
: _mlcg1(seed1), _mlcg2(seed2) { }
template<class It> additive_combine(It& first, It last)
: _mlcg1(first, last), _mlcg2(first, last) { }
void seed()
{
_mlcg1.seed();
_mlcg2.seed();
}
void seed(typename MLCG1::result_type seed1,
typename MLCG2::result_type seed2)
{
_mlcg1.seed(seed1);
_mlcg2.seed(seed2);
}
template<class It> void seed(It& first, It last)
{
_mlcg1.seed(first, last);
_mlcg2.seed(first, last);
}
result_type operator()() {
result_type z = _mlcg1() - _mlcg2();
if(z < 1)
z += MLCG1::modulus-1;
return z;
}
static bool validation(result_type x) { return val == x; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const additive_combine& r)
{ os << r._mlcg1 << " " << r._mlcg2; return os; }
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, additive_combine& r)
{ is >> r._mlcg1 >> std::ws >> r._mlcg2; return is; }
#endif
friend bool operator==(const additive_combine& x, const additive_combine& y)
{ return x._mlcg1 == y._mlcg1 && x._mlcg2 == y._mlcg2; }
friend bool operator!=(const additive_combine& x, const additive_combine& y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(const additive_combine& rhs) const
{ return _mlcg1 == rhs._mlcg1 && _mlcg2 == rhs._mlcg2; }
bool operator!=(const additive_combine& rhs) const
{ return !(*this == rhs); }
#endif
private:
MLCG1 _mlcg1;
MLCG2 _mlcg2;
};
} // namespace random
typedef random::additive_combine<
random::linear_congruential<int32_t, 40014, 0, 2147483563, 0>,
random::linear_congruential<int32_t, 40692, 0, 2147483399, 0>,
2060321752> ecuyer1988;
} // namespace boost
#endif // BOOST_RANDOM_ADDITIVE_COMBINE_HPP

View File

@ -0,0 +1,80 @@
/* boost random/bernoulli_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: bernoulli_distribution.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP
#define BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP
#include <cassert>
#include <iostream>
namespace boost {
// Bernoulli distribution: p(true) = p, p(false) = 1-p (boolean)
template<class RealType = double>
class bernoulli_distribution
{
public:
// In principle, this could work with both integer and floating-point
// types. Generating floating-point random numbers in the first
// place is probably more expensive, so use integer as input.
typedef int input_type;
typedef bool result_type;
explicit bernoulli_distribution(const RealType& p_arg = RealType(0.5))
: _p(p_arg)
{
assert(_p >= 0);
assert(_p <= 1);
}
// compiler-generated copy ctor and assignment operator are fine
RealType p() const { return _p; }
void reset() { }
template<class Engine>
result_type operator()(Engine& eng)
{
if(_p == RealType(0))
return false;
else
return RealType(eng() - (eng.min)()) <= _p * RealType((eng.max)()-(eng.min)());
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const bernoulli_distribution& bd)
{
os << bd._p;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, bernoulli_distribution& bd)
{
is >> std::ws >> bd._p;
return is;
}
#endif
private:
RealType _p;
};
} // namespace boost
#endif // BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP

View File

@ -0,0 +1,81 @@
/* boost random/binomial_distribution.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: binomial_distribution.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
*/
#ifndef BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP
#include <cmath>
#include <cassert>
#include <boost/random/bernoulli_distribution.hpp>
namespace boost {
// Knuth
template<class IntType = int, class RealType = double>
class binomial_distribution
{
public:
typedef typename bernoulli_distribution<RealType>::input_type input_type;
typedef IntType result_type;
explicit binomial_distribution(IntType t_arg = 1,
const RealType& p_arg = RealType(0.5))
: _bernoulli(p_arg), _t(t_arg)
{
assert(_t >= 0);
assert(RealType(0) <= p_arg && p_arg <= RealType(1));
}
// compiler-generated copy ctor and assignment operator are fine
IntType t() const { return _t; }
RealType p() const { return _bernoulli.p(); }
void reset() { }
template<class Engine>
result_type operator()(Engine& eng)
{
// TODO: This is O(_t), but it should be O(log(_t)) for large _t
result_type n = 0;
for(IntType i = 0; i < _t; ++i)
if(_bernoulli(eng))
++n;
return n;
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const binomial_distribution& bd)
{
os << bd._bernoulli << " " << bd._t;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, binomial_distribution& bd)
{
is >> std::ws >> bd._bernoulli >> std::ws >> bd._t;
return is;
}
#endif
private:
bernoulli_distribution<RealType> _bernoulli;
IntType _t;
};
} // namespace boost
#endif // BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP

View File

@ -0,0 +1,89 @@
/* boost random/cauchy_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: cauchy_distribution.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_CAUCHY_DISTRIBUTION_HPP
#define BOOST_RANDOM_CAUCHY_DISTRIBUTION_HPP
#include <cmath>
#include <iostream>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
namespace boost {
#if defined(__GNUC__) && (__GNUC__ < 3)
// Special gcc workaround: gcc 2.95.x ignores using-declarations
// in template classes (confirmed by gcc author Martin v. Loewis)
using std::tan;
#endif
// Cauchy distribution: p(x) = sigma/(pi*(sigma**2 + (x-median)**2))
template<class RealType = double>
class cauchy_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
explicit cauchy_distribution(result_type median_arg = result_type(0),
result_type sigma_arg = result_type(1))
: _median(median_arg), _sigma(sigma_arg) { }
// compiler-generated copy ctor and assignment operator are fine
result_type median() const { return _median; }
result_type sigma() const { return _sigma; }
void reset() { }
template<class Engine>
result_type operator()(Engine& eng)
{
// Can we have a boost::mathconst please?
const result_type pi = result_type(3.14159265358979323846);
#ifndef BOOST_NO_STDC_NAMESPACE
using std::tan;
#endif
return _median + _sigma * tan(pi*(eng()-result_type(0.5)));
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const cauchy_distribution& cd)
{
os << cd._median << " " << cd._sigma;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, cauchy_distribution& cd)
{
is >> std::ws >> cd._median >> std::ws >> cd._sigma;
return is;
}
#endif
private:
result_type _median, _sigma;
};
} // namespace boost
#endif // BOOST_RANDOM_CAUCHY_DISTRIBUTION_HPP

View File

@ -0,0 +1,359 @@
/* boost random/detail/const_mod.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: const_mod.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_CONST_MOD_HPP
#define BOOST_RANDOM_CONST_MOD_HPP
#include <cassert>
#include <boost/static_assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/integer_traits.hpp>
#include <boost/detail/workaround.hpp>
namespace boost {
namespace random {
/*
* Some random number generators require modular arithmetic. Put
* everything we need here.
* IntType must be an integral type.
*/
namespace detail {
template<bool is_signed>
struct do_add
{ };
template<>
struct do_add<true>
{
template<class IntType>
static IntType add(IntType m, IntType x, IntType c)
{
if (x < m - c)
return x + c;
else
return x - (m-c);
}
};
template<>
struct do_add<false>
{
template<class IntType>
static IntType add(IntType, IntType, IntType)
{
// difficult
assert(!"const_mod::add with c too large");
return 0;
}
};
} // namespace detail
#if !(defined(__BORLANDC__) && (__BORLANDC__ == 0x560))
template<class IntType, IntType m>
class const_mod
{
public:
static IntType add(IntType x, IntType c)
{
if(c == 0)
return x;
else if(c <= traits::const_max - m) // i.e. m+c < max
return add_small(x, c);
else
return detail::do_add<traits::is_signed>::add(m, x, c);
}
static IntType mult(IntType a, IntType x)
{
if(a == 1)
return x;
else if(m <= traits::const_max/a) // i.e. a*m <= max
return mult_small(a, x);
else if(traits::is_signed && (m%a < m/a))
return mult_schrage(a, x);
else {
// difficult
assert(!"const_mod::mult with a too large");
return 0;
}
}
static IntType mult_add(IntType a, IntType x, IntType c)
{
if(m <= (traits::const_max-c)/a) // i.e. a*m+c <= max
return (a*x+c) % m;
else
return add(mult(a, x), c);
}
static IntType invert(IntType x)
{ return x == 0 ? 0 : invert_euclidian(x); }
private:
typedef integer_traits<IntType> traits;
const_mod(); // don't instantiate
static IntType add_small(IntType x, IntType c)
{
x += c;
if(x >= m)
x -= m;
return x;
}
static IntType mult_small(IntType a, IntType x)
{
return a*x % m;
}
static IntType mult_schrage(IntType a, IntType value)
{
const IntType q = m / a;
const IntType r = m % a;
assert(r < q); // check that overflow cannot happen
value = a*(value%q) - r*(value/q);
// An optimizer bug in the SGI MIPSpro 7.3.1.x compiler requires this
// convoluted formulation of the loop (Synge Todo)
for(;;) {
if (value > 0)
break;
value += m;
}
return value;
}
// invert c in the finite field (mod m) (m must be prime)
static IntType invert_euclidian(IntType c)
{
// we are interested in the gcd factor for c, because this is our inverse
BOOST_STATIC_ASSERT(m > 0);
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
assert(boost::integer_traits<IntType>::is_signed);
#elif !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS)
BOOST_STATIC_ASSERT(boost::integer_traits<IntType>::is_signed);
#endif
assert(c > 0);
IntType l1 = 0;
IntType l2 = 1;
IntType n = c;
IntType p = m;
for(;;) {
IntType q = p / n;
l1 -= q * l2; // this requires a signed IntType!
p -= q * n;
if(p == 0)
return (l2 < 1 ? l2 + m : l2);
IntType q2 = n / p;
l2 -= q2 * l1;
n -= q2 * p;
if(n == 0)
return (l1 < 1 ? l1 + m : l1);
}
}
};
// The modulus is exactly the word size: rely on machine overflow handling.
// Due to a GCC bug, we cannot partially specialize in the presence of
// template value parameters.
template<>
class const_mod<unsigned int, 0>
{
typedef unsigned int IntType;
public:
static IntType add(IntType x, IntType c) { return x+c; }
static IntType mult(IntType a, IntType x) { return a*x; }
static IntType mult_add(IntType a, IntType x, IntType c) { return a*x+c; }
// m is not prime, thus invert is not useful
private: // don't instantiate
const_mod();
};
template<>
class const_mod<unsigned long, 0>
{
typedef unsigned long IntType;
public:
static IntType add(IntType x, IntType c) { return x+c; }
static IntType mult(IntType a, IntType x) { return a*x; }
static IntType mult_add(IntType a, IntType x, IntType c) { return a*x+c; }
// m is not prime, thus invert is not useful
private: // don't instantiate
const_mod();
};
// the modulus is some power of 2: rely partly on machine overflow handling
// we only specialize for rand48 at the moment
#ifndef BOOST_NO_INT64_T
template<>
class const_mod<uint64_t, uint64_t(1) << 48>
{
typedef uint64_t IntType;
public:
static IntType add(IntType x, IntType c) { return c == 0 ? x : mod(x+c); }
static IntType mult(IntType a, IntType x) { return mod(a*x); }
static IntType mult_add(IntType a, IntType x, IntType c)
{ return mod(a*x+c); }
static IntType mod(IntType x) { return x &= ((uint64_t(1) << 48)-1); }
// m is not prime, thus invert is not useful
private: // don't instantiate
const_mod();
};
#endif /* !BOOST_NO_INT64_T */
#else
//
// for some reason Borland C++ Builder 6 has problems with
// the full specialisations of const_mod, define a generic version
// instead, the compiler will optimise away the const-if statements:
//
template<class IntType, IntType m>
class const_mod
{
public:
static IntType add(IntType x, IntType c)
{
if(0 == m)
{
return x+c;
}
else
{
if(c == 0)
return x;
else if(c <= traits::const_max - m) // i.e. m+c < max
return add_small(x, c);
else
return detail::do_add<traits::is_signed>::add(m, x, c);
}
}
static IntType mult(IntType a, IntType x)
{
if(x == 0)
{
return a*x;
}
else
{
if(a == 1)
return x;
else if(m <= traits::const_max/a) // i.e. a*m <= max
return mult_small(a, x);
else if(traits::is_signed && (m%a < m/a))
return mult_schrage(a, x);
else {
// difficult
assert(!"const_mod::mult with a too large");
return 0;
}
}
}
static IntType mult_add(IntType a, IntType x, IntType c)
{
if(m == 0)
{
return a*x+c;
}
else
{
if(m <= (traits::const_max-c)/a) // i.e. a*m+c <= max
return (a*x+c) % m;
else
return add(mult(a, x), c);
}
}
static IntType invert(IntType x)
{ return x == 0 ? 0 : invert_euclidian(x); }
private:
typedef integer_traits<IntType> traits;
const_mod(); // don't instantiate
static IntType add_small(IntType x, IntType c)
{
x += c;
if(x >= m)
x -= m;
return x;
}
static IntType mult_small(IntType a, IntType x)
{
return a*x % m;
}
static IntType mult_schrage(IntType a, IntType value)
{
const IntType q = m / a;
const IntType r = m % a;
assert(r < q); // check that overflow cannot happen
value = a*(value%q) - r*(value/q);
while(value <= 0)
value += m;
return value;
}
// invert c in the finite field (mod m) (m must be prime)
static IntType invert_euclidian(IntType c)
{
// we are interested in the gcd factor for c, because this is our inverse
BOOST_STATIC_ASSERT(m > 0);
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(boost::integer_traits<IntType>::is_signed);
#endif
assert(c > 0);
IntType l1 = 0;
IntType l2 = 1;
IntType n = c;
IntType p = m;
for(;;) {
IntType q = p / n;
l1 -= q * l2; // this requires a signed IntType!
p -= q * n;
if(p == 0)
return (l2 < 1 ? l2 + m : l2);
IntType q2 = n / p;
l2 -= q2 * l1;
n -= q2 * p;
if(n == 0)
return (l1 < 1 ? l1 + m : l1);
}
}
};
#endif
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_CONST_MOD_HPP

View File

@ -0,0 +1,98 @@
/* boost random/detail/uniform_int_float.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: pass_through_engine.hpp 24096 2004-07-27 03:43:34Z dgregor $
*
*/
#ifndef BOOST_RANDOM_DETAIL_PASS_THROUGH_ENGINE_HPP
#define BOOST_RANDOM_DETAIL_PASS_THROUGH_ENGINE_HPP
#include <boost/config.hpp>
#include <boost/random/detail/ptr_helper.hpp>
namespace boost {
namespace random {
namespace detail {
template<class UniformRandomNumberGenerator>
class pass_through_engine
{
private:
typedef ptr_helper<UniformRandomNumberGenerator> helper_type;
public:
typedef typename helper_type::value_type base_type;
typedef typename base_type::result_type result_type;
explicit pass_through_engine(UniformRandomNumberGenerator rng)
// make argument an rvalue to avoid matching Generator& constructor
: _rng(static_cast<typename helper_type::rvalue_type>(rng))
{ }
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (base().min)(); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (base().max)(); }
base_type& base() { return helper_type::ref(_rng); }
const base_type& base() const { return helper_type::ref(_rng); }
result_type operator()() { return base()(); }
private:
UniformRandomNumberGenerator _rng;
};
#ifndef BOOST_NO_STD_LOCALE
template<class UniformRandomNumberGenerator, class CharT, class Traits>
std::basic_ostream<CharT,Traits>&
operator<<(
std::basic_ostream<CharT,Traits>& os
, const pass_through_engine<UniformRandomNumberGenerator>& ud
)
{
return os << ud.base();
}
template<class UniformRandomNumberGenerator, class CharT, class Traits>
std::basic_istream<CharT,Traits>&
operator>>(
std::basic_istream<CharT,Traits>& is
, const pass_through_engine<UniformRandomNumberGenerator>& ud
)
{
return is >> ud.base();
}
#else // no new streams
template<class UniformRandomNumberGenerator>
inline std::ostream&
operator<<(std::ostream& os,
const pass_through_engine<UniformRandomNumberGenerator>& ud)
{
return os << ud.base();
}
template<class UniformRandomNumberGenerator>
inline std::istream&
operator>>(std::istream& is,
const pass_through_engine<UniformRandomNumberGenerator>& ud)
{
return is >> ud.base();
}
#endif
} // namespace detail
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DETAIL_PASS_THROUGH_ENGINE_HPP

View File

@ -0,0 +1,94 @@
/* boost random/detail/ptr_helper.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: ptr_helper.hpp 24096 2004-07-27 03:43:34Z dgregor $
*
*/
#ifndef BOOST_RANDOM_DETAIL_PTR_HELPER_HPP
#define BOOST_RANDOM_DETAIL_PTR_HELPER_HPP
#include <boost/config.hpp>
namespace boost {
namespace random {
namespace detail {
// type_traits could help here, but I don't want to depend on type_traits.
template<class T>
struct ptr_helper
{
typedef T value_type;
typedef T& reference_type;
typedef const T& rvalue_type;
static reference_type ref(T& r) { return r; }
static const T& ref(const T& r) { return r; }
};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<class T>
struct ptr_helper<T&>
{
typedef T value_type;
typedef T& reference_type;
typedef T& rvalue_type;
static reference_type ref(T& r) { return r; }
static const T& ref(const T& r) { return r; }
};
template<class T>
struct ptr_helper<T*>
{
typedef T value_type;
typedef T& reference_type;
typedef T* rvalue_type;
static reference_type ref(T * p) { return *p; }
static const T& ref(const T * p) { return *p; }
};
#endif
} // namespace detail
} // namespace random
} // namespace boost
//
// BOOST_RANDOM_PTR_HELPER_SPEC --
//
// Helper macro for broken compilers defines specializations of
// ptr_helper.
//
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
# define BOOST_RANDOM_PTR_HELPER_SPEC(T) \
namespace boost { namespace random { namespace detail { \
template<> \
struct ptr_helper<T&> \
{ \
typedef T value_type; \
typedef T& reference_type; \
typedef T& rvalue_type; \
static reference_type ref(T& r) { return r; } \
static const T& ref(const T& r) { return r; } \
}; \
\
template<> \
struct ptr_helper<T*> \
{ \
typedef T value_type; \
typedef T& reference_type; \
typedef T* rvalue_type; \
static reference_type ref(T * p) { return *p; } \
static const T& ref(const T * p) { return *p; } \
}; \
}}}
#else
# define BOOST_RANDOM_PTR_HELPER_SPEC(T)
#endif
#endif // BOOST_RANDOM_DETAIL_PTR_HELPER_HPP

View File

@ -0,0 +1,89 @@
/* boost random/detail/signed_unsigned_tools.hpp header file
*
* Copyright Jens Maurer 2006
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*/
#ifndef BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
#define BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS
#include <boost/limits.hpp>
#include <boost/config.hpp>
#include <boost/type_traits/make_unsigned.hpp>
namespace boost {
namespace random {
namespace detail {
/*
* Compute x - y, we know that x >= y, return an unsigned value.
*/
template<class T, bool sgn = std::numeric_limits<T>::is_signed>
struct subtract { };
template<class T>
struct subtract<T, /* signed */ false>
{
typedef T result_type;
result_type operator()(T x, T y) { return x - y; }
};
template<class T>
struct subtract<T, /* signed */ true>
{
typedef typename make_unsigned<T>::type result_type;
result_type operator()(T x, T y)
{
if (y >= 0) // because x >= y, it follows that x >= 0, too
return result_type(x) - result_type(y);
if (x >= 0) // y < 0
// avoid the nasty two's complement case for y == min()
return result_type(x) + result_type(-(y+1)) + 1;
// both x and y are negative: no signed overflow
return result_type(x - y);
}
};
/*
* Compute x + y, x is unsigned, result fits in type of "y".
*/
template<class T1, class T2, bool sgn = std::numeric_limits<T2>::is_signed>
struct add { };
template<class T1, class T2>
struct add<T1, T2, /* signed */ false>
{
typedef T2 result_type;
result_type operator()(T1 x, T2 y) { return x + y; }
};
template<class T1, class T2>
struct add<T1, T2, /* signed */ true>
{
typedef T2 result_type;
result_type operator()(T1 x, T2 y)
{
if (y >= 0)
return x + y;
// y < 0
if (x >= T1(-(y+1))) // result >= 0 after subtraction
// avoid the nasty two's complement edge case for y == min()
return T2(x - T1(-(y+1)) - 1);
// abs(x) < abs(y), thus T2 able to represent x
return T2(x) + y;
}
};
} // namespace detail
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS

View File

@ -0,0 +1,84 @@
/* boost random/detail/uniform_int_float.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: uniform_int_float.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
*/
#ifndef BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
#define BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
#include <boost/config.hpp>
#include <boost/random/uniform_01.hpp>
namespace boost {
namespace random {
namespace detail {
template<class UniformRandomNumberGenerator, class IntType = unsigned long>
class uniform_int_float
{
public:
typedef UniformRandomNumberGenerator base_type;
typedef IntType result_type;
uniform_int_float(base_type rng, IntType min_arg = 0, IntType max_arg = 0xffffffff)
: _rng(rng), _min(min_arg), _max(max_arg)
{
init();
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
base_type& base() { return _rng.base(); }
const base_type& base() const { return _rng.base(); }
result_type operator()()
{
return static_cast<IntType>(_rng() * _range) + _min;
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_int_float& ud)
{
os << ud._min << " " << ud._max;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, uniform_int_float& ud)
{
is >> std::ws >> ud._min >> std::ws >> ud._max;
ud.init();
return is;
}
#endif
private:
void init()
{
_range = static_cast<base_result>(_max-_min)+1;
}
typedef typename base_type::result_type base_result;
uniform_01<base_type> _rng;
result_type _min, _max;
base_result _range;
};
} // namespace detail
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP

View File

@ -0,0 +1,121 @@
/* boost random/discard_block.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: discard_block.hpp 29116 2005-05-21 15:57:01Z dgregor $
*
* Revision history
* 2001-03-02 created
*/
#ifndef BOOST_RANDOM_DISCARD_BLOCK_HPP
#define BOOST_RANDOM_DISCARD_BLOCK_HPP
#include <iostream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
namespace boost {
namespace random {
template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r>
class discard_block
{
public:
typedef UniformRandomNumberGenerator base_type;
typedef typename base_type::result_type result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(unsigned int, total_block = p);
BOOST_STATIC_CONSTANT(unsigned int, returned_block = r);
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(total_block >= returned_block);
#endif
discard_block() : _rng(), _n(0) { }
explicit discard_block(const base_type & rng) : _rng(rng), _n(0) { }
template<class It> discard_block(It& first, It last)
: _rng(first, last), _n(0) { }
void seed() { _rng.seed(); _n = 0; }
template<class T> void seed(T s) { _rng.seed(s); _n = 0; }
template<class It> void seed(It& first, It last)
{ _n = 0; _rng.seed(first, last); }
const base_type& base() const { return _rng; }
result_type operator()()
{
if(_n >= returned_block) {
// discard values of random number generator
for( ; _n < total_block; ++_n)
_rng();
_n = 0;
}
++_n;
return _rng();
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.min)(); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.max)(); }
static bool validation(result_type x) { return true; } // dummy
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const discard_block& s)
{
os << s._rng << " " << s._n << " ";
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, discard_block& s)
{
is >> s._rng >> std::ws >> s._n >> std::ws;
return is;
}
#endif
friend bool operator==(const discard_block& x, const discard_block& y)
{ return x._rng == y._rng && x._n == y._n; }
friend bool operator!=(const discard_block& x, const discard_block& y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(const discard_block& rhs) const
{ return _rng == rhs._rng && _n == rhs._n; }
bool operator!=(const discard_block& rhs) const
{ return !(*this == rhs); }
#endif
private:
base_type _rng;
unsigned int _n;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r>
const bool discard_block<UniformRandomNumberGenerator, p, r>::has_fixed_range;
template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r>
const unsigned int discard_block<UniformRandomNumberGenerator, p, r>::total_block;
template<class UniformRandomNumberGenerator, unsigned int p, unsigned int r>
const unsigned int discard_block<UniformRandomNumberGenerator, p, r>::returned_block;
#endif
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_DISCARD_BLOCK_HPP

View File

@ -0,0 +1,81 @@
/* boost random/exponential_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: exponential_distribution.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_EXPONENTIAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_EXPONENTIAL_DISTRIBUTION_HPP
#include <cmath>
#include <cassert>
#include <iostream>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
namespace boost {
// exponential distribution: p(x) = lambda * exp(-lambda * x)
template<class RealType = double>
class exponential_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
explicit exponential_distribution(result_type lambda_arg = result_type(1))
: _lambda(lambda_arg) { assert(_lambda > result_type(0)); }
// compiler-generated copy ctor and assignment operator are fine
result_type lambda() const { return _lambda; }
void reset() { }
template<class Engine>
result_type operator()(Engine& eng)
{
#ifndef BOOST_NO_STDC_NAMESPACE
using std::log;
#endif
return -result_type(1) / _lambda * log(result_type(1)-eng());
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const exponential_distribution& ed)
{
os << ed._lambda;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, exponential_distribution& ed)
{
is >> std::ws >> ed._lambda;
return is;
}
#endif
private:
result_type _lambda;
};
} // namespace boost
#endif // BOOST_RANDOM_EXPONENTIAL_DISTRIBUTION_HPP

View File

@ -0,0 +1,133 @@
/* boost random/gamma_distribution.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: gamma_distribution.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
*/
#ifndef BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
#define BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP
#include <cmath>
#include <cassert>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/exponential_distribution.hpp>
namespace boost {
// Knuth
template<class RealType = double>
class gamma_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
explicit gamma_distribution(const result_type& alpha_arg = result_type(1))
: _exp(result_type(1)), _alpha(alpha_arg)
{
assert(_alpha > result_type(0));
init();
}
// compiler-generated copy ctor and assignment operator are fine
RealType alpha() const { return _alpha; }
void reset() { _exp.reset(); }
template<class Engine>
result_type operator()(Engine& eng)
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::tan; using std::sqrt; using std::exp; using std::log;
using std::pow;
#endif
if(_alpha == result_type(1)) {
return _exp(eng);
} else if(_alpha > result_type(1)) {
// Can we have a boost::mathconst please?
const result_type pi = result_type(3.14159265358979323846);
for(;;) {
result_type y = tan(pi * eng());
result_type x = sqrt(result_type(2)*_alpha-result_type(1))*y
+ _alpha-result_type(1);
if(x <= result_type(0))
continue;
if(eng() >
(result_type(1)+y*y) * exp((_alpha-result_type(1))
*log(x/(_alpha-result_type(1)))
- sqrt(result_type(2)*_alpha
-result_type(1))*y))
continue;
return x;
}
} else /* alpha < 1.0 */ {
for(;;) {
result_type u = eng();
result_type y = _exp(eng);
result_type x, q;
if(u < _p) {
x = exp(-y/_alpha);
q = _p*exp(-x);
} else {
x = result_type(1)+y;
q = _p + (result_type(1)-_p) * pow(x, _alpha-result_type(1));
}
if(u >= q)
continue;
return x;
}
}
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const gamma_distribution& gd)
{
os << gd._alpha;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, gamma_distribution& gd)
{
is >> std::ws >> gd._alpha;
gd.init();
return is;
}
#endif
private:
void init()
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::exp;
#endif
_p = exp(result_type(1)) / (_alpha + exp(result_type(1)));
}
exponential_distribution<RealType> _exp;
result_type _alpha;
// some data precomputed from the parameters
result_type _p;
};
} // namespace boost
#endif // BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP

View File

@ -0,0 +1,97 @@
/* boost random/geometric_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: geometric_distribution.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP
#define BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP
#include <cmath> // std::log
#include <cassert>
#include <iostream>
#include <boost/random/uniform_01.hpp>
namespace boost {
#if defined(__GNUC__) && (__GNUC__ < 3)
// Special gcc workaround: gcc 2.95.x ignores using-declarations
// in template classes (confirmed by gcc author Martin v. Loewis)
using std::log;
#endif
// geometric distribution: p(i) = (1-p) * pow(p, i-1) (integer)
template<class IntType = int, class RealType = double>
class geometric_distribution
{
public:
typedef RealType input_type;
typedef IntType result_type;
explicit geometric_distribution(const RealType& p_arg = RealType(0.5))
: _p(p_arg)
{
assert(RealType(0) < _p && _p < RealType(1));
init();
}
// compiler-generated copy ctor and assignment operator are fine
RealType p() const { return _p; }
void reset() { }
template<class Engine>
result_type operator()(Engine& eng)
{
#ifndef BOOST_NO_STDC_NAMESPACE
using std::log;
using std::floor;
#endif
return IntType(floor(log(RealType(1)-eng()) / _log_p)) + IntType(1);
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const geometric_distribution& gd)
{
os << gd._p;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, geometric_distribution& gd)
{
is >> std::ws >> gd._p;
gd.init();
return is;
}
#endif
private:
void init()
{
#ifndef BOOST_NO_STDC_NAMESPACE
using std::log;
#endif
_log_p = log(_p);
}
RealType _p;
RealType _log_p;
};
} // namespace boost
#endif // BOOST_RANDOM_GEOMETRIC_DISTRIBUTION_HPP

View File

@ -0,0 +1,128 @@
/* boost random/inversive_congruential.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: inversive_congruential.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
#define BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP
#include <iostream>
#include <cassert>
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/const_mod.hpp>
namespace boost {
namespace random {
// Eichenauer and Lehn 1986
template<class IntType, IntType a, IntType b, IntType p, IntType val>
class inversive_congruential
{
public:
typedef IntType result_type;
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
static const bool has_fixed_range = true;
static const result_type min_value = (b == 0 ? 1 : 0);
static const result_type max_value = p-1;
#else
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
#endif
BOOST_STATIC_CONSTANT(result_type, multiplier = a);
BOOST_STATIC_CONSTANT(result_type, increment = b);
BOOST_STATIC_CONSTANT(result_type, modulus = p);
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return b == 0 ? 1 : 0; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return p-1; }
explicit inversive_congruential(IntType y0 = 1) : value(y0)
{
BOOST_STATIC_ASSERT(b >= 0);
BOOST_STATIC_ASSERT(p > 1);
BOOST_STATIC_ASSERT(a >= 1);
if(b == 0)
assert(y0 > 0);
}
template<class It> inversive_congruential(It& first, It last)
{ seed(first, last); }
void seed(IntType y0 = 1) { value = y0; if(b == 0) assert(y0 > 0); }
template<class It> void seed(It& first, It last)
{
if(first == last)
throw std::invalid_argument("inversive_congruential::seed");
value = *first++;
}
IntType operator()()
{
typedef const_mod<IntType, p> do_mod;
value = do_mod::mult_add(a, do_mod::invert(value), b);
return value;
}
bool validation(result_type x) const { return val == x; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, inversive_congruential x)
{ os << x.value; return os; }
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, inversive_congruential& x)
{ is >> x.value; return is; }
#endif
friend bool operator==(inversive_congruential x, inversive_congruential y)
{ return x.value == y.value; }
friend bool operator!=(inversive_congruential x, inversive_congruential y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(inversive_congruential rhs) const
{ return value == rhs.value; }
bool operator!=(inversive_congruential rhs) const
{ return !(*this == rhs); }
#endif
private:
IntType value;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class IntType, IntType a, IntType b, IntType p, IntType val>
const bool inversive_congruential<IntType, a, b, p, val>::has_fixed_range;
template<class IntType, IntType a, IntType b, IntType p, IntType val>
const typename inversive_congruential<IntType, a, b, p, val>::result_type inversive_congruential<IntType, a, b, p, val>::min_value;
template<class IntType, IntType a, IntType b, IntType p, IntType val>
const typename inversive_congruential<IntType, a, b, p, val>::result_type inversive_congruential<IntType, a, b, p, val>::max_value;
template<class IntType, IntType a, IntType b, IntType p, IntType val>
const typename inversive_congruential<IntType, a, b, p, val>::result_type inversive_congruential<IntType, a, b, p, val>::multiplier;
template<class IntType, IntType a, IntType b, IntType p, IntType val>
const typename inversive_congruential<IntType, a, b, p, val>::result_type inversive_congruential<IntType, a, b, p, val>::increment;
template<class IntType, IntType a, IntType b, IntType p, IntType val>
const typename inversive_congruential<IntType, a, b, p, val>::result_type inversive_congruential<IntType, a, b, p, val>::modulus;
#endif
} // namespace random
typedef random::inversive_congruential<int32_t, 9102, 2147483647-36884165,
2147483647, 0> hellekalek1995;
} // namespace boost
#endif // BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP

View File

@ -0,0 +1,464 @@
/* boost random/lagged_fibonacci.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: lagged_fibonacci.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_LAGGED_FIBONACCI_HPP
#define BOOST_RANDOM_LAGGED_FIBONACCI_HPP
#include <cmath>
#include <iostream>
#include <algorithm> // std::max
#include <iterator>
#include <cmath> // std::pow
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/cstdint.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/detail/pass_through_engine.hpp>
namespace boost {
namespace random {
#if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
# define BOOST_RANDOM_EXTRACT_LF
#endif
#if defined(__APPLE_CC__) && defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ <= 3)
# define BOOST_RANDOM_EXTRACT_LF
#endif
# ifdef BOOST_RANDOM_EXTRACT_LF
namespace detail
{
template<class IStream, class F, class RealType>
IStream&
extract_lagged_fibonacci_01(
IStream& is
, F const& f
, unsigned int& i
, RealType* x
, RealType modulus)
{
is >> i >> std::ws;
for(unsigned int i = 0; i < f.long_lag; ++i)
{
RealType value;
is >> value >> std::ws;
x[i] = value / modulus;
}
return is;
}
template<class IStream, class F, class UIntType>
IStream&
extract_lagged_fibonacci(
IStream& is
, F const& f
, unsigned int& i
, UIntType* x)
{
is >> i >> std::ws;
for(unsigned int i = 0; i < f.long_lag; ++i)
is >> x[i] >> std::ws;
return is;
}
}
# endif
template<class UIntType, int w, unsigned int p, unsigned int q,
UIntType val = 0>
class lagged_fibonacci
{
public:
typedef UIntType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(int, word_size = w);
BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return wordmask; }
lagged_fibonacci() { init_wordmask(); seed(); }
explicit lagged_fibonacci(uint32_t value) { init_wordmask(); seed(value); }
template<class It> lagged_fibonacci(It& first, It last)
{ init_wordmask(); seed(first, last); }
// compiler-generated copy ctor and assignment operator are fine
private:
void init_wordmask()
{
wordmask = 0;
for(int j = 0; j < w; ++j)
wordmask |= (1u << j);
}
public:
void seed(uint32_t value = 331u)
{
minstd_rand0 gen(value);
for(unsigned int j = 0; j < long_lag; ++j)
x[j] = gen() & wordmask;
i = long_lag;
}
template<class It>
void seed(It& first, It last)
{
// word size could be smaller than the seed values
unsigned int j;
for(j = 0; j < long_lag && first != last; ++j, ++first)
x[j] = *first & wordmask;
i = long_lag;
if(first == last && j < long_lag)
throw std::invalid_argument("lagged_fibonacci::seed");
}
result_type operator()()
{
if(i >= long_lag)
fill();
return x[i++];
}
static bool validation(result_type x)
{
return x == val;
}
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const lagged_fibonacci& f)
{
os << f.i << " ";
for(unsigned int i = 0; i < f.long_lag; ++i)
os << f.x[i] << " ";
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, lagged_fibonacci& f)
{
# ifdef BOOST_RANDOM_EXTRACT_LF
return detail::extract_lagged_fibonacci(is, f, f.i, f.x);
# else
is >> f.i >> std::ws;
for(unsigned int i = 0; i < f.long_lag; ++i)
is >> f.x[i] >> std::ws;
return is;
# endif
}
#endif
friend bool operator==(const lagged_fibonacci& x, const lagged_fibonacci& y)
{ return x.i == y.i && std::equal(x.x, x.x+long_lag, y.x); }
friend bool operator!=(const lagged_fibonacci& x,
const lagged_fibonacci& y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(const lagged_fibonacci& rhs) const
{ return i == rhs.i && std::equal(x, x+long_lag, rhs.x); }
bool operator!=(const lagged_fibonacci& rhs) const
{ return !(*this == rhs); }
#endif
private:
void fill();
UIntType wordmask;
unsigned int i;
UIntType x[long_lag];
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class UIntType, int w, unsigned int p, unsigned int q, UIntType val>
const bool lagged_fibonacci<UIntType, w, p, q, val>::has_fixed_range;
template<class UIntType, int w, unsigned int p, unsigned int q, UIntType val>
const unsigned int lagged_fibonacci<UIntType, w, p, q, val>::long_lag;
template<class UIntType, int w, unsigned int p, unsigned int q, UIntType val>
const unsigned int lagged_fibonacci<UIntType, w, p, q, val>::short_lag;
#endif
template<class UIntType, int w, unsigned int p, unsigned int q, UIntType val>
void lagged_fibonacci<UIntType, w, p, q, val>::fill()
{
// two loops to avoid costly modulo operations
{ // extra scope for MSVC brokenness w.r.t. for scope
for(unsigned int j = 0; j < short_lag; ++j)
x[j] = (x[j] + x[j+(long_lag-short_lag)]) & wordmask;
}
for(unsigned int j = short_lag; j < long_lag; ++j)
x[j] = (x[j] + x[j-short_lag]) & wordmask;
i = 0;
}
// lagged Fibonacci generator for the range [0..1)
// contributed by Matthias Troyer
// for p=55, q=24 originally by G. J. Mitchell and D. P. Moore 1958
template<class T, unsigned int p, unsigned int q>
struct fibonacci_validation
{
BOOST_STATIC_CONSTANT(bool, is_specialized = false);
static T value() { return 0; }
static T tolerance() { return 0; }
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class T, unsigned int p, unsigned int q>
const bool fibonacci_validation<T, p, q>::is_specialized;
#endif
#define BOOST_RANDOM_FIBONACCI_VAL(T,P,Q,V,E) \
template<> \
struct fibonacci_validation<T, P, Q> \
{ \
BOOST_STATIC_CONSTANT(bool, is_specialized = true); \
static T value() { return V; } \
static T tolerance() \
{ return (std::max)(E, static_cast<T>(5*std::numeric_limits<T>::epsilon())); } \
};
// (The extra static_cast<T> in the std::max call above is actually
// unnecessary except for HP aCC 1.30, which claims that
// numeric_limits<double>::epsilon() doesn't actually return a double.)
BOOST_RANDOM_FIBONACCI_VAL(double, 607, 273, 0.4293817707235914, 1e-14)
BOOST_RANDOM_FIBONACCI_VAL(double, 1279, 418, 0.9421630240437659, 1e-14)
BOOST_RANDOM_FIBONACCI_VAL(double, 2281, 1252, 0.1768114046909004, 1e-14)
BOOST_RANDOM_FIBONACCI_VAL(double, 3217, 576, 0.1956232694868209, 1e-14)
BOOST_RANDOM_FIBONACCI_VAL(double, 4423, 2098, 0.9499762202147172, 1e-14)
BOOST_RANDOM_FIBONACCI_VAL(double, 9689, 5502, 0.05737836943695162, 1e-14)
BOOST_RANDOM_FIBONACCI_VAL(double, 19937, 9842, 0.5076528587449834, 1e-14)
BOOST_RANDOM_FIBONACCI_VAL(double, 23209, 13470, 0.5414473810619185, 1e-14)
BOOST_RANDOM_FIBONACCI_VAL(double, 44497,21034, 0.254135073399297, 1e-14)
#undef BOOST_RANDOM_FIBONACCI_VAL
template<class RealType, int w, unsigned int p, unsigned int q>
class lagged_fibonacci_01
{
public:
typedef RealType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(int, word_size = w);
BOOST_STATIC_CONSTANT(unsigned int, long_lag = p);
BOOST_STATIC_CONSTANT(unsigned int, short_lag = q);
lagged_fibonacci_01() { init_modulus(); seed(); }
explicit lagged_fibonacci_01(uint32_t value) { init_modulus(); seed(value); }
template<class Generator>
explicit lagged_fibonacci_01(Generator & gen) { init_modulus(); seed(gen); }
template<class It> lagged_fibonacci_01(It& first, It last)
{ init_modulus(); seed(first, last); }
// compiler-generated copy ctor and assignment operator are fine
private:
void init_modulus()
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::pow;
#endif
_modulus = pow(RealType(2), word_size);
}
public:
void seed(uint32_t value = 331u)
{
minstd_rand0 intgen(value);
seed(intgen);
}
// For GCC, moving this function out-of-line prevents inlining, which may
// reduce overall object code size. However, MSVC does not grok
// out-of-line template member functions.
template<class Generator>
void seed(Generator & gen)
{
// use pass-by-reference, but wrap argument in pass_through_engine
typedef detail::pass_through_engine<Generator&> ref_gen;
uniform_01<ref_gen, RealType> gen01 =
uniform_01<ref_gen, RealType>(ref_gen(gen));
// I could have used std::generate_n, but it takes "gen" by value
for(unsigned int j = 0; j < long_lag; ++j)
x[j] = gen01();
i = long_lag;
}
template<class It>
void seed(It& first, It last)
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::fmod;
using std::pow;
#endif
unsigned long mask = ~((~0u) << (w%32)); // now lowest w bits set
RealType two32 = pow(RealType(2), 32);
unsigned int j;
for(j = 0; j < long_lag && first != last; ++j, ++first) {
x[j] = RealType(0);
for(int k = 0; k < w/32 && first != last; ++k, ++first)
x[j] += *first / pow(two32,k+1);
if(first != last && mask != 0)
x[j] += fmod((*first & mask) / _modulus, RealType(1));
}
i = long_lag;
if(first == last && j < long_lag)
throw std::invalid_argument("lagged_fibonacci_01::seed");
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
result_type operator()()
{
if(i >= long_lag)
fill();
return x[i++];
}
static bool validation(result_type x)
{
result_type v = fibonacci_validation<result_type, p, q>::value();
result_type epsilon = fibonacci_validation<result_type, p, q>::tolerance();
// std::abs is a source of trouble: sometimes, it's not overloaded
// for double, plus the usual namespace std noncompliance -> avoid it
// using std::abs;
// return abs(x - v) < 5 * epsilon
return x > v - epsilon && x < v + epsilon;
}
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const lagged_fibonacci_01&f)
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::pow;
#endif
os << f.i << " ";
std::ios_base::fmtflags oldflags = os.flags(os.dec | os.fixed | os.left);
for(unsigned int i = 0; i < f.long_lag; ++i)
os << f.x[i] * f._modulus << " ";
os.flags(oldflags);
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, lagged_fibonacci_01& f)
{
# ifdef BOOST_RANDOM_EXTRACT_LF
return detail::extract_lagged_fibonacci_01(is, f, f.i, f.x, f._modulus);
# else
is >> f.i >> std::ws;
for(unsigned int i = 0; i < f.long_lag; ++i) {
typename lagged_fibonacci_01::result_type value;
is >> value >> std::ws;
f.x[i] = value / f._modulus;
}
return is;
# endif
}
#endif
friend bool operator==(const lagged_fibonacci_01& x,
const lagged_fibonacci_01& y)
{ return x.i == y.i && std::equal(x.x, x.x+long_lag, y.x); }
friend bool operator!=(const lagged_fibonacci_01& x,
const lagged_fibonacci_01& y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(const lagged_fibonacci_01& rhs) const
{ return i == rhs.i && std::equal(x, x+long_lag, rhs.x); }
bool operator!=(const lagged_fibonacci_01& rhs) const
{ return !(*this == rhs); }
#endif
private:
void fill();
unsigned int i;
RealType x[long_lag];
RealType _modulus;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class RealType, int w, unsigned int p, unsigned int q>
const bool lagged_fibonacci_01<RealType, w, p, q>::has_fixed_range;
template<class RealType, int w, unsigned int p, unsigned int q>
const unsigned int lagged_fibonacci_01<RealType, w, p, q>::long_lag;
template<class RealType, int w, unsigned int p, unsigned int q>
const unsigned int lagged_fibonacci_01<RealType, w, p, q>::short_lag;
template<class RealType, int w, unsigned int p, unsigned int q>
const int lagged_fibonacci_01<RealType,w,p,q>::word_size;
#endif
template<class RealType, int w, unsigned int p, unsigned int q>
void lagged_fibonacci_01<RealType, w, p, q>::fill()
{
// two loops to avoid costly modulo operations
{ // extra scope for MSVC brokenness w.r.t. for scope
for(unsigned int j = 0; j < short_lag; ++j) {
RealType t = x[j] + x[j+(long_lag-short_lag)];
if(t >= RealType(1))
t -= RealType(1);
x[j] = t;
}
}
for(unsigned int j = short_lag; j < long_lag; ++j) {
RealType t = x[j] + x[j-short_lag];
if(t >= RealType(1))
t -= RealType(1);
x[j] = t;
}
i = 0;
}
} // namespace random
typedef random::lagged_fibonacci_01<double, 48, 607, 273> lagged_fibonacci607;
typedef random::lagged_fibonacci_01<double, 48, 1279, 418> lagged_fibonacci1279;
typedef random::lagged_fibonacci_01<double, 48, 2281, 1252> lagged_fibonacci2281;
typedef random::lagged_fibonacci_01<double, 48, 3217, 576> lagged_fibonacci3217;
typedef random::lagged_fibonacci_01<double, 48, 4423, 2098> lagged_fibonacci4423;
typedef random::lagged_fibonacci_01<double, 48, 9689, 5502> lagged_fibonacci9689;
typedef random::lagged_fibonacci_01<double, 48, 19937, 9842> lagged_fibonacci19937;
typedef random::lagged_fibonacci_01<double, 48, 23209, 13470> lagged_fibonacci23209;
typedef random::lagged_fibonacci_01<double, 48, 44497, 21034> lagged_fibonacci44497;
// It is possible to partially specialize uniform_01<> on lagged_fibonacci_01<>
// to help the compiler generate efficient code. For GCC, this seems useless,
// because GCC optimizes (x-0)/(1-0) to (x-0). This is good enough for now.
} // namespace boost
#endif // BOOST_RANDOM_LAGGED_FIBONACCI_HPP

View File

@ -0,0 +1,258 @@
/* boost random/linear_congruential.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: linear_congruential.hpp 29116 2005-05-21 15:57:01Z dgregor $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
#define BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP
#include <iostream>
#include <cassert>
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/detail/const_mod.hpp>
#include <boost/detail/workaround.hpp>
namespace boost {
namespace random {
// compile-time configurable linear congruential generator
template<class IntType, IntType a, IntType c, IntType m, IntType val>
class linear_congruential
{
public:
typedef IntType result_type;
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
static const bool has_fixed_range = true;
static const result_type min_value = ( c == 0 ? 1 : 0 );
static const result_type max_value = m-1;
#else
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
#endif
BOOST_STATIC_CONSTANT(IntType, multiplier = a);
BOOST_STATIC_CONSTANT(IntType, increment = c);
BOOST_STATIC_CONSTANT(IntType, modulus = m);
// MSVC 6 and possibly others crash when encountering complicated integral
// constant expressions. Avoid the check for now.
// BOOST_STATIC_ASSERT(m == 0 || a < m);
// BOOST_STATIC_ASSERT(m == 0 || c < m);
explicit linear_congruential(IntType x0 = 1)
: _modulus(modulus), _x(_modulus ? (x0 % _modulus) : x0)
{
assert(c || x0); /* if c == 0 and x(0) == 0 then x(n) = 0 for all n */
// overflow check
// disabled because it gives spurious "divide by zero" gcc warnings
// assert(m == 0 || (a*(m-1)+c) % m == (c < a ? c-a+m : c-a));
// MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
#endif
}
template<class It>
linear_congruential(It& first, It last) { seed(first, last); }
// compiler-generated copy constructor and assignment operator are fine
void seed(IntType x0 = 1)
{
assert(c || x0);
_x = (_modulus ? (x0 % _modulus) : x0);
}
template<class It>
void seed(It& first, It last)
{
if(first == last)
throw std::invalid_argument("linear_congruential::seed");
IntType value = *first++;
_x = (_modulus ? (value % _modulus) : value);
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return c == 0 ? 1 : 0; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return modulus-1; }
IntType operator()()
{
_x = const_mod<IntType, m>::mult_add(a, _x, c);
return _x;
}
static bool validation(IntType x) { return val == x; }
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
// Use a member function; Streamable concept not supported.
bool operator==(const linear_congruential& rhs) const
{ return _x == rhs._x; }
bool operator!=(const linear_congruential& rhs) const
{ return !(*this == rhs); }
#else
friend bool operator==(const linear_congruential& x,
const linear_congruential& y)
{ return x._x == y._x; }
friend bool operator!=(const linear_congruential& x,
const linear_congruential& y)
{ return !(x == y); }
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const linear_congruential& lcg)
{
return os << lcg._x;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is,
linear_congruential& lcg)
{
return is >> lcg._x;
}
private:
#endif
#endif
IntType _modulus; // work-around for gcc "divide by zero" warning in ctor
IntType _x;
};
// probably needs the "no native streams" caveat for STLPort
#if !defined(__SGI_STL_PORT) && BOOST_WORKAROUND(__GNUC__, == 2)
template<class IntType, IntType a, IntType c, IntType m, IntType val>
std::ostream&
operator<<(std::ostream& os,
const linear_congruential<IntType,a,c,m,val>& lcg)
{
return os << lcg._x;
}
template<class IntType, IntType a, IntType c, IntType m, IntType val>
std::istream&
operator>>(std::istream& is,
linear_congruential<IntType,a,c,m,val>& lcg)
{
return is >> lcg._x;
}
#elif defined(BOOST_NO_OPERATORS_IN_NAMESPACE) || defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<class CharT, class Traits, class IntType, IntType a, IntType c, IntType m, IntType val>
std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const linear_congruential<IntType,a,c,m,val>& lcg)
{
return os << lcg._x;
}
template<class CharT, class Traits, class IntType, IntType a, IntType c, IntType m, IntType val>
std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is,
linear_congruential<IntType,a,c,m,val>& lcg)
{
return is >> lcg._x;
}
#endif
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class IntType, IntType a, IntType c, IntType m, IntType val>
const bool linear_congruential<IntType, a, c, m, val>::has_fixed_range;
template<class IntType, IntType a, IntType c, IntType m, IntType val>
const typename linear_congruential<IntType, a, c, m, val>::result_type linear_congruential<IntType, a, c, m, val>::min_value;
template<class IntType, IntType a, IntType c, IntType m, IntType val>
const typename linear_congruential<IntType, a, c, m, val>::result_type linear_congruential<IntType, a, c, m, val>::max_value;
template<class IntType, IntType a, IntType c, IntType m, IntType val>
const IntType linear_congruential<IntType,a,c,m,val>::modulus;
#endif
} // namespace random
// validation values from the publications
typedef random::linear_congruential<int32_t, 16807, 0, 2147483647,
1043618065> minstd_rand0;
typedef random::linear_congruential<int32_t, 48271, 0, 2147483647,
399268537> minstd_rand;
#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
// emulate the lrand48() C library function; requires support for uint64_t
class rand48
{
public:
typedef int32_t result_type;
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
static const bool has_fixed_range = true;
static const int32_t min_value = 0;
static const int32_t max_value = integer_traits<int32_t>::const_max;
#else
enum { has_fixed_range = false };
#endif
int32_t min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
int32_t max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::numeric_limits<int32_t>::max BOOST_PREVENT_MACRO_SUBSTITUTION (); }
explicit rand48(int32_t x0 = 1) : lcf(cnv(x0)) { }
explicit rand48(uint64_t x0) : lcf(x0) { }
template<class It> rand48(It& first, It last) : lcf(first, last) { }
// compiler-generated copy ctor and assignment operator are fine
void seed(int32_t x0 = 1) { lcf.seed(cnv(x0)); }
void seed(uint64_t x0) { lcf.seed(x0); }
template<class It> void seed(It& first, It last) { lcf.seed(first,last); }
int32_t operator()() { return static_cast<int32_t>(lcf() >> 17); }
// by experiment from lrand48()
static bool validation(int32_t x) { return x == 1993516219; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT,class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const rand48& r)
{ os << r.lcf; return os; }
template<class CharT,class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, rand48& r)
{ is >> r.lcf; return is; }
#endif
friend bool operator==(const rand48& x, const rand48& y)
{ return x.lcf == y.lcf; }
friend bool operator!=(const rand48& x, const rand48& y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(const rand48& rhs) const
{ return lcf == rhs.lcf; }
bool operator!=(const rand48& rhs) const
{ return !(*this == rhs); }
#endif
private:
random::linear_congruential<uint64_t,
uint64_t(0xDEECE66DUL) | (uint64_t(0x5) << 32), // xxxxULL is not portable
0xB, uint64_t(1)<<48, /* unknown */ 0> lcf;
static uint64_t cnv(int32_t x)
{ return (static_cast<uint64_t>(x) << 16) | 0x330e; }
};
#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */
} // namespace boost
#endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP

View File

@ -0,0 +1,145 @@
/* boost random/tausworthe.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: linear_feedback_shift.hpp 29116 2005-05-21 15:57:01Z dgregor $
*
*/
#ifndef BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP
#define BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP
#include <iostream>
#include <cassert>
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/limits.hpp>
namespace boost {
namespace random {
// Tausworte 1965
template<class UIntType, int w, int k, int q, int s, UIntType val>
class linear_feedback_shift
{
public:
typedef UIntType result_type;
// avoid the warning trouble when using (1<<w) on 32 bit machines
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(int, word_size = w);
BOOST_STATIC_CONSTANT(int, exponent1 = k);
BOOST_STATIC_CONSTANT(int, exponent2 = q);
BOOST_STATIC_CONSTANT(int, step_size = s);
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return wordmask; }
// MSVC 6 and possibly others crash when encountering complicated integral
// constant expressions. Avoid the checks for now.
// BOOST_STATIC_ASSERT(w > 0);
// BOOST_STATIC_ASSERT(q > 0);
// BOOST_STATIC_ASSERT(k < w);
// BOOST_STATIC_ASSERT(0 < 2*q && 2*q < k);
// BOOST_STATIC_ASSERT(0 < s && s <= k-q);
explicit linear_feedback_shift(UIntType s0 = 341) : wordmask(0)
{
// MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(std::numeric_limits<UIntType>::is_integer);
BOOST_STATIC_ASSERT(!std::numeric_limits<UIntType>::is_signed);
#endif
// avoid "left shift count >= with of type" warning
for(int i = 0; i < w; ++i)
wordmask |= (1u << i);
seed(s0);
}
template<class It> linear_feedback_shift(It& first, It last) : wordmask(0)
{
// MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(std::numeric_limits<UIntType>::is_integer);
BOOST_STATIC_ASSERT(!std::numeric_limits<UIntType>::is_signed);
#endif
// avoid "left shift count >= with of type" warning
for(int i = 0; i < w; ++i)
wordmask |= (1u << i);
seed(first, last);
}
void seed(UIntType s0 = 341) { assert(s0 >= (1 << (w-k))); value = s0; }
template<class It> void seed(It& first, It last)
{
if(first == last)
throw std::invalid_argument("linear_feedback_shift::seed");
value = *first++;
assert(value >= (1 << (w-k)));
}
result_type operator()()
{
const UIntType b = (((value << q) ^ value) & wordmask) >> (k-s);
const UIntType mask = ( (~static_cast<UIntType>(0)) << (w-k) ) & wordmask;
value = ((value & mask) << s) ^ b;
return value;
}
bool validation(result_type x) const { return val == x; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, linear_feedback_shift x)
{ os << x.value; return os; }
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, linear_feedback_shift& x)
{ is >> x.value; return is; }
#endif
friend bool operator==(linear_feedback_shift x, linear_feedback_shift y)
{ return x.value == y.value; }
friend bool operator!=(linear_feedback_shift x, linear_feedback_shift y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(linear_feedback_shift rhs) const
{ return value == rhs.value; }
bool operator!=(linear_feedback_shift rhs) const
{ return !(*this == rhs); }
#endif
private:
UIntType wordmask; // avoid "left shift count >= width of type" warnings
UIntType value;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class UIntType, int w, int k, int q, int s, UIntType val>
const bool linear_feedback_shift<UIntType, w, k, q, s, val>::has_fixed_range;
template<class UIntType, int w, int k, int q, int s, UIntType val>
const int linear_feedback_shift<UIntType, w, k, q, s, val>::word_size;
template<class UIntType, int w, int k, int q, int s, UIntType val>
const int linear_feedback_shift<UIntType, w, k, q, s, val>::exponent1;
template<class UIntType, int w, int k, int q, int s, UIntType val>
const int linear_feedback_shift<UIntType, w, k, q, s, val>::exponent2;
template<class UIntType, int w, int k, int q, int s, UIntType val>
const int linear_feedback_shift<UIntType, w, k, q, s, val>::step_size;
#endif
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP

View File

@ -0,0 +1,114 @@
/* boost random/lognormal_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: lognormal_distribution.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP
#include <cmath> // std::exp, std::sqrt
#include <cassert>
#include <iostream>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/normal_distribution.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
using ::log;
using ::sqrt;
}
#endif
namespace boost {
#if defined(__GNUC__) && (__GNUC__ < 3)
// Special gcc workaround: gcc 2.95.x ignores using-declarations
// in template classes (confirmed by gcc author Martin v. Loewis)
using std::sqrt;
using std::exp;
#endif
template<class RealType = double>
class lognormal_distribution
{
public:
typedef typename normal_distribution<RealType>::input_type input_type;
typedef RealType result_type;
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
explicit lognormal_distribution(result_type mean_arg = result_type(1),
result_type sigma_arg = result_type(1))
: _mean(mean_arg), _sigma(sigma_arg)
{
assert(_mean > result_type(0));
init();
}
// compiler-generated copy ctor and assignment operator are fine
RealType mean() const { return _mean; }
RealType sigma() const { return _sigma; }
void reset() { _normal.reset(); }
template<class Engine>
result_type operator()(Engine& eng)
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::exp;
#endif
return exp(_normal(eng) * _nsigma + _nmean);
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const lognormal_distribution& ld)
{
os << ld._normal << " " << ld._mean << " " << ld._sigma;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, lognormal_distribution& ld)
{
is >> std::ws >> ld._normal >> std::ws >> ld._mean >> std::ws >> ld._sigma;
ld.init();
return is;
}
#endif
private:
void init()
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::exp; using std::log; using std::sqrt;
#endif
_nmean = log(_mean*_mean/sqrt(_sigma*_sigma + _mean*_mean));
_nsigma = sqrt(log(_sigma*_sigma/_mean/_mean+result_type(1)));
}
RealType _mean, _sigma;
RealType _nmean, _nsigma;
normal_distribution<result_type> _normal;
};
} // namespace boost
#endif // BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP

View File

@ -0,0 +1,302 @@
/* boost random/mersenne_twister.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: mersenne_twister.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_MERSENNE_TWISTER_HPP
#define BOOST_RANDOM_MERSENNE_TWISTER_HPP
#include <iostream>
#include <algorithm> // std::copy
#include <stdexcept>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/integer_traits.hpp>
#include <boost/cstdint.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/random/detail/ptr_helper.hpp>
namespace boost {
namespace random {
// http://www.math.keio.ac.jp/matumoto/emt.html
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
class mersenne_twister
{
public:
typedef UIntType result_type;
BOOST_STATIC_CONSTANT(int, word_size = w);
BOOST_STATIC_CONSTANT(int, state_size = n);
BOOST_STATIC_CONSTANT(int, shift_size = m);
BOOST_STATIC_CONSTANT(int, mask_bits = r);
BOOST_STATIC_CONSTANT(UIntType, parameter_a = a);
BOOST_STATIC_CONSTANT(int, output_u = u);
BOOST_STATIC_CONSTANT(int, output_s = s);
BOOST_STATIC_CONSTANT(UIntType, output_b = b);
BOOST_STATIC_CONSTANT(int, output_t = t);
BOOST_STATIC_CONSTANT(UIntType, output_c = c);
BOOST_STATIC_CONSTANT(int, output_l = l);
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
mersenne_twister() { seed(); }
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520)
// Work around overload resolution problem (Gennadiy E. Rozental)
explicit mersenne_twister(const UIntType& value)
#else
explicit mersenne_twister(UIntType value)
#endif
{ seed(value); }
template<class It> mersenne_twister(It& first, It last) { seed(first,last); }
template<class Generator>
explicit mersenne_twister(Generator & gen) { seed(gen); }
// compiler-generated copy ctor and assignment operator are fine
void seed() { seed(UIntType(5489)); }
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x520)
// Work around overload resolution problem (Gennadiy E. Rozental)
void seed(const UIntType& value)
#else
void seed(UIntType value)
#endif
{
// New seeding algorithm from
// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
// In the previous versions, MSBs of the seed affected only MSBs of the
// state x[].
const UIntType mask = ~0u;
x[0] = value & mask;
for (i = 1; i < n; i++) {
// See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106
x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
}
}
// For GCC, moving this function out-of-line prevents inlining, which may
// reduce overall object code size. However, MSVC does not grok
// out-of-line definitions of member function templates.
template<class Generator>
void seed(Generator & gen)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(!std::numeric_limits<result_type>::is_signed);
#endif
// I could have used std::generate_n, but it takes "gen" by value
for(int j = 0; j < n; j++)
x[j] = gen();
i = n;
}
template<class It>
void seed(It& first, It last)
{
int j;
for(j = 0; j < n && first != last; ++j, ++first)
x[j] = *first;
i = n;
if(first == last && j < n)
throw std::invalid_argument("mersenne_twister::seed");
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return 0; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const
{
// avoid "left shift count >= with of type" warning
result_type res = 0;
for(int j = 0; j < w; ++j)
res |= (1u << j);
return res;
}
result_type operator()();
static bool validation(result_type v) { return val == v; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const mersenne_twister& mt)
{
for(int j = 0; j < mt.state_size; ++j)
os << mt.compute(j) << " ";
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, mersenne_twister& mt)
{
for(int j = 0; j < mt.state_size; ++j)
is >> mt.x[j] >> std::ws;
// MSVC (up to 7.1) and Borland (up to 5.64) don't handle the template
// value parameter "n" available from the class template scope, so use
// the static constant with the same value
mt.i = mt.state_size;
return is;
}
#endif
friend bool operator==(const mersenne_twister& x, const mersenne_twister& y)
{
for(int j = 0; j < state_size; ++j)
if(x.compute(j) != y.compute(j))
return false;
return true;
}
friend bool operator!=(const mersenne_twister& x, const mersenne_twister& y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(const mersenne_twister& rhs) const
{
for(int j = 0; j < state_size; ++j)
if(compute(j) != rhs.compute(j))
return false;
return true;
}
bool operator!=(const mersenne_twister& rhs) const
{ return !(*this == rhs); }
#endif
private:
// returns x(i-n+index), where index is in 0..n-1
UIntType compute(unsigned int index) const
{
// equivalent to (i-n+index) % 2n, but doesn't produce negative numbers
return x[ (i + n + index) % (2*n) ];
}
void twist(int block);
// state representation: next output is o(x(i))
// x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents
// x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)]
// The goal is to always have x(i-n) ... x(i-1) available for
// operator== and save/restore.
UIntType x[2*n];
int i;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const bool mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::has_fixed_range;
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::state_size;
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::shift_size;
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::mask_bits;
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::parameter_a;
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_u;
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_s;
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_b;
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_t;
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const UIntType mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_c;
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
const int mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::output_l;
#endif
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
void mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::twist(int block)
{
const UIntType upper_mask = (~0u) << r;
const UIntType lower_mask = ~upper_mask;
if(block == 0) {
for(int j = n; j < 2*n; j++) {
UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask);
x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
}
} else if (block == 1) {
// split loop to avoid costly modulo operations
{ // extra scope for MSVC brokenness w.r.t. for scope
for(int j = 0; j < n-m; j++) {
UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0);
}
}
for(int j = n-m; j < n-1; j++) {
UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
}
// last iteration
UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask);
x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0);
i = 0;
}
}
template<class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val>
inline typename mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::result_type
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::operator()()
{
if(i == n)
twist(0);
else if(i >= 2*n)
twist(1);
// Step 4
UIntType z = x[i];
++i;
z ^= (z >> u);
z ^= ((z << s) & b);
z ^= ((z << t) & c);
z ^= (z >> l);
return z;
}
} // namespace random
typedef random::mersenne_twister<uint32_t,32,351,175,19,0xccab8ee7,11,
7,0x31b6ab00,15,0xffe50000,17, 0xa37d3c92> mt11213b;
// validation by experiment from mt19937.c
typedef random::mersenne_twister<uint32_t,32,624,397,31,0x9908b0df,11,
7,0x9d2c5680,15,0xefc60000,18, 3346425566U> mt19937;
} // namespace boost
BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt19937)
#endif // BOOST_RANDOM_MERSENNE_TWISTER_HPP

View File

@ -0,0 +1,111 @@
/* boost random/normal_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: normal_distribution.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP
#define BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP
#include <cmath>
#include <cassert>
#include <iostream>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
namespace boost {
// deterministic Box-Muller method, uses trigonometric functions
template<class RealType = double>
class normal_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
explicit normal_distribution(const result_type& mean_arg = result_type(0),
const result_type& sigma_arg = result_type(1))
: _mean(mean_arg), _sigma(sigma_arg), _valid(false)
{
assert(_sigma >= result_type(0));
}
// compiler-generated copy constructor is NOT fine, need to purge cache
normal_distribution(const normal_distribution& other)
: _mean(other._mean), _sigma(other._sigma), _valid(false)
{
}
// compiler-generated copy ctor and assignment operator are fine
RealType mean() const { return _mean; }
RealType sigma() const { return _sigma; }
void reset() { _valid = false; }
template<class Engine>
result_type operator()(Engine& eng)
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::sqrt; using std::log; using std::sin; using std::cos;
#endif
if(!_valid) {
_r1 = eng();
_r2 = eng();
_cached_rho = sqrt(-result_type(2) * log(result_type(1)-_r2));
_valid = true;
} else {
_valid = false;
}
// Can we have a boost::mathconst please?
const result_type pi = result_type(3.14159265358979323846);
return _cached_rho * (_valid ?
cos(result_type(2)*pi*_r1) :
sin(result_type(2)*pi*_r1))
* _sigma + _mean;
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const normal_distribution& nd)
{
os << nd._mean << " " << nd._sigma << " "
<< nd._valid << " " << nd._cached_rho << " " << nd._r1;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, normal_distribution& nd)
{
is >> std::ws >> nd._mean >> std::ws >> nd._sigma
>> std::ws >> nd._valid >> std::ws >> nd._cached_rho
>> std::ws >> nd._r1;
return is;
}
#endif
private:
result_type _mean, _sigma;
result_type _r1, _r2, _cached_rho;
bool _valid;
};
} // namespace boost
#endif // BOOST_RANDOM_NORMAL_DISTRIBUTION_HPP

View File

@ -0,0 +1,99 @@
/* boost random/poisson_distribution.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: poisson_distribution.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
*/
#ifndef BOOST_RANDOM_POISSON_DISTRIBUTION_HPP
#define BOOST_RANDOM_POISSON_DISTRIBUTION_HPP
#include <cmath>
#include <cassert>
#include <iostream>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
namespace boost {
// Knuth
template<class IntType = int, class RealType = double>
class poisson_distribution
{
public:
typedef RealType input_type;
typedef IntType result_type;
explicit poisson_distribution(const RealType& mean_arg = RealType(1))
: _mean(mean_arg)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
// MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
assert(_mean > RealType(0));
init();
}
// compiler-generated copy ctor and assignment operator are fine
RealType mean() const { return _mean; }
void reset() { }
template<class Engine>
result_type operator()(Engine& eng)
{
// TODO: This is O(_mean), but it should be O(log(_mean)) for large _mean
RealType product = RealType(1);
for(result_type m = 0; ; ++m) {
product *= eng();
if(product <= _exp_mean)
return m;
}
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const poisson_distribution& pd)
{
os << pd._mean;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, poisson_distribution& pd)
{
is >> std::ws >> pd._mean;
pd.init();
return is;
}
#endif
private:
void init()
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::exp;
#endif
_exp_mean = exp(-_mean);
}
RealType _mean;
// some precomputed data from the parameters
RealType _exp_mean;
};
} // namespace boost
#endif // BOOST_RANDOM_POISSON_DISTRIBUTION_HPP

View File

@ -0,0 +1,56 @@
/* boost random/random_number_generator.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: random_number_generator.hpp 26164 2004-11-09 21:22:00Z jmaurer $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_RANDOM_NUMBER_GENERATOR_HPP
#define BOOST_RANDOM_RANDOM_NUMBER_GENERATOR_HPP
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/variate_generator.hpp>
namespace boost {
// a model for RandomNumberGenerator std:25.2.11 [lib.alg.random.shuffle]
template<class UniformRandomNumberGenerator, class IntType = long>
class random_number_generator
{
public:
typedef UniformRandomNumberGenerator base_type;
typedef IntType argument_type;
typedef IntType result_type;
random_number_generator(base_type& rng) : _rng(rng)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_integer);
#endif
}
// compiler-generated copy ctor is fine
// assignment is disallowed because there is a reference member
result_type operator()(argument_type n)
{
typedef uniform_int<IntType> dist_type;
return variate_generator<base_type&, dist_type>(_rng, dist_type(0, n-1))();
}
private:
base_type& _rng;
};
} // namespace boost
#endif // BOOST_RANDOM_RANDOM_NUMBER_GENERATOR_HPP

View File

@ -0,0 +1,50 @@
/* boost random/ranlux.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: ranlux.hpp 24096 2004-07-27 03:43:34Z dgregor $
*
* Revision history
* 2001-02-18 created
*/
#ifndef BOOST_RANDOM_RANLUX_HPP
#define BOOST_RANDOM_RANLUX_HPP
#include <boost/config.hpp>
#include <boost/random/subtract_with_carry.hpp>
#include <boost/random/discard_block.hpp>
namespace boost {
namespace random {
typedef subtract_with_carry<int, (1<<24), 10, 24, 0> ranlux_base;
typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01;
typedef subtract_with_carry_01<double, 48, 10, 24> ranlux64_base_01;
}
typedef random::discard_block<random::ranlux_base, 223, 24> ranlux3;
typedef random::discard_block<random::ranlux_base, 389, 24> ranlux4;
typedef random::discard_block<random::ranlux_base_01, 223, 24> ranlux3_01;
typedef random::discard_block<random::ranlux_base_01, 389, 24> ranlux4_01;
typedef random::discard_block<random::ranlux64_base_01, 223, 24> ranlux64_3_01;
typedef random::discard_block<random::ranlux64_base_01, 389, 24> ranlux64_4_01;
#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T)
namespace random {
typedef random::subtract_with_carry<int64_t, (int64_t(1)<<48), 10, 24, 0> ranlux64_base;
}
typedef random::discard_block<random::ranlux64_base, 223, 24> ranlux64_3;
typedef random::discard_block<random::ranlux64_base, 389, 24> ranlux64_4;
#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */
} // namespace boost
#endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP

View File

@ -0,0 +1,175 @@
/* boost random/shuffle_output.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: shuffle_output.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_SHUFFLE_OUTPUT_HPP
#define BOOST_RANDOM_SHUFFLE_OUTPUT_HPP
#include <iostream>
#include <algorithm> // std::copy
#include <cassert>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/random/linear_congruential.hpp>
namespace boost {
namespace random {
// Carter Bays and S.D. Durham 1979
template<class UniformRandomNumberGenerator, int k,
#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
typename UniformRandomNumberGenerator::result_type
#else
uint32_t
#endif
val = 0>
class shuffle_output
{
public:
typedef UniformRandomNumberGenerator base_type;
typedef typename base_type::result_type result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(int, buffer_size = k);
shuffle_output() : _rng() { init(); }
#if defined(BOOST_MSVC) && _MSC_VER < 1300
// MSVC does not implicitly generate the copy constructor here
shuffle_output(const shuffle_output & x)
: _rng(x._rng), y(x.y) { std::copy(x.v, x.v+k, v); }
#endif
template<class T>
explicit shuffle_output(T s) : _rng(s) { init(); }
explicit shuffle_output(const base_type & rng) : _rng(rng) { init(); }
template<class It> shuffle_output(It& first, It last)
: _rng(first, last) { init(); }
void seed() { _rng.seed(); init(); }
template<class T>
void seed(T s) { _rng.seed(s); init(); }
template<class It> void seed(It& first, It last)
{
_rng.seed(first, last);
init();
}
const base_type& base() const { return _rng; }
result_type operator()() {
// calculating the range every time may seem wasteful. However, this
// makes the information locally available for the optimizer.
result_type range = (max)()-(min)()+1;
int j = k*(y-(min)())/range;
// assert(0 <= j && j < k);
y = v[j];
v[j] = _rng();
return y;
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.min)(); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (_rng.max)(); }
static bool validation(result_type x) { return val == x; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const shuffle_output& s)
{
os << s._rng << " " << s.y << " ";
for(int i = 0; i < s.buffer_size; ++i)
os << s.v[i] << " ";
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, shuffle_output& s)
{
is >> s._rng >> std::ws >> s.y >> std::ws;
for(int i = 0; i < s.buffer_size; ++i)
is >> s.v[i] >> std::ws;
return is;
}
#endif
friend bool operator==(const shuffle_output& x, const shuffle_output& y)
{ return x._rng == y._rng && x.y == y.y && std::equal(x.v, x.v+k, y.v); }
friend bool operator!=(const shuffle_output& x, const shuffle_output& y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(const shuffle_output& rhs) const
{ return _rng == rhs._rng && y == rhs.y && std::equal(v, v+k, rhs.v); }
bool operator!=(const shuffle_output& rhs) const
{ return !(*this == rhs); }
#endif
private:
void init()
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_integer);
#endif
result_type range = (max)()-(min)();
assert(range > 0); // otherwise there would be little choice
if(static_cast<unsigned long>(k * range) <
static_cast<unsigned long>(range)) // not a sufficient condition
// likely overflow with bucket number computation
assert(!"overflow will occur");
// we cannot use std::generate, because it uses pass-by-value for _rng
for(result_type * p = v; p != v+k; ++p)
*p = _rng();
y = _rng();
}
base_type _rng;
result_type v[k];
result_type y;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class UniformRandomNumberGenerator, int k,
#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
typename UniformRandomNumberGenerator::result_type
#else
uint32_t
#endif
val>
const bool shuffle_output<UniformRandomNumberGenerator, k, val>::has_fixed_range;
template<class UniformRandomNumberGenerator, int k,
#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
typename UniformRandomNumberGenerator::result_type
#else
uint32_t
#endif
val>
const int shuffle_output<UniformRandomNumberGenerator, k, val>::buffer_size;
#endif
} // namespace random
// validation by experiment from Harry Erwin's generator.h (private e-mail)
typedef random::shuffle_output<
random::linear_congruential<uint32_t, 1366, 150889, 714025, 0>,
97, 139726> kreutzer1986;
} // namespace boost
#endif // BOOST_RANDOM_SHUFFLE_OUTPUT_HPP

View File

@ -0,0 +1,445 @@
/* boost random/subtract_with_carry.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: subtract_with_carry.hpp 29116 2005-05-21 15:57:01Z dgregor $
*
* Revision history
* 2002-03-02 created
*/
#ifndef BOOST_RANDOM_SUBTRACT_WITH_CARRY_HPP
#define BOOST_RANDOM_SUBTRACT_WITH_CARRY_HPP
#include <cmath>
#include <iostream>
#include <algorithm> // std::equal
#include <stdexcept>
#include <cmath> // std::pow
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/random/linear_congruential.hpp>
namespace boost {
namespace random {
#if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
# define BOOST_RANDOM_EXTRACT_SWC_01
#endif
#if defined(__APPLE_CC__) && defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ <= 3)
# define BOOST_RANDOM_EXTRACT_SWC_01
#endif
# ifdef BOOST_RANDOM_EXTRACT_SWC_01
namespace detail
{
template <class IStream, class SubtractWithCarry, class RealType>
void extract_subtract_with_carry_01(
IStream& is
, SubtractWithCarry& f
, RealType& carry
, RealType* x
, RealType modulus)
{
RealType value;
for(unsigned int j = 0; j < f.long_lag; ++j) {
is >> value >> std::ws;
x[j] = value / modulus;
}
is >> value >> std::ws;
carry = value / modulus;
}
}
# endif
// subtract-with-carry generator
// Marsaglia and Zaman
template<class IntType, IntType m, unsigned int s, unsigned int r,
IntType val>
class subtract_with_carry
{
public:
typedef IntType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = true);
BOOST_STATIC_CONSTANT(result_type, min_value = 0);
BOOST_STATIC_CONSTANT(result_type, max_value = m-1);
BOOST_STATIC_CONSTANT(result_type, modulus = m);
BOOST_STATIC_CONSTANT(unsigned int, long_lag = r);
BOOST_STATIC_CONSTANT(unsigned int, short_lag = s);
subtract_with_carry() {
// MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_signed);
BOOST_STATIC_ASSERT(std::numeric_limits<result_type>::is_integer);
#endif
seed();
}
explicit subtract_with_carry(uint32_t value) { seed(value); }
template<class Generator>
explicit subtract_with_carry(Generator & gen) { seed(gen); }
template<class It> subtract_with_carry(It& first, It last) { seed(first,last); }
// compiler-generated copy ctor and assignment operator are fine
void seed(uint32_t value = 19780503u)
{
random::linear_congruential<int32_t, 40014, 0, 2147483563, 0> intgen(value);
seed(intgen);
}
// For GCC, moving this function out-of-line prevents inlining, which may
// reduce overall object code size. However, MSVC does not grok
// out-of-line template member functions.
template<class Generator>
void seed(Generator & gen)
{
// I could have used std::generate_n, but it takes "gen" by value
for(unsigned int j = 0; j < long_lag; ++j)
x[j] = gen() % modulus;
carry = (x[long_lag-1] == 0);
k = 0;
}
template<class It>
void seed(It& first, It last)
{
unsigned int j;
for(j = 0; j < long_lag && first != last; ++j, ++first)
x[j] = *first % modulus;
if(first == last && j < long_lag)
throw std::invalid_argument("subtract_with_carry::seed");
carry = (x[long_lag-1] == 0);
k = 0;
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return min_value; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return max_value; }
result_type operator()()
{
int short_index = k - short_lag;
if(short_index < 0)
short_index += long_lag;
IntType delta;
if (x[short_index] >= x[k] + carry) {
// x(n) >= 0
delta = x[short_index] - (x[k] + carry);
carry = 0;
} else {
// x(n) < 0
delta = modulus - x[k] - carry + x[short_index];
carry = 1;
}
x[k] = delta;
++k;
if(k >= long_lag)
k = 0;
return delta;
}
public:
static bool validation(result_type x) { return x == val; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const subtract_with_carry& f)
{
for(unsigned int j = 0; j < f.long_lag; ++j)
os << f.compute(j) << " ";
os << f.carry << " ";
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, subtract_with_carry& f)
{
for(unsigned int j = 0; j < f.long_lag; ++j)
is >> f.x[j] >> std::ws;
is >> f.carry >> std::ws;
f.k = 0;
return is;
}
#endif
friend bool operator==(const subtract_with_carry& x, const subtract_with_carry& y)
{
for(unsigned int j = 0; j < r; ++j)
if(x.compute(j) != y.compute(j))
return false;
return true;
}
friend bool operator!=(const subtract_with_carry& x, const subtract_with_carry& y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(const subtract_with_carry& rhs) const
{
for(unsigned int j = 0; j < r; ++j)
if(compute(j) != rhs.compute(j))
return false;
return true;
}
bool operator!=(const subtract_with_carry& rhs) const
{ return !(*this == rhs); }
#endif
private:
// returns x(i-r+index), where index is in 0..r-1
IntType compute(unsigned int index) const
{
return x[(k+index) % long_lag];
}
// state representation; next output (state) is x(i)
// x[0] ... x[k] x[k+1] ... x[long_lag-1] represents
// x(i-k) ... x(i) x(i+1) ... x(i-k+long_lag-1)
// speed: base: 20-25 nsec
// ranlux_4: 230 nsec, ranlux_7: 430 nsec, ranlux_14: 810 nsec
// This state representation makes operator== and save/restore more
// difficult, because we've already computed "too much" and thus
// have to undo some steps to get at x(i-r) etc.
// state representation: next output (state) is x(i)
// x[0] ... x[k] x[k+1] ... x[long_lag-1] represents
// x(i-k) ... x(i) x(i-long_lag+1) ... x(i-k-1)
// speed: base 28 nsec
// ranlux_4: 370 nsec, ranlux_7: 688 nsec, ranlux_14: 1343 nsec
IntType x[long_lag];
unsigned int k;
int carry;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
const bool subtract_with_carry<IntType, m, s, r, val>::has_fixed_range;
template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
const IntType subtract_with_carry<IntType, m, s, r, val>::min_value;
template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
const IntType subtract_with_carry<IntType, m, s, r, val>::max_value;
template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
const IntType subtract_with_carry<IntType, m, s, r, val>::modulus;
template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
const unsigned int subtract_with_carry<IntType, m, s, r, val>::long_lag;
template<class IntType, IntType m, unsigned int s, unsigned int r, IntType val>
const unsigned int subtract_with_carry<IntType, m, s, r, val>::short_lag;
#endif
// use a floating-point representation to produce values in [0..1)
template<class RealType, int w, unsigned int s, unsigned int r, int val=0>
class subtract_with_carry_01
{
public:
typedef RealType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(int, word_size = w);
BOOST_STATIC_CONSTANT(unsigned int, long_lag = r);
BOOST_STATIC_CONSTANT(unsigned int, short_lag = s);
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(!std::numeric_limits<result_type>::is_integer);
#endif
subtract_with_carry_01() { init_modulus(); seed(); }
explicit subtract_with_carry_01(uint32_t value)
{ init_modulus(); seed(value); }
template<class It> subtract_with_carry_01(It& first, It last)
{ init_modulus(); seed(first,last); }
private:
void init_modulus()
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::pow;
#endif
_modulus = pow(RealType(2), word_size);
}
public:
// compiler-generated copy ctor and assignment operator are fine
void seed(uint32_t value = 19780503u)
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::fmod;
#endif
random::linear_congruential<int32_t, 40014, 0, 2147483563, 0> gen(value);
unsigned long array[(w+31)/32 * long_lag];
for(unsigned int j = 0; j < sizeof(array)/sizeof(unsigned long); ++j)
array[j] = gen();
unsigned long * start = array;
seed(start, array + sizeof(array)/sizeof(unsigned long));
}
template<class It>
void seed(It& first, It last)
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::fmod;
using std::pow;
#endif
unsigned long mask = ~((~0u) << (w%32)); // now lowest (w%32) bits set
RealType two32 = pow(RealType(2), 32);
unsigned int j;
for(j = 0; j < long_lag && first != last; ++j) {
x[j] = RealType(0);
for(int i = 0; i < w/32 && first != last; ++i, ++first)
x[j] += *first / pow(two32,i+1);
if(first != last && mask != 0) {
x[j] += fmod((*first & mask) / _modulus, RealType(1));
++first;
}
}
if(first == last && j < long_lag)
throw std::invalid_argument("subtract_with_carry_01::seed");
carry = (x[long_lag-1] ? 0 : 1 / _modulus);
k = 0;
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
result_type operator()()
{
int short_index = k - short_lag;
if(short_index < 0)
short_index += long_lag;
RealType delta = x[short_index] - x[k] - carry;
if(delta < 0) {
delta += RealType(1);
carry = RealType(1)/_modulus;
} else {
carry = 0;
}
x[k] = delta;
++k;
if(k >= long_lag)
k = 0;
return delta;
}
static bool validation(result_type x)
{ return x == val/pow(RealType(2), word_size); }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const subtract_with_carry_01& f)
{
#ifndef BOOST_NO_STDC_NAMESPACE
// allow for Koenig lookup
using std::pow;
#endif
std::ios_base::fmtflags oldflags = os.flags(os.dec | os.fixed | os.left);
for(unsigned int j = 0; j < f.long_lag; ++j)
os << (f.compute(j) * f._modulus) << " ";
os << (f.carry * f._modulus);
os.flags(oldflags);
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, subtract_with_carry_01& f)
{
# ifdef BOOST_RANDOM_EXTRACT_SWC_01
detail::extract_subtract_with_carry_01(is, f, f.carry, f.x, f._modulus);
# else
// MSVC (up to 7.1) and Borland (up to 5.64) don't handle the template type
// parameter "RealType" available from the class template scope, so use
// the member typedef
typename subtract_with_carry_01::result_type value;
for(unsigned int j = 0; j < long_lag; ++j) {
is >> value >> std::ws;
f.x[j] = value / f._modulus;
}
is >> value >> std::ws;
f.carry = value / f._modulus;
# endif
f.k = 0;
return is;
}
#endif
friend bool operator==(const subtract_with_carry_01& x,
const subtract_with_carry_01& y)
{
for(unsigned int j = 0; j < r; ++j)
if(x.compute(j) != y.compute(j))
return false;
return true;
}
friend bool operator!=(const subtract_with_carry_01& x,
const subtract_with_carry_01& y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(const subtract_with_carry_01& rhs) const
{
for(unsigned int j = 0; j < r; ++j)
if(compute(j) != rhs.compute(j))
return false;
return true;
}
bool operator!=(const subtract_with_carry_01& rhs) const
{ return !(*this == rhs); }
#endif
private:
RealType compute(unsigned int index) const;
unsigned int k;
RealType carry;
RealType x[long_lag];
RealType _modulus;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class RealType, int w, unsigned int s, unsigned int r, int val>
const bool subtract_with_carry_01<RealType, w, s, r, val>::has_fixed_range;
template<class RealType, int w, unsigned int s, unsigned int r, int val>
const int subtract_with_carry_01<RealType, w, s, r, val>::word_size;
template<class RealType, int w, unsigned int s, unsigned int r, int val>
const unsigned int subtract_with_carry_01<RealType, w, s, r, val>::long_lag;
template<class RealType, int w, unsigned int s, unsigned int r, int val>
const unsigned int subtract_with_carry_01<RealType, w, s, r, val>::short_lag;
#endif
template<class RealType, int w, unsigned int s, unsigned int r, int val>
RealType subtract_with_carry_01<RealType, w, s, r, val>::compute(unsigned int index) const
{
return x[(k+index) % long_lag];
}
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_SUBTRACT_WITH_CARRY_HPP

View File

@ -0,0 +1,101 @@
/* boost random/triangle_distribution.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: triangle_distribution.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP
#define BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP
#include <cmath>
#include <cassert>
#include <boost/random/uniform_01.hpp>
namespace boost {
// triangle distribution, with a smallest, b most probable, and c largest
// value.
template<class RealType = double>
class triangle_distribution
{
public:
typedef RealType input_type;
typedef RealType result_type;
explicit triangle_distribution(result_type a_arg = result_type(0),
result_type b_arg = result_type(0.5),
result_type c_arg = result_type(1))
: _a(a_arg), _b(b_arg), _c(c_arg)
{
assert(_a <= _b && _b <= _c);
init();
}
// compiler-generated copy ctor and assignment operator are fine
result_type a() const { return _a; }
result_type b() const { return _b; }
result_type c() const { return _c; }
void reset() { }
template<class Engine>
result_type operator()(Engine& eng)
{
#ifndef BOOST_NO_STDC_NAMESPACE
using std::sqrt;
#endif
result_type u = eng();
if( u <= q1 )
return _a + p1*sqrt(u);
else
return _c - d3*sqrt(d2*u-d1);
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const triangle_distribution& td)
{
os << td._a << " " << td._b << " " << td._c;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, triangle_distribution& td)
{
is >> std::ws >> td._a >> std::ws >> td._b >> std::ws >> td._c;
td.init();
return is;
}
#endif
private:
void init()
{
#ifndef BOOST_NO_STDC_NAMESPACE
using std::sqrt;
#endif
d1 = _b - _a;
d2 = _c - _a;
d3 = sqrt(_c - _b);
q1 = d1 / d2;
p1 = sqrt(d1 * d2);
}
result_type _a, _b, _c;
result_type d1, d2, d3, q1, p1;
};
} // namespace boost
#endif // BOOST_RANDOM_TRIANGLE_DISTRIBUTION_HPP

View File

@ -0,0 +1,97 @@
/* boost random/uniform_01.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: uniform_01.hpp 41369 2007-11-25 18:07:19Z bemandawes $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_01_HPP
#define BOOST_RANDOM_UNIFORM_01_HPP
#include <iostream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
namespace boost {
// Because it is so commonly used: uniform distribution on the real [0..1)
// range. This allows for specializations to avoid a costly int -> float
// conversion plus float multiplication
template<class UniformRandomNumberGenerator, class RealType = double>
class uniform_01
{
public:
typedef UniformRandomNumberGenerator base_type;
typedef RealType result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
explicit uniform_01(base_type rng)
: _rng(rng),
_factor(result_type(1) /
(result_type((_rng.max)()-(_rng.min)()) +
result_type(std::numeric_limits<base_result>::is_integer ? 1 : 0)))
{
}
// compiler-generated copy ctor and copy assignment are fine
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); }
base_type& base() { return _rng; }
const base_type& base() const { return _rng; }
void reset() { }
result_type operator()() {
for (;;) {
result_type result = result_type(_rng() - (_rng.min)()) * _factor;
if (result < result_type(1))
return result;
}
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_01& u)
{
os << u._rng;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, uniform_01& u)
{
is >> u._rng;
return is;
}
#endif
private:
typedef typename base_type::result_type base_result;
base_type _rng;
result_type _factor;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class UniformRandomNumberGenerator, class RealType>
const bool uniform_01<UniformRandomNumberGenerator, RealType>::has_fixed_range;
#endif
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_01_HPP

View File

@ -0,0 +1,162 @@
/* boost random/uniform_int.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: uniform_int.hpp 47233 2008-07-08 16:22:46Z steven_watanabe $
*
* Revision history
* 2001-04-08 added min<max assertion (N. Becker)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_INT_HPP
#define BOOST_RANDOM_UNIFORM_INT_HPP
#include <cassert>
#include <iostream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/random/uniform_smallint.hpp>
#include <boost/random/detail/signed_unsigned_tools.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
#include <boost/type_traits/is_float.hpp>
#endif
namespace boost {
// uniform integer distribution on [min, max]
template<class IntType = int>
class uniform_int
{
public:
typedef IntType input_type;
typedef IntType result_type;
typedef typename make_unsigned<result_type>::type range_type;
explicit uniform_int(IntType min_arg = 0, IntType max_arg = 9)
: _min(min_arg), _max(max_arg)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
// MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
#endif
assert(min_arg <= max_arg);
init();
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
void reset() { }
// can't have member function templates out-of-line due to MSVC bugs
template<class Engine>
result_type operator()(Engine& eng)
{
typedef typename Engine::result_type base_result;
// ranges are always unsigned
typedef typename make_unsigned<base_result>::type base_unsigned;
const base_result bmin = (eng.min)();
const base_unsigned brange =
random::detail::subtract<base_result>()((eng.max)(), (eng.min)());
if(_range == 0) {
return _min;
} else if(brange == _range) {
// this will probably never happen in real life
// basically nothing to do; just take care we don't overflow / underflow
base_unsigned v = random::detail::subtract<base_result>()(eng(), bmin);
return random::detail::add<base_unsigned, result_type>()(v, _min);
} else if(brange < _range) {
// use rejection method to handle things like 0..3 --> 0..4
for(;;) {
// concatenate several invocations of the base RNG
// take extra care to avoid overflows
range_type limit;
if(_range == (std::numeric_limits<range_type>::max)()) {
limit = _range/(range_type(brange)+1);
if(_range % range_type(brange)+1 == range_type(brange))
++limit;
} else {
limit = (_range+1)/(range_type(brange)+1);
}
// We consider "result" as expressed to base (brange+1):
// For every power of (brange+1), we determine a random factor
range_type result = range_type(0);
range_type mult = range_type(1);
while(mult <= limit) {
result += random::detail::subtract<base_result>()(eng(), bmin) * mult;
mult *= range_type(brange)+range_type(1);
}
if(mult == limit)
// _range+1 is an integer power of brange+1: no rejections required
return result;
// _range/mult < brange+1 -> no endless loop
result += uniform_int<range_type>(0, _range/mult)(eng) * mult;
if(result <= _range)
return random::detail::add<range_type, result_type>()(result, _min);
}
} else { // brange > range
if(brange / _range > 4 /* quantization_cutoff */ ) {
// the new range is vastly smaller than the source range,
// so quantization effects are not relevant
return boost::uniform_smallint<result_type>(_min, _max)(eng);
} else {
// use rejection method to handle cases like 0..5 -> 0..4
for(;;) {
base_unsigned result =
random::detail::subtract<base_result>()(eng(), bmin);
// result and range are non-negative, and result is possibly larger
// than range, so the cast is safe
if(result <= static_cast<base_unsigned>(_range))
return random::detail::add<base_unsigned, result_type>()(result, _min);
}
}
}
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_int& ud)
{
os << ud._min << " " << ud._max;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, uniform_int& ud)
{
# if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC == 1400
return detail::extract_uniform_int(is, ud, ud.impl);
# else
is >> std::ws >> ud._min >> std::ws >> ud._max;
ud.init();
return is;
# endif
}
#endif
private:
void init()
{
_range = random::detail::subtract<result_type>()(_max, _min);
}
// The result_type may be signed or unsigned, but the _range is always
// unsigned.
result_type _min, _max;
range_type _range;
};
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_INT_HPP

View File

@ -0,0 +1,86 @@
/* boost random/uniform_on_sphere.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: uniform_on_sphere.hpp 24096 2004-07-27 03:43:34Z dgregor $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP
#define BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP
#include <vector>
#include <algorithm> // std::transform
#include <functional> // std::bind2nd, std::divides
#include <boost/random/normal_distribution.hpp>
namespace boost {
template<class RealType = double, class Cont = std::vector<RealType> >
class uniform_on_sphere
{
public:
typedef RealType input_type;
typedef Cont result_type;
explicit uniform_on_sphere(int dim = 2) : _container(dim), _dim(dim) { }
// compiler-generated copy ctor and assignment operator are fine
void reset() { _normal.reset(); }
template<class Engine>
const result_type & operator()(Engine& eng)
{
RealType sqsum = 0;
for(typename Cont::iterator it = _container.begin();
it != _container.end();
++it) {
RealType val = _normal(eng);
*it = val;
sqsum += val * val;
}
#ifndef BOOST_NO_STDC_NAMESPACE
using std::sqrt;
#endif
// for all i: result[i] /= sqrt(sqsum)
std::transform(_container.begin(), _container.end(), _container.begin(),
std::bind2nd(std::divides<RealType>(), sqrt(sqsum)));
return _container;
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_on_sphere& sd)
{
os << sd._dim;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, uniform_on_sphere& sd)
{
is >> std::ws >> sd._dim;
sd._container.resize(sd._dim);
return is;
}
#endif
private:
normal_distribution<RealType> _normal;
result_type _container;
int _dim;
};
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP

View File

@ -0,0 +1,83 @@
/* boost random/uniform_real.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: uniform_real.hpp 47233 2008-07-08 16:22:46Z steven_watanabe $
*
* Revision history
* 2001-04-08 added min<max assertion (N. Becker)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_REAL_HPP
#define BOOST_RANDOM_UNIFORM_REAL_HPP
#include <cassert>
#include <iostream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
namespace boost {
// uniform distribution on a real range
template<class RealType = double>
class uniform_real
{
public:
typedef RealType input_type;
typedef RealType result_type;
explicit uniform_real(RealType min_arg = RealType(0),
RealType max_arg = RealType(1))
: _min(min_arg), _max(max_arg)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
#endif
assert(min_arg <= max_arg);
}
// compiler-generated copy ctor and assignment operator are fine
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
void reset() { }
template<class Engine>
result_type operator()(Engine& eng) {
return static_cast<result_type>(eng() - eng.min BOOST_PREVENT_MACRO_SUBSTITUTION())
/ static_cast<result_type>(eng.max BOOST_PREVENT_MACRO_SUBSTITUTION() - eng.min BOOST_PREVENT_MACRO_SUBSTITUTION())
* (_max - _min) + _min;
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_real& ud)
{
os << ud._min << " " << ud._max;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, uniform_real& ud)
{
is >> std::ws >> ud._min >> std::ws >> ud._max;
return is;
}
#endif
private:
RealType _min, _max;
};
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_REAL_HPP

View File

@ -0,0 +1,236 @@
/* boost random/uniform_smallint.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: uniform_smallint.hpp 47233 2008-07-08 16:22:46Z steven_watanabe $
*
* Revision history
* 2001-04-08 added min<max assertion (N. Becker)
* 2001-02-18 moved to individual header files
*/
#ifndef BOOST_RANDOM_UNIFORM_SMALLINT_HPP
#define BOOST_RANDOM_UNIFORM_SMALLINT_HPP
#include <cassert>
#include <iostream>
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/detail/workaround.hpp>
#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
#include <boost/type_traits/is_float.hpp>
#endif
namespace boost {
// uniform integer distribution on a small range [min, max]
namespace detail {
template <class InputStream, class UniformInt, class Impl>
InputStream& extract_uniform_int(InputStream& is, UniformInt& ud, Impl& impl)
{
typename UniformInt::result_type min, max;
is >> std::ws >> min >> std::ws >> max;
impl.set(min, max);
return is;
}
template<class UniformRandomNumberGenerator, class IntType>
struct uniform_smallint_integer
{
public:
typedef UniformRandomNumberGenerator base_type;
typedef IntType result_type;
uniform_smallint_integer(base_type & rng, IntType min_arg, IntType max_arg)
: _rng(&rng)
{ set(min_arg, max_arg); }
void set(result_type min, result_type max);
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
base_type& base() const { return *_rng; }
result_type operator()()
{
// we must not use the low bits here, because LCGs get very bad then
return (((*_rng)() - (_rng->min)()) / _factor) % _range + _min;
}
private:
typedef typename base_type::result_type base_result;
base_type * _rng;
IntType _min, _max;
base_result _range;
base_result _factor;
};
template<class UniformRandomNumberGenerator, class IntType>
void uniform_smallint_integer<UniformRandomNumberGenerator, IntType>::
set(result_type min_arg, result_type max_arg)
{
_min = min_arg;
_max = max_arg;
assert(min_arg <= max_arg);
_range = static_cast<base_result>(_max-_min)+1;
_factor = 1;
// LCGs get bad when only taking the low bits.
// (probably put this logic into a partial template specialization)
// Check how many low bits we can ignore before we get too much
// quantization error.
base_result r_base = (_rng->max)() - (_rng->min)();
if(r_base == (std::numeric_limits<base_result>::max)()) {
_factor = 2;
r_base /= 2;
}
r_base += 1;
if(r_base % _range == 0) {
// No quantization effects, good
_factor = r_base / _range;
} else {
// carefully avoid overflow; pessimizing heree
for( ; r_base/_range/32 >= _range; _factor *= 2)
r_base /= 2;
}
}
template<class UniformRandomNumberGenerator, class IntType>
class uniform_smallint_float
{
public:
typedef UniformRandomNumberGenerator base_type;
typedef IntType result_type;
uniform_smallint_float(base_type & rng, IntType min_arg, IntType max_arg)
: _rng(rng)
{
// MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
BOOST_STATIC_ASSERT(!std::numeric_limits<typename base_type::result_type>::is_integer);
#endif
assert(min_arg <= max_arg);
set(min_arg, max_arg);
}
void set(result_type min_arg, result_type max_arg)
{
_min = min_arg;
_max = max_arg;
_range = static_cast<base_result>(_max-_min)+1;
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
base_type& base() const { return _rng.base(); }
result_type operator()()
{
return static_cast<IntType>(_rng() * _range) + _min;
}
private:
typedef typename base_type::result_type base_result;
uniform_01<base_type> _rng;
IntType _min, _max;
base_result _range;
};
} // namespace detail
template<class IntType = int>
class uniform_smallint
{
public:
typedef IntType input_type;
typedef IntType result_type;
explicit uniform_smallint(IntType min_arg = 0, IntType max_arg = 9)
: _min(min_arg), _max(max_arg)
{
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
// MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_integer);
#endif
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; }
void reset() { }
template<class Engine>
result_type operator()(Engine& eng)
{
typedef typename Engine::result_type base_result;
base_result _range = static_cast<base_result>(_max-_min)+1;
base_result _factor = 1;
// LCGs get bad when only taking the low bits.
// (probably put this logic into a partial template specialization)
// Check how many low bits we can ignore before we get too much
// quantization error.
base_result r_base = (eng.max)() - (eng.min)();
if(r_base == (std::numeric_limits<base_result>::max)()) {
_factor = 2;
r_base /= 2;
}
r_base += 1;
if(r_base % _range == 0) {
// No quantization effects, good
_factor = r_base / _range;
} else {
// carefully avoid overflow; pessimizing heree
for( ; r_base/_range/32 >= _range; _factor *= 2)
r_base /= 2;
}
return ((eng() - (eng.min)()) / _factor) % _range + _min;
}
#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const uniform_smallint& ud)
{
os << ud._min << " " << ud._max;
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, uniform_smallint& ud)
{
# if BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
return detail::extract_uniform_int(is, ud, ud._impl);
# else
is >> std::ws >> ud._min >> std::ws >> ud._max;
return is;
# endif
}
#endif
private:
result_type _min;
result_type _max;
};
} // namespace boost
#endif // BOOST_RANDOM_UNIFORM_SMALLINT_HPP

View File

@ -0,0 +1,133 @@
/* boost random/variate_generator.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: variate_generator.hpp 27375 2005-02-14 11:53:50Z johnmaddock $
*
*/
#ifndef BOOST_RANDOM_RANDOM_GENERATOR_HPP
#define BOOST_RANDOM_RANDOM_GENERATOR_HPP
#include <boost/config.hpp>
// implementation details
#include <boost/detail/workaround.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/detail/pass_through_engine.hpp>
#include <boost/random/detail/uniform_int_float.hpp>
#include <boost/random/detail/ptr_helper.hpp>
// Borland C++ 5.6.0 has problems using its numeric_limits traits as
// template parameters
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x564)
#include <boost/type_traits/is_integral.hpp>
#endif
namespace boost {
namespace random {
namespace detail {
template<bool have_int, bool want_int>
struct engine_helper;
// for consistency, always have two levels of decorations
template<>
struct engine_helper<true, true>
{
template<class Engine, class DistInputType>
struct impl
{
typedef pass_through_engine<Engine> type;
};
};
template<>
struct engine_helper<false, false>
{
template<class Engine, class DistInputType>
struct impl
{
typedef uniform_01<Engine, DistInputType> type;
};
};
template<>
struct engine_helper<true, false>
{
template<class Engine, class DistInputType>
struct impl
{
typedef uniform_01<Engine, DistInputType> type;
};
};
template<>
struct engine_helper<false, true>
{
template<class Engine, class DistInputType>
struct impl
{
typedef uniform_int_float<Engine, unsigned long> type;
};
};
} // namespace detail
} // namespace random
template<class Engine, class Distribution>
class variate_generator
{
private:
typedef random::detail::pass_through_engine<Engine> decorated_engine;
public:
typedef typename decorated_engine::base_type engine_value_type;
typedef Engine engine_type;
typedef Distribution distribution_type;
typedef typename Distribution::result_type result_type;
variate_generator(Engine e, Distribution d)
: _eng(decorated_engine(e)), _dist(d) { }
result_type operator()() { return _dist(_eng); }
template<class T>
result_type operator()(T value) { return _dist(_eng, value); }
engine_value_type& engine() { return _eng.base().base(); }
const engine_value_type& engine() const { return _eng.base().base(); }
distribution_type& distribution() { return _dist; }
const distribution_type& distribution() const { return _dist; }
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (distribution().min)(); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return (distribution().max)(); }
private:
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x564)
typedef typename random::detail::engine_helper<
boost::is_integral<typename decorated_engine::result_type>::value,
boost::is_integral<typename Distribution::input_type>::value
>::BOOST_NESTED_TEMPLATE impl<decorated_engine, typename Distribution::input_type>::type internal_engine_type;
#else
enum {
have_int = std::numeric_limits<typename decorated_engine::result_type>::is_integer,
want_int = std::numeric_limits<typename Distribution::input_type>::is_integer
};
typedef typename random::detail::engine_helper<have_int, want_int>::BOOST_NESTED_TEMPLATE impl<decorated_engine, typename Distribution::input_type>::type internal_engine_type;
#endif
internal_engine_type _eng;
distribution_type _dist;
};
} // namespace boost
#endif // BOOST_RANDOM_RANDOM_GENERATOR_HPP

View File

@ -0,0 +1,130 @@
/* boost random/xor_combine.hpp header file
*
* Copyright Jens Maurer 2002
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: xor_combine.hpp 29116 2005-05-21 15:57:01Z dgregor $
*
*/
#ifndef BOOST_RANDOM_XOR_COMBINE_HPP
#define BOOST_RANDOM_XOR_COMBINE_HPP
#include <iostream>
#include <cassert>
#include <algorithm> // for std::min and std::max
#include <boost/config.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/cstdint.hpp> // uint32_t
namespace boost {
namespace random {
template<class URNG1, int s1, class URNG2, int s2,
#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
typename URNG1::result_type
#else
uint32_t
#endif
val = 0>
class xor_combine
{
public:
typedef URNG1 base1_type;
typedef URNG2 base2_type;
typedef typename base1_type::result_type result_type;
BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
BOOST_STATIC_CONSTANT(int, shift1 = s1);
BOOST_STATIC_CONSTANT(int, shfit2 = s2);
xor_combine() : _rng1(), _rng2()
{ }
xor_combine(const base1_type & rng1, const base2_type & rng2)
: _rng1(rng1), _rng2(rng2) { }
template<class It> xor_combine(It& first, It last)
: _rng1(first, last), _rng2( /* advanced by other call */ first, last) { }
void seed() { _rng1.seed(); _rng2.seed(); }
template<class It> void seed(It& first, It last)
{
_rng1.seed(first, last);
_rng2.seed(first, last);
}
const base1_type& base1() { return _rng1; }
const base2_type& base2() { return _rng2; }
result_type operator()()
{
// MSVC fails BOOST_STATIC_ASSERT with std::numeric_limits at class scope
#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) && !(defined(BOOST_MSVC) && BOOST_MSVC <= 1300)
BOOST_STATIC_ASSERT(std::numeric_limits<typename base1_type::result_type>::is_integer);
BOOST_STATIC_ASSERT(std::numeric_limits<typename base2_type::result_type>::is_integer);
BOOST_STATIC_ASSERT(std::numeric_limits<typename base1_type::result_type>::digits >= std::numeric_limits<typename base2_type::result_type>::digits);
#endif
return (_rng1() << s1) ^ (_rng2() << s2);
}
result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::min BOOST_PREVENT_MACRO_SUBSTITUTION((_rng1.min)(), (_rng2.min)()); }
result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return std::max BOOST_PREVENT_MACRO_SUBSTITUTION((_rng1.min)(), (_rng2.max)()); }
static bool validation(result_type x) { return val == x; }
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os, const xor_combine& s)
{
os << s._rng1 << " " << s._rng2 << " ";
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is, xor_combine& s)
{
is >> s._rng1 >> std::ws >> s._rng2 >> std::ws;
return is;
}
#endif
friend bool operator==(const xor_combine& x, const xor_combine& y)
{ return x._rng1 == y._rng1 && x._rng2 == y._rng2; }
friend bool operator!=(const xor_combine& x, const xor_combine& y)
{ return !(x == y); }
#else
// Use a member function; Streamable concept not supported.
bool operator==(const xor_combine& rhs) const
{ return _rng1 == rhs._rng1 && _rng2 == rhs._rng2; }
bool operator!=(const xor_combine& rhs) const
{ return !(*this == rhs); }
#endif
private:
base1_type _rng1;
base2_type _rng2;
};
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
// A definition is required even for integral static constants
template<class URNG1, int s1, class URNG2, int s2,
#ifndef BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
typename URNG1::result_type
#else
uint32_t
#endif
val>
const bool xor_combine<URNG1, s1, URNG2, s2, val>::has_fixed_range;
#endif
} // namespace random
} // namespace boost
#endif // BOOST_RANDOM_XOR_COMBINE_HPP

91
src/3rdparty/include/md5/md5.h vendored Normal file
View File

@ -0,0 +1,91 @@
/*
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
#ifndef md5_INCLUDED
# define md5_INCLUDED
/*
* This package supports both compile-time and run-time determination of CPU
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
* defined as non-zero, the code will be compiled to run only on big-endian
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
* run on either big- or little-endian CPUs, but will run slightly less
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/
typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */
/* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s {
md5_word_t count[2]; /* message length in bits, lsw first */
md5_word_t abcd[4]; /* digest buffer */
md5_byte_t buf[64]; /* accumulate block */
} md5_state_t;
#ifdef __cplusplus
extern "C"
{
#endif
/* Initialize the algorithm. */
void md5_init(md5_state_t *pms);
/* Append a string to the message. */
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
/* Finish the message and return the digest. */
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* md5_INCLUDED */

381
src/3rdparty/src/md5/md5.c vendored Normal file
View File

@ -0,0 +1,381 @@
/*
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.c is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
either statically or dynamically; added missing #include <string.h>
in library.
2002-03-11 lpd Corrected argument list for main(), and added int return
type, in test program and T value program.
2002-02-21 lpd Added missing #include <stdio.h> in test program.
2000-07-03 lpd Patched to eliminate warnings about "constant is
unsigned in ANSI C, signed in traditional"; made test program
self-checking.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1999-05-03 lpd Original version.
*/
#include "md5.h"
#include <string.h>
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else
# define BYTE_ORDER 0
#endif
#define T_MASK ((md5_word_t)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
static void
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
md5_word_t
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
md5_word_t X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
md5_word_t xbuf[16];
const md5_word_t *X;
#endif
{
#if BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const md5_byte_t *)0) & 3)) {
/* data are properly aligned */
X = (const md5_word_t *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
X = xbuf;
}
}
#endif
#if BYTE_ORDER == 0
else /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const md5_byte_t *xp = data;
int i;
# if BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
# else
# define xbuf X /* (static only) */
# endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + F(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, T1);
SET(d, a, b, c, 1, 12, T2);
SET(c, d, a, b, 2, 17, T3);
SET(b, c, d, a, 3, 22, T4);
SET(a, b, c, d, 4, 7, T5);
SET(d, a, b, c, 5, 12, T6);
SET(c, d, a, b, 6, 17, T7);
SET(b, c, d, a, 7, 22, T8);
SET(a, b, c, d, 8, 7, T9);
SET(d, a, b, c, 9, 12, T10);
SET(c, d, a, b, 10, 17, T11);
SET(b, c, d, a, 11, 22, T12);
SET(a, b, c, d, 12, 7, T13);
SET(d, a, b, c, 13, 12, T14);
SET(c, d, a, b, 14, 17, T15);
SET(b, c, d, a, 15, 22, T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + G(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, T17);
SET(d, a, b, c, 6, 9, T18);
SET(c, d, a, b, 11, 14, T19);
SET(b, c, d, a, 0, 20, T20);
SET(a, b, c, d, 5, 5, T21);
SET(d, a, b, c, 10, 9, T22);
SET(c, d, a, b, 15, 14, T23);
SET(b, c, d, a, 4, 20, T24);
SET(a, b, c, d, 9, 5, T25);
SET(d, a, b, c, 14, 9, T26);
SET(c, d, a, b, 3, 14, T27);
SET(b, c, d, a, 8, 20, T28);
SET(a, b, c, d, 13, 5, T29);
SET(d, a, b, c, 2, 9, T30);
SET(c, d, a, b, 7, 14, T31);
SET(b, c, d, a, 12, 20, T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
t = a + H(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, T33);
SET(d, a, b, c, 8, 11, T34);
SET(c, d, a, b, 11, 16, T35);
SET(b, c, d, a, 14, 23, T36);
SET(a, b, c, d, 1, 4, T37);
SET(d, a, b, c, 4, 11, T38);
SET(c, d, a, b, 7, 16, T39);
SET(b, c, d, a, 10, 23, T40);
SET(a, b, c, d, 13, 4, T41);
SET(d, a, b, c, 0, 11, T42);
SET(c, d, a, b, 3, 16, T43);
SET(b, c, d, a, 6, 23, T44);
SET(a, b, c, d, 9, 4, T45);
SET(d, a, b, c, 12, 11, T46);
SET(c, d, a, b, 15, 16, T47);
SET(b, c, d, a, 2, 23, T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + I(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, T49);
SET(d, a, b, c, 7, 10, T50);
SET(c, d, a, b, 14, 15, T51);
SET(b, c, d, a, 5, 21, T52);
SET(a, b, c, d, 12, 6, T53);
SET(d, a, b, c, 3, 10, T54);
SET(c, d, a, b, 10, 15, T55);
SET(b, c, d, a, 1, 21, T56);
SET(a, b, c, d, 8, 6, T57);
SET(d, a, b, c, 15, 10, T58);
SET(c, d, a, b, 6, 15, T59);
SET(b, c, d, a, 13, 21, T60);
SET(a, b, c, d, 4, 6, T61);
SET(d, a, b, c, 11, 10, T62);
SET(c, d, a, b, 2, 15, T63);
SET(b, c, d, a, 9, 21, T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void
md5_init(md5_state_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
void
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
{
const md5_byte_t *p = data;
int left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p);
/* Process a final partial block. */
if (left)
memcpy(pms->buf, p, left);
}
void
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
static const md5_byte_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
md5_byte_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}

View File

@ -69,4 +69,20 @@ namespace musik{ namespace core{
} }
// UTF Conversion MACROS
#ifdef UTF_WIDECHAR
#define UTF_TO_UTF8(s) musik::core::ConvertUTF8(s)
#define UTF_TO_UTF16(s) s
#define UTF8_TO_UTF(s) musik::core::ConvertUTF16(s)
#define UTF16_TO_UTF(s) s
#else
#define UTF_TO_UTF8(s) s
#define UTF_TO_UTF16(s) musik::core::ConvertUTF16(s)
#define UTF8_TO_UTF(s) s
#define UTF16_TO_UTF(s) musik::core::ConvertUTF8(s)
#endif

94
src/core/Crypt.cpp Normal file
View File

@ -0,0 +1,94 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2008, mC2 team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include <core/Crypt.h>
#include <core/config_format.h>
#include <md5/md5.h>
#include <boost/random.hpp>
//////////////////////////////////////////////////////////////////////////////
using namespace musik::core;
//////////////////////////////////////////////////////////////////////////////
std::string Crypt::GenerateSalt(){
const std::string characters("ABCDEFGHKLMNOPQRSTWXYZabcdefghjkmnpqrstwxyz123456789");
typedef boost::mt19937 RandomGenerator;
RandomGenerator randomGenerator;
boost::uniform_int<> randDistribution(0,(int)characters.size()-1);
boost::variate_generator<RandomGenerator&, boost::uniform_int<> > rand(randomGenerator, randDistribution);
std::string salt;
for(int i(0);i<64;++i){
salt += characters.at(rand());
}
return salt;
}
std::string Crypt::StaticSalt(){
return "mC2, don't be square";
}
std::string Crypt::Encrypt(std::string cryptContent,std::string salt){
md5_state_t md5State;
md5_init(&md5State);
std::string encryptString = cryptContent+salt;
md5_append(&md5State,(const md5_byte_t *)encryptString.c_str(),(int)encryptString.size());
// Encrypted result
md5_byte_t result[16];
// Get the results
md5_finish(&md5State, result);
// Add result to encryptedString
std::string encryptedHexString;
boost::format formatHex("%1$02x");
for(int i=0;i<16;++i){
int hex = result[i];
formatHex%hex;
encryptedHexString += formatHex.str();
formatHex.clear();
}
return encryptedHexString;
}

56
src/core/Crypt.h Normal file
View File

@ -0,0 +1,56 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2008, mC2 team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#include <core/config.h>
//////////////////////////////////////////////////////////////////////////////
namespace musik{ namespace core{
//////////////////////////////////////////////////////////////////////////////
class Crypt{
public:
static std::string GenerateSalt();
static std::string StaticSalt();
static std::string Encrypt(std::string cryptContent,std::string salt);
};
//////////////////////////////////////////////////////////////////////////////
} }
//////////////////////////////////////////////////////////////////////////////

View File

@ -41,6 +41,7 @@
#include <core/Preferences.h>
#include <core/xml/Parser.h>
#include <core/xml/Writer.h>
#include <core/Crypt.h>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
@ -120,11 +121,15 @@ bool Library::Remote::Startup(){
//////////////////////////////////////////
void Library::Remote::ReadThread(){
std::string username,password;
{
Preferences prefs("Connection",this->Identifier().c_str());
this->address = ConvertUTF8(prefs.GetString("address",UTF("localhost")));
this->port = ConvertUTF8(prefs.GetString("port",UTF("10543")));
this->address = UTF_TO_UTF8(prefs.GetString("address",UTF("localhost")));
this->port = UTF_TO_UTF8(prefs.GetString("port",UTF("10543")));
this->username = UTF_TO_UTF8(prefs.GetString("username",UTF("")));
this->password = UTF_TO_UTF8(prefs.GetString("password",UTF("")));
}
boost::asio::ip::tcp::resolver resolver(this->ioService);
@ -158,21 +163,27 @@ void Library::Remote::ReadThread(){
return;
}
// Successfully connected to server
// Start the WriteThread
try{
this->threads.create_thread(boost::bind(&Library::Remote::WriteThread,this));
}
catch(...){
this->Exit();
return;
}
try{
// Lets start recieving queries
xml::Parser parser(&this->socket);
if( xml::ParserNode rootNode=parser.ChildNode("musik")){
// Start by waiting for the authentication node
if( xml::ParserNode authNode=rootNode.ChildNode("authentication")){
authNode.WaitForContent();
this->sessionId = authNode.Content();
}else{
this->Exit();
return;
}
// Successfully connected to server
// Start the WriteThread
this->threads.create_thread(boost::bind(&Library::Remote::WriteThread,this));
while(xml::ParserNode node=rootNode.ChildNode()){
if(node.Name()=="queryresults"){
@ -223,6 +234,14 @@ void Library::Remote::WriteThread(){
// Start by writing the musik-tag
xml::WriterNode rootNode(writer,"musik");
//Start by writing the authentication
{
xml::WriterNode authNode(rootNode,"authentication");
authNode.Attributes()["username"] = this->username;
authNode.Content() = musik::core::Crypt::Encrypt(this->password,this->sessionId);
}
while(!this->Exited()){
Query::Ptr query(this->GetNextQuery());
@ -313,7 +332,7 @@ utfstring Library::Remote::BasePath(){
boost::asio::ip::tcp::endpoint endPoint = this->socket.remote_endpoint();
boost::asio::ip::address address = endPoint.address();
path += musik::core::ConvertUTF16(address.to_string());
path += UTF(":") + musik::core::ConvertUTF16(this->port) + UTF("/");
path += UTF8_TO_UTF(address.to_string());
path += UTF(":") + UTF8_TO_UTF(this->port) + UTF("/");
return path;
}

View File

@ -84,6 +84,9 @@ class Remote : public Library::Base{
std::string address;
std::string port;
std::string username;
std::string password;
std::string sessionId;
};
//////////////////////////////////////////

View File

@ -39,7 +39,7 @@
#include <core/Preferences.h>
#include <core/Common.h>
#include <core/Library/Base.h>
#include <core/db/Connection.h>
#include <core/Crypt.h>
#include <boost/bind.hpp>
@ -82,22 +82,37 @@ bool Server::Startup(){
return true;
}
utfstring Server::ServerIdentifier(){
return UTF("server");
}
void Server::ThreadLoop(){
// Get server preferences
musik::core::Preferences prefs("Server");
// Get directory and database paths
utfstring directory( musik::core::GetDataDirectory()+UTF("server/") );
utfstring directory( musik::core::GetDataDirectory()+this->ServerIdentifier()+UTF("/") );
utfstring database(directory+UTF("musik.db"));
this->httpServer.Startup(database);
// Create database
this->db.Open(database.c_str(),0,prefs.GetInt("DatabaseCache",4096));
Library::Base::CreateDatabase(this->db);
{
// Create database
db::Connection db;
db.Open(database.c_str(),0,prefs.GetInt("DatabaseCache",4096));
Library::Base::CreateDatabase(db);
/* {
db::Statement stmt("SELECT id,name,login,password FROM users",db);
while(stmt.Step()==db::Row){
boost::mutex::scoped_lock lock(this->serverMutex);
this->allUsers[stmt.ColumnTextUTF(2)] = server::UserPtr(new server::User(
stmt.ColumnInt(0),
stmt.ColumnTextUTF(2),
stmt.ColumnTextUTF(3),
stmt.ColumnTextUTF(1)
));
}
}
*/
this->httpServer.Startup(database);
// Start the indexer
this->indexer.database = database;
@ -121,7 +136,7 @@ void Server::ThreadLoop(){
}
void Server::SetNextConnection(){
this->nextConnection.reset( new musik::core::server::Connection(this->ioService) );
this->nextConnection.reset( new musik::core::server::Connection(this->ioService,this) );
this->acceptor.async_accept(this->nextConnection->Socket(),boost::bind(&Server::AcceptConnection,this,boost::asio::placeholders::error));
}
@ -147,3 +162,91 @@ void Server::CleanupConnections(){
}
}
bool Server::CreateUser(const utfstring username,const utfstring plainTextPassword,const utfstring name){
utfstring password(
UTF8_TO_UTF(
musik::core::Crypt::Encrypt(
UTF_TO_UTF8(plainTextPassword),musik::core::Crypt::StaticSalt())));
db::Statement stmt("INSERT INTO users (login,password,name) VALUES (?,?,?)",this->db);
stmt.BindTextUTF(0,username.c_str());
stmt.BindTextUTF(1,password.c_str());
stmt.BindTextUTF(2,name.c_str());
bool returnBool(stmt.Step()==db::Done);
this->UsersUpdated();
return returnBool;
}
bool Server::DeleteUser(const utfstring username){
db::Statement stmt("DELETE FROM users WHERE login=?",this->db);
stmt.BindTextUTF(0,username.c_str());
bool returnBool(stmt.Step()==db::Done);
this->UsersUpdated();
return returnBool;
}
server::UserVector Server::AllUsers(){
server::UserVector users;
db::Statement stmt("SELECT id,name,login,password FROM users ORDER BY login",this->db);
while(stmt.Step()==db::Row){
users.push_back(server::UserPtr(new server::User(
stmt.ColumnInt(0),
stmt.ColumnTextUTF(2),
stmt.ColumnTextUTF(3),
stmt.ColumnTextUTF(1)
)));
}
return users;
}
server::UserSessionVector Server::ConnectedUserSessions(){
boost::mutex::scoped_lock lock(this->serverMutex);
server::UserSessionVector userSessionVector;
for(server::UserSessionMap::iterator userSession=this->connectedUsers.begin();userSession!=this->connectedUsers.end();++userSession){
userSessionVector.push_back(userSession->second);
}
return userSessionVector;
}
bool Server::AddUserSession(server::UserSessionPtr userSession){
{
boost::mutex::scoped_lock lock(this->serverMutex);
this->connectedUsers[userSession->UniqueId()] = userSession;
}
this->UserSessionsUpdated();
return true;
}
bool Server::RemoveUserSession(server::UserSessionPtr userSession){
{
boost::mutex::scoped_lock lock(this->serverMutex);
this->connectedUsers.erase(userSession->UniqueId());
}
this->UserSessionsUpdated();
return true;
}
server::UserPtr Server::GetUser(const utfstring username){
server::UserPtr user;
db::Statement stmt("SELECT id,name,login,password FROM users WHERE login=?",this->db);
stmt.BindTextUTF(0,username);
if(stmt.Step()==db::Row){
user.reset( new server::User(
stmt.ColumnInt(0),
stmt.ColumnTextUTF(2),
stmt.ColumnTextUTF(3),
stmt.ColumnTextUTF(1)
));
}
return user;
}

View File

@ -37,15 +37,21 @@
#include <core/config.h>
#include <core/server/Connection.h>
#include <core/db/Connection.h>
#include <core/Indexer.h>
#include <core/http/Server.h>
#include <core/server/User.h>
#include <core/server/UserSession.h>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>
#include <sigslot/sigslot.h>
//////////////////////////////////////////////////////////////////////////////
namespace musik{ namespace core{
@ -70,6 +76,19 @@ class Server{
~Server(void);
bool Startup();
bool CreateUser(const utfstring username,const utfstring plainTextPassword,const utfstring name);
bool DeleteUser(const utfstring username);
server::UserVector AllUsers();
server::UserSessionVector ConnectedUserSessions();
public:
// Events
typedef sigslot::signal0<> UserUpdatedEvent;
UserUpdatedEvent UsersUpdated;
UserUpdatedEvent UserSessionsUpdated;
public:
Indexer indexer;
http::Server httpServer;
@ -83,6 +102,14 @@ class Server{
void SetNextConnection();
void CleanupConnections();
utfstring ServerIdentifier();
friend class server::Connection;
server::UserPtr GetUser(const utfstring username);
bool RemoveUserSession(server::UserSessionPtr userSession);
bool AddUserSession(server::UserSessionPtr userSession);
private:
// Variables
boost::asio::io_service ioService;
@ -95,6 +122,9 @@ class Server{
musik::core::server::ConnectionVector connections;
musik::core::server::ConnectionPtr nextConnection;
server::UserSessionMap connectedUsers;
db::Connection db;
};
typedef boost::shared_ptr<Server> ServerPtr;

View File

@ -204,6 +204,14 @@
RelativePath=".\config_format.h"
>
</File>
<File
RelativePath=".\Crypt.cpp"
>
</File>
<File
RelativePath=".\Crypt.h"
>
</File>
<File
RelativePath=".\Preferences.cpp"
>
@ -568,6 +576,22 @@
RelativePath=".\Server.h"
>
</File>
<File
RelativePath=".\server\User.cpp"
>
</File>
<File
RelativePath=".\server\User.h"
>
</File>
<File
RelativePath=".\server\UserSession.cpp"
>
</File>
<File
RelativePath=".\server\UserSession.h"
>
</File>
</Filter>
<Filter
Name="xml"

View File

@ -35,22 +35,30 @@
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include <core/server/Connection.h>
#include <core/Common.h>
#include <core/Preferences.h>
#include <core/Query/Factory.h>
#include <core/server/User.h>
#include <core/server/UserSession.h>
#include <core/xml/Parser.h>
#include <core/xml/ParserNode.h>
#include <core/xml/Writer.h>
#include <core/xml/WriterNode.h>
#include <core/Server.h>
#include <core/Crypt.h>
#include <boost/bind.hpp>
using namespace musik::core::server;
Connection::Connection(boost::asio::io_service &ioService)
Connection::Connection(boost::asio::io_service &ioService,musik::core::Server *server)
:socket(ioService)
,Base(UTF("Server"))
,server(server)
,salt(musik::core::Crypt::GenerateSalt())
{
}
@ -93,6 +101,37 @@ void Connection::ReadThread(){
if( musik::core::xml::ParserNode root = xmlParser.ChildNode("musik") ){
// musik node initialized
// Wait for authentication
if( musik::core::xml::ParserNode userNode = root.ChildNode("authentication") ){
userNode.WaitForContent();
// Get the user
UserPtr user = this->server->GetUser(musik::core::ConvertUTF16(userNode.Attributes()["username"]));
if(user){
// Create a new usersession
UserSessionPtr userSession( new UserSession(user,this->salt) );
// Check if encrypted password is the same
if( musik::core::Crypt::Encrypt(UTF_TO_UTF8(user->Password()),this->salt)==userNode.Content() ){
boost::mutex::scoped_lock lock(this->libraryMutex);
this->userSession = userSession;
this->server->AddUserSession(userSession);
}
}
}
{
// Notify writing thread that the authentication have been read (or failed)
boost::mutex::scoped_lock lock(this->libraryMutex);
this->authCondition.notify_all();
}
if(!this->userSession){
// if there is no authentication node, then it has failed to authenticate
this->Exit();
}
musik::core::Query::QueryMap queryMap;
musik::core::Query::Factory::GetQueries(queryMap);
@ -198,6 +237,29 @@ void Connection::WriteThread(){
// Lets start with a <musik> node
musik::core::xml::WriterNode musikNode(xmlWriter,"musik");
// Start by initializing the user
// Send a random salt for password encryption
{
musik::core::xml::WriterNode initNode(musikNode,"authentication");
initNode.Content() = this->salt;
}
// Wait for maximum 30 seconds for authentication
{
boost::mutex::scoped_lock lock(this->libraryMutex);
boost::xtime waitTime;
boost::xtime_get(&waitTime, boost::TIME_UTC);
waitTime.sec += 30;
if(!this->userSession){
this->authCondition.timed_wait(lock,waitTime);
}
}
if(!this->userSession){
// No user after 30 second, exit.
this->Exit();
}
while(!this->Exited()){
Query::Ptr sendQuery;

View File

@ -35,9 +35,18 @@
//////////////////////////////////////////////////////////////////////////////
#pragma once
//////////////////////////////////////////////////////////////////////////////
// Forward declare
namespace musik{ namespace core{
class Server;
} }
//////////////////////////////////////////////////////////////////////////////
#include <core/config.h>
#include <core/Library/Base.h>
#include <core/db/Connection.h>
#include <core/server/UserSession.h>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/thread.hpp>
@ -59,7 +68,7 @@ typedef std::vector<ConnectionPtr> ConnectionVector;
class Connection : public musik::core::Library::Base{
public:
Connection(boost::asio::io_service &ioService);
Connection(boost::asio::io_service &ioService,musik::core::Server *server);
~Connection(void);
utfstring GetInfo();
@ -82,8 +91,11 @@ class Connection : public musik::core::Library::Base{
musik::core::db::Connection db;
UserSessionPtr userSession;
std::string salt;
boost::condition authCondition;
musik::core::Server *server;
};

69
src/core/server/User.cpp Normal file
View File

@ -0,0 +1,69 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2008, Daniel Önnerby
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include <core/server/User.h>
//////////////////////////////////////////////////////////////////////////////
using namespace musik::core::server;
//////////////////////////////////////////////////////////////////////////////
User::User(int id,const utfchar *username,const utfchar *password,const utfchar *name)
:id(id)
,username(username)
,password(password)
,name(name)
{
}
User::~User(void)
{
}
utfstring& User::Username(){
return this->username;
}
utfstring& User::Password(){
return this->password;
}
utfstring& User::Name(){
return this->name;
}

77
src/core/server/User.h Normal file
View File

@ -0,0 +1,77 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2008, Daniel Önnerby
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#include <core/config.h>
#include <map>
#include <vector>
#include <set>
#include <boost/shared_ptr.hpp>
//////////////////////////////////////////////////////////////////////////////
namespace musik{ namespace core{ namespace server{
//////////////////////////////////////////////////////////////////////////////
class User
{
public:
User(int id,const utfchar *username,const utfchar *password,const utfchar *name);
~User(void);
utfstring& Username();
utfstring& Password();
utfstring& Name();
protected:
int id;
utfstring username;
utfstring password;
utfstring name;
};
typedef boost::shared_ptr<User> UserPtr;
typedef std::map<utfstring,UserPtr> UserMap;
typedef std::vector<UserPtr> UserVector;
typedef std::set<UserPtr> UserSet;
//////////////////////////////////////////////////////////////////////////////
} } }
//////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,58 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2008, Daniel Önnerby
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include <core/server/UserSession.h>
//////////////////////////////////////////////////////////////////////////////
using namespace musik::core::server;
//////////////////////////////////////////////////////////////////////////////
UserSession::UserSession(UserPtr& user,std::string uniqueId)
:user(user)
,uniqueId(uniqueId)
{
}
UserSession::~UserSession(void)
{
}
std::string UserSession::UniqueId(){
return this->uniqueId;
}

View File

@ -0,0 +1,73 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2008, Daniel Önnerby
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#include <core/config.h>
#include <core/server/User.h>
#include <map>
#include <vector>
#include <boost/shared_ptr.hpp>
//////////////////////////////////////////////////////////////////////////////
namespace musik{ namespace core{ namespace server{
//////////////////////////////////////////////////////////////////////////////
class UserSession
{
public:
UserSession(UserPtr& user,std::string uniqueId);
~UserSession(void);
std::string UniqueId();
protected:
UserPtr user;
std::string uniqueId;
};
typedef boost::shared_ptr<UserSession> UserSessionPtr;
typedef std::map<std::string,UserSessionPtr> UserSessionMap;
typedef std::vector<UserSessionPtr> UserSessionVector;
//////////////////////////////////////////////////////////////////////////////
} } }
//////////////////////////////////////////////////////////////////////////////

View File

@ -39,6 +39,8 @@
#include "pch.hpp"
#include <core/LibraryFactory.h>
#include <core/Preferences.h>
#include <core/Crypt.h>
#include <core/Common.h>
#include <cube/dialog/AddLibraryController.hpp>
#include <cube/dialog/AddLibraryView.hpp>
@ -86,6 +88,8 @@ void AddLibraryController::OnOK(win32cpp::Button* button){
musik::core::Preferences prefs("Connection",this->view->name->Caption().c_str() );
prefs.SetString("address",this->view->remoteHost->Caption().c_str());
prefs.SetString("port",this->view->remotePort->Caption().c_str());
prefs.SetString("username",this->view->username->Caption().c_str());
prefs.SetString("password",UTF8_TO_UTF(musik::core::Crypt::Encrypt(UTF_TO_UTF8(this->view->remotePort->Caption().c_str()),musik::core::Crypt::StaticSalt())).c_str());
}
library->Startup();

View File

@ -68,13 +68,16 @@ void AddLibraryView::OnCreated()
topRowLayout->SetDefaultChildFill(false);
topRowLayout->SetDefaultChildAlignment(win32cpp::ChildAlignMiddle);
Label *label;
Size labelSize(80,0);
// First rows column layout
LinearLayout* firstColumnLayout = new LinearLayout(LinearColumnLayout);
firstColumnLayout->SetDefaultChildFill(false);
firstColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignCenter);
Label* title = firstColumnLayout->AddChild(new Label(_T("Add Library")));
title->SetFont(boldFont);
label = firstColumnLayout->AddChild(new Label(_T("Add Library")));
label->SetFont(boldFont);
topRowLayout->AddChild(firstColumnLayout);
@ -82,25 +85,39 @@ void AddLibraryView::OnCreated()
LinearLayout* secondColumnLayout = new LinearLayout(LinearColumnLayout);
secondColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignTop);
win32cpp::Label* nameLabel = secondColumnLayout->AddChild(new Label(_T("Library name:") ));
this->name = secondColumnLayout->AddChild(new EditView(160,20 ));
label = secondColumnLayout->AddChild(new Label(_T("Library name:") ));
label->Resize(labelSize);
this->name = secondColumnLayout->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(secondColumnLayout);
// Third rows column layout
if(this->type==musik::core::LibraryFactory::Remote){
LinearLayout* remoteHostColumnLayout = new LinearLayout(LinearColumnLayout);
// remoteHostColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignTop);
remoteHostColumnLayout->AddChild(new Label(_T("Remote host:") ));
this->remoteHost = remoteHostColumnLayout->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(remoteHostColumnLayout);
LinearLayout* row;
row = new LinearLayout(LinearColumnLayout);
label = row->AddChild(new Label(_T("Remote host:") ));
label->Resize(labelSize);
this->remoteHost = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
LinearLayout* remotePortColumnLayout = new LinearLayout(LinearColumnLayout);
// remotePortColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignTop);
remotePortColumnLayout->AddChild(new Label(_T("Remote port:") ));
this->remotePort = remotePortColumnLayout->AddChild(new EditView(100,20 ));
row = new LinearLayout(LinearColumnLayout);
label = row->AddChild(new Label(_T("Remote port:") ));
label->Resize(labelSize);
this->remotePort = row->AddChild(new EditView(100,20 ));
this->remotePort->SetCaption(uistring(_T("10543")));
topRowLayout->AddChild(remotePortColumnLayout);
topRowLayout->AddChild(row);
row = new LinearLayout(LinearColumnLayout);
label = row->AddChild(new Label(_T("Username:") ));
label->Resize(labelSize);
this->username = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
row = new LinearLayout(LinearColumnLayout);
label = row->AddChild(new Label(_T("Password:") ));
label->Resize(labelSize);
this->password = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
}
// Last rows column layout

View File

@ -62,7 +62,7 @@ class AddLibraryView: public win32cpp::Frame{
virtual void OnCreated();
win32cpp::Button *okButton, *cancelButton;
win32cpp::EditView *name, *remoteHost, *remotePort;
win32cpp::EditView *name, *remoteHost, *remotePort,*username,*password;
private:
int type;

View File

@ -40,6 +40,8 @@
#include <server/resources/resource.h>
#include <server/SyncpathController.hpp>
#include <server/SyncpathView.hpp>
#include <server/users/UsersController.hpp>
#include <server/users/UsersView.hpp>
#include <core/Preferences.h>
@ -67,6 +69,7 @@ using namespace win32cpp;
,timer(200)
,statusLabel(NULL)
,syncpathController(NULL)
,usersController(NULL)
{
this->mainWindow.Created.connect(
@ -77,6 +80,7 @@ using namespace win32cpp;
MainWindowController::~MainWindowController()
{
delete this->syncpathController;
delete this->usersController;
}
void MainWindowController::OnMainWindowCreated(Window* window)
@ -141,7 +145,8 @@ void MainWindowController::OnMainWindowCreated(Window* window)
this->syncpathController = new SyncpathController(*synpathView,&this->server->indexer);
// Users tab
Frame *usersView = tabs->AddTab(uistring(_T("Users")), new Frame());
users::UsersView *usersView = tabs->AddTab(uistring(_T("Users")), new users::UsersView());
this->usersController = new users::UsersController(*usersView,this->server.get());
// Settings tab
Frame *settingsView = tabs->AddTab(uistring(_T("Settings")), new Frame());

View File

@ -45,6 +45,9 @@ namespace win32cpp{
}
namespace musik { namespace server {
class SyncpathController;
namespace users {
class UsersController;
}
} }
//////////////////////////////////////////////////////////////////////////////
@ -79,6 +82,7 @@ class MainWindowController : public EventHandler
win32cpp::Label *statusLabel;
win32cpp::Frame *mainFrame;
SyncpathController *syncpathController;
users::UsersController *usersController;
win32cpp::Timer timer;

View File

@ -239,6 +239,62 @@
>
</File>
</Filter>
<Filter
Name="User settings"
>
<File
RelativePath=".\users\UsersController.cpp"
>
</File>
<File
RelativePath=".\users\UsersController.hpp"
>
</File>
<File
RelativePath=".\users\UsersListController.cpp"
>
</File>
<File
RelativePath=".\users\UsersListController.hpp"
>
</File>
<File
RelativePath=".\users\UsersListModel.cpp"
>
</File>
<File
RelativePath=".\users\UsersListModel.hpp"
>
</File>
<File
RelativePath=".\users\UsersView.cpp"
>
</File>
<File
RelativePath=".\users\UsersView.hpp"
>
</File>
<Filter
Name="dialog"
>
<File
RelativePath=".\users\EditUserController.cpp"
>
</File>
<File
RelativePath=".\users\EditUserController.hpp"
>
</File>
<File
RelativePath=".\users\EditUserView.cpp"
>
</File>
<File
RelativePath=".\users\EditUserView.hpp"
>
</File>
</Filter>
</Filter>
</Filter>
<File
RelativePath=".\main.cpp"

View File

@ -0,0 +1,94 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include <server/users/EditUserController.hpp>
#include <server/users/EditUserView.hpp>
#include <core/Crypt.h>
#include <core/Common.h>
#include <win32cpp/Window.hpp>
#include <win32cpp/Button.hpp>
#include <win32cpp/EditView.hpp>
//////////////////////////////////////////////////////////////////////////////
using namespace musik::server::users;
using namespace win32cpp;
//////////////////////////////////////////////////////////////////////////////
EditUserController::EditUserController(win32cpp::TopLevelWindow &mainWindow,musik::core::Server *server)
:mainWindow(mainWindow)
,view(NULL)
,server(server)
{
this->view = new EditUserView();
this->mainWindow.AddChild(this->view);
this->view->Handle()
? this->OnViewCreated(this->view)
: this->view->Created.connect(this, &EditUserController::OnViewCreated);
}
EditUserController::~EditUserController(){
}
void EditUserController::OnViewCreated(Window* window)
{
this->view->cancelButton->Pressed.connect(this,&EditUserController::OnCancel);
this->view->okButton->Pressed.connect(this,&EditUserController::OnOK);
}
void EditUserController::OnCancel(win32cpp::Button* button){
this->mainWindow.Close();
}
void EditUserController::OnOK(win32cpp::Button* button){
// TODO: Save user
this->server->CreateUser(
this->view->username->Caption(),
UTF8_TO_UTF(musik::core::Crypt::Encrypt( musik::core::ConvertUTF8(this->view->password->Caption()),musik::core::Crypt::StaticSalt())),
this->view->nickname->Caption()
);
this->mainWindow.Close();
}

View File

@ -0,0 +1,81 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
//////////////////////////////////////////////////////////////////////////////
// Forward declare
namespace win32cpp{
class Window;
class Button;
}
//////////////////////////////////////////////////////////////////////////////
#include <core/Server.h>
#include <win32cpp/Types.hpp>
#include <win32cpp/TopLevelWindow.hpp>
#include <boost/shared_ptr.hpp>
//////////////////////////////////////////////////////////////////////////////
namespace musik { namespace server { namespace users{
class EditUserView; // forward
//////////////////////////////////////////////////////////////////////////////
class EditUserController : public win32cpp::EventHandler{
public:
EditUserController(win32cpp::TopLevelWindow &mainWindow,musik::core::Server *server);
~EditUserController();
private:
void OnViewCreated(win32cpp::Window* window);
void OnCancel(win32cpp::Button* button);
void OnOK(win32cpp::Button* button);
EditUserView* view;
win32cpp::TopLevelWindow &mainWindow;
musik::core::Server *server;
};
//////////////////////////////////////////////////////////////////////////////
} } } // musik::cube::dialog

View File

@ -0,0 +1,119 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include <server/users/EditUserView.hpp>
#include <win32cpp/Label.hpp>
#include <win32cpp/Button.hpp>
#include <win32cpp/LinearLayout.hpp>
#include <win32cpp/BarLayout.hpp>
#include <win32cpp/EditView.hpp>
//////////////////////////////////////////////////////////////////////////////
using namespace musik::server::users;
using namespace win32cpp;
//////////////////////////////////////////////////////////////////////////////
EditUserView::EditUserView()
: Frame(NULL,FramePadding(6))
{
}
void EditUserView::OnCreated()
{
FontRef boldFont(Font::Create());
boldFont->SetBold(true);
// Top Row layout
LinearLayout* topRowLayout = new LinearLayout(LinearRowLayout);
topRowLayout->SetDefaultChildFill(false);
topRowLayout->SetDefaultChildAlignment(win32cpp::ChildAlignMiddle);
// First rows column layout
LinearLayout* firstColumnLayout = new LinearLayout(LinearColumnLayout);
firstColumnLayout->SetDefaultChildFill(false);
firstColumnLayout->SetDefaultChildAlignment(win32cpp::ChildAlignCenter);
Label* title = firstColumnLayout->AddChild(new Label(_T("Add user")));
title->SetFont(boldFont);
topRowLayout->AddChild(firstColumnLayout);
LinearLayout* row;
Label* label;
// Username
row = new LinearLayout(LinearColumnLayout);
label = row->AddChild(new Label(_T("Username:") ));
label->Resize(Size(80,0));
this->username = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
// Password
row = new LinearLayout(LinearColumnLayout);
label = row->AddChild(new Label(_T("Password:") ));
label->Resize(Size(80,0));
this->password = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
// Nickname
row = new LinearLayout(LinearColumnLayout);
label = row->AddChild(new Label(_T("Nickname:") ));
label->Resize(Size(80,0));
this->nickname = row->AddChild(new EditView(160,20 ));
topRowLayout->AddChild(row);
// Last rows column layout
LinearLayout* bottomButtonLayout = new LinearLayout(LinearColumnLayout);
bottomButtonLayout->SetDefaultChildFill(false);
this->cancelButton = bottomButtonLayout->AddChild(new Button(_T("Cancel")));
this->okButton = bottomButtonLayout->AddChild(new Button(_T("OK")));
this->cancelButton->Resize(60,20);
this->okButton->Resize(60,20);
topRowLayout->AddChild(bottomButtonLayout);
topRowLayout->SetChildAlignment(bottomButtonLayout,ChildAlignRight);
this->AddChild(topRowLayout);
}

View File

@ -0,0 +1,73 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
//////////////////////////////////////////////////////////////////////////////
// Forward declare
namespace win32cpp{
class Button;
class EditView;
}
//////////////////////////////////////////////////////////////////////////////
#include <win32cpp/Frame.hpp>
//////////////////////////////////////////////////////////////////////////////
namespace musik { namespace server { namespace users {
//////////////////////////////////////////////////////////////////////////////
// forward
class EditUserController;
//////////////////////////////////////////////////////////////////////////////
class EditUserView: public win32cpp::Frame{
public:
EditUserView();
virtual void OnCreated();
win32cpp::Button *okButton, *cancelButton;
win32cpp::EditView *username, *nickname, *password;
private:
};
//////////////////////////////////////////////////////////////////////////////
} } } // musik::cube::dialog

View File

@ -0,0 +1,96 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include <server/users/UsersController.hpp>
#include <server/users/UsersView.hpp>
#include <server/users/UsersListController.hpp>
#include <server/users/EditUserController.hpp>
#include <win32cpp/Button.hpp>
#include <win32cpp/Label.hpp>
#include <win32cpp/Window.hpp>
#include <win32cpp/Application.hpp>
//////////////////////////////////////////////////////////////////////////////
using namespace win32cpp;
using namespace musik::server::users;
//////////////////////////////////////////////////////////////////////////////
UsersController::UsersController(UsersView& usersView,musik::core::Server *server)
:usersView(usersView)
,server(server)
{
this->usersView.Handle()
? this->OnViewCreated(&this->usersView)
: this->usersView.Created.connect(this, &UsersController::OnViewCreated);
this->usersView.Resized.connect(
this, &UsersController::OnViewResized);
}
void UsersController::OnViewCreated(Window* window)
{
this->usersView.addUserButton->Pressed.connect(this,&UsersController::OnAddUser);
this->usersView.removeUserButton->Pressed.connect(this,&UsersController::OnRemoveUser);
this->usersListController.reset(new UsersListController(*this->usersView.usersList,this));
}
void UsersController::OnViewResized(Window* window, Size size)
{
}
void UsersController::OnAddUser(Button* button){
win32cpp::TopLevelWindow popupDialog(_T("Add user"));
popupDialog.SetMinimumSize(Size(300, 200));
EditUserController addUser(popupDialog,this->server);
popupDialog.ShowModal(win32cpp::TopLevelWindow::FindFromAncestor(&this->usersView));
}
void UsersController::OnRemoveUser(Button* button){
this->usersListController->RemoveSelectedUsers();
}

View File

@ -0,0 +1,85 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
//////////////////////////////////////////////////////////////////////////////
// Forward declare
namespace musik { namespace server { namespace users {
class UsersView;
class UsersModel;
class UsersListController;
} } }
namespace win32cpp{
class Window;
class Button;
}
//////////////////////////////////////////////////////////////////////////////
#include <core/Server.h>
#include <win32cpp/Types.hpp>
#include <win32cpp/WindowGeometry.hpp>
#include <boost/shared_ptr.hpp>
namespace musik { namespace server{ namespace users {
//////////////////////////////////////////////////////////////////////////////
class UsersController : public win32cpp::EventHandler
{
public:
UsersController(UsersView& usersView,musik::core::Server *server);
private:
void OnViewCreated(win32cpp::Window* window);
void OnViewResized(win32cpp::Window* window, win32cpp::Size size);
UsersView& usersView;
void OnAddUser(win32cpp::Button* button);
void OnRemoveUser(win32cpp::Button* button);
typedef boost::shared_ptr<UsersListController> UsersListControllerRef;
UsersListControllerRef usersListController;
public:
musik::core::Server *server;
};
//////////////////////////////////////////////////////////////////////////////
} } } // musik::server

View File

@ -0,0 +1,101 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include <server/users/UsersListController.hpp>
#include <server/users/UsersListModel.hpp>
#include <server/users/UsersController.hpp>
//////////////////////////////////////////////////////////////////////////////
using namespace musik::server::users;
using namespace win32cpp;
//////////////////////////////////////////////////////////////////////////////
UsersListController::UsersListController(win32cpp::ListView &listView,UsersController *usersController)
: listView(listView)
, usersController(usersController)
{
this->model.reset(new UsersListModel(this));
this->listView.Handle()
? this->OnViewCreated(&listView)
: this->listView.Created.connect(this, &UsersListController::OnViewCreated);
}
void UsersListController::OnViewCreated(Window* window){
this->listView.SetScrollBarVisibility(HorizontalScrollBar, false);
typedef ListView::Column Column;
Size clientSize = this->listView.ClientSize();
this->mainColumn = Column::Create(_T("Username"), clientSize.width);
this->listView.AddColumn(this->mainColumn);
this->listView.EnableColumnResizing(false);
this->listView.SetModel(this->model);
//
int itemHeight = this->listView.RowHeight();
this->listView.SetRowHeight(max(itemHeight, 17));
this->listView.Resized.connect(
this, &UsersListController::OnResized);
}
void UsersListController::OnResized(Window* window, Size size)
{
this->listView.SetColumnWidth(this->mainColumn, this->listView.ClientSize().width);
}
void UsersListController::RemoveSelectedUsers(){
UsersListModel* model = (UsersListModel*)this->model.get();
musik::core::Server *server = this->usersController->server;
if(server && model){
win32cpp::ListView::RowIndexList selectedRows(this->listView.SelectedRows());
for(win32cpp::ListView::RowIndexList::iterator row=selectedRows.begin();row!=selectedRows.end();++row){
server->DeleteUser(model->users[*row]->Username());
}
}
}

View File

@ -0,0 +1,78 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
//////////////////////////////////////////////////////////////////////////////
#include <win32cpp/ListView.hpp>
//////////////////////////////////////////////////////////////////////////////
// Forward
namespace musik { namespace server { namespace users {
class UsersController;
class UsersListModel;
} } }
namespace musik { namespace server { namespace users {
//////////////////////////////////////////////////////////////////////////////
class UsersListController : public win32cpp::EventHandler{
public:
UsersListController(win32cpp::ListView &listView,UsersController *usersController);
void RemoveSelectedUsers();
private:
void OnViewCreated(win32cpp::Window* window);
void OnResized(win32cpp::Window* window, win32cpp::Size size);
win32cpp::ListView& listView;
win32cpp::ListView::ModelRef model;
win32cpp::ListView::ColumnRef mainColumn;
friend class UsersListModel;
UsersController* usersController;
};
//////////////////////////////////////////////////////////////////////////////
} } } // musik::cube::settings

View File

@ -0,0 +1,92 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include <server/users/UsersListModel.hpp>
#include <server/users/UsersController.hpp>
#include <win32cpp/ApplicationThread.hpp>
#include <core/Server.h>
//////////////////////////////////////////////////////////////////////////////
using namespace musik::server::users;
using namespace win32cpp;
//////////////////////////////////////////////////////////////////////////////
UsersListModel::UsersListModel(UsersListController *controller)
: controller(controller)
{
musik::core::Server *server = this->controller->usersController->server;
if(server){
server->UsersUpdated.connect(this,&UsersListModel::OnUsersUpdated);
}
this->UpdateUsersList();
}
uistring UsersListModel::CellValueToString(int rowIndex, ListView::ColumnRef column){
if(rowIndex<this->users.size() && rowIndex>=0){
return this->users[rowIndex]->Username();
}
return uistring();
}
void UsersListModel::UpdateUsersList(){
musik::core::Server *server = this->controller->usersController->server;
if(server){
this->users = server->AllUsers();
}
this->SetRowCount(0);
this->SetRowCount((int)this->users.size());
}
void UsersListModel::OnUsersUpdated(){
if(!win32cpp::ApplicationThread::InMainThread()){
win32cpp::ApplicationThread::Call0(this,&UsersListModel::OnUsersUpdated);
return;
}
this->UpdateUsersList();
}

View File

@ -0,0 +1,73 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
//////////////////////////////////////////////////////////////////////////////
#include <core/server/User.h>
#include <server/users/UsersListController.hpp>
#include <win32cpp/ListView.hpp>
//////////////////////////////////////////////////////////////////////////////
namespace musik { namespace server { namespace users {
//////////////////////////////////////////////////////////////////////////////
class UsersListModel : public win32cpp::ListView::Model, public win32cpp::EventHandler{
public:
UsersListModel(UsersListController *controller);
virtual win32cpp::uistring CellValueToString(int rowIndex, win32cpp::ListView::ColumnRef column);
void UpdateUsersList();
private:
void OnUsersUpdated();
UsersListController *controller;
friend class UsersListController;
musik::core::server::UserVector users;
};
//////////////////////////////////////////////////////////////////////////////
} } } // musik::server

View File

@ -0,0 +1,90 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include <server/users/UsersView.hpp>
#include <win32cpp/LinearLayout.hpp>
#include <win32cpp/Button.hpp>
#include <win32cpp/ListView.hpp>
#include <win32cpp/Label.hpp>
//////////////////////////////////////////////////////////////////////////////
using namespace musik::server::users;
//////////////////////////////////////////////////////////////////////////////
UsersView::UsersView()
{
}
void UsersView::OnCreated()
{
LinearLayout* pathLayout = new LinearLayout(LinearColumnLayout);
LinearLayout* pathButtonsLayout = new LinearLayout(LinearRowLayout);
// Path ListView
this->usersList = pathLayout->AddChild(new ListView());
pathLayout->SetDefaultChildFill(true);
// pathLayout->SetSizeConstraints(LayoutFillParent,120);
pathLayout->SetFlexibleChild(this->usersList);
// pathButtons layout
this->addUserButton = pathButtonsLayout->AddChild(new Button(_T("Add user")));
this->removeUserButton = pathButtonsLayout->AddChild(new Button(_T("Remove user")));
this->addUserButton->Resize(90, 24);
this->removeUserButton->Resize(90, 24);
pathButtonsLayout->SetDefaultChildFill(false);
pathButtonsLayout->SetDefaultChildAlignment(ChildAlignMiddle);
pathButtonsLayout->SetSizeConstraints(90,LayoutFillParent);
pathLayout->AddChild(pathButtonsLayout);
// Add to the layout
this->AddChild(new Frame(pathLayout,FramePadding(20)));
}

View File

@ -0,0 +1,79 @@
//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright © 2007, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
//////////////////////////////////////////////////////////////////////////////
// Forward declare
namespace win32cpp{
class Button;
class ListView;
class Label;
}
//////////////////////////////////////////////////////////////////////////////
#include <win32cpp/Frame.hpp>
//////////////////////////////////////////////////////////////////////////////
using namespace win32cpp;
namespace musik { namespace server { namespace users {
//////////////////////////////////////////////////////////////////////////////
// forward
class UsersController;
//////////////////////////////////////////////////////////////////////////////
class UsersView: public Frame
{
public:
UsersView();
protected:
virtual void OnCreated();
friend class UsersController;
Button *addUserButton,*removeUserButton;
ListView *usersList;
};
//////////////////////////////////////////////////////////////////////////////
} } } // musik::server

View File

@ -81,10 +81,10 @@ bool SysTray::DeleteIcon(UINT uid)
{
if(SysTray::iconList.find(uid) != SysTray::iconList.end()) {
if(::Shell_NotifyIcon(NIM_DELETE, &SysTray::iconList[uid]) != 0) {
SysTray::iconList.erase(uid);
/* SysTray::iconList.erase(uid);
SysTray::menuList.erase(uid);
SysTray::optionsList.erase(uid);
*/
return true;
}
}