Created
March 31, 2023 18:02
-
-
Save hirosof/94b389fb9dd076921a42dd93e9adf621 to your computer and use it in GitHub Desktop.
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
#pragma once | |
#include <limits> | |
#include <stdexcept> | |
template <typename T> class GeneralCounter { | |
private: | |
const bool m_is_signed_type = std::numeric_limits<T>::is_signed; | |
T m_start; | |
T m_end; | |
T m_update; | |
T m_frame_count; | |
static bool s_isRangeValue( T value, T range_x, T range_y ) { | |
if ( range_x > range_y ) return s_isRangeValue( value, range_y, range_x ); | |
return ( value >= range_x ) && ( value <= range_y ); | |
} | |
static T s_clipValue( T value, T range_x, T range_y ) { | |
if ( range_x > range_y ) return s_clipValue( value, range_y, range_x ); | |
T v = ( value > range_y ) ? range_y : value; | |
return ( v < range_x ) ? range_x : v; | |
} | |
public: | |
GeneralCounter( ) { | |
const T default_start = 0; | |
const T default_end = 10; | |
const T default_update = 1; | |
change( default_start, default_end, default_update ); | |
} | |
GeneralCounter( T startValue, T endValue, T updateValue = 1 ){ | |
change( startValue, endValue, updateValue ); | |
} | |
template <typename U, size_t elements> GeneralCounter( const U( &array_value )[elements] ) { | |
change( 0, static_cast<T>( elements - 1 ), 1 ); | |
} | |
void change( T startValue, T endValue, T updateValue = 1 ) { | |
if ( updateValue == 0 ) { | |
throw std::invalid_argument( "不正パラメータ:カウンター更新値が0です" ); | |
} | |
if ( m_is_signed_type ) { | |
if ( ( endValue - startValue ) / updateValue < 0 ) { | |
throw std::exception( "実現不可能なカウンター:終点値に到達不可能なカウンターです。" ); | |
} | |
} else { | |
if ( startValue > endValue ) { | |
throw std::exception( "実現不可能なカウンター:終点値に到達不可能なカウンターです。" ); | |
} | |
} | |
m_start = startValue; | |
m_end = endValue; | |
m_update = updateValue; | |
reset( ); | |
} | |
template <typename U, size_t elements> void change_of_array_size( const U (&array_value)[elements] ) { | |
change( 0, static_cast<T>(elements - 1), 1 ); | |
} | |
T get_setting_start( void ) const { | |
return m_start; | |
} | |
T get_setting_end( void ) const { | |
return m_end; | |
} | |
T get_setting_update( void )const { | |
return m_update; | |
} | |
void reset( void ) { | |
m_frame_count = 0; | |
} | |
void update( void ) { | |
if ( checkWithin( ) ) m_frame_count++; | |
} | |
T get_frame( void ) const{ | |
return m_frame_count; | |
} | |
T get_raw_value( void ) const { | |
return m_start + m_frame_count * m_update; | |
} | |
T get( void )const { | |
return s_clipValue( get_raw_value( ), m_start, m_end ); | |
} | |
bool checkWithin( void ) const { | |
return s_isRangeValue( get_raw_value( ), m_start, m_end ); | |
} | |
}; | |
サンプル使用コードの実行結果
【GeneralCounterRun<int>( 0, 5, 1 )】
『0』から『5』まで『1』刻みでカウント
name get rawget frame
forループ内 0 0 0
forループ内 1 1 1
forループ内 2 2 2
forループ内 3 3 3
forループ内 4 4 4
forループ内 5 5 5
forループ後 5 6 6
【GeneralCounterRun<int>( 1, 10, 3 )】
『1』から『10』まで『3』刻みでカウント
name get rawget frame
forループ内 1 1 0
forループ内 4 4 1
forループ内 7 7 2
forループ内 10 10 3
forループ後 10 13 4
【GeneralCounterRun<int>( 5, 0, -1 )】
『5』から『0』まで『-1』刻みでカウント
name get rawget frame
forループ内 5 5 0
forループ内 4 4 1
forループ内 3 3 2
forループ内 2 2 3
forループ内 1 1 4
forループ内 0 0 5
forループ後 0 -1 6
【GeneralCounterRun<double>( 0, 1, 0.2 )】
『0』から『1』まで『0.2』刻みでカウント
name get rawget frame
forループ内 0 0 0
forループ内 0.2 0.2 1
forループ内 0.4 0.4 2
forループ内 0.6 0.6 3
forループ内 0.8 0.8 4
forループ内 1 1 5
forループ後 1 1.2 6
【GeneralCounterRun<int>( 5, 0, 0 )】 (実現不可能なケース)
std::exception("不正パラメータ:カウンター更新値が0です")
【GeneralCounterRun<int>( 5, 0, 1 )】 (実現不可能なケース)
std::exception("実現不可能なカウンター:終点値に到達不可能なカウンターです。")
【GeneralCounterRun<int>( 0, 5, -1 )】 (実現不可能なケース)
std::exception("実現不可能なカウンター:終点値に到達不可能なカウンターです。")
配列内容出力
[0] 5.25
[1] 2.4
[2] 6.001
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
サンプル使用コード