[go: nahoru, domu]

blob: 00edbec8a8febe1a5f369b829e8493ad86baa314 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2011 The Chromium Authors
willchan@chromium.org951269b2010-06-15 19:39:242// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_TEMPLATE_UTIL_H_
6#define BASE_TEMPLATE_UTIL_H_
willchan@chromium.org951269b2010-06-15 19:39:247
danakja26bdfc2016-04-13 22:08:038#include <stddef.h>
Avi Drissman02aadae12022-05-04 02:50:489
jbroman6bcfec422016-05-26 00:28:4610#include <iosfwd>
Brett Wilson322a5462017-08-03 23:59:1211#include <iterator>
tzik403cb6c2016-03-10 07:17:2512#include <type_traits>
danakja26bdfc2016-04-13 22:08:0313#include <utility>
ajwong@chromium.orgb38d3572011-02-15 01:27:3814
Jan Wilken Dörrie2d7bca02021-04-19 19:59:3215#include "base/compiler_specific.h"
willchan@chromium.org792cdcf2010-12-15 09:55:3516
willchan@chromium.org951269b2010-06-15 19:39:2417namespace base {
18
danakja26bdfc2016-04-13 22:08:0319namespace internal {
20
Peter Kastingb2887c32024-01-08 21:41:0421// Used to detect whether the given type is an iterator. This is normally used
Brett Wilson322a5462017-08-03 23:59:1222// with std::enable_if to provide disambiguation for functions that take
23// templatzed iterators as input.
24template <typename T, typename = void>
25struct is_iterator : std::false_type {};
26
27template <typename T>
Avi Drissman1089236e2022-04-28 13:44:4128struct is_iterator<
29 T,
30 std::void_t<typename std::iterator_traits<T>::iterator_category>>
Brett Wilson322a5462017-08-03 23:59:1231 : std::true_type {};
32
Jan Wilken Dörrie9f8955f2020-09-16 10:27:1833// Helper to express preferences in an overload set. If more than one overload
34// are available for a given set of parameters the overload with the higher
35// priority will be chosen.
36template <size_t I>
37struct priority_tag : priority_tag<I - 1> {};
38
39template <>
40struct priority_tag<0> {};
41
danakja26bdfc2016-04-13 22:08:0342} // namespace internal
43
Jan Wilken Dörrief89fc2ac2021-03-05 06:51:2244namespace internal {
45
46// The indirection with std::is_enum<T> is required, because instantiating
47// std::underlying_type_t<T> when T is not an enum is UB prior to C++20.
Andrew Rayskiy629912382023-10-18 22:58:4248template <typename T, bool = std::is_enum_v<T>>
Jan Wilken Dörrief89fc2ac2021-03-05 06:51:2249struct IsScopedEnumImpl : std::false_type {};
50
51template <typename T>
Andrew Rayskiy629912382023-10-18 22:58:4252struct IsScopedEnumImpl<T, /*std::is_enum_v<T>=*/true>
Avi Drissmanc109efd2022-04-27 22:03:3553 : std::negation<std::is_convertible<T, std::underlying_type_t<T>>> {};
Jan Wilken Dörrief89fc2ac2021-03-05 06:51:2254
55} // namespace internal
56
57// Implementation of C++23's std::is_scoped_enum
58//
59// Reference: https://en.cppreference.com/w/cpp/types/is_scoped_enum
60template <typename T>
61struct is_scoped_enum : internal::IsScopedEnumImpl<T> {};
62
willchan@chromium.org951269b2010-06-15 19:39:2463} // namespace base
64
dpolukhin@chromium.org81e8ebf2010-09-16 07:59:2765#endif // BASE_TEMPLATE_UTIL_H_