Determined to hack templates

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
engi
Posts: 161
Joined: April 7th, 2014, 6:00 am
Location: Brazil

Determined to hack templates

Post by engi » June 19th, 2014, 10:11 pm

Trying to implement a template class in a .cpp file instead of the .h file, of course one does not simply define a template method in another translation unit, unless you happen to be using Intel's compiler, but I digress..

To do that I'm using a hack where you call some static methods inside another class, and I simply call them from the templated class, of course these methods are defined in the .cpp file, the problem is they can be called from other translation units as well, I would like to avoid that if possible.. any ideas?

Here's what I've tried so far:

- Make the methods private and friend the templated class
Doesn't work, I would have to template this other class as well if I did that, which would take me back to where I started

- Empty namespace
LNK2001


So right now I have them in another class, which is defined in the .cpp file, but as I've mentioned they can still be accessed from other files..

Code: Select all

#pragma once

#include "IResource.h"
#include <vector>
#include <type_traits>


class _detail
{
public:
    static hResource CreateUniformBuffer(hResource bindingPoint, std::size_t size);
    static void DeleteUniformBuffer(hResource bufferID);
    static void RegisterShader(hResource shaderID, hResource bindingPoint, const char* block_name);
    static void RegisterShader(std::vector<hResource> shaders, hResource bindingPoint, const char* block_name);
    static void BindUniformBuffer(hResource bufferID);
    static void FillUniformBuffer(hResource bufferID, std::size_t size, void* data);
};

template <typename _struct>
class UniformBlock sealed : public IResource
{

    static hResource s_bindingPoint;

private:

    hResource UBO_ID;
    hResource bindingPoint;
    char* _block_name;
    std::size_t buffer_size;

public:

    explicit UniformBlock(const char* block_name)
    {
        static_assert(!std::is_pointer<_struct>::value, "UniformBlock - Pointer data types are not allowed");

        bindingPoint = s_bindingPoint;
        ++s_bindingPoint;

        buffer_size = sizeof(_struct);

        std::size_t str_length = strlen(block_name);
        _block_name = new char[str_length + 1];
        memcpy(_block_name, block_name, str_length);
        _block_name[str_length] = '\0';

        UBO_ID = _detail::CreateUniformBuffer(bindingPoint, buffer_size);
        OutputInfo("Created uniform buffer ID: " << UBO_ID, 5);
    }

    ~UniformBlock()
    {
        _detail::DeleteUniformBuffer(UBO_ID);
        DeleteArrayHeap(_block_name);

        OutputInfo("Deleted uniform buffer ID: " << UBO_ID, 5);
    }

    __forceinline void MapShaderBlock(hResource shader)
    {
        _detail::RegisterShader(shader, bindingPoint, _block_name);
    }

    __forceinline void MapShaderBlock(std::vector<hResource> shaders)
    {
        _detail::RegisterShader(shaders, bindingPoint, _block_name);
    }

    __forceinline void Update(_struct& data)
    {
        _detail::FillUniformBuffer(UBO_ID, buffer_size, static_cast<void *> (&data));
    }

    __forceinline void Bind() override
    {
        _detail::BindUniformBuffer(UBO_ID);
    }

    __forceinline hResource ID() const override
    {
        return UBO_ID;
    }
};

template <typename _struct>
hResource UniformBlock<_struct>::s_bindingPoint = 0;

0x5f3759df

Post Reply