//#####################################################################
// Copyright 2009, Michael Lentine.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
#include <Core/Particles/ARRAY_COLLECTION_ELEMENT.h>
#include <Core/Arrays/ARRAY_VIEW.h>
#include <Core/Matrices/DIAGONAL_MATRIX.h>
#include <Core/Matrices/FRAME.h>
#include <Core/Matrices/MATRIX.h>
#include <Core/Matrices/SYMMETRIC_MATRIX.h>
#include <Core/Particles/ARRAY_COLLECTION_ELEMENT_BASE.h>
#include <Core/Read_Write/READ_WRITE.h>
#include <Core/Symbolics/SYMBOLIC.h>
#include <Core/Tensors/SYMMETRIC_TENSOR.h>
#include <Core/Vectors/TWIST.h>
namespace PhysBAM{
//#####################################################################
// Constructor
//#####################################################################
template<class T> ARRAY_COLLECTION_ELEMENT<T>::
ARRAY_COLLECTION_ELEMENT(ARRAY_VIEW<T>* array_input)
    :array(array_input),buffer_size(0)
{
    owns_data=false;
}
//#####################################################################
// Constructor
//#####################################################################
template<class T> ARRAY_COLLECTION_ELEMENT<T>::
ARRAY_COLLECTION_ELEMENT()
    :array(new ARRAY_VIEW<T>(0,0))
{
}
//#####################################################################
// Destructor
//#####################################################################
template<class T> ARRAY_COLLECTION_ELEMENT<T>::
~ARRAY_COLLECTION_ELEMENT()
{
    ARRAY_VIEW<T> temp(0,0);
    temp.Exchange(*array);
    delete[] temp.Get_Array_Pointer();
    if(owns_data) delete array;
}
//#####################################################################
// Function Clean_Memory
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Clean_Memory()
{
    Reallocate(0);
}
//#####################################################################
// Function Clear
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Clear(const int p)
{
    (*array)(p)=T();
}
//#####################################################################
// Function Clear_Range
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Clear_Range(const int start,const int end)
{
    for(int i=start;i<end;i++) (*array)(i)=T();
}
//#####################################################################
// Function Set_Size
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Set_Size(const int new_size)
{
    assert(buffer_size>=new_size);
    int n=array->m;
    array->m=new_size;
    Clear_Range(n,array->m);
}
//#####################################################################
// Function Reallocate
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Reallocate(const int new_size)
{
    if(new_size<array->m) array->m=new_size;
    buffer_size=new_size;
    assert(array->m<=buffer_size);
    ARRAY_VIEW<T> temp(new T[Value(new_size)],array->m);
    temp=*array;
    temp.Exchange(*array);
    delete[] temp.Get_Array_Pointer();
}
//#####################################################################
// Function Copy_Element
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Copy_Element(const int from,const int to)
{
    (*array)(to)=(*array)(from);
}
//#####################################################################
// Function Copy_Element
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Copy_Element(const ARRAY_COLLECTION_ELEMENT_BASE& from_attribute,const int from,const int to)
{
    (*array)(to)=(*dynamic_cast<const ARRAY_COLLECTION_ELEMENT<T>&>(from_attribute).array)(from);
}
//#####################################################################
// Function Copy_With_Offset
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Copy_With_Offset(const ARRAY_COLLECTION_ELEMENT_BASE& from_attribute,const int offset)
{
    auto&a=*dynamic_cast<const ARRAY_COLLECTION_ELEMENT<T>&>(from_attribute).array;
    std::copy(a.begin(),a.end(),array->begin()+offset);
}
//#####################################################################
// Function Type_Name
//#####################################################################
template<class T> const char* ARRAY_COLLECTION_ELEMENT<T>::
Type_Name() const
{
    return typeid(ARRAY_COLLECTION_ELEMENT<T>).name();
}
//#####################################################################
// Function Read
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Read(TYPED_ISTREAM& input)
{
    Read_Binary(input,*array);
}
//#####################################################################
// Function Write
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Write(TYPED_OSTREAM& output) const
{
    Write_Binary(output,*array);
}
//#####################################################################
// Function Print
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Print(std::ostream& output,const int p) const
{
    output<<name<<" = "<<(*array)(p)<<std::endl;
}
//#####################################################################
// Function Text_Write
//#####################################################################
template<class T> void ARRAY_COLLECTION_ELEMENT<T>::
Text_Write(std::ostream& output,const int p) const
{
    output<<"("<<name<<": "<<(*array)(p)<<")";
}
//#####################################################################
// Function Clone_Default
//#####################################################################
template<class T> ARRAY_COLLECTION_ELEMENT_BASE* ARRAY_COLLECTION_ELEMENT<T>::
Clone_Default() const
{
    return new ARRAY_COLLECTION_ELEMENT<T>;
}
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<double,0> >;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<double,1> >;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<double,2> >;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<double,3> >;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<float,0> >;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<float,1> >;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<float,2> >;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<float,3> >;
template class ARRAY_COLLECTION_ELEMENT<FRAME<VECTOR<double,1> > >;
template class ARRAY_COLLECTION_ELEMENT<FRAME<VECTOR<double,2> > >;
template class ARRAY_COLLECTION_ELEMENT<FRAME<VECTOR<double,3> > >;
template class ARRAY_COLLECTION_ELEMENT<FRAME<VECTOR<float,1> > >;
template class ARRAY_COLLECTION_ELEMENT<FRAME<VECTOR<float,2> > >;
template class ARRAY_COLLECTION_ELEMENT<FRAME<VECTOR<float,3> > >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<double,0,0> >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<double,1,1> >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<double,2,2> >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<double,3,3> >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<float,0,0> >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<float,1,1> >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<float,2,2> >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<float,3,3> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<double,0> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<double,1> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<double,2> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<double,3> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<float,0> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<float,1> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<float,2> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<float,3> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<double,0,0,0> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<double,0,1,1> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<double,0,2,2> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<double,0,3,3> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<float,0,0,0> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<float,0,1,1> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<float,0,2,2> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<float,0,3,3> >;
template class ARRAY_COLLECTION_ELEMENT<TWIST<VECTOR<double,1> > >;
template class ARRAY_COLLECTION_ELEMENT<TWIST<VECTOR<double,2> > >;
template class ARRAY_COLLECTION_ELEMENT<TWIST<VECTOR<double,3> > >;
template class ARRAY_COLLECTION_ELEMENT<TWIST<VECTOR<float,1> > >;
template class ARRAY_COLLECTION_ELEMENT<TWIST<VECTOR<float,2> > >;
template class ARRAY_COLLECTION_ELEMENT<TWIST<VECTOR<float,3> > >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<double,0> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<double,1> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<double,2> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<double,3> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<float,0> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<float,1> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<float,2> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<float,3> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<int,0> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<int,1> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<int,2> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<int,3> >;
template class ARRAY_COLLECTION_ELEMENT<bool>;
template class ARRAY_COLLECTION_ELEMENT<double>;
template class ARRAY_COLLECTION_ELEMENT<float>;
template class ARRAY_COLLECTION_ELEMENT<int>;
template class ARRAY_COLLECTION_ELEMENT<unsigned short>;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<SYMBOLIC,0> >;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<SYMBOLIC,1> >;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<SYMBOLIC,2> >;
template class ARRAY_COLLECTION_ELEMENT<DIAGONAL_MATRIX<SYMBOLIC,3> >;
template class ARRAY_COLLECTION_ELEMENT<FRAME<VECTOR<SYMBOLIC,1> > >;
template class ARRAY_COLLECTION_ELEMENT<FRAME<VECTOR<SYMBOLIC,2> > >;
template class ARRAY_COLLECTION_ELEMENT<FRAME<VECTOR<SYMBOLIC,3> > >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<SYMBOLIC,0,0> >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<SYMBOLIC,1,1> >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<SYMBOLIC,2,2> >;
template class ARRAY_COLLECTION_ELEMENT<MATRIX<SYMBOLIC,3,3> >;
template class ARRAY_COLLECTION_ELEMENT<SYMBOLIC>;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<SYMBOLIC,0> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<SYMBOLIC,1> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<SYMBOLIC,2> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_MATRIX<SYMBOLIC,3> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<SYMBOLIC,0,0,0> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<SYMBOLIC,0,1,1> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<SYMBOLIC,0,2,2> >;
template class ARRAY_COLLECTION_ELEMENT<SYMMETRIC_TENSOR<SYMBOLIC,0,3,3> >;
template class ARRAY_COLLECTION_ELEMENT<TWIST<VECTOR<SYMBOLIC,1> > >;
template class ARRAY_COLLECTION_ELEMENT<TWIST<VECTOR<SYMBOLIC,2> > >;
template class ARRAY_COLLECTION_ELEMENT<TWIST<VECTOR<SYMBOLIC,3> > >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<SYMBOLIC,0> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<SYMBOLIC,1> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<SYMBOLIC,2> >;
template class ARRAY_COLLECTION_ELEMENT<VECTOR<SYMBOLIC,3> >;
}
