#pragma once #include #include #include #include namespace boost_ext { namespace detail { /** Emulation of "thread_local" storage keyword. Copyright (c) 2013, Fredrik Orderud. */ template class thread_local_impl : boost::noncopyable { public: thread_local_impl (T default) : m_default(default) { } operator T () const { using namespace boost; unique_lock lock(m_mutex); std::map::const_iterator it = m_map.find(this_thread::get_id()); if (it == m_map.end()) return m_default; return it->second; } thread_local_impl & operator = (const T & val) { using namespace boost; unique_lock lock(m_mutex); m_map[this_thread::get_id()] = val; return *this; } private: const T m_default; std::map m_map; mutable boost::mutex m_mutex; }; } // namespace detail /** Work-around for missing "thread_local" keyword support in non-C++11 compilers. The macro translates into either "thread_local", "__declspec(thread)", "__thread" or a thread_local emulation, depending on platform and compiler. Copyright (c) 2013, Fredrik Orderud. */ #ifndef BOOST_THREAD_LOCAL_RESTRICTED # if __cplusplus >= 201103L // C++11 conformant compiler # define BOOST_THREAD_LOCAL_RESTRICTED(T) thread_local T # elif defined _WIN32 // Windows platform # if (defined _MSC_VER) && (_MSC_VER >= 1700) && (!defined _USING_V110_SDK71_) // MSVC >=11 in non-WinXP compatible mode # define BOOST_THREAD_LOCAL_RESTRICTED(T) __declspec(thread) T # else # define BOOST_THREAD_LOCAL_RESTRICTED(T) detail::thread_local_impl # endif # else // non-Windows platform # define BOOST_THREAD_LOCAL_RESTRICTED(T) __thread T # endif #endif } // namespace boost_ext