namespace Aftr { //T is the type used to store a color channel, such as uint8_t, float, or double //C is the number of color channels desired, such as 3 or 4, etc. template< typename T, uint8_t C > AftrColorT::AftrColorT() : data{0} { for( auto& v : this->data ) v = std::numeric_limits::max(); } template< typename T, uint8_t C > AftrColorT::AftrColorT( std::initializer_list colors ) { if( colors.size() != C ) { std::cout << "ERROR: " << AFTR_FILE_LINE_STR << ": AftrColorT: User passed in wrong number of colors -- colors.size() (" << colors.size() << ") != templated val (" << uint(C) << ")...\n"; std::abort(); } std::copy( colors.begin(), colors.end(), data.begin() ); } template T& AftrColorT::operator [] ( size_t i ) noexcept { if( i >= C ) { std::cout << "ERROR: " << AFTR_FILE_LINE_STR << ": User tried to access color index " << i << ", but num color channels C was only " << uint( C ) << "...\n"; std::abort(); } return this->data[i]; } template const T& AftrColorT::operator [] ( size_t i ) const noexcept { if( i >= C ) { std::cout << "ERROR: " << AFTR_FILE_LINE_STR << ": User tried to access color index " << i << ", but num color channels C was only " << uint( C ) << "...\n"; std::abort(); } return this->data[i]; } template bool AftrColorT::operator ==( const AftrColorT& c ) const noexcept { return std::equal( this->data.cbegin(), this->data.cend(), c.cbegin() ); } template AftrColorT AftrColorT::operator+( const AftrColorT& c ) const noexcept { AftrColorT sum; std::transform( this->cbegin(), this->cend(), c.cbegin(), sum.begin(), std::plus() ); return sum; } template AftrColorT AftrColorT::operator+( const T& v ) const noexcept { AftrColorT sum; std::transform( this->cbegin(), this->cend(), sum.begin(), [&v] ( const T& a ) { return a + v; } ); return sum; } template AftrColorT& AftrColorT::operator+=( const AftrColorT& c ) noexcept { std::transform( this->begin(), this->end(), c.cbegin(), this->begin(), std::plus() ); return *this; } template AftrColorT AftrColorT::operator-( const AftrColorT& c ) const noexcept { AftrColorT diff; std::transform( this->cbegin(), this->cend(), c.cbegin(), diff.begin(), std::minus() ); return diff; } template AftrColorT AftrColorT::operator-( const T& v ) const noexcept { AftrColorT diff; std::transform( this->cbegin(), this->cend(), diff.begin(), [&v] ( const T& a ) { return a - v; } ); return diff; } template AftrColorT& AftrColorT::operator-=( const AftrColorT& c ) noexcept { std::transform( this->begin(), this->end(), c.cbegin(), this->begin(), std::minus() ); return *this; } template std::string AftrColorT::toString() const noexcept { std::stringstream ss; ss << "["; for( int i = 0; i < C; ++i ) { ss << data[i]; if( i != C - 1 ) ss << ","; } ss << "]"; return ss.str(); } }