1 //
2 // detail/std_global.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2016 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()57 T& 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