Skip to content

Instantly share code, notes, and snippets.

@Jiwan
Last active December 13, 2020 15:11
Show Gist options
  • Save Jiwan/cb66d01c38128a351f42 to your computer and use it in GitHub Desktop.
Save Jiwan/cb66d01c38128a351f42 to your computer and use it in GitHub Desktop.

Revisions

  1. Jiwan revised this gist Feb 4, 2016. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions repository_shared_ptr.cpp
    Original file line number Diff line number Diff line change
    @@ -6,8 +6,6 @@ struct DefaultSlotKey;
    template <class Type, class Key = DefaultSlotKey>
    class Slot
    {

    // TODO: replace this horrible mutex with an atomic shared_ptr when using gcc 5.x.
    public:
    std::shared_ptr<Type> doGet() const
    {
  2. Jiwan created this gist Feb 4, 2016.
    80 changes: 80 additions & 0 deletions repository_shared_ptr.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,80 @@
    #include <iostream>
    #include <string>

    struct DefaultSlotKey;

    template <class Type, class Key = DefaultSlotKey>
    class Slot
    {

    // TODO: replace this horrible mutex with an atomic shared_ptr when using gcc 5.x.
    public:
    std::shared_ptr<Type> doGet() const
    {
    return value_;
    }

    void doSet(const std::shared_ptr<Type> &value)
    {
    value_ = value;
    }

    private:
    std::shared_ptr<Type> value_;
    };

    template<class... Slots>
    class Repository : private Slots... {
    public:
    template <class Type, class Key = DefaultSlotKey>
    std::shared_ptr<Type> get()
    {
    static_assert(std::is_base_of<Slot<Type, Key>, Repository<Slots...>>::value,
    "Please ensure that this type or this key exists in this repository");
    return Slot<Type, Key>::doGet();
    }

    template <class Type, class Key = DefaultSlotKey>
    void set(const std::shared_ptr<Type>& value)
    {
    static_assert(std::is_base_of<Slot<Type, Key>, Repository<Slots...>>::value,
    "Please ensure that this type or this key exists in this repository");
    Slot<Type, Key>::doSet(value);
    }

    template <class Type, class Key = DefaultSlotKey, class ...Args>
    void emplace(Args&&... args)
    {
    static_assert(std::is_base_of<Slot<Type, Key>, Repository<Slots...>>::value,
    "Please ensure that this type or this key exists in this repository");
    Slot<Type, Key>::doSet(std::make_shared<Type>(std::forward<Args>(args)...));
    }

    template <class Type, class Key = DefaultSlotKey>
    auto getWatcher() -> decltype(std::declval<Slot<Type, Key>>().doGetWatcher())
    {
    return Slot<Type, Key>::doGetWatcher();
    }
    };

    // Incomplete types used as compile-time keys.
    struct Key1;
    struct Key2;

    // Create a type for our repository.
    using MyRepository = Repository
    <
    Slot<int>, // Let's pick the type of our slots.
    Slot<std::string>
    >;

    int main()
    {
    MyRepository myRepository;
    myRepository.emplace<std::string>("toto");

    std::cout << *myRepository.get<std::string>();


    return EXIT_SUCCESS;
    }