Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong single_service when it should be service #126

Open
01Pollux opened this issue May 8, 2024 · 2 comments
Open

Wrong single_service when it should be service #126

01Pollux opened this issue May 8, 2024 · 2 comments

Comments

@01Pollux
Copy link

01Pollux commented May 8, 2024

Describe the bug
Attempting to use container.service<> on a service that implements autowire_service, will result in copy of the object rather than move since its using single_service instead of service.

template<typename T, typename Map = map<>, std::size_t max_dependencies = detail::default_max_dependency>
using autowire_service = single_service<T, kgr::mapped_autowire<Map, max_dependencies>>;
template<typename T, typename Map = map<>, std::size_t max_dependencies = detail::default_max_dependency>
using autowire_single_service = single_service<T, kgr::mapped_autowire<Map, max_dependencies>>;

To Reproduce
1- Create main.cpp with the following content:

struct Noisy
{
    std::string Name;

    Noisy(const char* Name) :
        Name(Name)
    {
        printf("Noisy::Noisy(%s);\n", Name);
    }

    Noisy(const Noisy& o) :
        Name(o.Name)
    {
        printf("Noisy::Noisy(const Noisy&=%s);\n", Name.c_str());
    }

    Noisy(Noisy&& o) :
        Name(std::move(o.Name))
    {
        printf("Noisy::Noisy(Noisy&&=%s);\n", Name.c_str());
    }

    Noisy& operator=(const Noisy& o)
    {
        Name = o.Name;
        printf("Noisy& Noisy::operator=(const Noisy&=%s);\n", Name.c_str());
        return *this;
    }

    Noisy& operator=(Noisy&& o)
    {
        Name = o.Name;
        printf("Noisy& Noisy::operator=(Noisy&&=%s);\n", Name.c_str());
        return *this;
    }

    ~Noisy()
    {
        printf("Noisy::~Noisy(%s);\n", Name.c_str());
    }
};

struct System1 : Noisy
{
public:
    System1() :
        Noisy("System1")
    {
    }
};

struct System2 : Noisy
{
    System2() :
        Noisy("System2")
    {
    }
};

template<typename T, typename Map = kgr::map<>, std::size_t max_dependencies = kgr::detail::default_max_dependency>
using correct_autowire_service = kgr::service<T, kgr::mapped_autowire<Map, max_dependencies>>;

struct Subsystem1 : correct_autowire_service<System1>
{
};

struct Subsystem2 : kgr::autowire_service<System2>
{
};

auto service_map(System1 const&) -> Subsystem1;
auto service_map(System2 const&) -> Subsystem2;

int main()
{
    kgr::container container;

    auto a = container.service<Subsystem1>();
    auto b = container.service<Subsystem2>();

    // auto& a0 = container.service<Subsystem1>(); // triggers compilation error (correct)
    // auto& b1 = container.service<Subsystem2>(); // should not compile

    return 0;
}

Expected behavior
The program should not make copies of the service but instead move it around
the output for the previous sample:

Noisy::Noisy(System1);
Noisy::Noisy(Noisy&&=System1);
Noisy::~Noisy();
Noisy::Noisy(Noisy&&=System1);
Noisy::~Noisy();
Noisy::Noisy(System2);
Noisy::Noisy(const Noisy&=System2);
Noisy::~Noisy(System2);
Noisy::~Noisy(System1);
Noisy::~Noisy(System2);

Desktop (please complete the following information):

  • OS: Windows
  • Compiler: MSVC
  • Version: 19.39.33523

Additional context
Another note i've noticed is that it moves the object two times instead of once.

@gracicot gracicot added the bug label May 9, 2024
@gracicot gracicot added this to the 4.3.3 milestone May 9, 2024
@gracicot
Copy link
Owner

gracicot commented May 9, 2024

I confirm the issue. The workaround is to use kgr::service<System2, kgr::autowire> or your alias. This is caused by the alias autowire_service pointing to the wrong type.

@gracicot
Copy link
Owner

gracicot commented May 9, 2024

For the moving two time, this is a consequence of how kangaru 4 is designed. kangaru 5 won't have this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants