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.
C++11 example for my post - An introduction to C++'s variadic templates: a thread-safe multi-type map - using shared_ptr
#include <iostream>
#include <string>
struct DefaultSlotKey;
template <class Type, class Key = DefaultSlotKey>
class Slot
{
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment