#pragma once
#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
namespace SimpleBLE::Factory {
template <typename T>
struct Builder : public T {
using T::internal_;
using PtrT = decltype(Builder::internal_);
Builder() { this->internal_ = std::make_shared<InternalT>(); }
using InternalT = typename std::remove_reference<decltype(*(Builder::internal_))>::type;
Builder(PtrT&& internal) { this->internal_ = std::move(internal); }
template <typename dPtr>
Builder(dPtr&& internal) {
this->internal_ = internal;
}
template <typename... ARG>
Builder(ARG&&... args) {
using InternalT = typename std::remove_reference<decltype(*(Builder::internal_))>::type;
this->internal_ = std::make_shared<InternalT>(std::forward<ARG>(args)...);
}
};
template <typename ARG>
struct BuildDeduce {
template <typename T>
operator T() && {
return Builder<T>(std::move(arg));
}
ARG arg;
};
struct BuildDeduce0 {
template <typename T>
operator T() && {
return Builder<T>();
}
};
template <typename ARG>
auto build(ARG x) {
return BuildDeduce<ARG>{std::move(x)};
}
template <typename = void>
auto build() {
return BuildDeduce0{};
}
}