//#####################################################################
// Copyright 2006-2008, Geoffrey Irving, Craig Schroeder.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Header VECTOR_FORWARD
//#####################################################################
#ifndef __VECTOR_FORWARD__
#define __VECTOR_FORWARD__

#include <Core/Read_Write/READ_WRITE_FORWARD.h>
#include <Core/Utilities/TYPE_UTILITIES.h>
namespace PhysBAM{

template<class T,int d> class VECTOR;
template<class T,int d> class ZERO_VECTOR;

template<class T> class INTERVAL;
template<class T> class QUATERNION;
template<class TV> class ROTATION;
template<class T> class TETRAHEDRAL_GROUP;
template<class TV> class FRAME;
template<class TV> class TWIST;

template<class T,class ID> class ARRAY;

template<class T> struct IS_SCALAR_BLOCK;
template<class T,int d> struct IS_SCALAR_BLOCK<VECTOR<T,d> > {static const bool value=(d>0) && IS_SCALAR_BLOCK<T>::value;};
template<class T,int d,class RW> struct IS_BINARY_IO_SAFE<VECTOR<T,d>,RW> {static const bool value=(d>0) && IS_BINARY_IO_SAFE<T,RW>::value;};

template<class T> struct HAS_CHEAP_COPY;
template<class T,int d> struct HAS_CHEAP_COPY<VECTOR<T,d> > {static const bool value=true;};

template<class T> struct IS_VECTOR{static const bool value=false;};
template<class T,int d> struct IS_VECTOR<ZERO_VECTOR<T,d> > {static const bool value=true;};
template<class T,int d> struct IS_VECTOR<VECTOR<T,d> > {static const bool value=true;};
template<class T> struct IS_VECTOR<ARRAY<T,int> > {static const bool value=true;};

static constexpr int vec_gen=0;
static constexpr int vec_zero=1;

template<class T,int type,int m> struct VEC_TYPE_;
template<class T,int m> struct VEC_TYPE_<T,vec_zero,m>{typedef std::conditional_t<(m>=0),ZERO_VECTOR<T,m>,ARRAY<T,int>> TYPE;};
template<class T,int m> struct VEC_TYPE_<T,vec_gen,m>{typedef std::conditional_t<(m>=0),VECTOR<T,m>,ARRAY<T,int>> TYPE;};
template<class T,int type,int m> using VEC_TYPE=typename VEC_TYPE_<T,type,m>::TYPE;

}
#endif
