#ifndef __AMSCPPNARRAY_IMPLINITS_HPP__
#define __AMSCPPNARRAY_IMPLINITS_HPP__

namespace ams
{
namespace narray
{

    template<typename T> void narray_arange_tf(
        narray<T> *in,
        const T low, const T high, const T incr,
        int threadnum, int nthreads
    )
    {
        int I0,I1,Is,I;
        Is = in->length/nthreads;
        I0 = Is*threadnum;
        I1 = (threadnum>=(nthreads-1))? in->length: Is*(threadnum+1);
        for(I=I0;I<I1;I++)
        {
            in->data[I] = low + incr*I;
        }
    }

template<typename T> narray<T> arange(const T low, const T high, const T incr)
{
    narray<T> ret;
    narray_size_t I;
    int J;
    int nthreads;
    std::vector<std::thread*> threads;

    narray_size_t N = (narray_size_t)((high-low)/incr);
    if(N<=0)
    {
        N = 0;
    }
    ret.resize(N);

    if(ret.length==0)
    {
        return ret;
    }

    if(ret.length<narray_thread_sz)
    {
        for(I=0;I<ret.length;I++)
        {
            ret.data[I] = low + incr*I;
        }
    }
    else
    {
        //threaded operation
        nthreads = std::thread::hardware_concurrency();
        nthreads = (nthreads<1) ? 1 : nthreads;
        nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads;
        //if(nthreads<1) nthreads=1;
        //if(nthreads>narray_max_threads) nthreads = narray_max_threads;
        threads.resize(nthreads);
        for(J=0;J<nthreads;J++)
        {
            threads[J] = new(std::nothrow) std::thread(
                &narray_arange_tf<T>,
                &ret,
                low,high,incr,
                J,nthreads
            );
        }
        for(J=0;J<nthreads;J++)
        {
            if(threads[J]!=NULL)
            { 
                threads[J]->join(); 
                delete threads[J]; 
                threads[J]= NULL;
            }
        }
    }



    return ret;
}

template<typename T> narray<T> zeros(const narray_size_t N)
{
    narray<T> ret;
    ret.resize(N);
    ret.setall(0);

    return ret;
}

template<typename T> narray<T> ones(const narray_size_t N)
{
    narray<T> ret;
    ret.resize(N);
    ret.setall(1);

    return ret;
}


};
};

#endif