1 | #pragma once |
---|---|
2 | |
3 | #include "DateLUTImpl.h" |
4 | #include <unordered_map> |
5 | #include <atomic> |
6 | #include <mutex> |
7 | #include <memory> |
8 | #include <boost/noncopyable.hpp> |
9 | |
10 | // Also defined in Core/Defines.h |
11 | #if !defined(ALWAYS_INLINE) |
12 | #if defined(_MSC_VER) |
13 | #define ALWAYS_INLINE __forceinline |
14 | #else |
15 | #define ALWAYS_INLINE __attribute__((__always_inline__)) |
16 | #endif |
17 | #endif |
18 | |
19 | |
20 | /// This class provides lazy initialization and lookup of singleton DateLUTImpl objects for a given timezone. |
21 | class DateLUT : private boost::noncopyable |
22 | { |
23 | public: |
24 | /// Return singleton DateLUTImpl instance for the default time zone. |
25 | static ALWAYS_INLINE const DateLUTImpl & instance() |
26 | { |
27 | const auto & date_lut = getInstance(); |
28 | return *date_lut.default_impl.load(std::memory_order_acquire); |
29 | } |
30 | |
31 | /// Return singleton DateLUTImpl instance for a given time zone. |
32 | static ALWAYS_INLINE const DateLUTImpl & instance(const std::string & time_zone) |
33 | { |
34 | const auto & date_lut = getInstance(); |
35 | if (time_zone.empty()) |
36 | return *date_lut.default_impl.load(std::memory_order_acquire); |
37 | |
38 | return date_lut.getImplementation(time_zone); |
39 | } |
40 | |
41 | static void setDefaultTimezone(const std::string & time_zone) |
42 | { |
43 | auto & date_lut = getInstance(); |
44 | const auto & impl = date_lut.getImplementation(time_zone); |
45 | date_lut.default_impl.store(&impl, std::memory_order_release); |
46 | } |
47 | |
48 | protected: |
49 | DateLUT(); |
50 | |
51 | private: |
52 | static DateLUT & getInstance(); |
53 | |
54 | const DateLUTImpl & getImplementation(const std::string & time_zone) const; |
55 | |
56 | using DateLUTImplPtr = std::unique_ptr<DateLUTImpl>; |
57 | |
58 | /// Time zone name -> implementation. |
59 | mutable std::unordered_map<std::string, DateLUTImplPtr> impls; |
60 | mutable std::mutex mutex; |
61 | |
62 | std::atomic<const DateLUTImpl *> default_impl; |
63 | }; |
64 |