Program Listing for File NodeScopeManager.hpp

Return to documentation for file (src/rdf4cpp/bnode_mngt/NodeScopeManager.hpp)

#ifndef RDF4CPP_NODESCOPEMANAGER_HPP
#define RDF4CPP_NODESCOPEMANAGER_HPP

#include <string_view>
#include <rdf4cpp/bnode_mngt/NodeScope.hpp>

namespace rdf4cpp::bnode_mngt {

template<typename M>
concept NodeScopeManager = requires (M &m, std::string_view scope_name) {
    { m.scope(scope_name) } -> NodeScope;
};

struct DynNodeScopeManagerPtr {
private:
    struct VTable {
        DynNodeScopePtr (*scope)(void *self, std::string_view);

        template<NodeScopeManager M>
        static VTable const *make() {
            static constexpr VTable vtable{
                .scope = [](void *self, std::string_view label) -> DynNodeScopePtr {
                    return static_cast<M *>(self)->scope(label);
                }};

            return &vtable;
        }
    };

    void *instance_;
    VTable const *vtable_;

public:
    DynNodeScopeManagerPtr() noexcept : DynNodeScopeManagerPtr{nullptr} {
    }

    DynNodeScopeManagerPtr(std::nullptr_t) noexcept : instance_{nullptr}, vtable_{nullptr} {
    }

    template<NodeScopeManager M>
    DynNodeScopeManagerPtr(M &manager) noexcept : instance_{&manager}, vtable_{VTable::make<M>()} {
    }

    template<NodeScopeManager M>
    DynNodeScopeManagerPtr(M *manager) noexcept : instance_{manager}, vtable_{VTable::make<M>()} {
    }

    [[nodiscard]] DynNodeScopePtr scope(std::string_view label) {
        return vtable_->scope(instance_, label);
    }

    friend bool operator==(DynNodeScopeManagerPtr const &self, std::nullptr_t) noexcept {
        return self.instance_ == nullptr;
    }
};
static_assert(NodeScopeManager<DynNodeScopeManagerPtr>);

} // namespace rdf4cpp::bnode_mngt

#endif  //RDF4CPP_NODESCOPEMANAGER_HPP