Five examples: basic capability query, convenience methods, dynamic capability check through polymorphic interface, capability-driven queue selection, and a comparison table of all queue implementations.
#include <iostream>
#include <memory>
#include <string>
{
std::cout << "=== Example 1: Basic Capability Query ===" << std::endl;
auto mutex_queue = std::make_shared<job_queue>();
auto lockfree_queue = std::make_unique<detail::lockfree_job_queue>();
auto mutex_caps = mutex_queue->get_capabilities();
auto lockfree_caps = lockfree_queue->get_capabilities();
std::cout << "\njob_queue capabilities:" << std::endl;
std::cout << " exact_size: " << std::boolalpha << mutex_caps.exact_size << std::endl;
std::cout << " atomic_empty_check: " << mutex_caps.atomic_empty_check << std::endl;
std::cout << " lock_free: " << mutex_caps.lock_free << std::endl;
std::cout << " wait_free: " << mutex_caps.wait_free << std::endl;
std::cout << " supports_batch: " << mutex_caps.supports_batch << std::endl;
std::cout << " supports_blocking_wait: " << mutex_caps.supports_blocking_wait << std::endl;
std::cout << " supports_stop: " << mutex_caps.supports_stop << std::endl;
std::cout << "\ndetail::lockfree_job_queue capabilities:" << std::endl;
std::cout << " exact_size: " << lockfree_caps.exact_size << std::endl;
std::cout << " atomic_empty_check: " << lockfree_caps.atomic_empty_check << std::endl;
std::cout << " lock_free: " << lockfree_caps.lock_free << std::endl;
std::cout << " wait_free: " << lockfree_caps.wait_free << std::endl;
std::cout << " supports_batch: " << lockfree_caps.supports_batch << std::endl;
std::cout << " supports_blocking_wait: " << lockfree_caps.supports_blocking_wait << std::endl;
std::cout << " supports_stop: " << lockfree_caps.supports_stop << std::endl;
std::cout << std::endl;
}
{
std::cout << "=== Example 2: Convenience Methods ===" << std::endl;
auto queue = std::make_shared<job_queue>();
std::cout << "\nUsing convenience methods on job_queue:" << std::endl;
if (queue->has_exact_size()) {
std::cout << " [OK] Queue size is exact: " << queue->size() << std::endl;
}
if (queue->has_atomic_empty()) {
std::cout << " [OK] Empty check is atomic: " << std::boolalpha << queue->empty() << std::endl;
}
if (!queue->is_lock_free()) {
std::cout << " [OK] Queue uses mutex (good for accuracy)" << std::endl;
}
if (!queue->is_wait_free()) {
std::cout << " [OK] Queue is not wait-free" << std::endl;
}
if (queue->supports_batch()) {
std::cout << " [OK] Batch operations supported" << std::endl;
}
if (queue->supports_blocking_wait()) {
std::cout << " [OK] Blocking wait supported" << std::endl;
}
if (queue->supports_stop()) {
std::cout << " [OK] Stop signaling supported" << std::endl;
}
std::cout << std::endl;
}
{
std::cout << "=== Example 3: Dynamic Capability Check ===" << std::endl;
std::cout << "\nChecking capabilities through scheduler_interface*:" << std::endl;
std::cout << " [OK] Scheduler supports capability introspection" << std::endl;
if (cap->has_exact_size()) {
std::cout << " -> Safe to use size() for decisions" << std::endl;
} else {
std::cout << " -> size() is approximate, use with caution" << std::endl;
}
if (cap->is_lock_free()) {
std::cout << " -> Lock-free implementation (high throughput)" << std::endl;
} else {
std::cout << " -> Mutex-based implementation (accurate metrics)" << std::endl;
}
if (cap->supports_blocking_wait()) {
std::cout << " -> Blocking dequeue available" << std::endl;
} else {
std::cout << " -> Use polling/spin-wait for dequeue" << std::endl;
}
} else {
std::cout << " [!] Scheduler does not support capability introspection" << std::endl;
}
std::cout << std::endl;
}
std::unique_ptr<scheduler_interface>
queue_;
public:
{
if (need_exact_metrics) {
auto jq = std::make_unique<job_queue>();
} else {
auto lfq = std::make_unique<detail::lockfree_job_queue>();
}
}
{
std::cout <<
" Exact queue size: " <<
get_size() << std::endl;
} else {
std::cout <<
" Approximate queue size: ~" <<
get_size() << std::endl;
}
}
private:
{
return jq->size();
}
return lfq->size();
}
}
return 0;
}
};
{
std::cout << "=== Example 4: Capability-Driven Selection ===" << std::endl;
std::cout << "\nCreating processors with different requirements:" << std::endl;
std::cout << "\n[Monitoring Processor] (needs exact metrics)" << std::endl;
std::cout << " exact_metrics_available: " << std::boolalpha
<< monitoring_processor.has_exact_metrics() << std::endl;
monitoring_processor.log_status();
std::cout << "\n[Logging Processor] (approximate is fine)" << std::endl;
std::cout << " exact_metrics_available: "
<< logging_processor.has_exact_metrics() << std::endl;
logging_processor.log_status();
std::cout << std::endl;
}
{
std::cout << "=== Example 5: Capability Comparison Table ===" << std::endl;
auto mutex_q = std::make_shared<job_queue>();
auto lockfree_q = std::make_unique<detail::lockfree_job_queue>();
auto adaptive_q = std::make_unique<adaptive_job_queue>();
std::cout << "\n" << name << ":" << std::endl;
std::cout << " exact_size = " << std::boolalpha << caps.exact_size << std::endl;
std::cout << " atomic_empty_check = " << caps.atomic_empty_check << std::endl;
std::cout << " lock_free = " << caps.lock_free << std::endl;
std::cout << " wait_free = " << caps.wait_free << std::endl;
std::cout << " supports_batch = " << caps.supports_batch << std::endl;
std::cout << " supports_blocking = " << caps.supports_blocking_wait << std::endl;
std::cout << " supports_stop = " << caps.supports_stop << std::endl;
};
print_caps("job_queue (mutex-based)", mutex_q->get_capabilities());
print_caps("detail::lockfree_job_queue", lockfree_q->get_capabilities());
print_caps("adaptive_job_queue (default mode)", adaptive_q->get_capabilities());
std::cout << "\n--- Summary Table ---" << std::endl;
std::cout << "Queue Type | exact | atomic | lock-free | batch | blocking" << std::endl;
std::cout << "----------------------|-------|--------|-----------|-------|----------" << std::endl;
auto caps = mutex_q->get_capabilities();
std::cout << "job_queue | "
<< (caps.exact_size ? "Y" : "N") << " | "
<< (caps.atomic_empty_check ? "Y" : "N") << " | "
<< (caps.lock_free ? "Y" : "N") << " | "
<< (caps.supports_batch ? "Y" : "N") << " | "
<< (caps.supports_blocking_wait ? "Y" : "N") << std::endl;
caps = lockfree_q->get_capabilities();
std::cout << "detail::lockfree_job_queue | "
<< (caps.exact_size ? "Y" : "N") << " | "
<< (caps.atomic_empty_check ? "Y" : "N") << " | "
<< (caps.lock_free ? "Y" : "N") << " | "
<< (caps.supports_batch ? "Y" : "N") << " | "
<< (caps.supports_blocking_wait ? "Y" : "N") << std::endl;
caps = adaptive_q->get_capabilities();
std::cout << "adaptive_job_queue | "
<< (caps.exact_size ? "Y" : "N") << " | "
<< (caps.atomic_empty_check ? "Y" : "N") << " | "
<< (caps.lock_free ? "Y" : "N") << " | "
<< (caps.supports_batch ? "Y" : "N") << " | "
<< (caps.supports_blocking_wait ? "Y" : "N") << std::endl;
std::cout << std::endl;
}
{
std::cout << "Queue Capabilities Sample" << std::endl;
std::cout << "=========================" << std::endl;
std::cout << std::endl;
std::cout << "This sample demonstrates queue_capabilities_interface usage" << std::endl;
std::cout << "for runtime capability introspection." << std::endl;
std::cout << std::endl;
try {
auto queue = std::make_unique<job_queue>();
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
return 1;
}
std::cout << "All examples completed successfully!" << std::endl;
return 0;
}
Adaptive queue that auto-switches between mutex and lock-free modes.
Specialized job class that encapsulates user-defined callbacks.
Smart job processor that adapts to queue capabilities.
SmartJobProcessor(bool need_exact_metrics)
bool exact_metrics_available_
bool has_exact_metrics() const
std::unique_ptr< scheduler_interface > queue_
Lock-free Multi-Producer Multi-Consumer (MPMC) job queue (Internal implementation)
A thread-safe job queue for managing and dispatching work items.
Mixin interface for queue capability introspection.
Scheduler interface for queuing and retrieving jobs.
Thread-safe FIFO job queue with optional bounded size.
Lock-free MPMC job queue using Michael-Scott algorithm with hazard pointers.
Core threading foundation of the thread system library.
Mixin interface for queue capability introspection.
void basic_capability_query()
Example 1: Basic capability query.
void capability_driven_selection()
Example 4: Capability-driven queue selection.
void capability_comparison()
Example 5: Capability comparison table.
void dynamic_capability_check(scheduler_interface *scheduler)
Example 3: Dynamic capability check (polymorphic)
void convenience_methods()
Example 2: Convenience methods.
Abstract scheduler interface for queuing and retrieving jobs.
Runtime-queryable queue capabilities descriptor.