Program Listing for File Conduit.hpp

Return to documentation for file (include/uit/fixtures/Conduit.hpp)

#pragma once
#ifndef UIT_FIXTURES_CONDUIT_HPP_INCLUDE
#define UIT_FIXTURES_CONDUIT_HPP_INCLUDE

#include <memory>
#include <stddef.h>
#include <utility>

#include "../ducts/Duct.hpp"
#include "../spouts/Inlet.hpp"
#include "../spouts/Outlet.hpp"

namespace uit {

template<typename ImplSpec>
class Conduit {

  using duct_t = uit::internal::Duct<ImplSpec>;

  std::shared_ptr<duct_t> duct;

  template<typename Inlet>
  using inlet_wrapper_t = typename ImplSpec::template inlet_wrapper_t<Inlet>;
  template<typename Outlet>
  using outlet_wrapper_t = typename ImplSpec::template outlet_wrapper_t<Outlet>;

public:

  using inlet_t = inlet_wrapper_t< uit::Inlet<ImplSpec> >;
  using outlet_t = outlet_wrapper_t< uit::Outlet<ImplSpec> >;

private:

  inlet_t inlet;
  outlet_t outlet;

public:

  Conduit(Conduit& other) = default;

  Conduit(const Conduit& other) = default;

  Conduit(Conduit&& other) = default;

  template <typename... Args>
  Conduit(Args&&... args) : duct(
    std::make_shared<internal::Duct<ImplSpec>>( std::forward<Args>(args)... )
  ), inlet(duct)
  , outlet(duct)
  { ; }

  template <size_t N>
  decltype(auto) get() const {
    if constexpr (N == 0) return inlet;
    else if constexpr (N == 1) return outlet;
  }

  inlet_t& GetInlet() { return inlet; }

  outlet_t& GetOutlet() { return outlet; }

};

} // namespace uit

namespace std {

  template<typename ImplSpec>
  struct tuple_size<uit::Conduit<ImplSpec>>
    : std::integral_constant<size_t, 2>{};

  template<typename ImplSpec, size_t N>
  struct tuple_element<N, uit::Conduit<ImplSpec>> {
    using type = decltype(
      std::declval<uit::Conduit<ImplSpec>>().template get<N>()
    );
  };

} // namespace std

#endif // #ifndef UIT_FIXTURES_CONDUIT_HPP_INCLUDE