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

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

Issue 2829083002: Add constexpr TaskTraits constructor. (Closed)
Patch Set: unretained 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 // 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 // When the following call is made:
35 // GetValueFromArgListImpl(CallFirstTag(), GetterType(), args...);
36 // The compiler prefers using the first overload of GetValueFromArgListImpl(),
37 // because the type of the first argument matches exactly. This overload returns
38 // getter.GetValueFromArg(first_arg), where |first_arg| is the first element in
39 // |args|. If getter.GetValueFromArg(first_arg) isn't defined, the compiler uses
40 // the second or the third overload instead (depending on whether |args| is
41 // empty). The second overload discards |first_arg| and makes a recursive call
42 // to GetValueFromArgListImpl() with CallFirstTag() as first argument. The third
43 // overload returns getter.GetDefaultValue().
44
45 // Tag dispatching.
46 struct CallSecondTag {};
47 struct CallFirstTag : CallSecondTag {};
48
49 // Overload 1: Get value from first argument. Check that no argument in |args|
50 // has the same type as |first_arg|.
51 template <class GetterType,
52 class FirstArgType,
53 class... ArgTypes,
54 class TestGetValueFromArgDefined =
55 decltype(std::declval<GetterType>().GetValueFromArg(
56 std::declval<FirstArgType>()))>
57 constexpr typename GetterType::ValueType GetValueFromArgListImpl(
58 CallFirstTag,
59 GetterType getter,
60 const FirstArgType& first_arg,
61 const ArgTypes&... args) {
62 static_assert(!HasArgOfType<FirstArgType, ArgTypes...>::value,
63 "Multiple arguments of the same type were provided to the "
64 "constructor of TaskTraits.");
65 return getter.GetValueFromArg(first_arg);
66 }
67
68 // Overload 2: Discard first argument.
69 template <class GetterType, class FirstArgType, class... ArgTypes>
70 constexpr typename GetterType::ValueType GetValueFromArgListImpl(
71 CallSecondTag,
72 GetterType getter,
73 const FirstArgType&,
74 const ArgTypes&... args) {
75 return GetValueFromArgListImpl(CallFirstTag(), getter, args...);
76 }
77
78 // Overload 3: Default value.
79 template <class GetterType>
80 constexpr typename GetterType::ValueType GetValueFromArgListImpl(
81 CallSecondTag,
gab 2017/04/28 18:03:40 I guess it doesn't matter that this is CallFirstTa
fdoray 2017/04/28 18:40:36 Done.
82 GetterType getter) {
83 return getter.GetDefaultValue();
84 }
85
86 // If there is an argument |arg_of_type| of type Getter::ArgType in |args|,
87 // returns getter.GetValueFromArg(arg_of_type). If there are more than one
88 // argument of type Getter::ArgType in |args|, generates a compile-time error.
89 // Otherwise, returns getter.GetDefaultValue().
90 //
91 // |getter| must provide:
92 //
93 // ValueType:
94 // The return type of GetValueFromArgListImpl().
95 //
96 // ArgType:
97 // The type of the argument from which GetValueFromArgListImpl() derives its
98 // return value.
99 //
100 // ValueType GetValueFromArg(ArgType):
101 // Converts an argument of type ArgType into a value returned by
102 // GetValueFromArgListImpl().
103 //
104 // ValueType GetDefaultValue():
105 // Returns the value returned by GetValueFromArgListImpl() if none of its
106 // arguments is of type ArgType.
107 template <class GetterType, class... ArgTypes>
108 constexpr typename GetterType::ValueType GetValueFromArgList(
109 GetterType getter,
110 const ArgTypes&... args) {
111 return GetValueFromArgListImpl(CallFirstTag(), getter, args...);
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

Powered by Google App Engine
This is Rietveld 408576698