Add polymorphism support to Ref
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "metric.hpp"
|
||||
#include "perfetto_categories.hpp"
|
||||
#include "process_collector.hpp"
|
||||
#include "reference.hpp"
|
||||
#include "server.hpp"
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
@@ -181,7 +182,7 @@ int main(int argc, char *argv[]) {
|
||||
#endif
|
||||
|
||||
// Register the process collector for default metrics.
|
||||
metric::register_collector(std::make_shared<ProcessCollector>());
|
||||
metric::register_collector(make_ref<ProcessCollector>());
|
||||
|
||||
std::string config_file = "config.toml";
|
||||
|
||||
|
||||
@@ -444,7 +444,7 @@ struct Metric {
|
||||
}
|
||||
|
||||
static auto &get_collectors() {
|
||||
using CollectorRegistry = std::vector<std::shared_ptr<Collector>>;
|
||||
using CollectorRegistry = std::vector<Ref<Collector>>;
|
||||
static CollectorRegistry *collectors = new CollectorRegistry();
|
||||
return *collectors;
|
||||
}
|
||||
@@ -1803,7 +1803,7 @@ void reset_metrics_for_testing() {
|
||||
// when threads exit naturally
|
||||
}
|
||||
|
||||
void register_collector(std::shared_ptr<Collector> collector) {
|
||||
void register_collector(Ref<Collector> collector) {
|
||||
std::unique_lock<std::mutex> _{Metric::mutex};
|
||||
++Metric::registration_version;
|
||||
Metric::get_collectors().push_back(std::move(collector));
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "arena.hpp"
|
||||
#include "reference.hpp"
|
||||
|
||||
namespace metric {
|
||||
|
||||
@@ -255,12 +256,12 @@ struct Collector {
|
||||
/**
|
||||
* @brief Register a collector with the metrics system.
|
||||
*
|
||||
* The system will hold a shared_ptr to the collector and call its collect()
|
||||
* The system will hold a Ref to the collector and call its collect()
|
||||
* method during each metric rendering.
|
||||
*
|
||||
* @param collector A shared_ptr to the collector to be registered.
|
||||
* @param collector A Ref to the collector to be registered.
|
||||
*/
|
||||
void register_collector(std::shared_ptr<Collector> collector);
|
||||
void register_collector(Ref<Collector> collector);
|
||||
|
||||
// Note: Histograms do not support callbacks due to their multi-value nature
|
||||
// (buckets + sum + count). Use static histogram metrics only.
|
||||
|
||||
@@ -135,6 +135,18 @@ template <typename T> struct Ref {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting copy constructor for polymorphism (Derived -> Base)
|
||||
*/
|
||||
template <typename U>
|
||||
Ref(const Ref<U> &other) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
: ptr(other.ptr), control_block(other.control_block) {
|
||||
if (control_block) {
|
||||
control_block->increment_strong();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment operator
|
||||
*/
|
||||
@@ -150,6 +162,22 @@ template <typename T> struct Ref {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting assignment operator for polymorphism (Derived -> Base)
|
||||
*/
|
||||
template <typename U>
|
||||
Ref &operator=(const Ref<U> &other) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
{
|
||||
release();
|
||||
ptr = other.ptr;
|
||||
control_block = other.control_block;
|
||||
if (control_block) {
|
||||
control_block->increment_strong();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move constructor - transfers ownership
|
||||
*/
|
||||
@@ -159,6 +187,17 @@ template <typename T> struct Ref {
|
||||
other.control_block = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting move constructor for polymorphism (Derived -> Base)
|
||||
*/
|
||||
template <typename U>
|
||||
Ref(Ref<U> &&other) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
: ptr(other.ptr), control_block(other.control_block) {
|
||||
other.ptr = nullptr;
|
||||
other.control_block = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Move assignment operator
|
||||
*/
|
||||
@@ -173,6 +212,22 @@ template <typename T> struct Ref {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting move assignment operator for polymorphism (Derived ->
|
||||
* Base)
|
||||
*/
|
||||
template <typename U>
|
||||
Ref &operator=(Ref<U> &&other) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
{
|
||||
release();
|
||||
ptr = other.ptr;
|
||||
control_block = other.control_block;
|
||||
other.ptr = nullptr;
|
||||
other.control_block = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset to empty state
|
||||
*/
|
||||
@@ -233,6 +288,7 @@ private:
|
||||
friend Ref<U> make_ref(Args &&...args);
|
||||
|
||||
template <typename U> friend struct WeakRef;
|
||||
template <typename U> friend struct Ref;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -302,6 +358,83 @@ template <typename T> struct WeakRef {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting copy constructor from WeakRef for polymorphism
|
||||
*/
|
||||
template <typename U>
|
||||
WeakRef(const WeakRef<U> &other) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
: control_block(other.control_block) {
|
||||
if (control_block) {
|
||||
control_block->increment_weak();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting copy constructor from Ref for polymorphism
|
||||
*/
|
||||
template <typename U>
|
||||
WeakRef(const Ref<U> &ref) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
: control_block(ref.control_block) {
|
||||
if (control_block) {
|
||||
control_block->increment_weak();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting copy assignment from WeakRef for polymorphism
|
||||
*/
|
||||
template <typename U>
|
||||
WeakRef &operator=(const WeakRef<U> &other) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
{
|
||||
release();
|
||||
control_block = other.control_block;
|
||||
if (control_block) {
|
||||
control_block->increment_weak();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting copy assignment from Ref for polymorphism
|
||||
*/
|
||||
template <typename U>
|
||||
WeakRef &operator=(const Ref<U> &ref) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
{
|
||||
release();
|
||||
control_block = ref.control_block;
|
||||
if (control_block) {
|
||||
control_block->increment_weak();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting move constructor from WeakRef for polymorphism
|
||||
*/
|
||||
template <typename U>
|
||||
WeakRef(WeakRef<U> &&other) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
: control_block(other.control_block) {
|
||||
other.control_block = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converting move assignment from WeakRef for polymorphism
|
||||
*/
|
||||
template <typename U>
|
||||
WeakRef &operator=(WeakRef<U> &&other) noexcept
|
||||
requires std::is_convertible_v<U *, T *>
|
||||
{
|
||||
release();
|
||||
control_block = other.control_block;
|
||||
other.control_block = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy assignment from WeakRef
|
||||
*/
|
||||
@@ -393,6 +526,7 @@ private:
|
||||
}
|
||||
|
||||
template <typename U> friend struct Ref;
|
||||
template <typename U> friend struct WeakRef;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "config.hpp"
|
||||
#include "connection_handler.hpp"
|
||||
#include "connection_registry.hpp"
|
||||
#include "reference.hpp"
|
||||
|
||||
/**
|
||||
* High-performance multi-threaded server for handling network connections.
|
||||
|
||||
Reference in New Issue
Block a user