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