Path: blob/main/contrib/llvm-project/libcxx/include/__flat_set/utils.h
213766 views
// -*- C++ -*-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-exception6//7//===----------------------------------------------------------------------===//89#ifndef _LIBCPP___FLAT_SET_UTILS_H10#define _LIBCPP___FLAT_SET_UTILS_H1112#include <__config>13#include <__iterator/iterator_traits.h>14#include <__ranges/access.h>15#include <__ranges/concepts.h>16#include <__type_traits/container_traits.h>17#include <__type_traits/decay.h>18#include <__utility/exception_guard.h>19#include <__utility/forward.h>20#include <__utility/move.h>2122#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)23# pragma GCC system_header24#endif2526_LIBCPP_PUSH_MACROS27#include <__undef_macros>2829#if _LIBCPP_STD_VER >= 233031_LIBCPP_BEGIN_NAMESPACE_STD3233// These utilities are defined in a class instead of a namespace so that this class can be befriended more easily.34struct __flat_set_utils {35// Emplace a key into a flat_{multi}set, at the exact position that36// __it point to, assuming that the key is not already present in the set.37// When an exception is thrown during the emplacement, the function will clear the set if the container does not38// have strong exception safety guarantee on emplacement.39template <class _Set, class _Iter, class _KeyArg>40_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static auto41__emplace_exact_pos(_Set& __set, _Iter&& __iter, _KeyArg&& __key) {42using _KeyContainer = typename decay_t<_Set>::container_type;43auto __on_failure = std::__make_exception_guard([&]() noexcept {44if constexpr (!__container_traits<_KeyContainer>::__emplacement_has_strong_exception_safety_guarantee) {45__set.clear() /* noexcept */;46}47});48auto __key_it = __set.__keys_.emplace(__iter.__base(), std::forward<_KeyArg>(__key));49__on_failure.__complete();50return typename decay_t<_Set>::iterator(std::move(__key_it));51}5253template <class _Set, class _InputIterator>54_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void55__append(_Set& __set, _InputIterator __first, _InputIterator __last) {56__set.__keys_.insert(__set.__keys_.end(), std::move(__first), std::move(__last));57}5859template <class _Set, class _Range>60_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 static void __append(_Set& __set, _Range&& __rng) {61if constexpr (requires { __set.__keys_.insert_range(__set.__keys_.end(), std::forward<_Range>(__rng)); }) {62// C++23 Sequence Container should have insert_range member function63// Note that not all Sequence Containers provide append_range.64__set.__keys_.insert_range(__set.__keys_.end(), std::forward<_Range>(__rng));65} else if constexpr (ranges::common_range<_Range> &&66__has_input_iterator_category<ranges::iterator_t<_Range>>::value) {67__set.__keys_.insert(__set.__keys_.end(), ranges::begin(__rng), ranges::end(__rng));68} else {69for (auto&& __x : __rng) {70__set.__keys_.insert(__set.__keys_.end(), std::forward<decltype(__x)>(__x));71}72}73}74};75_LIBCPP_END_NAMESPACE_STD7677#endif // _LIBCPP_STD_VER >= 237879_LIBCPP_POP_MACROS8081#endif // #define _LIBCPP___FLAT_SET_UTILS_H828384