Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@
*.a
*.lib

# Executables
*.exe
*.out
*.app
# Executables
*.exe
*.out
*.app

# Node.js dependencies
node_modules/
package-lock.json

# Build directories
build/
gcc/
48 changes: 30 additions & 18 deletions include/factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@
#ifndef _FACTORY_H_
#define _FACTORY_H_

#include <iostream>
#include <iostream>
#include <stdexcept>
#include <metacommon/common.h>

namespace dp14 {

template <typename T, typename U, typename... Args>
class factory_registrator;

template <typename T, typename... Args>
template <typename T, typename U, typename... Args>
class factory_registrator;

/**
* Factory pattern implementation with type registration
*
* WARNING: This class is NOT thread-safe. External synchronization
* is required for concurrent access.
*/
template <typename T, typename... Args>
class factory;

namespace detail {
Expand Down Expand Up @@ -62,9 +69,9 @@ class factory
key_impl keyimpl = get_key<U>();
auto it = _map_registrators.find(keyimpl);
if (it != _map_registrators.end())
{
std::cout << "Already registered key " << keyimpl << std::endl;
throw std::exception();
{
std::cout << "Already registered key " << keyimpl << std::endl;
throw std::runtime_error("Key already registered in factory");
}
else
{
Expand All @@ -81,10 +88,10 @@ class factory
{
_map_registrators.erase(get_key<U>());
}
else
{
std::cout << "Already unregistered key " << keyimpl << std::endl;
throw std::exception();
else
{
std::cout << "Already unregistered key " << keyimpl << std::endl;
throw std::runtime_error("Key already unregistered in factory");
}
}

Expand Down Expand Up @@ -114,9 +121,9 @@ class factory
{
auto it = _map_registrators.find(keyimpl);
if (it == _map_registrators.end())
{
std::cout << "Can't found key in map: " << keyimpl << std::endl;
throw std::exception();
{
std::cout << "Can't found key in map: " << keyimpl << std::endl;
throw std::runtime_error("Key not found in factory registry");
}
return (it->second)(std::forward<Args>(data)...);
}
Expand Down Expand Up @@ -149,9 +156,14 @@ class factory_registrator
return std::make_unique<U>(std::forward<Args>(data)...);
}

~factory_registrator()
{
_f.template unregister_type<U>();
~factory_registrator()
{
try {
_f.template unregister_type<U>();
} catch (...) {
// Destructors should not throw exceptions
// Log error or handle silently
}
}

protected:
Expand Down
151 changes: 85 additions & 66 deletions include/memoize.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#ifndef _MEMOIZE_H_
#define _MEMOIZE_H_

#ifndef _MEMOIZE_H_
#define _MEMOIZE_H_

#include <stdexcept>
#include <metacommon/common.h>

namespace dp14 {

template <typename T, typename U, typename... Args>
class memoize_registrator;

template <typename T, typename... Args>
template <typename T, typename U, typename... Args>
class memoize_registrator;

/**
* Memoize pattern implementation with caching and type registration
*
* WARNING: This class is NOT thread-safe. External synchronization
* is required for concurrent access.
*/
template <typename T, typename... Args>
class memoize;

namespace detail {
Expand Down Expand Up @@ -68,9 +75,9 @@ class memoize
key_impl keyimpl = get_key<U>();
auto it = _map_registrators.find(keyimpl);
if (it != _map_registrators.end())
{
std::cout << "Already registered key " << keyimpl << std::endl;
throw std::exception();
{
std::cout << "Already registered key " << keyimpl << std::endl;
throw std::runtime_error("Key already registered in memoize");
}
else
{
Expand All @@ -87,10 +94,10 @@ class memoize
{
_map_registrators.erase(get_key<U>());
}
else
{
std::cout << "Already unregistered key " << keyimpl << std::endl;
throw std::exception();
else
{
std::cout << "Already unregistered key " << keyimpl << std::endl;
throw std::runtime_error("Key already unregistered in memoize");
}
}

Expand All @@ -107,37 +114,43 @@ class memoize
return exists(get_key<U>(), std::forward<Args>(data)...);
}

template <typename TYPE_KEY>
std::shared_ptr<T> get(TYPE_KEY keyimpl_str, Args&&... data) const
{
auto keyimpl = detail::memoize::get_hash(keyimpl_str);
key_cache key = get_base_hash(keyimpl, std::forward<Args>(data)...);
auto obj = _get(keyimpl, key, std::forward<Args>(data)...);
_map_cache_shared.emplace(key, obj);
return obj;
template <typename TYPE_KEY>
std::shared_ptr<T> get(TYPE_KEY keyimpl_str, Args&&... data) const
{
auto keyimpl = detail::memoize::get_hash(keyimpl_str);
key_cache key = get_base_hash(keyimpl, std::forward<Args>(data)...);
auto obj = _get(keyimpl, key, std::forward<Args>(data)...);
// Only add to shared cache if not already present to avoid unnecessary entries
_map_cache_shared.emplace(key, obj); // emplace won't insert if key already exists
return obj;
}

template <typename TYPE_KEY>
auto execute(TYPE_KEY keyimpl_str, Args&&... data) const
{
auto keyimpl = detail::memoize::get_hash(keyimpl_str);
key_cache key = get_base_hash(keyimpl, std::forward<Args>(data)...);
auto code = _get(keyimpl, key, std::forward<Args>(data)...);
_map_cache_shared.emplace(key, code);
return code->get();
}

template <typename TYPE_KEY>
void clear(TYPE_KEY keyimpl_str, Args&&... data) const
{
auto keyimpl = detail::memoize::get_hash(keyimpl_str);
key_cache key = get_base_hash(keyimpl, std::forward<Args>(data)...);
_map_cache_shared.erase(key);
template <typename TYPE_KEY>
auto execute(TYPE_KEY keyimpl_str, Args&&... data) const
{
auto keyimpl = detail::memoize::get_hash(keyimpl_str);
key_cache key = get_base_hash(keyimpl, std::forward<Args>(data)...);
auto code = _get(keyimpl, key, std::forward<Args>(data)...);
// Only add to shared cache if not already present to avoid unnecessary entries
_map_cache_shared.emplace(key, code); // emplace won't insert if key already exists
return code->get();
}

void clear() const
{
_map_cache_shared.clear();
template <typename TYPE_KEY>
void clear(TYPE_KEY keyimpl_str, Args&&... data) const
{
auto keyimpl = detail::memoize::get_hash(keyimpl_str);
key_cache key = get_base_hash(keyimpl, std::forward<Args>(data)...);
// Clear from both caches for consistency
_map_cache.erase(key);
_map_cache_shared.erase(key);
}

void clear() const
{
// Clear both caches
_map_cache.clear();
_map_cache_shared.clear();
}

template <typename U>
Expand All @@ -163,9 +176,9 @@ class memoize

auto itc = _map_registrators.find(keyimpl);
if (itc == _map_registrators.end())
{
std::cout << "Can't found key in map: " << key << std::endl;
throw std::exception();
{
std::cout << "Can't found key in map: " << key << std::endl;
throw std::runtime_error("Key not found in memoize registry");
}

std::shared_ptr<T> new_product = (itc->second)(std::forward<Args>(data)...);
Expand All @@ -184,25 +197,26 @@ class memoize
return _exists(keyimpl, std::forward<Args>(data)...) != _map_cache.end();
}

cache_iterator _exists(const key_impl& keyimpl, Args&&... data) const
{
key_cache key = get_base_hash(keyimpl, std::forward<Args>(data)...);
cache_iterator it = _map_cache.find(key);
cache_iterator ite = _map_cache.end();
if (it != ite)
{
// pointer cached can be dangled
if (!it->second.expired())
{
return it;
}
else
{
// remove expired dangled pointer
_map_cache.erase(key);
}
}
return ite;
cache_iterator _exists(const key_impl& keyimpl, Args&&... data) const
{
key_cache key = get_base_hash(keyimpl, std::forward<Args>(data)...);
cache_iterator it = _map_cache.find(key);
cache_iterator ite = _map_cache.end();
if (it != ite)
{
// pointer cached can be dangled
if (!it->second.expired())
{
return it;
}
else
{
// remove expired dangled pointer
// Note: This modifies mutable _map_cache which is allowed in const methods
_map_cache.erase(key);
}
}
return ite;
}

protected:
Expand Down Expand Up @@ -235,9 +249,14 @@ class memoize_registrator
return std::make_shared<U>(std::forward<Args>(data)...);
}

~memoize_registrator()
{
_m.template unregister_type<U>();
~memoize_registrator()
{
try {
_m.template unregister_type<U>();
} catch (...) {
// Destructors should not throw exceptions
// Log error or handle silently
}
}

protected:
Expand Down
Loading