peerplays-fc/include/fc/thread/thread_specific.hpp

85 lines
1.5 KiB
C++
Raw Normal View History

2014-08-27 16:20:19 +00:00
#pragma once
#include "thread.hpp"
namespace fc
{
namespace detail
{
unsigned get_next_unused_thread_storage_slot();
unsigned get_next_unused_task_storage_slot();
}
template <typename T>
class thread_specific_ptr
{
private:
unsigned slot;
public:
thread_specific_ptr() :
slot(detail::get_next_unused_thread_storage_slot())
{}
T* get() const
{
return static_cast<T*>(detail::get_thread_specific_data(slot));
}
T* operator->() const
{
return get();
}
T& operator*() const
{
return *get();
}
operator bool() const
{
return get() != static_cast<T*>(0);
}
static void cleanup_function(void* obj)
{
delete static_cast<T*>(obj);
}
void reset(T* new_value = 0)
{
detail::set_thread_specific_data(slot, new_value, cleanup_function);
}
};
template <typename T>
class task_specific_ptr
{
private:
unsigned slot;
public:
task_specific_ptr() :
slot(detail::get_next_unused_task_storage_slot())
{}
T* get() const
{
return static_cast<T*>(detail::get_task_specific_data(slot));
}
T* operator->() const
{
return get();
}
T& operator*() const
{
return *get();
}
operator bool() const
{
return get() != static_cast<T*>(0);
}
static void cleanup_function(void* obj)
{
delete static_cast<T*>(obj);
}
void reset(T* new_value = 0)
{
detail::set_task_specific_data(slot, new_value, cleanup_function);
}
};
}