diff options
-rw-r--r-- | examples/basic/src/bootstrap.cpp | 4 | ||||
-rw-r--r-- | examples/basic/src/interfaces/enemy.hpp | 8 | ||||
-rw-r--r-- | include/yacppdic/container.hpp | 12 | ||||
-rw-r--r-- | include/yacppdic/detail/auto_wirable-impl.hpp | 2 | ||||
-rw-r--r-- | include/yacppdic/detail/container-impl.hpp | 17 | ||||
-rw-r--r-- | include/yacppdic/detail/internal/object_identifier.hpp | 8 | ||||
-rw-r--r-- | include/yacppdic/tagging.hpp | 38 |
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 { }; |