// Copyright 2024 The PDFium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CORE_FXCRT_CONTAINERS_CONTAINS_H_ #define CORE_FXCRT_CONTAINERS_CONTAINS_H_ #include #include #include #include "core/fxcrt/template_util.h" namespace pdfium { namespace internal { // Small helper to detect whether a given type has a nested `key_type` typedef. // Used below to catch misuses of the API for associative containers. template struct HasKeyType : std::false_type {}; template struct HasKeyType> : std::true_type {}; // Utility type traits used for specializing pdfium::Contains() below. template struct HasFindWithNpos : std::false_type {}; template struct HasFindWithNpos< Container, Element, std::void_t().find( std::declval()) != Container::npos)>> : std::true_type {}; template struct HasFindWithEnd : std::false_type {}; template struct HasFindWithEnd< Container, Element, std::void_t().find( std::declval()) != std::declval().end())>> : std::true_type {}; template struct HasContains : std::false_type {}; template struct HasContains< Container, Element, std::void_t().contains( std::declval()))>> : std::true_type {}; } // namespace internal // General purpose implementation to check if |container| contains |value|. template ::value && !internal::HasFindWithEnd::value && !internal::HasContains::value>* = nullptr> bool Contains(const Container& container, const Value& value) { static_assert( !internal::HasKeyType::value, "Error: About to perform linear search on an associative container. " "Either use a more generic comparator (e.g. std::less<>) or, if a linear " "search is desired, provide an explicit projection parameter."); using std::begin; using std::end; return std::find(begin(container), end(container), value) != end(container); } // Specialized Contains() implementation for when |container| has a find() // member function and a static npos member, but no contains() member function. template ::value && !internal::HasContains::value>* = nullptr> bool Contains(const Container& container, const Value& value) { return container.find(value) != Container::npos; } // Specialized Contains() implementation for when |container| has a find() // and end() member function, but no contains() member function. template ::value && !internal::HasContains::value>* = nullptr> bool Contains(const Container& container, const Value& value) { return container.find(value) != container.end(); } // Specialized Contains() implementation for when |container| has a contains() // member function. template < typename Container, typename Value, std::enable_if_t::value>* = nullptr> bool Contains(const Container& container, const Value& value) { return container.contains(value); } } // namespace pdfium #endif // CORE_FXCRT_CONTAINERS_CONTAINS_H_