aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/basic/src/bootstrap.cpp4
-rw-r--r--examples/basic/src/interfaces/enemy.hpp8
-rw-r--r--include/yacppdic/container.hpp12
-rw-r--r--include/yacppdic/detail/auto_wirable-impl.hpp2
-rw-r--r--include/yacppdic/detail/container-impl.hpp17
-rw-r--r--include/yacppdic/detail/internal/object_identifier.hpp8
-rw-r--r--include/yacppdic/tagging.hpp38
7 files changed, 62 insertions, 27 deletions
diff --git a/examples/basic/src/bootstrap.cpp b/examples/basic/src/bootstrap.cpp
index ac81bd9..78c5a37 100644
--- a/examples/basic/src/bootstrap.cpp
+++ b/examples/basic/src/bootstrap.cpp
@@ -27,7 +27,7 @@ auto bootstrap() -> yacppdic::Container
return std::make_unique<Enemy>(65);
}
)
- .when_tagged(SMALL_ENEMY_TAG);
+ .when_tagged<SMALL_ENEMY_TAG>();
container.bind<IEnemyFactory>()
.to_factory(
@@ -36,7 +36,7 @@ auto bootstrap() -> yacppdic::Container
return std::make_unique<Enemy>(130);
}
)
- .when_tagged(BIG_ENEMY_TAG);
+ .when_tagged<BIG_ENEMY_TAG>();
return container;
}
diff --git a/examples/basic/src/interfaces/enemy.hpp b/examples/basic/src/interfaces/enemy.hpp
index 5ad7d90..d0b6337 100644
--- a/examples/basic/src/interfaces/enemy.hpp
+++ b/examples/basic/src/interfaces/enemy.hpp
@@ -1,14 +1,12 @@
#pragma once
#include <yacppdic/factory.hpp>
+#include <yacppdic/tagging.hpp>
#include <memory>
-// NOLINTNEXTLINE(modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays)
-constexpr char SMALL_ENEMY_TAG[] = "small";
-
-// NOLINTNEXTLINE(modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays)
-constexpr char BIG_ENEMY_TAG[] = "big";
+constexpr yacppdic::Tag SMALL_ENEMY_TAG = "small";
+constexpr yacppdic::Tag BIG_ENEMY_TAG = "big";
// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
class IEnemy
diff --git a/include/yacppdic/container.hpp b/include/yacppdic/container.hpp
index 0003520..6191fed 100644
--- a/include/yacppdic/container.hpp
+++ b/include/yacppdic/container.hpp
@@ -5,6 +5,7 @@
#include "yacppdic/concepts.hpp"
#include "yacppdic/detail/internal/object_identifier.hpp"
#include "yacppdic/factory.hpp"
+#include "yacppdic/tagging.hpp"
#include <concepts>
#include <functional>
@@ -34,7 +35,8 @@ template <typename Interface>
class BindingWhen
{
public:
- void when_tagged(std::string_view tag) noexcept;
+ template <Tag tag>
+ void when_tagged() noexcept;
private:
internal::Bindings &_bindings;
@@ -85,13 +87,13 @@ public:
requires IsFactory<AFactory>
auto get() const noexcept -> AFactory;
- template <class Interface>
+ template <class Interface, Tag tag>
requires Abstract<Interface>
- auto get_tagged(const char *tag) const noexcept -> std::unique_ptr<Interface>;
+ auto get_tagged() const noexcept -> std::unique_ptr<Interface>;
- template <typename AFactory>
+ template <typename AFactory, Tag tag>
requires IsFactory<AFactory>
- auto get_tagged(const char *tag) const noexcept -> AFactory;
+ auto get_tagged() const noexcept -> AFactory;
private:
internal::Bindings _bindings;
diff --git a/include/yacppdic/detail/auto_wirable-impl.hpp b/include/yacppdic/detail/auto_wirable-impl.hpp
index e81f34c..a6b1506 100644
--- a/include/yacppdic/detail/auto_wirable-impl.hpp
+++ b/include/yacppdic/detail/auto_wirable-impl.hpp
@@ -20,7 +20,7 @@ auto AutoWirable<Interface, ObjectImpl, Dependencies...>::_get_dependency(
const Container &container
) noexcept
{
- return container.get_tagged<typename Dependency::Target>(Dependency::get_tag());
+ return container.get_tagged<typename Dependency::Target, Dependency::get_tag()>();
}
template <typename Interface, typename ObjectImpl, typename... Dependencies>
diff --git a/include/yacppdic/detail/container-impl.hpp b/include/yacppdic/detail/container-impl.hpp
index 7480dee..5d74616 100644
--- a/include/yacppdic/detail/container-impl.hpp
+++ b/include/yacppdic/detail/container-impl.hpp
@@ -20,13 +20,14 @@ BindingWhen<Interface>::BindingWhen(
}
template <typename Interface>
-void BindingWhen<Interface>::when_tagged(std::string_view tag) noexcept
+template <Tag tag>
+void BindingWhen<Interface>::when_tagged() noexcept
{
auto wrapped = _bindings.at(_object_identifier);
_bindings.erase(_object_identifier);
- auto tagged_object_identifier = internal::ObjectIdentifier::create<Interface>(tag);
+ auto tagged_object_identifier = internal::ObjectIdentifier::create<Interface, tag>();
_bindings[tagged_object_identifier] = wrapped;
}
@@ -120,11 +121,11 @@ auto Container::get() const noexcept -> AFactory
return wrapper->get();
}
-template <class Interface>
+template <class Interface, Tag tag>
requires Abstract<Interface>
-auto Container::get_tagged(const char *tag) const noexcept -> std::unique_ptr<Interface>
+auto Container::get_tagged() const noexcept -> std::unique_ptr<Interface>
{
- auto object_identifier = internal::ObjectIdentifier::create<Interface>(tag);
+ auto object_identifier = internal::ObjectIdentifier::create<Interface, tag>();
if (!_bindings.contains(object_identifier))
{
@@ -142,11 +143,11 @@ auto Container::get_tagged(const char *tag) const noexcept -> std::unique_ptr<In
return wrapper->get();
}
-template <typename AFactory>
+template <typename AFactory, Tag tag>
requires IsFactory<AFactory>
-auto Container::get_tagged(const char *tag) const noexcept -> AFactory
+auto Container::get_tagged() const noexcept -> AFactory
{
- auto object_identifier = internal::ObjectIdentifier::create<AFactory>(tag);
+ auto object_identifier = internal::ObjectIdentifier::create<AFactory, tag>();
if (!_bindings.contains(object_identifier))
{
diff --git a/include/yacppdic/detail/internal/object_identifier.hpp b/include/yacppdic/detail/internal/object_identifier.hpp
index c82b3e8..bf7aeaf 100644
--- a/include/yacppdic/detail/internal/object_identifier.hpp
+++ b/include/yacppdic/detail/internal/object_identifier.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "yacppdic/tagging.hpp"
+
#include <string_view>
#include <typeinfo>
@@ -30,10 +32,10 @@ public:
return static_cast<ObjectIdentifier>(typeid(Type));
}
- template <typename Type>
- static auto create(std::string_view tag) noexcept -> ObjectIdentifier
+ template <typename Type, Tag tag>
+ static auto create() noexcept -> ObjectIdentifier
{
- return ObjectIdentifier(typeid(Type), tag);
+ return ObjectIdentifier(typeid(Type), tag.str());
}
private:
diff --git a/include/yacppdic/tagging.hpp b/include/yacppdic/tagging.hpp
index 012a46a..498ff5d 100644
--- a/include/yacppdic/tagging.hpp
+++ b/include/yacppdic/tagging.hpp
@@ -1,11 +1,43 @@
#pragma once
+#include <algorithm>
+#include <array>
+#include <cstddef>
+#include <string_view>
#include <utility>
namespace yacppdic
{
-template <typename TargetType, char const *tag>
+template <typename Value, std::size_t length>
+// NOLINTNEXTLINE(modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays)
+using CStyleConstRefArray = const Value (&)[length];
+
+template <std::size_t length>
+class Tag
+{
+public:
+ using Storage = std::array<char, length + 1>;
+
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ constexpr Tag(CStyleConstRefArray<char, length + 1> in_data) noexcept
+ {
+ std::copy(std::begin(in_data), std::end(in_data), data.begin());
+ }
+
+ [[nodiscard]] constexpr auto str() const noexcept -> std::string_view
+ {
+ return data.data();
+ }
+
+ // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
+ Storage data{};
+};
+
+template <size_t length>
+Tag(CStyleConstRefArray<char, length>) -> Tag<length - 1>;
+
+template <typename TargetType, Tag tag>
// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
class Tagged
{
@@ -16,7 +48,7 @@ public:
Tagged(const Tagged &tagged) noexcept = delete;
Tagged(Tagged &&tagged) noexcept = delete;
- static constexpr auto get_tag() noexcept -> char const *
+ static constexpr auto get_tag() noexcept -> decltype(tag)
{
return tag;
}
@@ -30,7 +62,7 @@ struct is_tagged : public std::false_type // NOLINT(readability-identifier-namin
{
};
-template <typename TargetType, char const *tag>
+template <typename TargetType, Tag tag>
struct is_tagged<Tagged<TargetType, tag>> : public std::true_type
{
};