// SPDX-FileComment: This file is part of TNL - Template Numerical Library (https://tnl-project.org/)
// SPDX-License-Identifier: MIT

#pragma once

#include <TNL/Containers/StaticVector.h>
#include <TNL/Containers/detail/VectorAssignment.h>

namespace TNL::Containers {

template< int Size, typename Real >
template< typename T1, typename T2, typename Operation >
constexpr StaticVector< Size, Real >::StaticVector(
   const Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >& expr )
: StaticArray< Size, Real >()
{
   detail::VectorAssignment< StaticVector< Size, Real >, Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation > >::
      assignStatic( *this, expr );
}

template< int Size, typename Real >
template< typename T, typename Operation >
constexpr StaticVector< Size, Real >::StaticVector( const Expressions::StaticUnaryExpressionTemplate< T, Operation >& expr )
: StaticArray< Size, Real >()
{
   detail::VectorAssignment< StaticVector< Size, Real >, Expressions::StaticUnaryExpressionTemplate< T, Operation > >::
      assignStatic( *this, expr );
}

template< int Size, typename Real >
template< typename VectorExpression >
constexpr StaticVector< Size, Real >&
StaticVector< Size, Real >::operator=( const VectorExpression& expression )
{
   detail::VectorAssignment< StaticVector< Size, Real >, VectorExpression >::assignStatic( *this, expression );
   return *this;
}

template< int Size, typename Real >
template< typename VectorExpression >
constexpr StaticVector< Size, Real >&
StaticVector< Size, Real >::operator+=( const VectorExpression& expression )
{
   detail::VectorAssignmentWithOperation< StaticVector, VectorExpression >::additionStatic( *this, expression );
   return *this;
}

template< int Size, typename Real >
template< typename VectorExpression >
constexpr StaticVector< Size, Real >&
StaticVector< Size, Real >::operator-=( const VectorExpression& expression )
{
   detail::VectorAssignmentWithOperation< StaticVector, VectorExpression >::subtractionStatic( *this, expression );
   return *this;
}

template< int Size, typename Real >
template< typename VectorExpression >
constexpr StaticVector< Size, Real >&
StaticVector< Size, Real >::operator*=( const VectorExpression& expression )
{
   detail::VectorAssignmentWithOperation< StaticVector, VectorExpression >::multiplicationStatic( *this, expression );
   return *this;
}

template< int Size, typename Real >
template< typename VectorExpression >
constexpr StaticVector< Size, Real >&
StaticVector< Size, Real >::operator/=( const VectorExpression& expression )
{
   detail::VectorAssignmentWithOperation< StaticVector, VectorExpression >::divisionStatic( *this, expression );
   return *this;
}

template< int Size, typename Real >
template< typename VectorExpression >
constexpr StaticVector< Size, Real >&
StaticVector< Size, Real >::operator%=( const VectorExpression& expression )
{
   detail::VectorAssignmentWithOperation< StaticVector, VectorExpression >::moduloStatic( *this, expression );
   return *this;
}

}  // namespace TNL::Containers
