#ifndef __AMSCU_CPUTHREADING_IMPL_HPP__
#define __AMSCU_CPUTHREADING_IMPL_HPP__

namespace amscuda
{
namespace util
{
    
template<typename callable, typename ... argst> int threaded_execute(callable &&fptr, int64_t psize, argst&&... args)
{
    int ret = amscu_success;

    int I;
    std::vector<std::thread*> threads;
    int nthreads = amscpu_cputhreading_threadplan(psize);

    if(nthreads<=1)
    {
        nthreads = 1;
        I = 0;
        // std::invoke(
        //     std::forward<callable>(fptr),
        //     I,
        //     nthreads,
        //     std::forward<argst>(args)...
        // );

        //std::invoke is a C++17 feature, and mingw8 complains even so.
        // Can I get away with just calling the functions?
        fptr(I,nthreads,std::forward<argst>(args)...);
    }
    else
    {
        threads.resize(nthreads);
        for(I=0;I<nthreads;I++) threads[I] = NULL;
        for(I=0;I<nthreads;I++)
        {
            threads[I] = new(std::nothrow) std::thread
            (
                std::forward<callable>(fptr),
                I,
                nthreads,
                std::forward<argst>(args)...
            );
        }
        for(I=0;I<nthreads;I++)
        {
            if(threads[I]==NULL)
            { //null thread creation failure check
                //printf("debug check!\n");
                ret = amscu_failure;
            }
        }
        for(I=0;I<nthreads;I++)
        {
            if(threads[I]!=NULL)
            {
                threads[I]->join();
                delete threads[I];
                threads[I] = NULL;
            }
        }
    }

    return ret;
}



};
};

#endif 