Program Listing for File MemoizeCtor.hpp¶
↰ Return to documentation for file (include/sgpl/utility/MemoizeCtor.hpp)
#pragma once
#ifndef SGPL_UTILITY_MEMOIZECTOR_HPP_INCLUDE
#define SGPL_UTILITY_MEMOIZECTOR_HPP_INCLUDE
#include <type_traits>
#include "../../../third-party/conduit/include/uitsl/polyfill/remove_cvref.hpp"
#include "../../../third-party/conduit/include/uit_emp/datastructs/Cache.hpp"
#include "../../../third-party/conduit/include/uit_emp/datastructs/tuple_utils.hpp"
namespace sgpl {
template<typename T>
class MemoizeCtor : public T {
// workaround for inline static thread_local member on g++
template<typename... Args>
inline static auto& cache() {
using cache_t = uit_emp::Cache<
std::tuple<Args... >,
T,
uit_emp::TupleHash<Args... >
>;
thread_local cache_t cache{};
return cache;
}
public:
template<typename... Args>
MemoizeCtor(Args&& ...args) : T(
lookup(std::forward<Args>(args)...)
) { }
MemoizeCtor(const MemoizeCtor&) = default;
MemoizeCtor(MemoizeCtor&&) = default;
template<typename... Args>
static const T& lookup(Args&& ...args) {
return cache<std::remove_cvref_t<Args>...>().GetRef(
std::tuple<std::remove_cvref_t<Args>...>{ args... },
[&](std::tuple<std::remove_cvref_t<Args>...>){ return T( std::forward<Args>(args)... ); }
);
}
};
} // namespace sgpl
#endif // #ifndef SGPL_UTILITY_MEMOIZECTOR_HPP_INCLUDE