MyCurry/src/gamelib/constrained_value.hpp

110 lines
3.1 KiB
C++

/*
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
This file is part of MyCurry.
MyCurry is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MyCurry is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <boost/call_traits.hpp>
#include <boost/algorithm/clamp.hpp>
#include <cassert>
namespace curry {
template <typename T>
class ScalarConstrainer {
public:
typename boost::call_traits<T>::const_reference operator() (
typename boost::call_traits<T>::param_type parMin,
typename boost::call_traits<T>::param_type parMax,
typename boost::call_traits<T>::param_type parValue
) {
return boost::algorithm::clamp(parValue, parMin, parMax);
}
};
template <typename T, typename Constrainer=ScalarConstrainer<T>>
class ConstrainedValue {
using T_param = typename boost::call_traits<T>::param_type;
public:
ConstrainedValue (T_param parMin, T_param parMax, T_param parValue);
virtual ~ConstrainedValue() noexcept = default;
void set (T_param parNew);
typename boost::call_traits<T>::const_reference get() const;
typename boost::call_traits<T>::const_reference get_min() const;
typename boost::call_traits<T>::const_reference get_max() const;
void change_minmax (T_param parMin, T_param parMax);
ConstrainedValue& operator= (T_param parValue);
private:
T m_min;
T m_max;
T m_value;
};
template <typename T, typename Constrainer>
ConstrainedValue<T, Constrainer>::ConstrainedValue (
T_param parMin,
T_param parMax,
T_param parValue
) :
m_min(parMin),
m_max(parMax),
m_value(parValue)
{
assert(parMin <= parMax);
}
template <typename T, typename Constrainer>
void ConstrainedValue<T, Constrainer>::set (T_param parNew) {
m_value = Constrainer()(m_min, m_max, parNew);
}
template <typename T, typename Constrainer>
typename boost::call_traits<T>::const_reference ConstrainedValue<T, Constrainer>::get() const {
return m_value;
}
template <typename T, typename Constrainer>
typename boost::call_traits<T>::const_reference ConstrainedValue<T, Constrainer>::get_min() const {
return m_min;
}
template <typename T, typename Constrainer>
typename boost::call_traits<T>::const_reference ConstrainedValue<T, Constrainer>::get_max() const {
return m_max;
}
template <typename T, typename Constrainer>
void ConstrainedValue<T, Constrainer>::change_minmax (
T_param parMin,
T_param parMax
) {
assert(parMin <= parMax);
m_min = parMin;
m_max = parMax;
this->set(m_value);
}
template <typename T, typename Constrainer>
ConstrainedValue<T, Constrainer>& ConstrainedValue<T, Constrainer>::operator= (T_param parValue) {
this->set(parValue);
return *this;
}
} //namespace curry