| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #ifndef _LIBCPP___FORMAT_BUFFER_H |
| #define _LIBCPP___FORMAT_BUFFER_H |
|
|
| #include <__algorithm/copy_n.h> |
| #include <__algorithm/fill_n.h> |
| #include <__algorithm/max.h> |
| #include <__algorithm/min.h> |
| #include <__algorithm/ranges_copy.h> |
| #include <__algorithm/transform.h> |
| #include <__algorithm/unwrap_iter.h> |
| #include <__concepts/same_as.h> |
| #include <__config> |
| #include <__format/concepts.h> |
| #include <__format/enable_insertable.h> |
| #include <__format/format_to_n_result.h> |
| #include <__iterator/back_insert_iterator.h> |
| #include <__iterator/concepts.h> |
| #include <__iterator/incrementable_traits.h> |
| #include <__iterator/iterator_traits.h> |
| #include <__iterator/wrap_iter.h> |
| #include <__memory/addressof.h> |
| #include <__memory/allocate_at_least.h> |
| #include <__memory/allocator.h> |
| #include <__memory/allocator_traits.h> |
| #include <__memory/construct_at.h> |
| #include <__memory/destroy.h> |
| #include <__memory/uninitialized_algorithms.h> |
| #include <__type_traits/add_pointer.h> |
| #include <__type_traits/conditional.h> |
| #include <__utility/exception_guard.h> |
| #include <__utility/move.h> |
| #include <stdexcept> |
| #include <string_view> |
|
|
| #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| # pragma GCC system_header |
| #endif |
|
|
| _LIBCPP_PUSH_MACROS |
| #include <__undef_macros> |
|
|
| _LIBCPP_BEGIN_NAMESPACE_STD |
|
|
| #if _LIBCPP_STD_VER >= 20 |
|
|
| namespace __format { |
|
|
| |
| class _LIBCPP_HIDE_FROM_ABI __max_output_size { |
| public: |
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __max_output_size(size_t __max_size) : __max_size_{__max_size} {} |
|
|
| |
| |
| |
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __write_request(size_t __code_units) { |
| size_t __result = |
| __code_units_written_ < __max_size_ ? std::min(__code_units, __max_size_ - __code_units_written_) : 0; |
| __code_units_written_ += __code_units; |
| return __result; |
| } |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __code_units_written() const noexcept { return __code_units_written_; } |
|
|
| private: |
| size_t __max_size_; |
| |
| |
| size_t __code_units_written_{0}; |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| template <__fmt_char_type _CharT> |
| class __output_buffer { |
| public: |
| using value_type _LIBCPP_NODEBUG = _CharT; |
| using __prepare_write_type _LIBCPP_NODEBUG = void (*)(__output_buffer<_CharT>&, size_t); |
|
|
| [[nodiscard]] |
| _LIBCPP_HIDE_FROM_ABI explicit __output_buffer(_CharT* __ptr, size_t __capacity, __prepare_write_type __function) |
| : __output_buffer{__ptr, __capacity, __function, nullptr} {} |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __output_buffer( |
| _CharT* __ptr, size_t __capacity, __prepare_write_type __function, __max_output_size* __max_output_size) |
| : __ptr_(__ptr), __capacity_(__capacity), __prepare_write_(__function), __max_output_size_(__max_output_size) {} |
|
|
| _LIBCPP_HIDE_FROM_ABI void __buffer_flushed() { __size_ = 0; } |
|
|
| _LIBCPP_HIDE_FROM_ABI void __buffer_moved(_CharT* __ptr, size_t __capacity) { |
| __ptr_ = __ptr; |
| __capacity_ = __capacity; |
| } |
|
|
| _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return std::back_insert_iterator{*this}; } |
|
|
| |
| _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { |
| if (__max_output_size_ && __max_output_size_->__write_request(1) == 0) |
| return; |
|
|
| _LIBCPP_ASSERT_INTERNAL( |
| __ptr_ && __size_ < __capacity_ && __available() >= 1, "attempted to write outside the buffer"); |
|
|
| __ptr_[__size_++] = __c; |
|
|
| |
| |
| if (__size_ == __capacity_) |
| __prepare_write(0); |
| } |
|
|
| |
| |
| |
| |
| template <__fmt_char_type _InCharT> |
| _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| size_t __n = __str.size(); |
| if (__max_output_size_) { |
| __n = __max_output_size_->__write_request(__n); |
| if (__n == 0) |
| return; |
| } |
|
|
| const _InCharT* __first = __str.data(); |
| do { |
| __prepare_write(__n); |
| size_t __chunk = std::min(__n, __available()); |
| std::copy_n(__first, __chunk, std::addressof(__ptr_[__size_])); |
| __size_ += __chunk; |
| __first += __chunk; |
| __n -= __chunk; |
| } while (__n); |
| } |
|
|
| |
| |
| |
| template <contiguous_iterator _Iterator, |
| class _UnaryOperation, |
| __fmt_char_type _InCharT = typename iterator_traits<_Iterator>::value_type> |
| _LIBCPP_HIDE_FROM_ABI void __transform(_Iterator __first, _Iterator __last, _UnaryOperation __operation) { |
| _LIBCPP_ASSERT_INTERNAL(__first <= __last, "not a valid range"); |
|
|
| size_t __n = static_cast<size_t>(__last - __first); |
| if (__max_output_size_) { |
| __n = __max_output_size_->__write_request(__n); |
| if (__n == 0) |
| return; |
| } |
|
|
| do { |
| __prepare_write(__n); |
| size_t __chunk = std::min(__n, __available()); |
| std::transform(__first, __first + __chunk, std::addressof(__ptr_[__size_]), __operation); |
| __size_ += __chunk; |
| __first += __chunk; |
| __n -= __chunk; |
| } while (__n); |
| } |
|
|
| |
| _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { |
| if (__max_output_size_) { |
| __n = __max_output_size_->__write_request(__n); |
| if (__n == 0) |
| return; |
| } |
|
|
| do { |
| __prepare_write(__n); |
| size_t __chunk = std::min(__n, __available()); |
| std::fill_n(std::addressof(__ptr_[__size_]), __chunk, __value); |
| __size_ += __chunk; |
| __n -= __chunk; |
| } while (__n); |
| } |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __capacity() const { return __capacity_; } |
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __size() const { return __size_; } |
|
|
| private: |
| _CharT* __ptr_; |
| size_t __capacity_; |
| size_t __size_{0}; |
| void (*__prepare_write_)(__output_buffer<_CharT>&, size_t); |
| __max_output_size* __max_output_size_; |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __available() const { return __capacity_ - __size_; } |
|
|
| _LIBCPP_HIDE_FROM_ABI void __prepare_write(size_t __code_units) { |
| |
| __code_units += 1; |
| if (__available() < __code_units) |
| __prepare_write_(*this, __code_units + 1); |
| } |
| }; |
|
|
| template <class _OutIt, class _CharT> |
| concept __enable_direct_output = |
| __fmt_char_type<_CharT> && |
| (same_as<_OutIt, _CharT*> |
| |
| |
| || same_as<_OutIt, __wrap_iter<_CharT*>>); |
|
|
| |
| |
| |
| |
| |
| |
| |
| template <class _Container> |
| concept __insertable = |
| __enable_insertable<_Container> && __fmt_char_type<typename _Container::value_type> && |
| requires(_Container& __t, |
| add_pointer_t<typename _Container::value_type> __first, |
| add_pointer_t<typename _Container::value_type> __last) { __t.insert(__t.end(), __first, __last); }; |
|
|
| |
| template <class _It> |
| struct __back_insert_iterator_container { |
| using type _LIBCPP_NODEBUG = void; |
| }; |
|
|
| template <__insertable _Container> |
| struct __back_insert_iterator_container<back_insert_iterator<_Container>> { |
| using type _LIBCPP_NODEBUG = _Container; |
| }; |
|
|
| |
| template <__fmt_char_type _CharT> |
| class __allocating_buffer : public __output_buffer<_CharT> { |
| public: |
| __allocating_buffer(const __allocating_buffer&) = delete; |
| __allocating_buffer& operator=(const __allocating_buffer&) = delete; |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __allocating_buffer() : __allocating_buffer{nullptr} {} |
|
|
| [[nodiscard]] |
| _LIBCPP_HIDE_FROM_ABI explicit __allocating_buffer(__max_output_size* __max_output_size) |
| : __output_buffer<_CharT>{__small_buffer_, __buffer_size_, __prepare_write, __max_output_size} {} |
|
|
| _LIBCPP_HIDE_FROM_ABI ~__allocating_buffer() { |
| if (__ptr_ != __small_buffer_) |
| _Alloc{}.deallocate(__ptr_, this->__capacity()); |
| } |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__ptr_, this->__size()}; } |
|
|
| private: |
| using _Alloc _LIBCPP_NODEBUG = allocator<_CharT>; |
|
|
| |
| |
| static constexpr size_t __buffer_size_ = 256; |
| _CharT __small_buffer_[__buffer_size_]; |
|
|
| _CharT* __ptr_{__small_buffer_}; |
|
|
| _LIBCPP_HIDE_FROM_ABI void __grow_buffer(size_t __capacity) { |
| if (__capacity < __buffer_size_) |
| return; |
|
|
| _LIBCPP_ASSERT_INTERNAL(__capacity > this->__capacity(), "the buffer must grow"); |
|
|
| |
| |
| _Alloc __alloc; |
| auto __result = std::__allocate_at_least(__alloc, __capacity); |
| std::copy_n(__ptr_, this->__size(), __result.ptr); |
| if (__ptr_ != __small_buffer_) |
| __alloc.deallocate(__ptr_, this->__capacity()); |
|
|
| __ptr_ = __result.ptr; |
| this->__buffer_moved(__ptr_, __result.count); |
| } |
|
|
| _LIBCPP_HIDE_FROM_ABI void __prepare_write(size_t __size_hint) { |
| __grow_buffer(std::max<size_t>(this->__capacity() + __size_hint, this->__capacity() * 1.6)); |
| } |
|
|
| _LIBCPP_HIDE_FROM_ABI static void __prepare_write(__output_buffer<_CharT>& __buffer, size_t __size_hint) { |
| static_cast<__allocating_buffer<_CharT>&>(__buffer).__prepare_write(__size_hint); |
| } |
| }; |
|
|
| |
| template <class _OutIt, __fmt_char_type _CharT> |
| class __direct_iterator_buffer : public __output_buffer<_CharT> { |
| public: |
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __direct_iterator_buffer(_OutIt __out_it) |
| : __direct_iterator_buffer{__out_it, nullptr} {} |
|
|
| [[nodiscard]] |
| _LIBCPP_HIDE_FROM_ABI explicit __direct_iterator_buffer(_OutIt __out_it, __max_output_size* __max_output_size) |
| : __output_buffer<_CharT>{std::__unwrap_iter(__out_it), __buffer_size, __prepare_write, __max_output_size}, |
| __out_it_(__out_it) {} |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { return __out_it_ + this->__size(); } |
|
|
| private: |
| |
| |
| |
| |
| static constexpr size_t __buffer_size = -1; |
|
|
| _OutIt __out_it_; |
|
|
| _LIBCPP_HIDE_FROM_ABI static void |
| __prepare_write([[maybe_unused]] __output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) { |
| std::__throw_length_error("__direct_iterator_buffer"); |
| } |
| }; |
|
|
| |
| template <class _OutIt, __fmt_char_type _CharT> |
| class __container_inserter_buffer : public __output_buffer<_CharT> { |
| public: |
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __container_inserter_buffer(_OutIt __out_it) |
| : __container_inserter_buffer{__out_it, nullptr} {} |
|
|
| [[nodiscard]] |
| _LIBCPP_HIDE_FROM_ABI explicit __container_inserter_buffer(_OutIt __out_it, __max_output_size* __max_output_size) |
| : __output_buffer<_CharT>{__small_buffer_, __buffer_size, __prepare_write, __max_output_size}, |
| __container_{__out_it.__get_container()} {} |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __out_it() && { |
| __container_->insert(__container_->end(), __small_buffer_, __small_buffer_ + this->__size()); |
| return std::back_inserter(*__container_); |
| } |
|
|
| private: |
| typename __back_insert_iterator_container<_OutIt>::type* __container_; |
|
|
| |
| |
| |
| |
| static constexpr size_t __buffer_size = 256; |
| _CharT __small_buffer_[__buffer_size]; |
|
|
| _LIBCPP_HIDE_FROM_ABI void __prepare_write() { |
| __container_->insert(__container_->end(), __small_buffer_, __small_buffer_ + this->__size()); |
| this->__buffer_flushed(); |
| } |
|
|
| _LIBCPP_HIDE_FROM_ABI static void |
| __prepare_write(__output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) { |
| static_cast<__container_inserter_buffer<_OutIt, _CharT>&>(__buffer).__prepare_write(); |
| } |
| }; |
|
|
| |
| |
| |
| |
| template <class _OutIt, __fmt_char_type _CharT> |
| class __iterator_buffer : public __allocating_buffer<_CharT> { |
| public: |
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __iterator_buffer(_OutIt __out_it) |
| : __allocating_buffer<_CharT>{}, __out_it_{std::move(__out_it)} {} |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit __iterator_buffer(_OutIt __out_it, __max_output_size* __max_output_size) |
| : __allocating_buffer<_CharT>{__max_output_size}, __out_it_{std::move(__out_it)} {} |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __out_it() && { |
| return std::ranges::copy(this->__view(), std::move(__out_it_)).out; |
| } |
|
|
| private: |
| _OutIt __out_it_; |
| }; |
|
|
| |
| template <class _OutIt, __fmt_char_type _CharT> |
| class __buffer_selector { |
| using _Container _LIBCPP_NODEBUG = __back_insert_iterator_container<_OutIt>::type; |
|
|
| public: |
| using type _LIBCPP_NODEBUG = |
| conditional_t<!same_as<_Container, void>, |
| __container_inserter_buffer<_OutIt, _CharT>, |
| conditional_t<__enable_direct_output<_OutIt, _CharT>, |
| __direct_iterator_buffer<_OutIt, _CharT>, |
| __iterator_buffer<_OutIt, _CharT>>>; |
| }; |
|
|
| |
| template <class _OutIt, __fmt_char_type _CharT> |
| class __format_to_n_buffer : private __buffer_selector<_OutIt, _CharT>::type { |
| public: |
| using _Base _LIBCPP_NODEBUG = __buffer_selector<_OutIt, _CharT>::type; |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_to_n_buffer(_OutIt __out_it, iter_difference_t<_OutIt> __n) |
| : _Base{std::move(__out_it), std::addressof(__max_output_size_)}, |
| __max_output_size_{__n < 0 ? size_t{0} : static_cast<size_t>(__n)} {} |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return _Base::__make_output_iterator(); } |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __result() && { |
| return {static_cast<_Base&&>(*this).__out_it(), |
| static_cast<iter_difference_t<_OutIt>>(__max_output_size_.__code_units_written())}; |
| } |
|
|
| private: |
| __max_output_size __max_output_size_; |
| }; |
|
|
| |
| |
| |
| |
| template <__fmt_char_type _CharT> |
| class __formatted_size_buffer : private __output_buffer<_CharT> { |
| public: |
| using _Base _LIBCPP_NODEBUG = __output_buffer<_CharT>; |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __formatted_size_buffer() |
| : _Base{nullptr, 0, __prepare_write, std::addressof(__max_output_size_)} {} |
|
|
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return _Base::__make_output_iterator(); } |
|
|
| |
| |
| [[nodiscard]] _LIBCPP_HIDE_FROM_ABI size_t __result() && { return __max_output_size_.__code_units_written(); } |
|
|
| private: |
| __max_output_size __max_output_size_{0}; |
|
|
| _LIBCPP_HIDE_FROM_ABI static void |
| __prepare_write([[maybe_unused]] __output_buffer<_CharT>& __buffer, [[maybe_unused]] size_t __size_hint) { |
| |
| _LIBCPP_ASSERT_INTERNAL( |
| false, "Since __max_output_size_.__max_size_ == 0 there should never be call to this function."); |
| } |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| template <__fmt_char_type _CharT> |
| class __retarget_buffer { |
| using _Alloc _LIBCPP_NODEBUG = allocator<_CharT>; |
|
|
| public: |
| using value_type _LIBCPP_NODEBUG = _CharT; |
|
|
| struct __iterator { |
| using difference_type _LIBCPP_NODEBUG = ptrdiff_t; |
| using value_type _LIBCPP_NODEBUG = _CharT; |
|
|
| _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer) |
| : __buffer_(std::addressof(__buffer)) {} |
| _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(const _CharT& __c) { |
| __buffer_->push_back(__c); |
| return *this; |
| } |
| _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator=(_CharT&& __c) { |
| __buffer_->push_back(__c); |
| return *this; |
| } |
|
|
| _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator*() { return *this; } |
| _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { return *this; } |
| _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) { return *this; } |
| __retarget_buffer* __buffer_; |
| }; |
|
|
| __retarget_buffer(const __retarget_buffer&) = delete; |
| __retarget_buffer& operator=(const __retarget_buffer&) = delete; |
|
|
| _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) { |
| |
| |
| |
| |
| |
| |
| |
| auto __result = std::__allocate_at_least(__alloc_, std::max(__size_hint, 256 / sizeof(_CharT))); |
| __ptr_ = __result.ptr; |
| __capacity_ = __result.count; |
| } |
|
|
| _LIBCPP_HIDE_FROM_ABI ~__retarget_buffer() { |
| std::destroy_n(__ptr_, __size_); |
| allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_); |
| } |
|
|
| _LIBCPP_HIDE_FROM_ABI __iterator __make_output_iterator() { return __iterator{*this}; } |
|
|
| _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { |
| std::construct_at(__ptr_ + __size_, __c); |
| ++__size_; |
|
|
| if (__size_ == __capacity_) |
| __grow_buffer(); |
| } |
|
|
| template <__fmt_char_type _InCharT> |
| _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) { |
| size_t __n = __str.size(); |
| if (__size_ + __n >= __capacity_) |
| |
| __grow_buffer(__size_ + __n + 1); |
|
|
| std::uninitialized_copy_n(__str.data(), __n, __ptr_ + __size_); |
| __size_ += __n; |
| } |
|
|
| template <contiguous_iterator _Iterator, |
| class _UnaryOperation, |
| __fmt_char_type _InCharT = typename iterator_traits<_Iterator>::value_type> |
| _LIBCPP_HIDE_FROM_ABI void __transform(_Iterator __first, _Iterator __last, _UnaryOperation __operation) { |
| _LIBCPP_ASSERT_INTERNAL(__first <= __last, "not a valid range"); |
|
|
| size_t __n = static_cast<size_t>(__last - __first); |
| if (__size_ + __n >= __capacity_) |
| |
| __grow_buffer(__size_ + __n + 1); |
|
|
| std::uninitialized_default_construct_n(__ptr_ + __size_, __n); |
| std::transform(__first, __last, __ptr_ + __size_, std::move(__operation)); |
| __size_ += __n; |
| } |
|
|
| _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { |
| if (__size_ + __n >= __capacity_) |
| |
| __grow_buffer(__size_ + __n + 1); |
|
|
| std::uninitialized_fill_n(__ptr_ + __size_, __n, __value); |
| __size_ += __n; |
| } |
|
|
| _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__ptr_, __size_}; } |
|
|
| private: |
| _LIBCPP_HIDE_FROM_ABI void __grow_buffer() { __grow_buffer(__capacity_ * 1.6); } |
|
|
| _LIBCPP_HIDE_FROM_ABI void __grow_buffer(size_t __capacity) { |
| _LIBCPP_ASSERT_INTERNAL(__capacity > __capacity_, "the buffer must grow"); |
| auto __result = std::__allocate_at_least(__alloc_, __capacity); |
| auto __guard = std::__make_exception_guard([&] { |
| allocator_traits<_Alloc>::deallocate(__alloc_, __result.ptr, __result.count); |
| }); |
| |
| |
| std::uninitialized_move_n(__ptr_, __size_, __result.ptr); |
| __guard.__complete(); |
| std::destroy_n(__ptr_, __size_); |
| allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_); |
|
|
| __ptr_ = __result.ptr; |
| __capacity_ = __result.count; |
| } |
| _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_; |
| _CharT* __ptr_; |
| size_t __capacity_; |
| size_t __size_{0}; |
| }; |
|
|
| } |
|
|
| #endif |
|
|
| _LIBCPP_END_NAMESPACE_STD |
|
|
| _LIBCPP_POP_MACROS |
|
|
| #endif |
|
|