Last active
August 29, 2015 14:19
-
-
Save jrandom/62d6741e5d1eb65a8060 to your computer and use it in GitHub Desktop.
Mutatable Value Macro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Mutatable_Value.h | |
// Tools/Genetics | |
// | |
#ifndef Tools_Genetics_Mutateable_Value_h | |
#define Tools_Genetics_Mutateable_Value_h | |
// ================================================================================ Standard Includes | |
// Standard Includes | |
// -------------------------------------------------------------------------------- | |
#include <limits> | |
#include <utility> | |
// ================================================================================ Tools Includes | |
// Tools Includes | |
// -------------------------------------------------------------------------------- | |
#include "Tools/Core/Math.h" | |
#include "Tools/Core/Random.h" | |
#include "Tools/File/Raw.h" | |
namespace Genetics | |
{ | |
// ============================================================================ Mutateable_ ## | |
// Mutatable_ ## | |
// | |
// Utility class to simplify basic mutating values. Created as a macro since | |
// C++ doesn't allow for floating-point template value arguments. | |
// | |
// I am so very sorry... | |
// ---------------------------------------------------------------------------- | |
#define Declare_Mutatable_Value(TAG, VALUE_TYPE, VALUE_MIN, VALUE_MAX, VALUE_DEFAULT) \ | |
\ | |
class Mutatable_ ## TAG final\ | |
{ \ | |
public:\ | |
/* -------------------------------------------------------------------- Types */ \ | |
using This_t = Mutatable_ ## TAG;\ | |
using Value_t = VALUE_TYPE;\ | |
using Pair_t = std::pair< This_t, This_t >;\ | |
using Value_Pair_t = std::pair< Value_t, Value_t >;\ | |
\ | |
private:\ | |
/* -------------------------------------------------------------------- Constants */ \ | |
static constexpr Value_t Value_Min = Value_t( VALUE_MIN );\ | |
static constexpr Value_t Value_Max = Value_t( VALUE_MAX );\ | |
\ | |
/* -------------------------------------------------------------------- State */ \ | |
Value_t _value;\ | |
\ | |
\ | |
public:\ | |
/* ==================================================================== Constructors */ \ | |
/* Constructors */ \ | |
/* -------------------------------------------------------------------- Construct( zero ) */ \ | |
Mutatable_ ## TAG () noexcept\ | |
\ | |
: _value( VALUE_DEFAULT )\ | |
{}\ | |
\ | |
/* -------------------------------------------------------------------- Construct( value ) */ \ | |
Mutatable_ ## TAG ( Value_t value ) noexcept\ | |
\ | |
: _value( Math::Clamp(value, Value_Min, Value_Max) )\ | |
{}\ | |
\ | |
/* -------------------------------------------------------------------- Construct( copy ) */ \ | |
Mutatable_ ## TAG ( const This_t & source ) noexcept\ | |
\ | |
: _value( source._value )\ | |
{} \ | |
\ | |
/* -------------------------------------------------------------------- Construct( random ) */ \ | |
Mutatable_ ## TAG ( Random::Generator & rng ) noexcept\ | |
\ | |
: _value( rng.Number(Value_Min, Value_Max) )\ | |
{}\ | |
\ | |
/* -------------------------------------------------------------------- Construct( random with initial allowed range ) */ \ | |
Mutatable_ ## TAG ( Random::Generator & rng, \ | |
const Value_Pair_t min_max_initial_range ) noexcept\ | |
\ | |
: Mutatable_ ## TAG( rng.Number(min_max_initial_range.first, min_max_initial_range.second) )\ | |
{}\ | |
\ | |
/* -------------------------------------------------------------------- Construct( muatate ) */ \ | |
Mutatable_ ## TAG ( const This_t & source,\ | |
Random::Generator & rng,\ | |
const float mutation_rate ) noexcept\ | |
\ | |
: _value( rng.Chance( mutation_rate )\ | |
? rng.Number( Value_Min, Value_Max )\ | |
: source._value )\ | |
{}\ | |
\ | |
/* -------------------------------------------------------------------- Construct( from file ) */ \ | |
Mutatable_ ## TAG ( File::Raw_In & infile )\ | |
\ | |
: _value( Value_From_File(infile) )\ | |
{}\ | |
\ | |
\ | |
public:\ | |
/* ==================================================================== Accessors and Overloads */ \ | |
/* Accessors and Overloads*/ \ | |
/* -------------------------------------------------------------------- */ \ | |
Value_t Value () const noexcept { return _value; }\ | |
operator Value_t() const noexcept { return _value; }\ | |
\ | |
This_t & operator=( Value_t value ) noexcept { _value = Math::Clamp(value, Value_Min, Value_Max ); return *this; }\ | |
\ | |
\ | |
public:\ | |
/* ==================================================================== Public API */ \ | |
/* Public API */ \ | |
/* -------------------------------------------------------------------- Duplicate() */ \ | |
static Pair_t Duplicate( const This_t & source, \ | |
Random::Generator & rng ) \ | |
{\ | |
/* Standard duplication has no special case, so rng is unused here */ \ | |
/* I apologize for all the compiler warnings this incurs. */ \ | |
return { source, source }; \ | |
}\ | |
\ | |
/* -------------------------------------------------------------------- Persist() */ \ | |
void Persist( File::Raw_Out & outfile ) const\ | |
{\ | |
outfile.Write( _value );\ | |
}\ | |
\ | |
\ | |
private:\ | |
/* ==================================================================== Private Static API */ \ | |
/* Private Static API */ \ | |
/* -------------------------------------------------------------------- Value_From_File() */ \ | |
static Value_t Value_From_File( File::Raw_In & infile )\ | |
{\ | |
Value_t value;\ | |
\ | |
infile.Read_Into( &value );\ | |
\ | |
return value;\ | |
}\ | |
} | |
// ============================================================================ Mutatable Value Presets | |
// Mutatable Value Presets | |
// ---------------------------------------------------------------------------- | |
Declare_Mutatable_Value( Float_01, float, 0.0f, 1.0f, 0.0f ); | |
Declare_Mutatable_Value( Double_01, double, 0.0, 1.0, 0.0 ); | |
Declare_Mutatable_Value( Float_PosNeg1, float, -1.0f, 1.0f, 0.0f ); | |
Declare_Mutatable_Value( Double_PosNeg1, double, -1.0, 1.0, 0.0 ); | |
Declare_Mutatable_Value( Float_PosNeg2, float, -2.0f, 2.0f, 0.0f ); | |
Declare_Mutatable_Value( Double_PosNeg2, double, -2.0, 2.0, 0.0 ); | |
Declare_Mutatable_Value( Int8, int_fast8_t, std::numeric_limits< int8_t >::min(), std::numeric_limits< int8_t >::max(), int_fast8_t (0) ); | |
Declare_Mutatable_Value( Int16, int_fast16_t, std::numeric_limits< int16_t >::min(), std::numeric_limits< int16_t >::max(), int_fast16_t(0) ); | |
Declare_Mutatable_Value( Int32, int_fast32_t, std::numeric_limits< int32_t >::min(), std::numeric_limits< int32_t >::max(), int_fast32_t(0) ); | |
Declare_Mutatable_Value( Int64, int_fast64_t, std::numeric_limits< int64_t >::min(), std::numeric_limits< int64_t >::max(), int_fast64_t(0) ); | |
Declare_Mutatable_Value( Uint8, uint_fast8_t, std::numeric_limits< uint8_t >::min(), std::numeric_limits< uint8_t >::max(), uint_fast8_t (0) ); | |
Declare_Mutatable_Value( Uint16, uint_fast16_t, std::numeric_limits< uint16_t>::min(), std::numeric_limits< uint16_t >::max(), uint_fast16_t(0) ); | |
Declare_Mutatable_Value( Uint32, uint_fast32_t, std::numeric_limits< uint32_t>::min(), std::numeric_limits< uint32_t >::max(), uint_fast32_t(0) ); | |
Declare_Mutatable_Value( Uint64, uint_fast64_t, std::numeric_limits< uint64_t>::min(), std::numeric_limits< uint64_t >::max(), uint_fast64_t(0) ); | |
using Mutatable_Probability = Mutatable_Float_01; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment