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

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

Issue 2829083002: Add constexpr TaskTraits constructor. (Closed)
Patch Set: CR-robliao-48 Created 3 years, 8 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
« no previous file with comments | « base/task_scheduler/task_traits.cc ('k') | base/task_scheduler/task_traits_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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<ArgTypes...>>::type {};
23
24 // ArgsAreConvertible<CheckedType, ArgTypes...>::value is true iff all types in
25 // ArgTypes are convertible to CheckedType.
26 template <class...>
27 struct ArgsAreConvertible : std::true_type {};
28 template <class CheckedType, class FirstArgType, class... ArgTypes>
29 struct ArgsAreConvertible<CheckedType, FirstArgType, ArgTypes...>
30 : std::conditional<std::is_convertible<FirstArgType, CheckedType>::value,
31 ArgsAreConvertible<CheckedType, ArgTypes...>,
32 std::false_type>::type {};
33
34 // If there is an argument |arg_of_type| of type Getter::ArgType in |args|,
35 // returns getter.GetValueFromArg(arg_of_type). If there are more than one
36 // argument of type |arg_of_type| in |args|, generates a compile-time error.
37 // Otherwise, returns getter.GetDefaultValue().
38 //
39 // |getter| must provide:
40 //
41 // ValueType:
42 // The return type of GetValueFromArgListImpl().
43 //
44 // ArgType:
45 // The type of the argument from which GetValueFromArgListImpl() derives its
46 // return value.
47 //
48 // ValueType GetValueFromArg(ArgType):
49 // Converts an argument of type ArgType into a value returned by
50 // GetValueFromArgListImpl().
51 //
52 // ValueType GetDefaultValue():
53 // Returns the value returned by GetValueFromArgListImpl() if none of its
54 // arguments is of type ArgType.
55 template <class GetterType, class... ArgTypes>
56 constexpr typename GetterType::ValueType GetValueFromArgList(
57 GetterType getter,
58 const ArgTypes&... args) {
59 return GetValueFromArgListImpl(CallFirstTag(), getter, args...);
60 }
61
62 // Implementation details:
63 //
64 // When the following call is made:
65 // GetValueFromArgListImpl(CallFirstTag(), GetterType(), args...);
66 // The compiler prefers using the first overload of GetValueFromArgListImpl(),
67 // because the type of the first argument matches exactly. This overload returns
68 // getter.GetValueFromArg(first_arg), where |first_arg| is the first element in
69 // |args|. If getter.GetValueFromArg(first_arg) isn't defined, the compiler uses
70 // the second or the third overload instead (depending on whether |args| is
71 // empty). The second overload discards |first_arg| and makes a recursive call
72 // to GetValueFromArgListImpl() with CallFirstTag() as first argument. The third
73 // overload returns getter.GetDefaultValue().
74 struct CallSecondTag {};
robliao 2017/04/26 21:15:54 These will unfortunately need to be moved upwards
fdoray 2017/04/27 13:26:00 Done.
75 struct CallFirstTag : CallSecondTag {};
76
77 // Overload 1: Get value from first argument. Check that no argument in |args|
78 // has the same type as |first_arg|.
79 template <class GetterType,
80 class FirstArgType,
81 class... ArgTypes,
82 class TestGetValueFromArgDefined =
83 decltype(std::declval<GetterType>().GetValueFromArg(
84 std::declval<FirstArgType>()))>
85 constexpr typename GetterType::ValueType GetValueFromArgListImpl(
86 CallFirstTag,
87 GetterType getter,
88 const FirstArgType& first_arg,
89 const ArgTypes&... args) {
90 static_assert(!HasArgOfType<FirstArgType, ArgTypes...>::value,
91 "Multiple arguments of the same type were provided to the "
92 "constructor of TaskTraits.");
93 return getter.GetValueFromArg(first_arg);
94 }
95
96 // Overload 2: Discard first argument.
97 template <class GetterType, class FirstArgType, class... ArgTypes>
98 constexpr typename GetterType::ValueType GetValueFromArgListImpl(
99 CallSecondTag,
100 GetterType getter,
101 const FirstArgType&,
102 const ArgTypes&... args) {
103 return GetValueFromArgListImpl(CallFirstTag(), getter, args...);
104 }
105
106 // Overload 3: Default value.
107 template <class GetterType>
108 constexpr typename GetterType::ValueType GetValueFromArgListImpl(
109 CallSecondTag,
110 GetterType getter) {
111 return getter.GetDefaultValue();
112 }
113
114 template <typename ArgType>
115 struct BooleanArgGetter {
116 using ValueType = bool;
117 constexpr ValueType GetValueFromArg(ArgType) const { return true; }
118 constexpr ValueType GetDefaultValue() const { return false; }
119 };
120
121 template <typename ArgType, ArgType DefaultValue>
122 struct EnumArgGetter {
123 using ValueType = ArgType;
124 constexpr ValueType GetValueFromArg(ArgType arg) const { return arg; }
125 constexpr ValueType GetDefaultValue() const { return DefaultValue; }
126 };
127
128 } // namespace internal
129 } // namespace base
130
131 #endif // BASE_TASK_SCHEDULER_TASK_TRAITS_DETAILS_H_
OLDNEW
« no previous file with comments | « base/task_scheduler/task_traits.cc ('k') | base/task_scheduler/task_traits_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698