Program Listing for File multifactory.hpp

Return to documentation for file (rcppsw/patterns/factory/multifactory.hpp)

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <memory>

#include "rcppsw/patterns/factory/base_factory.hpp"
#include "rcppsw/patterns/singleton/singleton.hpp"

/*******************************************************************************
 * Namespaces/Decls
 ******************************************************************************/
namespace rcppsw::patterns::factory {

namespace detail {

/*******************************************************************************
 * Class Definitions
 ******************************************************************************/
template<typename TBase, typename TType, typename...Args>
class factory_singleton : public singleton::singleton<base_factory<TType,
                                                                   std::unique_ptr,
                                                                   TBase,
                                                                   Args...>> {};
template <typename TType,
          template <class WrappedTBase, typename...> class TPointerWrapper,
          typename TBase>
class multifactory {
 public:
  multifactory(void) = default;
  virtual ~multifactory(void) = default;

  template <typename TDerived, typename...Args>
  void register_type(const std::string& name) {
    static_assert(std::is_base_of<TBase, TDerived>::value,
                  "register_type() only accepts types derived from the base");
    factory_singleton<TType,
                      TBase,
                      Args...>().instance().template register_type<TDerived>(name);
  }

  template<typename TDerived, typename ...Args>
  TPointerWrapper<TBase> create(const std::string& name, Args...args) {
    factory_singleton<TType,
                      TBase,
                      Args...>().instance().create(name, args...);
  }
};

} /* namespace detail */


template<typename TBase, typename...Args>
class releasing_multifactory : public detail::multifactory<detail::factory_releasing_type,
                                                           std::unique_ptr,
                                                           TBase> {
 public:
  ~releasing_multifactory(void) override = default;
};

template<typename TBase, typename...Args>
class sharing_multifactory : public detail::multifactory<detail::factory_sharing_type,
                                                         std::shared_ptr,
                                                         TBase> {
 public:
  ~sharing_multifactory(void) override = default;
};

} /* namespace rcppsw::patterns::factory */