DEV Community

Mark Nefedov
Mark Nefedov

Posted on • Edited on

1 1

Template based configuration.

Templates can be used, to avoid virtual function calls.

#include <iostream>

struct Impl1{
    void Run(){
        std::cout << "Impl1" << std::endl;
    }
};

struct Impl2{
    void Run(){
        std::cout << "Impl2" << std::endl;
    }
};


template<typename T>
struct Runner{
    T RunImplementation;
    void MainLoop(){        
        RunImplementation.Run();
    }
};

int main()
{
  Runner<Impl1> loop1;
  Runner<Impl2> loop2;
  loop1.MainLoop();
  loop2.MainLoop();
}
Enter fullscreen mode Exit fullscreen mode

Types can be selected at compile-time, this can be useful if you want to implement some kind of adaptive templates. For example you can store big objects on the heap and small in the stack.

template<typename T>
using sharedPtrTypeSelector = 
    typename std::conditional<sizeof(T) <= sizeof(std::shared_ptr<T>), T, std::shared_ptr<T>>::type;

    template<typename T>
    class swStorage{
        sharedPtrTypeSelector<T> data;
    public:
        bool operator==(const swStorage &rhs) const {
            if constexpr (std::is_pointer_v<sharedPtrTypeSelector<T>>)
                return *data == *rhs.data;
            else
                return data == rhs.data;
        }
        bool operator!=(const swStorage &rhs) const {
            return !(rhs == *this);
        }

        operator T() const {
            if constexpr (std::is_pointer_v<sharedPtrTypeSelector<T>>)
                return *data;
            else
                return data;
        }

        swStorage(){
            if constexpr (std::is_pointer_v<sharedPtrTypeSelector<T>>)
                data = std::make_shared<T>(0);
        }

        explicit swStorage(const T& newData){
            if constexpr (std::is_pointer_v<sharedPtrTypeSelector<T>>)
                data = std::make_shared<T>(newData);
            else
                data = newData;
        }
    };
Enter fullscreen mode Exit fullscreen mode

For example, I've used it to optimize storage in an Octree.

GitHub logo marknefedov / cubic-octree

Cubic octree, with on-demand node allocation.

Cubic-octree CodeFactor Codacy Badge

Cubic octree with array-like access. Originally made to store voxel data for minecraft-like terrain.

Example

Octree<int, 5> octree; // This will create octree of size 32x32x32 with only root node allocated
octree.set(1, 2, 3, 4) // This will allocate nodes down to depth of 5 and set node at position [1,2,3] to value 4.
int val = octree.get(1, 2, 3) // Get value at node [1,2,3]
octree.SimplifyTree() // Collapse nodes with same values.
Enter fullscreen mode Exit fullscreen mode

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay