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