diff --git a/src/3rdparty/3rdparty.vcproj b/src/3rdparty/3rdparty.vcproj index 60a4feaf9..e1a7e3c21 100644 --- a/src/3rdparty/3rdparty.vcproj +++ b/src/3rdparty/3rdparty.vcproj @@ -39,7 +39,7 @@ + + + + + + diff --git a/src/3rdparty/include/boost/random.hpp b/src/3rdparty/include/boost/random.hpp new file mode 100644 index 000000000..0a4cfb8a4 --- /dev/null +++ b/src/3rdparty/include/boost/random.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + typedef random::xor_combine, 0, + random::linear_feedback_shift, 0, 0>, 0, + random::linear_feedback_shift, 0, 0> taus88; +} // namespace boost + +// misc +#include + +// distributions +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_RANDOM_HPP diff --git a/src/3rdparty/include/boost/random/additive_combine.hpp b/src/3rdparty/include/boost/random/additive_combine.hpp new file mode 100644 index 000000000..b4faebcd5 --- /dev/null +++ b/src/3rdparty/include/boost/random/additive_combine.hpp @@ -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 +#include // for std::min and std::max +#include +#include +#include + +namespace boost { +namespace random { + +// L'Ecuyer 1988 +template +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 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 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const additive_combine& r) + { os << r._mlcg1 << " " << r._mlcg2; return os; } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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, + random::linear_congruential, + 2060321752> ecuyer1988; + +} // namespace boost + +#endif // BOOST_RANDOM_ADDITIVE_COMBINE_HPP diff --git a/src/3rdparty/include/boost/random/bernoulli_distribution.hpp b/src/3rdparty/include/boost/random/bernoulli_distribution.hpp new file mode 100644 index 000000000..30fdf8aee --- /dev/null +++ b/src/3rdparty/include/boost/random/bernoulli_distribution.hpp @@ -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 +#include + +namespace boost { + +// Bernoulli distribution: p(true) = p, p(false) = 1-p (boolean) +template +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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const bernoulli_distribution& bd) + { + os << bd._p; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, bernoulli_distribution& bd) + { + is >> std::ws >> bd._p; + return is; + } +#endif + +private: + RealType _p; +}; + +} // namespace boost + +#endif // BOOST_RANDOM_BERNOULLI_DISTRIBUTION_HPP diff --git a/src/3rdparty/include/boost/random/binomial_distribution.hpp b/src/3rdparty/include/boost/random/binomial_distribution.hpp new file mode 100644 index 000000000..6bc612928 --- /dev/null +++ b/src/3rdparty/include/boost/random/binomial_distribution.hpp @@ -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 +#include +#include + +namespace boost { + +// Knuth +template +class binomial_distribution +{ +public: + typedef typename bernoulli_distribution::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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const binomial_distribution& bd) + { + os << bd._bernoulli << " " << bd._t; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, binomial_distribution& bd) + { + is >> std::ws >> bd._bernoulli >> std::ws >> bd._t; + return is; + } +#endif + +private: + bernoulli_distribution _bernoulli; + IntType _t; +}; + +} // namespace boost + +#endif // BOOST_RANDOM_BINOMIAL_DISTRIBUTION_HPP diff --git a/src/3rdparty/include/boost/random/cauchy_distribution.hpp b/src/3rdparty/include/boost/random/cauchy_distribution.hpp new file mode 100644 index 000000000..71982f0e1 --- /dev/null +++ b/src/3rdparty/include/boost/random/cauchy_distribution.hpp @@ -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 +#include +#include +#include + +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 cauchy_distribution +{ +public: + typedef RealType input_type; + typedef RealType result_type; + +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + BOOST_STATIC_ASSERT(!std::numeric_limits::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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const cauchy_distribution& cd) + { + os << cd._median << " " << cd._sigma; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 diff --git a/src/3rdparty/include/boost/random/detail/const_mod.hpp b/src/3rdparty/include/boost/random/detail/const_mod.hpp new file mode 100644 index 000000000..275585344 --- /dev/null +++ b/src/3rdparty/include/boost/random/detail/const_mod.hpp @@ -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 +#include +#include +#include +#include + +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 + struct do_add + { }; + + template<> + struct do_add + { + template + 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 + { + template + 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 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::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 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::is_signed); +#elif !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) + BOOST_STATIC_ASSERT(boost::integer_traits::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 +{ + 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 +{ + 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 +{ + 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 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::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 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::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 diff --git a/src/3rdparty/include/boost/random/detail/pass_through_engine.hpp b/src/3rdparty/include/boost/random/detail/pass_through_engine.hpp new file mode 100644 index 000000000..e9b1d12cd --- /dev/null +++ b/src/3rdparty/include/boost/random/detail/pass_through_engine.hpp @@ -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 +#include + + +namespace boost { +namespace random { +namespace detail { + +template +class pass_through_engine +{ +private: + typedef ptr_helper 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(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 +std::basic_ostream& +operator<<( + std::basic_ostream& os + , const pass_through_engine& ud + ) +{ + return os << ud.base(); +} + +template +std::basic_istream& +operator>>( + std::basic_istream& is + , const pass_through_engine& ud + ) +{ + return is >> ud.base(); +} + +#else // no new streams + +template +inline std::ostream& +operator<<(std::ostream& os, + const pass_through_engine& ud) +{ + return os << ud.base(); +} + +template +inline std::istream& +operator>>(std::istream& is, + const pass_through_engine& ud) +{ + return is >> ud.base(); +} + +#endif + +} // namespace detail +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_DETAIL_PASS_THROUGH_ENGINE_HPP + diff --git a/src/3rdparty/include/boost/random/detail/ptr_helper.hpp b/src/3rdparty/include/boost/random/detail/ptr_helper.hpp new file mode 100644 index 000000000..d583afe8e --- /dev/null +++ b/src/3rdparty/include/boost/random/detail/ptr_helper.hpp @@ -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 + + +namespace boost { +namespace random { +namespace detail { + +// type_traits could help here, but I don't want to depend on type_traits. +template +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 +struct ptr_helper +{ + 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 +{ + 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 \ +{ \ + 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 \ +{ \ + 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 diff --git a/src/3rdparty/include/boost/random/detail/signed_unsigned_tools.hpp b/src/3rdparty/include/boost/random/detail/signed_unsigned_tools.hpp new file mode 100644 index 000000000..5ec90f80c --- /dev/null +++ b/src/3rdparty/include/boost/random/detail/signed_unsigned_tools.hpp @@ -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 +#include +#include + +namespace boost { +namespace random { +namespace detail { + + +/* + * Compute x - y, we know that x >= y, return an unsigned value. + */ + +template::is_signed> +struct subtract { }; + +template +struct subtract +{ + typedef T result_type; + result_type operator()(T x, T y) { return x - y; } +}; + +template +struct subtract +{ + typedef typename make_unsigned::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::is_signed> +struct add { }; + +template +struct add +{ + typedef T2 result_type; + result_type operator()(T1 x, T2 y) { return x + y; } +}; + +template +struct add +{ + 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 + diff --git a/src/3rdparty/include/boost/random/detail/uniform_int_float.hpp b/src/3rdparty/include/boost/random/detail/uniform_int_float.hpp new file mode 100644 index 000000000..8d12fd589 --- /dev/null +++ b/src/3rdparty/include/boost/random/detail/uniform_int_float.hpp @@ -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 +#include + + +namespace boost { +namespace random { +namespace detail { + +template +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(_rng() * _range) + _min; + } + +#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_int_float& ud) + { + os << ud._min << " " << ud._max; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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(_max-_min)+1; + } + + typedef typename base_type::result_type base_result; + uniform_01 _rng; + result_type _min, _max; + base_result _range; +}; + + +} // namespace detail +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP diff --git a/src/3rdparty/include/boost/random/discard_block.hpp b/src/3rdparty/include/boost/random/discard_block.hpp new file mode 100644 index 000000000..9594514fb --- /dev/null +++ b/src/3rdparty/include/boost/random/discard_block.hpp @@ -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 +#include +#include +#include + + +namespace boost { +namespace random { + +template +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 discard_block(It& first, It last) + : _rng(first, last), _n(0) { } + void seed() { _rng.seed(); _n = 0; } + template void seed(T s) { _rng.seed(s); _n = 0; } + template 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const discard_block& s) + { + os << s._rng << " " << s._n << " "; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 +const bool discard_block::has_fixed_range; +template +const unsigned int discard_block::total_block; +template +const unsigned int discard_block::returned_block; +#endif + +} // namespace random + +} // namespace boost + +#endif // BOOST_RANDOM_DISCARD_BLOCK_HPP diff --git a/src/3rdparty/include/boost/random/exponential_distribution.hpp b/src/3rdparty/include/boost/random/exponential_distribution.hpp new file mode 100644 index 000000000..77b52d44e --- /dev/null +++ b/src/3rdparty/include/boost/random/exponential_distribution.hpp @@ -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 +#include +#include +#include +#include + +namespace boost { + +// exponential distribution: p(x) = lambda * exp(-lambda * x) +template +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::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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const exponential_distribution& ed) + { + os << ed._lambda; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, exponential_distribution& ed) + { + is >> std::ws >> ed._lambda; + return is; + } +#endif + +private: + result_type _lambda; +}; + +} // namespace boost + +#endif // BOOST_RANDOM_EXPONENTIAL_DISTRIBUTION_HPP diff --git a/src/3rdparty/include/boost/random/gamma_distribution.hpp b/src/3rdparty/include/boost/random/gamma_distribution.hpp new file mode 100644 index 000000000..1713668b3 --- /dev/null +++ b/src/3rdparty/include/boost/random/gamma_distribution.hpp @@ -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 +#include +#include +#include +#include + +namespace boost { + +// Knuth +template +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::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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const gamma_distribution& gd) + { + os << gd._alpha; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 _exp; + result_type _alpha; + // some data precomputed from the parameters + result_type _p; +}; + +} // namespace boost + +#endif // BOOST_RANDOM_GAMMA_DISTRIBUTION_HPP diff --git a/src/3rdparty/include/boost/random/geometric_distribution.hpp b/src/3rdparty/include/boost/random/geometric_distribution.hpp new file mode 100644 index 000000000..d7cda6af2 --- /dev/null +++ b/src/3rdparty/include/boost/random/geometric_distribution.hpp @@ -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 // std::log +#include +#include +#include + +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 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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const geometric_distribution& gd) + { + os << gd._p; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 + diff --git a/src/3rdparty/include/boost/random/inversive_congruential.hpp b/src/3rdparty/include/boost/random/inversive_congruential.hpp new file mode 100644 index 000000000..03094ac6c --- /dev/null +++ b/src/3rdparty/include/boost/random/inversive_congruential.hpp @@ -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 +#include +#include +#include +#include +#include + +namespace boost { +namespace random { + +// Eichenauer and Lehn 1986 +template +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 inversive_congruential(It& first, It last) + { seed(first, last); } + + void seed(IntType y0 = 1) { value = y0; if(b == 0) assert(y0 > 0); } + template void seed(It& first, It last) + { + if(first == last) + throw std::invalid_argument("inversive_congruential::seed"); + value = *first++; + } + IntType operator()() + { + typedef const_mod 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, inversive_congruential x) + { os << x.value; return os; } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 +const bool inversive_congruential::has_fixed_range; +template +const typename inversive_congruential::result_type inversive_congruential::min_value; +template +const typename inversive_congruential::result_type inversive_congruential::max_value; +template +const typename inversive_congruential::result_type inversive_congruential::multiplier; +template +const typename inversive_congruential::result_type inversive_congruential::increment; +template +const typename inversive_congruential::result_type inversive_congruential::modulus; +#endif + +} // namespace random + +typedef random::inversive_congruential hellekalek1995; + +} // namespace boost + +#endif // BOOST_RANDOM_INVERSIVE_CONGRUENTIAL_HPP diff --git a/src/3rdparty/include/boost/random/lagged_fibonacci.hpp b/src/3rdparty/include/boost/random/lagged_fibonacci.hpp new file mode 100644 index 000000000..f1422856e --- /dev/null +++ b/src/3rdparty/include/boost/random/lagged_fibonacci.hpp @@ -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 +#include +#include // std::max +#include +#include // std::pow +#include +#include +#include +#include +#include +#include +#include + +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 + 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 + 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 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 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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& 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 + friend std::basic_istream& + operator>>(std::basic_istream& 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 +const bool lagged_fibonacci::has_fixed_range; +template +const unsigned int lagged_fibonacci::long_lag; +template +const unsigned int lagged_fibonacci::short_lag; +#endif + +template +void lagged_fibonacci::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 +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 +const bool fibonacci_validation::is_specialized; +#endif + +#define BOOST_RANDOM_FIBONACCI_VAL(T,P,Q,V,E) \ +template<> \ +struct fibonacci_validation \ +{ \ + BOOST_STATIC_CONSTANT(bool, is_specialized = true); \ + static T value() { return V; } \ + static T tolerance() \ +{ return (std::max)(E, static_cast(5*std::numeric_limits::epsilon())); } \ +}; +// (The extra static_cast in the std::max call above is actually +// unnecessary except for HP aCC 1.30, which claims that +// numeric_limits::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 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 + explicit lagged_fibonacci_01(Generator & gen) { init_modulus(); seed(gen); } + template 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 + void seed(Generator & gen) + { + // use pass-by-reference, but wrap argument in pass_through_engine + typedef detail::pass_through_engine ref_gen; + uniform_01 gen01 = + uniform_01(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 + 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::value(); + result_type epsilon = fibonacci_validation::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 + friend std::basic_ostream& + operator<<(std::basic_ostream& 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 + friend std::basic_istream& + operator>>(std::basic_istream& 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 +const bool lagged_fibonacci_01::has_fixed_range; +template +const unsigned int lagged_fibonacci_01::long_lag; +template +const unsigned int lagged_fibonacci_01::short_lag; +template +const int lagged_fibonacci_01::word_size; + +#endif + +template +void lagged_fibonacci_01::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 lagged_fibonacci607; +typedef random::lagged_fibonacci_01 lagged_fibonacci1279; +typedef random::lagged_fibonacci_01 lagged_fibonacci2281; +typedef random::lagged_fibonacci_01 lagged_fibonacci3217; +typedef random::lagged_fibonacci_01 lagged_fibonacci4423; +typedef random::lagged_fibonacci_01 lagged_fibonacci9689; +typedef random::lagged_fibonacci_01 lagged_fibonacci19937; +typedef random::lagged_fibonacci_01 lagged_fibonacci23209; +typedef random::lagged_fibonacci_01 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 diff --git a/src/3rdparty/include/boost/random/linear_congruential.hpp b/src/3rdparty/include/boost/random/linear_congruential.hpp new file mode 100644 index 000000000..ee51a5c82 --- /dev/null +++ b/src/3rdparty/include/boost/random/linear_congruential.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace random { + +// compile-time configurable linear congruential generator +template +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::is_integer); +#endif + } + + template + 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 + 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::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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, + const linear_congruential& lcg) + { + return os << lcg._x; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 +std::ostream& +operator<<(std::ostream& os, + const linear_congruential& lcg) +{ + return os << lcg._x; +} + +template +std::istream& +operator>>(std::istream& is, + linear_congruential& 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 +std::basic_ostream& +operator<<(std::basic_ostream& os, + const linear_congruential& lcg) +{ + return os << lcg._x; +} + +template +std::basic_istream& +operator>>(std::basic_istream& is, + linear_congruential& lcg) +{ + return is >> lcg._x; +} +#endif + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// A definition is required even for integral static constants +template +const bool linear_congruential::has_fixed_range; +template +const typename linear_congruential::result_type linear_congruential::min_value; +template +const typename linear_congruential::result_type linear_congruential::max_value; +template +const IntType linear_congruential::modulus; +#endif + +} // namespace random + +// validation values from the publications +typedef random::linear_congruential minstd_rand0; +typedef random::linear_congruential 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::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::max BOOST_PREVENT_MACRO_SUBSTITUTION (); } + + explicit rand48(int32_t x0 = 1) : lcf(cnv(x0)) { } + explicit rand48(uint64_t x0) : lcf(x0) { } + template 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 void seed(It& first, It last) { lcf.seed(first,last); } + + int32_t operator()() { return static_cast(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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const rand48& r) + { os << r.lcf; return os; } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 lcf; + static uint64_t cnv(int32_t x) + { return (static_cast(x) << 16) | 0x330e; } +}; +#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */ + +} // namespace boost + +#endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP diff --git a/src/3rdparty/include/boost/random/linear_feedback_shift.hpp b/src/3rdparty/include/boost/random/linear_feedback_shift.hpp new file mode 100644 index 000000000..7280ab10c --- /dev/null +++ b/src/3rdparty/include/boost/random/linear_feedback_shift.hpp @@ -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 +#include +#include +#include +#include +#include + +namespace boost { +namespace random { + +// Tausworte 1965 +template +class linear_feedback_shift +{ +public: + typedef UIntType result_type; + // avoid the warning trouble when using (1< 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::is_integer); + BOOST_STATIC_ASSERT(!std::numeric_limits::is_signed); +#endif + + // avoid "left shift count >= with of type" warning + for(int i = 0; i < w; ++i) + wordmask |= (1u << i); + seed(s0); + } + + template 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::is_integer); + BOOST_STATIC_ASSERT(!std::numeric_limits::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 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(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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, linear_feedback_shift x) + { os << x.value; return os; } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 +const bool linear_feedback_shift::has_fixed_range; +template +const int linear_feedback_shift::word_size; +template +const int linear_feedback_shift::exponent1; +template +const int linear_feedback_shift::exponent2; +template +const int linear_feedback_shift::step_size; +#endif + +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_LINEAR_FEEDBACK_SHIFT_HPP diff --git a/src/3rdparty/include/boost/random/lognormal_distribution.hpp b/src/3rdparty/include/boost/random/lognormal_distribution.hpp new file mode 100644 index 000000000..624aa5146 --- /dev/null +++ b/src/3rdparty/include/boost/random/lognormal_distribution.hpp @@ -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 // std::exp, std::sqrt +#include +#include +#include +#include +#include + +#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 lognormal_distribution +{ +public: + typedef typename normal_distribution::input_type input_type; + typedef RealType result_type; + +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + BOOST_STATIC_ASSERT(!std::numeric_limits::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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const lognormal_distribution& ld) + { + os << ld._normal << " " << ld._mean << " " << ld._sigma; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 _normal; +}; + +} // namespace boost + +#endif // BOOST_RANDOM_LOGNORMAL_DISTRIBUTION_HPP diff --git a/src/3rdparty/include/boost/random/mersenne_twister.hpp b/src/3rdparty/include/boost/random/mersenne_twister.hpp new file mode 100644 index 000000000..85f990f43 --- /dev/null +++ b/src/3rdparty/include/boost/random/mersenne_twister.hpp @@ -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 +#include // std::copy +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace random { + +// http://www.math.keio.ac.jp/matumoto/emt.html +template +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 mersenne_twister(It& first, It last) { seed(first,last); } + + template + 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 + void seed(Generator & gen) + { +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + BOOST_STATIC_ASSERT(!std::numeric_limits::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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const mersenne_twister& mt) + { + for(int j = 0; j < mt.state_size; ++j) + os << mt.compute(j) << " "; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 +const bool mersenne_twister::has_fixed_range; +template +const int mersenne_twister::state_size; +template +const int mersenne_twister::shift_size; +template +const int mersenne_twister::mask_bits; +template +const UIntType mersenne_twister::parameter_a; +template +const int mersenne_twister::output_u; +template +const int mersenne_twister::output_s; +template +const UIntType mersenne_twister::output_b; +template +const int mersenne_twister::output_t; +template +const UIntType mersenne_twister::output_c; +template +const int mersenne_twister::output_l; +#endif + +template +void mersenne_twister::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 +inline typename mersenne_twister::result_type +mersenne_twister::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 mt11213b; + +// validation by experiment from mt19937.c +typedef random::mersenne_twister mt19937; + +} // namespace boost + +BOOST_RANDOM_PTR_HELPER_SPEC(boost::mt19937) + +#endif // BOOST_RANDOM_MERSENNE_TWISTER_HPP diff --git a/src/3rdparty/include/boost/random/normal_distribution.hpp b/src/3rdparty/include/boost/random/normal_distribution.hpp new file mode 100644 index 000000000..4785c5779 --- /dev/null +++ b/src/3rdparty/include/boost/random/normal_distribution.hpp @@ -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 +#include +#include +#include +#include + +namespace boost { + +// deterministic Box-Muller method, uses trigonometric functions +template +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::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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const normal_distribution& nd) + { + os << nd._mean << " " << nd._sigma << " " + << nd._valid << " " << nd._cached_rho << " " << nd._r1; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 diff --git a/src/3rdparty/include/boost/random/poisson_distribution.hpp b/src/3rdparty/include/boost/random/poisson_distribution.hpp new file mode 100644 index 000000000..727488828 --- /dev/null +++ b/src/3rdparty/include/boost/random/poisson_distribution.hpp @@ -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 +#include +#include +#include +#include + +namespace boost { + +// Knuth +template +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::is_integer); + BOOST_STATIC_ASSERT(!std::numeric_limits::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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const poisson_distribution& pd) + { + os << pd._mean; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 diff --git a/src/3rdparty/include/boost/random/random_number_generator.hpp b/src/3rdparty/include/boost/random/random_number_generator.hpp new file mode 100644 index 000000000..eaf32e534 --- /dev/null +++ b/src/3rdparty/include/boost/random/random_number_generator.hpp @@ -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 +#include +#include +#include +#include + +namespace boost { + +// a model for RandomNumberGenerator std:25.2.11 [lib.alg.random.shuffle] +template +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::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 dist_type; + return variate_generator(_rng, dist_type(0, n-1))(); + } + +private: + base_type& _rng; +}; + +} // namespace boost + +#endif // BOOST_RANDOM_RANDOM_NUMBER_GENERATOR_HPP diff --git a/src/3rdparty/include/boost/random/ranlux.hpp b/src/3rdparty/include/boost/random/ranlux.hpp new file mode 100644 index 000000000..7334551d0 --- /dev/null +++ b/src/3rdparty/include/boost/random/ranlux.hpp @@ -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 +#include +#include + +namespace boost { + +namespace random { + typedef subtract_with_carry ranlux_base; + typedef subtract_with_carry_01 ranlux_base_01; + typedef subtract_with_carry_01 ranlux64_base_01; +} + +typedef random::discard_block ranlux3; +typedef random::discard_block ranlux4; + +typedef random::discard_block ranlux3_01; +typedef random::discard_block ranlux4_01; + +typedef random::discard_block ranlux64_3_01; +typedef random::discard_block ranlux64_4_01; + +#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T) +namespace random { + typedef random::subtract_with_carry ranlux64_base; +} +typedef random::discard_block ranlux64_3; +typedef random::discard_block ranlux64_4; +#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */ + +} // namespace boost + +#endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP diff --git a/src/3rdparty/include/boost/random/shuffle_output.hpp b/src/3rdparty/include/boost/random/shuffle_output.hpp new file mode 100644 index 000000000..1af940dff --- /dev/null +++ b/src/3rdparty/include/boost/random/shuffle_output.hpp @@ -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 +#include // std::copy +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace random { + +// Carter Bays and S.D. Durham 1979 +template +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 + explicit shuffle_output(T s) : _rng(s) { init(); } + explicit shuffle_output(const base_type & rng) : _rng(rng) { init(); } + template shuffle_output(It& first, It last) + : _rng(first, last) { init(); } + void seed() { _rng.seed(); init(); } + template + void seed(T s) { _rng.seed(s); init(); } + template 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& 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 + friend std::basic_istream& + operator>>(std::basic_istream& 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::is_integer); +#endif + result_type range = (max)()-(min)(); + assert(range > 0); // otherwise there would be little choice + if(static_cast(k * range) < + static_cast(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 +const bool shuffle_output::has_fixed_range; + +template +const int shuffle_output::buffer_size; +#endif + +} // namespace random + +// validation by experiment from Harry Erwin's generator.h (private e-mail) +typedef random::shuffle_output< + random::linear_congruential, + 97, 139726> kreutzer1986; + + +} // namespace boost + +#endif // BOOST_RANDOM_SHUFFLE_OUTPUT_HPP diff --git a/src/3rdparty/include/boost/random/subtract_with_carry.hpp b/src/3rdparty/include/boost/random/subtract_with_carry.hpp new file mode 100644 index 000000000..7332305ec --- /dev/null +++ b/src/3rdparty/include/boost/random/subtract_with_carry.hpp @@ -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 +#include +#include // std::equal +#include +#include // std::pow +#include +#include +#include +#include +#include +#include + + +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 + 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 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::is_signed); + BOOST_STATIC_ASSERT(std::numeric_limits::is_integer); +#endif + seed(); + } + explicit subtract_with_carry(uint32_t value) { seed(value); } + template + explicit subtract_with_carry(Generator & gen) { seed(gen); } + template 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 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 + 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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& 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 + friend std::basic_istream& + operator>>(std::basic_istream& 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 +const bool subtract_with_carry::has_fixed_range; +template +const IntType subtract_with_carry::min_value; +template +const IntType subtract_with_carry::max_value; +template +const IntType subtract_with_carry::modulus; +template +const unsigned int subtract_with_carry::long_lag; +template +const unsigned int subtract_with_carry::short_lag; +#endif + + +// use a floating-point representation to produce values in [0..1) +template +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::is_integer); +#endif + + subtract_with_carry_01() { init_modulus(); seed(); } + explicit subtract_with_carry_01(uint32_t value) + { init_modulus(); seed(value); } + template 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 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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& 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 + friend std::basic_istream& + operator>>(std::basic_istream& 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 +const bool subtract_with_carry_01::has_fixed_range; +template +const int subtract_with_carry_01::word_size; +template +const unsigned int subtract_with_carry_01::long_lag; +template +const unsigned int subtract_with_carry_01::short_lag; +#endif + +template +RealType subtract_with_carry_01::compute(unsigned int index) const +{ + return x[(k+index) % long_lag]; +} + + +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_SUBTRACT_WITH_CARRY_HPP diff --git a/src/3rdparty/include/boost/random/triangle_distribution.hpp b/src/3rdparty/include/boost/random/triangle_distribution.hpp new file mode 100644 index 000000000..1f0f4ff98 --- /dev/null +++ b/src/3rdparty/include/boost/random/triangle_distribution.hpp @@ -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 +#include +#include + +namespace boost { + +// triangle distribution, with a smallest, b most probable, and c largest +// value. +template +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 + 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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const triangle_distribution& td) + { + os << td._a << " " << td._b << " " << td._c; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 diff --git a/src/3rdparty/include/boost/random/uniform_01.hpp b/src/3rdparty/include/boost/random/uniform_01.hpp new file mode 100644 index 000000000..747153e58 --- /dev/null +++ b/src/3rdparty/include/boost/random/uniform_01.hpp @@ -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 +#include +#include +#include + +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 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::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::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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_01& u) + { + os << u._rng; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 +const bool uniform_01::has_fixed_range; +#endif + +} // namespace boost + +#endif // BOOST_RANDOM_UNIFORM_01_HPP diff --git a/src/3rdparty/include/boost/random/uniform_int.hpp b/src/3rdparty/include/boost/random/uniform_int.hpp new file mode 100644 index 000000000..0e6742058 --- /dev/null +++ b/src/3rdparty/include/boost/random/uniform_int.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#include +#endif + +namespace boost { + +// uniform integer distribution on [min, max] +template +class uniform_int +{ +public: + typedef IntType input_type; + typedef IntType result_type; + typedef typename make_unsigned::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::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 + result_type operator()(Engine& eng) + { + typedef typename Engine::result_type base_result; + // ranges are always unsigned + typedef typename make_unsigned::type base_unsigned; + const base_result bmin = (eng.min)(); + const base_unsigned brange = + random::detail::subtract()((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()(eng(), bmin); + return random::detail::add()(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::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()(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(0, _range/mult)(eng) * mult; + if(result <= _range) + return random::detail::add()(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(_min, _max)(eng); + } else { + // use rejection method to handle cases like 0..5 -> 0..4 + for(;;) { + base_unsigned result = + random::detail::subtract()(eng(), bmin); + // result and range are non-negative, and result is possibly larger + // than range, so the cast is safe + if(result <= static_cast(_range)) + return random::detail::add()(result, _min); + } + } + } + } + +#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_int& ud) + { + os << ud._min << " " << ud._max; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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()(_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 diff --git a/src/3rdparty/include/boost/random/uniform_on_sphere.hpp b/src/3rdparty/include/boost/random/uniform_on_sphere.hpp new file mode 100644 index 000000000..9b8ab35cf --- /dev/null +++ b/src/3rdparty/include/boost/random/uniform_on_sphere.hpp @@ -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 +#include // std::transform +#include // std::bind2nd, std::divides +#include + +namespace boost { + +template > +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 + 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(), sqrt(sqsum))); + return _container; + } + +#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_on_sphere& sd) + { + os << sd._dim; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, uniform_on_sphere& sd) + { + is >> std::ws >> sd._dim; + sd._container.resize(sd._dim); + return is; + } +#endif + +private: + normal_distribution _normal; + result_type _container; + int _dim; +}; + +} // namespace boost + +#endif // BOOST_RANDOM_UNIFORM_ON_SPHERE_HPP diff --git a/src/3rdparty/include/boost/random/uniform_real.hpp b/src/3rdparty/include/boost/random/uniform_real.hpp new file mode 100644 index 000000000..bc02a9221 --- /dev/null +++ b/src/3rdparty/include/boost/random/uniform_real.hpp @@ -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 +#include +#include +#include +#include + +namespace boost { + +// uniform distribution on a real range +template +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::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 + result_type operator()(Engine& eng) { + return static_cast(eng() - eng.min BOOST_PREVENT_MACRO_SUBSTITUTION()) + / static_cast(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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_real& ud) + { + os << ud._min << " " << ud._max; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 diff --git a/src/3rdparty/include/boost/random/uniform_smallint.hpp b/src/3rdparty/include/boost/random/uniform_smallint.hpp new file mode 100644 index 000000000..3decd0e60 --- /dev/null +++ b/src/3rdparty/include/boost/random/uniform_smallint.hpp @@ -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 +#include +#include +#include +#include +#include +#include +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +#include +#endif + + +namespace boost { + +// uniform integer distribution on a small range [min, max] + +namespace detail { + +template +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 +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 +void uniform_smallint_integer:: +set(result_type min_arg, result_type max_arg) +{ + _min = min_arg; + _max = max_arg; + assert(min_arg <= max_arg); + + _range = static_cast(_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::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 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::is_integer); + BOOST_STATIC_ASSERT(!std::numeric_limits::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(_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(_rng() * _range) + _min; + } + +private: + typedef typename base_type::result_type base_result; + uniform_01 _rng; + IntType _min, _max; + base_result _range; +}; + + +} // namespace detail + + + + +template +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::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 + result_type operator()(Engine& eng) + { + typedef typename Engine::result_type base_result; + base_result _range = static_cast(_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::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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_smallint& ud) + { + os << ud._min << " " << ud._max; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 diff --git a/src/3rdparty/include/boost/random/variate_generator.hpp b/src/3rdparty/include/boost/random/variate_generator.hpp new file mode 100644 index 000000000..f207dbb46 --- /dev/null +++ b/src/3rdparty/include/boost/random/variate_generator.hpp @@ -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 + +// implementation details +#include +#include +#include +#include +#include + +// Borland C++ 5.6.0 has problems using its numeric_limits traits as +// template parameters +#if BOOST_WORKAROUND(__BORLANDC__, <= 0x564) +#include +#endif + +namespace boost { + +namespace random { +namespace detail { + +template +struct engine_helper; + +// for consistency, always have two levels of decorations +template<> +struct engine_helper +{ + template + struct impl + { + typedef pass_through_engine type; + }; +}; + +template<> +struct engine_helper +{ + template + struct impl + { + typedef uniform_01 type; + }; +}; + +template<> +struct engine_helper +{ + template + struct impl + { + typedef uniform_01 type; + }; +}; + +template<> +struct engine_helper +{ + template + struct impl + { + typedef uniform_int_float type; + }; +}; + +} // namespace detail +} // namespace random + + +template +class variate_generator +{ +private: + typedef random::detail::pass_through_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 + 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::value, + boost::is_integral::value + >::BOOST_NESTED_TEMPLATE impl::type internal_engine_type; +#else + enum { + have_int = std::numeric_limits::is_integer, + want_int = std::numeric_limits::is_integer + }; + typedef typename random::detail::engine_helper::BOOST_NESTED_TEMPLATE impl::type internal_engine_type; +#endif + + internal_engine_type _eng; + distribution_type _dist; +}; + +} // namespace boost + +#endif // BOOST_RANDOM_RANDOM_GENERATOR_HPP diff --git a/src/3rdparty/include/boost/random/xor_combine.hpp b/src/3rdparty/include/boost/random/xor_combine.hpp new file mode 100644 index 000000000..b986209b7 --- /dev/null +++ b/src/3rdparty/include/boost/random/xor_combine.hpp @@ -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 +#include +#include // for std::min and std::max +#include +#include +#include +#include // uint32_t + + +namespace boost { +namespace random { + +template +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 xor_combine(It& first, It last) + : _rng1(first, last), _rng2( /* advanced by other call */ first, last) { } + void seed() { _rng1.seed(); _rng2.seed(); } + template 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::is_integer); + BOOST_STATIC_ASSERT(std::numeric_limits::is_integer); + BOOST_STATIC_ASSERT(std::numeric_limits::digits >= std::numeric_limits::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 + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const xor_combine& s) + { + os << s._rng1 << " " << s._rng2 << " "; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& 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 +const bool xor_combine::has_fixed_range; +#endif + +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_XOR_COMBINE_HPP diff --git a/src/3rdparty/include/md5/md5.h b/src/3rdparty/include/md5/md5.h new file mode 100644 index 000000000..698c995d8 --- /dev/null +++ b/src/3rdparty/include/md5/md5.h @@ -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 + . 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 . + 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 */ diff --git a/src/3rdparty/src/md5/md5.c b/src/3rdparty/src/md5/md5.c new file mode 100644 index 000000000..c35d96c5e --- /dev/null +++ b/src/3rdparty/src/md5/md5.c @@ -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 + . 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 + 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 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 + +#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)); +} diff --git a/src/core/Common.h b/src/core/Common.h index ddedb420c..8538d12ad 100644 --- a/src/core/Common.h +++ b/src/core/Common.h @@ -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 diff --git a/src/core/Crypt.cpp b/src/core/Crypt.cpp new file mode 100644 index 000000000..d4b54b54d --- /dev/null +++ b/src/core/Crypt.cpp @@ -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 +#include + +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +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 > 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; +} diff --git a/src/core/Crypt.h b/src/core/Crypt.h new file mode 100644 index 000000000..7c8382db1 --- /dev/null +++ b/src/core/Crypt.h @@ -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 + +////////////////////////////////////////////////////////////////////////////// + +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); +}; + +////////////////////////////////////////////////////////////////////////////// +} } +////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/Library/Remote.cpp b/src/core/Library/Remote.cpp index e0fd1d85a..811a4c073 100644 --- a/src/core/Library/Remote.cpp +++ b/src/core/Library/Remote.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -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; } diff --git a/src/core/Library/Remote.h b/src/core/Library/Remote.h index d015d987e..8d4def769 100644 --- a/src/core/Library/Remote.h +++ b/src/core/Library/Remote.h @@ -84,6 +84,9 @@ class Remote : public Library::Base{ std::string address; std::string port; + std::string username; + std::string password; + std::string sessionId; }; ////////////////////////////////////////// diff --git a/src/core/Server.cpp b/src/core/Server.cpp index 30634de8d..195a49995 100644 --- a/src/core/Server.cpp +++ b/src/core/Server.cpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include @@ -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; +} + + diff --git a/src/core/Server.h b/src/core/Server.h index c5b179ea6..dbac2aa07 100644 --- a/src/core/Server.h +++ b/src/core/Server.h @@ -37,15 +37,21 @@ #include #include +#include #include #include +#include +#include #include #include #include #include +#include +#include + ////////////////////////////////////////////////////////////////////////////// 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 ServerPtr; diff --git a/src/core/core.vcproj b/src/core/core.vcproj index 74fc6c5aa..c6d608437 100644 --- a/src/core/core.vcproj +++ b/src/core/core.vcproj @@ -204,6 +204,14 @@ RelativePath=".\config_format.h" > + + + + @@ -568,6 +576,22 @@ RelativePath=".\Server.h" > + + + + + + + + +#include #include #include +#include +#include #include #include #include #include +#include +#include + #include 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 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; diff --git a/src/core/server/Connection.h b/src/core/server/Connection.h index 163aeabfd..bf2b7beae 100644 --- a/src/core/server/Connection.h +++ b/src/core/server/Connection.h @@ -35,9 +35,18 @@ ////////////////////////////////////////////////////////////////////////////// #pragma once +////////////////////////////////////////////////////////////////////////////// +// Forward declare +namespace musik{ namespace core{ + class Server; +} } +////////////////////////////////////////////////////////////////////////////// + + #include #include #include +#include #include #include #include @@ -59,7 +68,7 @@ typedef std::vector 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; }; diff --git a/src/core/server/User.cpp b/src/core/server/User.cpp new file mode 100644 index 000000000..98a2177ab --- /dev/null +++ b/src/core/server/User.cpp @@ -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 +////////////////////////////////////////////////////////////////////////////// + +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; +} + + + diff --git a/src/core/server/User.h b/src/core/server/User.h new file mode 100644 index 000000000..6b88e3b86 --- /dev/null +++ b/src/core/server/User.h @@ -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 + +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +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 UserPtr; +typedef std::map UserMap; +typedef std::vector UserVector; +typedef std::set UserSet; + +////////////////////////////////////////////////////////////////////////////// +} } } +////////////////////////////////////////////////////////////////////////////// + diff --git a/src/core/server/UserSession.cpp b/src/core/server/UserSession.cpp new file mode 100644 index 000000000..4c15b0674 --- /dev/null +++ b/src/core/server/UserSession.cpp @@ -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 + +////////////////////////////////////////////////////////////////////////////// + +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; +} + diff --git a/src/core/server/UserSession.h b/src/core/server/UserSession.h new file mode 100644 index 000000000..b25d8a752 --- /dev/null +++ b/src/core/server/UserSession.h @@ -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 +#include + +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +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 UserSessionPtr; +typedef std::map UserSessionMap; +typedef std::vector UserSessionVector; +////////////////////////////////////////////////////////////////////////////// +} } } +////////////////////////////////////////////////////////////////////////////// + diff --git a/src/cube/dialog/AddLibraryController.cpp b/src/cube/dialog/AddLibraryController.cpp index 9c8f6129e..ae7264bfd 100644 --- a/src/cube/dialog/AddLibraryController.cpp +++ b/src/cube/dialog/AddLibraryController.cpp @@ -39,6 +39,8 @@ #include "pch.hpp" #include #include +#include +#include #include #include @@ -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(); diff --git a/src/cube/dialog/AddLibraryView.cpp b/src/cube/dialog/AddLibraryView.cpp index e0a798498..e80072eb0 100644 --- a/src/cube/dialog/AddLibraryView.cpp +++ b/src/cube/dialog/AddLibraryView.cpp @@ -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 diff --git a/src/cube/dialog/AddLibraryView.hpp b/src/cube/dialog/AddLibraryView.hpp index 20a22eae4..bc525ddb2 100644 --- a/src/cube/dialog/AddLibraryView.hpp +++ b/src/cube/dialog/AddLibraryView.hpp @@ -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; diff --git a/src/server/MainWindowController.cpp b/src/server/MainWindowController.cpp index 363c19c3a..4d357b141 100644 --- a/src/server/MainWindowController.cpp +++ b/src/server/MainWindowController.cpp @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include @@ -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()); diff --git a/src/server/MainWindowController.hpp b/src/server/MainWindowController.hpp index debb3624d..60629efd7 100644 --- a/src/server/MainWindowController.hpp +++ b/src/server/MainWindowController.hpp @@ -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; diff --git a/src/server/musikServer.vcproj b/src/server/musikServer.vcproj index 227ac613a..d128b398e 100644 --- a/src/server/musikServer.vcproj +++ b/src/server/musikServer.vcproj @@ -239,6 +239,62 @@ > + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#include +#include +#include + +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +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(); +} diff --git a/src/server/users/EditUserController.hpp b/src/server/users/EditUserController.hpp new file mode 100644 index 000000000..bc33650f8 --- /dev/null +++ b/src/server/users/EditUserController.hpp @@ -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 +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +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 diff --git a/src/server/users/EditUserView.cpp b/src/server/users/EditUserView.cpp new file mode 100644 index 000000000..4459122cc --- /dev/null +++ b/src/server/users/EditUserView.cpp @@ -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 + +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +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); + +} diff --git a/src/server/users/EditUserView.hpp b/src/server/users/EditUserView.hpp new file mode 100644 index 000000000..b7d8e16af --- /dev/null +++ b/src/server/users/EditUserView.hpp @@ -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 + +////////////////////////////////////////////////////////////////////////////// + +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 + diff --git a/src/server/users/UsersController.cpp b/src/server/users/UsersController.cpp new file mode 100644 index 000000000..45ba6eb44 --- /dev/null +++ b/src/server/users/UsersController.cpp @@ -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 +#include +#include +#include + +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +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(); +} + + diff --git a/src/server/users/UsersController.hpp b/src/server/users/UsersController.hpp new file mode 100644 index 000000000..1cc29839c --- /dev/null +++ b/src/server/users/UsersController.hpp @@ -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 +#include +#include +#include + +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 UsersListControllerRef; + UsersListControllerRef usersListController; + public: + musik::core::Server *server; +}; + +////////////////////////////////////////////////////////////////////////////// + +} } } // musik::server diff --git a/src/server/users/UsersListController.cpp b/src/server/users/UsersListController.cpp new file mode 100644 index 000000000..e5b6d1e2f --- /dev/null +++ b/src/server/users/UsersListController.cpp @@ -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 +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +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()); + } + + } + +} diff --git a/src/server/users/UsersListController.hpp b/src/server/users/UsersListController.hpp new file mode 100644 index 000000000..54c2b019a --- /dev/null +++ b/src/server/users/UsersListController.hpp @@ -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 + +////////////////////////////////////////////////////////////////////////////// +// 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 diff --git a/src/server/users/UsersListModel.cpp b/src/server/users/UsersListModel.cpp new file mode 100644 index 000000000..7aedbad68 --- /dev/null +++ b/src/server/users/UsersListModel.cpp @@ -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 +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +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(rowIndexusers.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(); + +} + diff --git a/src/server/users/UsersListModel.hpp b/src/server/users/UsersListModel.hpp new file mode 100644 index 000000000..7820b7c03 --- /dev/null +++ b/src/server/users/UsersListModel.hpp @@ -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 +#include +#include + +////////////////////////////////////////////////////////////////////////////// + +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 diff --git a/src/server/users/UsersView.cpp b/src/server/users/UsersView.cpp new file mode 100644 index 000000000..fb566089a --- /dev/null +++ b/src/server/users/UsersView.cpp @@ -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 + +#include +#include +#include +#include + + +////////////////////////////////////////////////////////////////////////////// + +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))); + +} diff --git a/src/server/users/UsersView.hpp b/src/server/users/UsersView.hpp new file mode 100644 index 000000000..fb0941bae --- /dev/null +++ b/src/server/users/UsersView.hpp @@ -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 + +////////////////////////////////////////////////////////////////////////////// + +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 + diff --git a/src/win32cpp/SysTray.cpp b/src/win32cpp/SysTray.cpp index 296d56384..b5a00396f 100644 --- a/src/win32cpp/SysTray.cpp +++ b/src/win32cpp/SysTray.cpp @@ -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; } }