When I try to call a templated function the compiler does not recognise the angle brackets for what they are.
I have one class called ArrayOfStacks which works perfectly fine when tested. I have another called GenericChunkAllocator which has a static member of type ArrayOfStacks. When I call the ArrayOfStacks member in GenericChunkAllocator the templating doesn't work correctly as described above.
For the purposes of testing I created the simplest function I could void foo() just to show the errors, the same errors occur in "real" use.
Any help would be greatly appreciated.
Relevant code and compiler errors are below.
chunkAllocator.hpp:
#pragma once
#include <array>
#include <vector>
#include <utility>
#include <memory>
#include "log2.hpp"
#include "accessParameterPack.hpp"
#include "cumulativeSumParameterPack.hpp"
#include "standardAllocatorInterface.hpp"
namespace awmms
{
namespace memoryManagement
{
template<size_t... stackSizes>
class ArrayOfStacks
{
public:
template<size_t stackNum>
constexpr void push(void* element);
template<size_t stackNum>
constexpr void* pop();
template<size_t stackNum>
constexpr void* top();
template<size_t stackNum>
constexpr double currentCapacity();
private:
constexpr static std::array<size_t, sizeof...(stackSizes)> sm_stackSizes = {stackSizes...};
constexpr static std::array<size_t, sizeof...(stackSizes)> sm_stackBottoms = cumulativeSumParameterPack<size_t, stackSizes...>((-1 * accessParameterPack<size_t, 0, stackSizes...>()));
std::array<size_t, sizeof...(stackSizes)> m_stackIndexes = {};
void* m_container[(... + stackSizes)];
};
struct RawMemoryAllocationRecord
{
void* ptr;
size_t size;
};
template<int allocatorID, double defaultFillPercentage, size_t... stackSizes>
class GenericChunkAllocator
{
public:
template<size_t n>
constexpr void* allocate();
template<size_t n>
constexpr void deallocate(void* p);
template<size_t size>
constexpr void fill(double percentage = defaultFillPercentage);
constexpr void fillAll(double percentage = defaultFillPercentage);
void foo();
private:
constexpr void emergencyFill();
static awmms::memoryManagement::ArrayOfStacks<stackSizes...> sm_arrayOfStacks;
static std::vector<RawMemoryAllocationRecord> sm_rawAllocations;
};
}
chunkAllocator.inl:
#pragma once
namespace awmms
{
namespace memoryManagement
{
template<size_t... stackSizes>
template<size_t stackNum>
constexpr void ArrayOfStacks<stackSizes...>::push(void* element)
{
typedef ArrayOfStacks<stackSizes...> thisT;
if(m_stackIndexes[stackNum] < thisT::sm_stackSizes[stackNum])
{
this->m_container[thisT::sm_stackBottoms[stackNum] + this->m_stackIndexes[stackNum]] = element;
this->m_stackIndexes[stackNum]++;
}
}
template<size_t... stackSizes>
template<size_t stackNum>
constexpr void* ArrayOfStacks<stackSizes...>::pop()
{
typedef ArrayOfStacks<stackSizes...> thisT;
if(AWMMS_EXPECT(this->m_stackIndexes[stackNum] == 0, false))
{
return nullptr;
}
else
{
auto returnValue = this->m_container[thisT::sm_stackBottoms[stackNum] + this->m_stackIndexes[stackNum] - 1];
this->m_stackIndexes[stackNum]--;
return returnValue;
}
}
template<size_t... stackSizes>
template<size_t stackNum>
constexpr void* ArrayOfStacks<stackSizes...>::top()
{
typedef ArrayOfStacks<stackSizes...> thisT;
return this->m_container[thisT::sm_stackBottoms[stackNum] + this->m_stackIndexes[stackNum] - 1];
}
template<size_t... stackSizes>
template<size_t stackNum>
constexpr double ArrayOfStacks<stackSizes...>::currentCapacity()
{
typedef ArrayOfStacks<stackSizes...> thisT;
size_t spaceLeft = thisT::sm_stackSizes[stackNum] - this->m_stackIndexes[stackNum];
size_t spaceTotal = thisT::sm_stackSizes[stackNum];
return static_cast<double>(spaceLeft) / static_cast<double>(spaceTotal);
}
template<int allocatorID, double defaultFillPercentage, size_t... stackSizes>
//awmms::memoryManagement::ArrayOfStacks<stackSizes...> sm_arrayOfStacks = awmms::memoryManagement::ArrayOfStacks<stackSizes...>();
awmms::memoryManagement::ArrayOfStacks<stackSizes...> sm_arrayOfStacks = {};
template<int allocatorID, double defaultFillPercentage, size_t... stackSizes>
std::vector<RawMemoryAllocationRecord> sm_rawAllocations = {};
template<int allocatorID, double defaultFillPercentage, size_t... stackSizes>
template<size_t n>
constexpr void* GenericChunkAllocator<allocatorID, defaultFillPercentage, stackSizes...>::allocate()
{
//typedef GenericChunkAllocator<allocatorID, defaultFillPercentage, stackSizes...> thisT;
//constexpr size_t ptrSize = n<4 ? static_cast<size_t>(awmms::log2(n)) - 1 : 0;
//void* ptr = thisT::sm_arrayOfStacks.pop<ptrSize>();
return nullptr;
}
template<int allocatorID, double defaultFillPercentage, size_t... stackSizes>
template<size_t n>
constexpr void GenericChunkAllocator<allocatorID, defaultFillPercentage, stackSizes...>::deallocate(void* p)
{
return;
}
template<int allocatorID, double defaultFillPercentage, size_t... stackSizes>
template<size_t size>
constexpr void GenericChunkAllocator<allocatorID, defaultFillPercentage, stackSizes...>::fill(double percentage)
{
return;
}
template<int allocatorID, double defaultFillPercentage, size_t... stackSizes>
constexpr void GenericChunkAllocator<allocatorID, defaultFillPercentage, stackSizes...>::fillAll(double percentage)
{
return;
}
template<int allocatorID, double defaultFillPercentage, size_t... stackSizes>
constexpr void GenericChunkAllocator<allocatorID, defaultFillPercentage, stackSizes...>::emergencyFill()
{
return;
}
template<int allocatorID, double defaultFillPercentage, size_t... stackSizes>
void GenericChunkAllocator<allocatorID, defaultFillPercentage, stackSizes...>::foo()
{
typedef GenericChunkAllocator<allocatorID, defaultFillPercentage, stackSizes...> thisT;
thisT::sm_arrayOfStacks.push<0>(nullptr);
thisT::sm_arrayOfStacks.pop<0>();
}
}
}
I have created an instance of the class and called foo() from main. The errors are as follows:
/home/ebony/git/Ebony-Ayers/awmms/tests/src/../../src/chunkAllocator.inl: In member function ‘void awmms::memoryManagement::GenericChunkAllocator<allocatorID, defaultFillPercentage, stackSizes>::foo()’:
/home/ebony/git/Ebony-Ayers/awmms/tests/src/../../src/chunkAllocator.inl:104:56: error: expected primary-expression before ‘)’ token
104 | thisT::sm_arrayOfStacks.pop<0>();
| ^
/home/ebony/git/Ebony-Ayers/awmms/tests/src/../../src/chunkAllocator.inl: In instantiation of ‘void awmms::memoryManagement::GenericChunkAllocator<allocatorID, defaultFillPercentage, stackSizes>::foo() [with int allocatorID = 0; double defaultFillPercentage = 5.0e-1; long unsigned int ...stackSizes = {10, 10, 10, 10, 10, 10}]’:
/home/ebony/git/Ebony-Ayers/awmms/tests/src/main.cpp:15:7: required from here
/home/ebony/git/Ebony-Ayers/awmms/tests/src/../../src/chunkAllocator.inl:103:53: error: invalid operands of types ‘<unresolved overloaded function type>’ and ‘int’ to binary ‘operator<’
103 | thisT::sm_arrayOfStacks.push<0>(nullptr);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/home/ebony/git/Ebony-Ayers/awmms/tests/src/../../src/chunkAllocator.inl:104:52: error: invalid operands of types ‘<unresolved overloaded function type>’ and ‘int’ to binary ‘operator<’
104 | thisT::sm_arrayOfStacks.pop<0>();
|