1 // 2 // detail/std_global.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #ifndef ASIO_DETAIL_STD_GLOBAL_HPP 12 #define ASIO_DETAIL_STD_GLOBAL_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include "asio/detail/config.hpp" 19 20 #if defined(ASIO_HAS_STD_CALL_ONCE) 21 22 #include <exception> 23 #include <mutex> 24 25 #include "asio/detail/push_options.hpp" 26 27 namespace asio { 28 namespace detail { 29 30 template <typename T> 31 struct std_global_impl 32 { 33 // Helper function to perform initialisation. do_initasio::detail::std_global_impl34 static void do_init() 35 { 36 instance_.ptr_ = new T; 37 } 38 39 // Destructor automatically cleans up the global. ~std_global_implasio::detail::std_global_impl40 ~std_global_impl() 41 { 42 delete ptr_; 43 } 44 45 static std::once_flag init_once_; 46 static std_global_impl instance_; 47 T* ptr_; 48 }; 49 50 template <typename T> 51 std::once_flag std_global_impl<T>::init_once_; 52 53 template <typename T> 54 std_global_impl<T> std_global_impl<T>::instance_; 55 56 template <typename T> std_global()57T& std_global() 58 { 59 std::call_once(std_global_impl<T>::init_once_, &std_global_impl<T>::do_init); 60 return *std_global_impl<T>::instance_.ptr_; 61 } 62 63 } // namespace detail 64 } // namespace asio 65 66 #include "asio/detail/pop_options.hpp" 67 68 #endif // defined(ASIO_HAS_STD_CALL_ONCE) 69 70 #endif // ASIO_DETAIL_STD_GLOBAL_HPP 71