1*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
2*5f757f3fSDimitry Andric //
3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5f757f3fSDimitry Andric //
7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
8*5f757f3fSDimitry Andric 
9*5f757f3fSDimitry Andric // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html
10*5f757f3fSDimitry Andric 
11*5f757f3fSDimitry Andric #include <chrono>
12*5f757f3fSDimitry Andric 
13*5f757f3fSDimitry Andric #include <__mutex/unique_lock.h>
14*5f757f3fSDimitry Andric #include <forward_list>
15*5f757f3fSDimitry Andric 
16*5f757f3fSDimitry Andric // When threads are not available the locking is not required.
17*5f757f3fSDimitry Andric #ifndef _LIBCPP_HAS_NO_THREADS
18*5f757f3fSDimitry Andric #  include <shared_mutex>
19*5f757f3fSDimitry Andric #endif
20*5f757f3fSDimitry Andric 
21*5f757f3fSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
22*5f757f3fSDimitry Andric 
23*5f757f3fSDimitry Andric namespace chrono {
24*5f757f3fSDimitry Andric 
25*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
26*5f757f3fSDimitry Andric //                          Private API
27*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
28*5f757f3fSDimitry Andric 
29*5f757f3fSDimitry Andric class tzdb_list::__impl {
30*5f757f3fSDimitry Andric public:
__impl(tzdb && __tzdb)31*5f757f3fSDimitry Andric   explicit __impl(tzdb&& __tzdb) { __tzdb_.push_front(std::move(__tzdb)); }
32*5f757f3fSDimitry Andric 
33*5f757f3fSDimitry Andric   using const_iterator = tzdb_list::const_iterator;
34*5f757f3fSDimitry Andric 
front() const35*5f757f3fSDimitry Andric   const tzdb& front() const noexcept {
36*5f757f3fSDimitry Andric #ifndef _LIBCPP_HAS_NO_THREADS
37*5f757f3fSDimitry Andric     shared_lock __lock{__mutex_};
38*5f757f3fSDimitry Andric #endif
39*5f757f3fSDimitry Andric     return __tzdb_.front();
40*5f757f3fSDimitry Andric   }
41*5f757f3fSDimitry Andric 
erase_after(const_iterator __p)42*5f757f3fSDimitry Andric   const_iterator erase_after(const_iterator __p) {
43*5f757f3fSDimitry Andric #ifndef _LIBCPP_HAS_NO_THREADS
44*5f757f3fSDimitry Andric     unique_lock __lock{__mutex_};
45*5f757f3fSDimitry Andric #endif
46*5f757f3fSDimitry Andric     return __tzdb_.erase_after(__p);
47*5f757f3fSDimitry Andric   }
48*5f757f3fSDimitry Andric 
__emplace_front(tzdb && __tzdb)49*5f757f3fSDimitry Andric   tzdb& __emplace_front(tzdb&& __tzdb) {
50*5f757f3fSDimitry Andric #ifndef _LIBCPP_HAS_NO_THREADS
51*5f757f3fSDimitry Andric     unique_lock __lock{__mutex_};
52*5f757f3fSDimitry Andric #endif
53*5f757f3fSDimitry Andric     return __tzdb_.emplace_front(std::move(__tzdb));
54*5f757f3fSDimitry Andric   }
55*5f757f3fSDimitry Andric 
begin() const56*5f757f3fSDimitry Andric   const_iterator begin() const noexcept {
57*5f757f3fSDimitry Andric #ifndef _LIBCPP_HAS_NO_THREADS
58*5f757f3fSDimitry Andric     shared_lock __lock{__mutex_};
59*5f757f3fSDimitry Andric #endif
60*5f757f3fSDimitry Andric     return __tzdb_.begin();
61*5f757f3fSDimitry Andric   }
end() const62*5f757f3fSDimitry Andric   const_iterator end() const noexcept {
63*5f757f3fSDimitry Andric     //  forward_list<T>::end does not access the list, so no need to take a lock.
64*5f757f3fSDimitry Andric     return __tzdb_.end();
65*5f757f3fSDimitry Andric   }
66*5f757f3fSDimitry Andric 
cbegin() const67*5f757f3fSDimitry Andric   const_iterator cbegin() const noexcept { return begin(); }
cend() const68*5f757f3fSDimitry Andric   const_iterator cend() const noexcept { return end(); }
69*5f757f3fSDimitry Andric 
70*5f757f3fSDimitry Andric private:
71*5f757f3fSDimitry Andric #ifndef _LIBCPP_HAS_NO_THREADS
72*5f757f3fSDimitry Andric   mutable shared_mutex __mutex_;
73*5f757f3fSDimitry Andric #endif
74*5f757f3fSDimitry Andric   forward_list<tzdb> __tzdb_;
75*5f757f3fSDimitry Andric };
76*5f757f3fSDimitry Andric 
77*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
78*5f757f3fSDimitry Andric //                           Public API
79*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
80*5f757f3fSDimitry Andric 
tzdb_list(tzdb && __tzdb)81*5f757f3fSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI tzdb_list::tzdb_list(tzdb&& __tzdb) : __impl_{new __impl(std::move(__tzdb))} {}
82*5f757f3fSDimitry Andric 
~tzdb_list()83*5f757f3fSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI tzdb_list::~tzdb_list() { delete __impl_; }
84*5f757f3fSDimitry Andric 
front() const85*5f757f3fSDimitry Andric _LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI const tzdb& tzdb_list::front() const noexcept {
86*5f757f3fSDimitry Andric   return __impl_->front();
87*5f757f3fSDimitry Andric }
88*5f757f3fSDimitry Andric 
erase_after(const_iterator __p)89*5f757f3fSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::erase_after(const_iterator __p) {
90*5f757f3fSDimitry Andric   return __impl_->erase_after(__p);
91*5f757f3fSDimitry Andric }
92*5f757f3fSDimitry Andric 
__emplace_front(tzdb && __tzdb)93*5f757f3fSDimitry Andric _LIBCPP_EXPORTED_FROM_ABI tzdb& tzdb_list::__emplace_front(tzdb&& __tzdb) {
94*5f757f3fSDimitry Andric   return __impl_->__emplace_front(std::move(__tzdb));
95*5f757f3fSDimitry Andric }
96*5f757f3fSDimitry Andric 
begin() const97*5f757f3fSDimitry Andric _LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::begin() const noexcept {
98*5f757f3fSDimitry Andric   return __impl_->begin();
99*5f757f3fSDimitry Andric }
end() const100*5f757f3fSDimitry Andric _LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::end() const noexcept {
101*5f757f3fSDimitry Andric   return __impl_->end();
102*5f757f3fSDimitry Andric }
103*5f757f3fSDimitry Andric 
cbegin() const104*5f757f3fSDimitry Andric _LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::cbegin() const noexcept {
105*5f757f3fSDimitry Andric   return __impl_->cbegin();
106*5f757f3fSDimitry Andric }
cend() const107*5f757f3fSDimitry Andric _LIBCPP_NODISCARD_EXT _LIBCPP_EXPORTED_FROM_ABI tzdb_list::const_iterator tzdb_list::cend() const noexcept {
108*5f757f3fSDimitry Andric   return __impl_->cend();
109*5f757f3fSDimitry Andric }
110*5f757f3fSDimitry Andric 
111*5f757f3fSDimitry Andric } // namespace chrono
112*5f757f3fSDimitry Andric 
113*5f757f3fSDimitry Andric _LIBCPP_END_NAMESPACE_STD
114