//======================================================================
// RangeValue
//=====================================================================
//======================================================================
const std::map<RangeValue::LockType,std::string> RangeValue::LOCK_TYPE_NAMES {
{LockType::INCREASE,"increase"s},{LockType::DECREASE,"decrease"s},
{LockType::LOCKED,"locked"s}
};
//=====================================================================
auto RangeValue::nameForType(LockType type) -> const std::string &{
return LOCK_TYPE_NAMES.at(type) ;
}
//======================================================================
auto RangeValue::typeForName(const std::string &name) -> LockType{
auto lname = util::lower(name) ;
auto iter = std::find_if(LOCK_TYPE_NAMES.begin(),LOCK_TYPE_NAMES.end(),[&lname](const std::pair<LockType,std::string> &entry){
return entry.second == lname ;
});
if (iter != LOCK_TYPE_NAMES.end()){
return iter->first ;
}
throw std::runtime_error("Unknown lock type name: "s+name);
}
//=====================================================================
auto RangeValue::describe() const -> std::string {
return std::to_string(this->value)+","s+nameForType(lock)+";"s+range.describe();
}
//=====================================================================
RangeValue::RangeValue(int maxValue,int minValue,RangeValue::LockType lock ){
this->value = minValue ;
lock = lock ;
range = util::range_t<int>(minValue,maxValue) ;
}
//=====================================================================
RangeValue::RangeValue(const std::string &line) :RangeValue(){
auto [base,r] = util::split(line,";") ;
auto [lev,loc] = util::split(base,",");
this->value = std::stoi(lev,nullptr,0);
lock = typeForName(loc) ;
range = util::range_t<int>(r) ;
}
//=====================================================================
RangeValue::RangeValue(int value, util::range_t<int> &range, RangeValue::LockType lock):RangeValue() {
this->value = value ;
this->range = range ;
this->lock = lock ;
}
//====================================================================
auto RangeValue::applyDelta(int change) -> int{
auto amount = change ;
if (lock == RangeValue::LOCKED){
return 0 ;
}
if (!range.inRange(this->value + change)) {
if (this->value+change < range.lowValue){
amount = -(this->value - range.lowValue);
}
else {
amount = range.highValue - this->value ;
}
}
if (lock == RangeValue::INCREASE && amount < 0) {
return 0 ;
}
this->value += amount ;
return amount ;
}
//====================================================================
auto RangeValue::operator+=(int change) -> RangeValue&{
applyDelta(change);
return *this;
}
//====================================================================
auto RangeValue::operator-=(int change) -> RangeValue&{
applyDelta(-change);
return *this ;
}
//====================================================================
auto RangeValue::operator<(const RangeValue &entry) const-> bool {
return this->value<entry.value ;
}
//====================================================================
auto RangeValue::operator==(const RangeValue &entry) const -> bool {
return this->value == entry.value ;
}
//====================================================================
auto RangeValue::operator!=(const RangeValue &entry) const -> bool {
return !this->operator==(entry) ;
}
// RangeValue
//=====================================================================
//======================================================================
const std::map<RangeValue::LockType,std::string> RangeValue::LOCK_TYPE_NAMES {
{LockType::INCREASE,"increase"s},{LockType::DECREASE,"decrease"s},
{LockType::LOCKED,"locked"s}
};
//=====================================================================
auto RangeValue::nameForType(LockType type) -> const std::string &{
return LOCK_TYPE_NAMES.at(type) ;
}
//======================================================================
auto RangeValue::typeForName(const std::string &name) -> LockType{
auto lname = util::lower(name) ;
auto iter = std::find_if(LOCK_TYPE_NAMES.begin(),LOCK_TYPE_NAMES.end(),[&lname](const std::pair<LockType,std::string> &entry){
return entry.second == lname ;
});
if (iter != LOCK_TYPE_NAMES.end()){
return iter->first ;
}
throw std::runtime_error("Unknown lock type name: "s+name);
}
//=====================================================================
auto RangeValue::describe() const -> std::string {
return std::to_string(this->value)+","s+nameForType(lock)+";"s+range.describe();
}
//=====================================================================
RangeValue::RangeValue(int maxValue,int minValue,RangeValue::LockType lock ){
this->value = minValue ;
lock = lock ;
range = util::range_t<int>(minValue,maxValue) ;
}
//=====================================================================
RangeValue::RangeValue(const std::string &line) :RangeValue(){
auto [base,r] = util::split(line,";") ;
auto [lev,loc] = util::split(base,",");
this->value = std::stoi(lev,nullptr,0);
lock = typeForName(loc) ;
range = util::range_t<int>(r) ;
}
//=====================================================================
RangeValue::RangeValue(int value, util::range_t<int> &range, RangeValue::LockType lock):RangeValue() {
this->value = value ;
this->range = range ;
this->lock = lock ;
}
//====================================================================
auto RangeValue::applyDelta(int change) -> int{
auto amount = change ;
if (lock == RangeValue::LOCKED){
return 0 ;
}
if (!range.inRange(this->value + change)) {
if (this->value+change < range.lowValue){
amount = -(this->value - range.lowValue);
}
else {
amount = range.highValue - this->value ;
}
}
if (lock == RangeValue::INCREASE && amount < 0) {
return 0 ;
}
this->value += amount ;
return amount ;
}
//====================================================================
auto RangeValue::operator+=(int change) -> RangeValue&{
applyDelta(change);
return *this;
}
//====================================================================
auto RangeValue::operator-=(int change) -> RangeValue&{
applyDelta(-change);
return *this ;
}
//====================================================================
auto RangeValue::operator<(const RangeValue &entry) const-> bool {
return this->value<entry.value ;
}
//====================================================================
auto RangeValue::operator==(const RangeValue &entry) const -> bool {
return this->value == entry.value ;
}
//====================================================================
auto RangeValue::operator!=(const RangeValue &entry) const -> bool {
return !this->operator==(entry) ;
}