Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: base/task_scheduler/task_traits_details.h

Issue 2829083002: Add constexpr TaskTraits constructor. (Closed)
Patch Set: CR gab Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // 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_TASK_SCHEDULER_TASK_TRAITS_DETAILS_H_
6 #define BASE_TASK_SCHEDULER_TASK_TRAITS_DETAILS_H_
7
8 #include <type_traits>
9 #include <utility>
10
11 namespace base {
12 namespace internal {
13
14 // HasArgOfType<CheckedType, ArgTypes...>::value is true iff a type in ArgTypes
15 // matches CheckedType.
16 template <class...>
17 struct HasArgOfType : std::false_type {};
18 template <class CheckedType, class FirstArgType, class... ArgTypes>
19 struct HasArgOfType<CheckedType, FirstArgType, ArgTypes...>
20 : std::conditional<std::is_same<CheckedType, FirstArgType>::value,
21 std::true_type,
22 HasArgOfType<CheckedType, ArgTypes...>>::type {};
23
24 // When the following call is made:
25 // GetValueFromArgListImpl(CallFirstTag(), GetterType(), args...);
26 // The compiler prefers using the first overload of GetValueFromArgListImpl(),
27 // because the type of the first argument matches exactly. This overload returns
28 // getter.GetValueFromArg(first_arg), where |first_arg| is the first element in
29 // |args|. If getter.GetValueFromArg(first_arg) isn't defined, the compiler uses
30 // the second or the third overload instead (depending on whether |args| is
31 // empty). The second overload discards |first_arg| and makes a recursive call
32 // to GetValueFromArgListImpl() with CallFirstTag() as first argument. The third
33 // overload returns getter.GetDefaultValue().
34
35 // Tag dispatching.
36 struct CallSecondTag {};
37 struct CallFirstTag : CallSecondTag {};
38
39 // Overload 1: Get value from first argument. Check that no argument in |args|
40 // has the same type as |first_arg|.
41 template <class GetterType,
42 class FirstArgType,
43 class... ArgTypes,
44 class TestGetValueFromArgDefined =
45 decltype(std::declval<GetterType>().GetValueFromArg(
46 std::declval<FirstArgType>()))>
47 constexpr typename GetterType::ValueType GetValueFromArgListImpl(
48 CallFirstTag,
49 GetterType getter,
50 const FirstArgType& first_arg,
51 const ArgTypes&... args) {
52 static_assert(!HasArgOfType<FirstArgType, ArgTypes...>::value,
53 "Multiple arguments of the same type were provided to the "
54 "constructor of TaskTraits.");
55 return getter.GetValueFromArg(first_arg);
56 }
57
58 // Overload 2: Discard first argument.
59 template <class GetterType, class FirstArgType, class... ArgTypes>
60 constexpr typename GetterType::ValueType GetValueFromArgListImpl(
61 CallSecondTag,
62 GetterType getter,
63 const FirstArgType&,
64 const ArgTypes&... args) {
65 return GetValueFromArgListImpl(CallFirstTag(), getter, args...);
66 }
67
68 // Overload 3: Default value.
69 template <class GetterType>
70 constexpr typename GetterType::ValueType GetValueFromArgListImpl(
71 CallFirstTag,
gab 2017/04/28 19:00:31 I meant to reorder this to be Overload 1 so that l
fdoray 2017/05/01 17:13:10 Done.
72 GetterType getter) {
73 return getter.GetDefaultValue();
74 }
75
76 // If there is an argument |arg_of_type| of type Getter::ArgType in |args|,
77 // returns getter.GetValueFromArg(arg_of_type). If there are more than one
78 // argument of type Getter::ArgType in |args|, generates a compile-time error.
79 // Otherwise, returns getter.GetDefaultValue().
80 //
81 // |getter| must provide:
82 //
83 // ValueType:
84 // The return type of GetValueFromArgListImpl().
85 //
86 // ArgType:
87 // The type of the argument from which GetValueFromArgListImpl() derives its
88 // return value.
89 //
90 // ValueType GetValueFromArg(ArgType):
91 // Converts an argument of type ArgType into a value returned by
92 // GetValueFromArgListImpl().
93 //
94 // ValueType GetDefaultValue():
95 // Returns the value returned by GetValueFromArgListImpl() if none of its
96 // arguments is of type ArgType.
97 template <class GetterType, class... ArgTypes>
98 constexpr typename GetterType::ValueType GetValueFromArgList(
99 GetterType getter,
100 const ArgTypes&... args) {
101 return GetValueFromArgListImpl(CallFirstTag(), getter, args...);
102 }
103
104 template <typename ArgType>
105 struct BooleanArgGetter {
106 using ValueType = bool;
107 constexpr ValueType GetValueFromArg(ArgType) const { return true; }
108 constexpr ValueType GetDefaultValue() const { return false; }
109 };
110
111 template <typename ArgType, ArgType DefaultValue>
112 struct EnumArgGetter {
113 using ValueType = ArgType;
114 constexpr ValueType GetValueFromArg(ArgType arg) const { return arg; }
115 constexpr ValueType GetDefaultValue() const { return DefaultValue; }
116 };
117
118 // Allows instantiation of multiple types in one statement. Used to prevent
119 // instantiation of the constructor of TaskTraits with inappropriate argument
120 // types.
121 template <class...>
122 struct InitTypes {};
123
124 } // namespace internal
125 } // namespace base
126
127 #endif // BASE_TASK_SCHEDULER_TASK_TRAITS_DETAILS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698