// RuntimeForStatic base library | C+- (SysRoutine) | Author: Sergei Y.Kitáev
#pragma once
#include "include_restrictions.h"
namespace RuntimeForStatic {
//==================================================================================================

template<typename T>static T $subst::NullSubst( T value, T subst )
{
   return value ? value : subst;
}
template<typename T>static T $subst::NullSubst( T value,
                                                const std::initializer_list<T>& substitution_list )
{
   if ( value ) return value;
   for (auto sv: substitution_list)
      if ( sv ) return sv;
}

//--------------------------------------------------------------------------------------------------

template<typename T>static T $subst::Exchange(T& location,T newValue) $ret_previous
{
   T intial = location; location = newValue; return intial;
}
template<typename T>static T $subst::ExchangeR(T& location,const T& newValue) $ret_previous
{
   T intial = location; location = newValue; return intial;
}

template<typename T>static T $subst::CompareExchange( T& location,
                                                      T exchange,
                                                      T comparand ) $ret_initial
{
   T intial = location; if ( location == comparand ) location = exchange; return intial;
}
template<typename T>static T $subst::CompareExchangeR( T& location,
                                                       const T& exchange,
                                                       const T& comparand ) $ret_initial
{
   T intial = location; if ( location == comparand ) location = exchange; return intial;
}

template<typename T>static T ExchangeAsBool(T& location,bool newValue) $ret_previous
{
   return Exchange<T>( location, (T)$Ops::IntFromBool( newValue ) );
}
template<typename T>static T& ExchangeAsBoolR(T& location,const bool& newValue) $ret_previous
{
   return ExchangeR<T>( location, (T)$Ops::IntFromBool( newValue ) );
}

template<typename T>static T $subst::NullExchange(T& location) $ret_previous
{
   return Exchange( location, (T)NULL );
}

//--------------------------------------------------------------------------------------------------

template<typename T>static T $subst::ReplaceNull(T& location,T newValue) $ret_target
{
   if ( !location ) location = newValue; return location;
}
template<typename T>static T $subst::ReplaceNullR(T& location,const T& newValue) $ret_target
{
   if ( !location ) location = newValue; return location;
}

template<typename T>static T $subst::SetIfEqual(T& location,T newValue,T comparand) $ret_target
{
   if ( location == comparand ) location = newValue; return location;
}
template<typename T>static T $subst::SetIfEqualR( T& location, const T& newValue, T& comparand )
                                                  $ret_target
{
   if ( location == comparand ) location = newValue; return location;
}

//==================================================================================================
} // RuntimeForStatic
