/******************************************************************************/
/* SRD - DATA - INLINE CODE ***************************************************/
/******************************************************************************/

#ifndef _H_EBCL_INLINE_SRDDATA
#define _H_EBCL_INLINE_SRDDATA
#include <ebcl/SRDData.hh>
namespace ebcl {


/*= T_SRDLocationChaining ====================================================*/

inline T_SRDLocationChaining::T_SRDLocationChaining(
		const E_SRDLocationChaining how ,
		const uint32_t depth ,
		SP_SRDLocation const& to ) noexcept
	: circumstances( how ) , depth( depth ) , location( to )
{ }

inline bool T_SRDLocationChaining::isGenerated( ) const noexcept
{
	return circumstances == E_SRDLocationChaining::GENERATED
		|| circumstances == E_SRDLocationChaining::SUBSTITUTED;
}


/*= T_SRDLocation ============================================================*/

inline T_SRDLocation::T_SRDLocation( ) noexcept
	: source_( ) , line_( 0 ) , character_( 0 )
{ }

inline T_SRDLocation& T_SRDLocation::operator= (
		T_SRDLocation&& other ) noexcept
{
	swap( *this , other );
	return *this;
}

inline T_SRDLocation::T_SRDLocation(
		T_SRDToken const& token ) noexcept
	: T_SRDLocation( )
{
	if ( token.hasLocation( ) ) {
		*this = token.location( );
	}
}

/*----------------------------------------------------------------------------*/

inline void T_SRDLocation::chain(
		const E_SRDLocationChaining how ,
		SP_SRDLocation const& to ) noexcept
{
	chain( how , 0 , to );
}

inline void T_SRDLocation::chain(
		const E_SRDLocationChaining how ,
		const uint32_t depth ,
		SP_SRDLocation const& to ) noexcept
{
	assert( bool( to ) );
	chaining_.setNew( how , depth , to );
}

inline void T_SRDLocation::clearChain( ) noexcept
{
	chaining_.clear( );
}

/*----------------------------------------------------------------------------*/

inline bool T_SRDLocation::unknown( ) const noexcept
{
	return source_.size( ) == 0;
}

inline T_String const& T_SRDLocation::source( ) const noexcept
{
	return source_;
}

inline bool T_SRDLocation::binary( ) const noexcept
{
	return line_ == 0;
}

inline uint32_t T_SRDLocation::line( ) const noexcept
{
	return line_;
}

inline size_t T_SRDLocation::character( ) const noexcept
{
	return character_;
}

inline size_t T_SRDLocation::byte( ) const noexcept
{
	return character_;
}

inline bool T_SRDLocation::isChained( ) const noexcept
{
	return chaining_;
}

inline T_SRDLocationChaining const& T_SRDLocation::chaining( ) const noexcept
{
	return *chaining_;
}


/*= T_SRDError ===============================================================*/

inline T_SRDError::T_SRDError(
		T_String error ,
		T_SRDLocation location ,
		const E_SRDErrorType type ) noexcept
	: error_( std::move( error ) ) ,
		location_( std::move( location ) ) ,
		type_( type )
{ }

/*----------------------------------------------------------------------------*/

inline T_SRDError::T_SRDError(
		T_SRDError const& other ) noexcept
	: error_( other.error_ ) ,
		location_( other.location_ ) ,
		type_( other.type_ )
{ }

inline T_SRDError& T_SRDError::operator= (
		T_SRDError const& other ) noexcept
{
	error_ = other.error_;
	location_ = other.location_;
	type_ = other.type_;
	return *this;
}

/*----------------------------------------------------------------------------*/

inline T_SRDError::T_SRDError(
		T_SRDError&& other ) noexcept
	: error_( ) , location_( )
{
	swap( *this , other );
}

inline T_SRDError& T_SRDError::operator=(
		T_SRDError&& other ) noexcept
{
	swap( *this , other );
	return *this;
}

/*----------------------------------------------------------------------------*/

inline M_DECLARE_SWAP( T_SRDError )
{
	using std::swap;
	swap( lhs.error_ , rhs.error_ );
	swap( lhs.location_ , rhs.location_ );
	swap( lhs.type_ , rhs.type_ );
}

/*----------------------------------------------------------------------------*/

inline T_String const& T_SRDError::error( ) const noexcept
{
	return error_;
}

inline T_SRDLocation const& T_SRDError::location( ) const noexcept
{
	return location_;
}

inline E_SRDErrorType T_SRDError::type( ) const noexcept
{
	return type_;
}


/*= T_SRDErrors ==============================================================*/

template< typename ... ArgTypes >
inline void T_SRDErrors::add(
		char const* error ,
		ArgTypes&&... locationArgs )
{
	add( InPlace::v , T_String::Pooled( error ) ,
			T_SRDLocation( std::forward< ArgTypes >( locationArgs ) ... ) );
}

template< typename ... ArgTypes >
inline void T_SRDErrors::add(
		T_String const& error ,
		ArgTypes&&... locationArgs )
{
	add( InPlace::v , error ,
			T_SRDLocation( std::forward< ArgTypes >( locationArgs ) ... ) );
}

template< typename ... ArgTypes >
inline void T_SRDErrors::details(
		char const* error ,
		ArgTypes&&... locationArgs )
{
	add( InPlace::v , T_String::Pooled( error ) ,
			T_SRDLocation( std::forward< ArgTypes >( locationArgs ) ... ) ,
			true );
}

template< typename ... ArgTypes >
inline void T_SRDErrors::details(
		T_String const& error ,
		ArgTypes&&... locationArgs )
{
	add( InPlace::v , error ,
			T_SRDLocation( std::forward< ArgTypes >( locationArgs ) ... ) ,
			true );
}

template< typename ... ArgTypes >
inline void T_SRDErrors::add(
		InPlace ,
		ArgTypes&&... args )
{
	checkAdded( errors_.addNew( std::forward< ArgTypes >( args ) ... ) );
}

inline void T_SRDErrors::add(
		T_SRDError const& error )
{
	checkAdded( errors_.addNew( error ) );
}

inline void T_SRDErrors::add(
		T_SRDError&& error )
{
	checkAdded( errors_.addNew( std::move( error ) ) );
}

/*----------------------------------------------------------------------------*/

inline uint32_t T_SRDErrors::size( ) const noexcept
{
	return errors_.size( );
}

inline T_SRDError const& T_SRDErrors::operator[] (
		uint32_t index ) const noexcept
{
	return errors_[ index ];
}

inline void T_SRDErrors::clear( ) noexcept
{
	errors_.clear( );
	errCount_ = 0;
}


/*= X_SRDErrors ==============================================================*/

inline X_SRDErrors::X_SRDErrors( T_SRDErrors const& errors )
	: errors( errors )
{ }


/*= T_SRDToken ===============================================================*/

inline T_SRDToken::T_SRDToken(
		const E_SRDTokenType type ) noexcept
	: type_( type )
{ }

inline T_SRDToken::T_SRDToken( T_SRDToken&& other ) noexcept
{
	swap( *this , other );
}

inline T_SRDToken& T_SRDToken::operator= ( T_SRDToken&& other ) noexcept
{
	swap( *this , other );
	return *this;
}

/*----------------------------------------------------------------------------*/

template< typename T >
inline T_SRDToken T_SRDToken::Binary(
		T const* const data ,
		const uint32_t count ) noexcept
{
	return Binary( (uint8_t const*) data , count );
}

template< >
inline T_SRDToken T_SRDToken::Binary< uint8_t >(
		uint8_t const* const data ,
		const uint32_t count ) noexcept
{
	return Binary( NewShared< T_Buffer< uint8_t > >( data , count ) );
}

template< typename T >
inline T_SRDToken T_SRDToken::Binary(
		T_Buffer< T > const& data ) noexcept
{
	if ( data.size( ) == 0 ) {
		return Binary( NewShared< T_Buffer< uint8_t > >( ) );
	} else {
		return Binary( (uint8_t const*) &data[ 0 ] , data.bytes( ) );
	}
}


/*----------------------------------------------------------------------------*/

inline E_SRDTokenType T_SRDToken::type( ) const
{
	return type_;
}

inline bool T_SRDToken::isText( ) const
{
	return type_ == E_SRDTokenType::WORD || type_ == E_SRDTokenType::STRING;
}

inline bool T_SRDToken::isNumeric( ) const
{
	return isInteger( ) || type_ == E_SRDTokenType::FLOAT;
}

inline bool T_SRDToken::isInteger( ) const
{
	return type_ == E_SRDTokenType::INT || type_ == E_SRDTokenType::LONG;
}

/*----------------------------------------------------------------------------*/

inline T_String const& T_SRDToken::text( ) const
{
	return text_;
}

inline T_SRDList const& T_SRDToken::list( ) const
{
	return *list_;
}

inline T_SRDList& T_SRDToken::list( )
{
	return *list_;
}

inline int64_t T_SRDToken::longValue( ) const
{
	return longValue_;
}

inline double T_SRDToken::floatValue( ) const
{
	return floatValue_;
}

inline T_String const& T_SRDToken::stringValue( ) const
{
	return stringValue_;
}

inline T_Buffer< uint8_t > const& T_SRDToken::binary( ) const
{
	return *binary_;
}

/*----------------------------------------------------------------------------*/

inline bool T_SRDToken::operator ==( T_SRDToken const& other ) const
{
	return compare( other ) == 0;
}

inline bool T_SRDToken::operator !=( T_SRDToken const& other ) const
{
	return compare( other ) != 0;
}

inline bool T_SRDToken::operator >( T_SRDToken const& other ) const
{
	return compare( other ) > 0;
}

inline bool T_SRDToken::operator <( T_SRDToken const& other ) const
{
	return compare( other ) < 0;
}

inline bool T_SRDToken::operator >=( T_SRDToken const& other ) const
{
	return compare( other ) >= 0;
}

inline bool T_SRDToken::operator <=( T_SRDToken const& other ) const
{
	return compare( other ) <= 0;
}

inline M_DEFINE_COMPARATOR( T_SRDToken )
{
	return a.compare( b );
}

/*----------------------------------------------------------------------------*/

inline bool T_SRDToken::hasLocation( ) const noexcept
{
	return bool( location_ );
}

inline T_SRDLocation& T_SRDToken::location( ) noexcept
{
	return *location_;
}

inline T_SRDLocation const& T_SRDToken::location( ) const noexcept
{
	return *location_;
}


} // namespace
#endif // _H_EBCL_INLINE_SRDDATA