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.
21class DateLUT : private boost::noncopyable
22{
23public:
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
48protected:
49 DateLUT();
50
51private:
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