Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 | |
|
gab
2017/04/25 17:48:15
Remove this empty line (consistent with EOF)
fdoray
2017/04/26 17:20:33
Done.
| |
| 13 namespace internal { | |
| 14 | |
| 15 // CheckNoArgOfType() generates a compile-time error if it receives an argument | |
| 16 // of type UnwantedType. The second overload checks the type of the first | |
| 17 // argument and makes a recursive call with the remaining arguments. The first | |
| 18 // overload takes no argument and is used to end the recursion. Both overloads | |
| 19 // return a bool because it is invalid for a constexpr function to return void. | |
| 20 template <class UnwantedType> | |
| 21 constexpr bool CheckNoArgOfType() { | |
| 22 return true; | |
| 23 } | |
| 24 | |
| 25 template <class UnwantedType, class FirstArgType, class... ArgTypes> | |
| 26 constexpr bool CheckNoArgOfType(const FirstArgType&, const ArgTypes&... args) { | |
|
etipdoray
2017/04/24 20:22:02
CheckNoArgOfType can be implemented without recurs
fdoray
2017/04/26 17:20:33
Done.
| |
| 27 static_assert(!std::is_same<UnwantedType, FirstArgType>::value, | |
|
etipdoray
2017/04/24 20:22:02
It would be best to check instead if the associate
fdoray
2017/04/26 17:20:33
not possible in c++11
| |
| 28 "Multiple arguments of the same type were provided to the " | |
| 29 "constructor of TaskTraits."); | |
| 30 return CheckNoArgOfType<UnwantedType>(args...); | |
| 31 } | |
| 32 | |
| 33 // When the following call is made: | |
| 34 // GetValueFromArgList(CallFirstTag(), GetterType(), args...); | |
| 35 // The compiler prefers using the 3rd overload of GetValueFromArgList(), because | |
| 36 // the type of the first argument matches exactly. That overload uses | |
| 37 // Getter::operator()(FirstArgType) to extract a value from |first_arg|. If | |
| 38 // Getter::operator()(FirstArgType) isn't defined, the compiler uses the first | |
| 39 // or the second overload instead (depending on whether |args| is empty). The | |
| 40 // first overload returns a default value obtained from Getter::operator()(). | |
| 41 // The second overload discards |first_arg| and calls back GetValueFromArgList() | |
| 42 // with CallFirstTag() as first argument. | |
| 43 struct CallSecondTag {}; | |
| 44 struct CallFirstTag : CallSecondTag {}; | |
| 45 | |
| 46 // Overload 1: Default value. | |
| 47 template <class GetterType> | |
| 48 constexpr auto GetValueFromArgList(CallSecondTag, GetterType getter) | |
|
gab
2017/04/25 17:48:15
I think
constexpr GetterType GetValueFromArgList(
fdoray
2017/04/26 17:20:33
Done.
| |
| 49 -> decltype(getter()) { | |
| 50 return getter(); | |
| 51 } | |
| 52 | |
| 53 // Overload 2: Discard first argument. | |
| 54 template <class GetterType, class FirstArgType, class... ArgTypes> | |
| 55 constexpr auto GetValueFromArgList(CallSecondTag, | |
| 56 GetterType getter, | |
| 57 const FirstArgType&, | |
| 58 const ArgTypes&... args) | |
| 59 -> decltype(GetValueFromArgList(CallFirstTag(), getter, args...)) { | |
|
gab
2017/04/25 17:48:15
Actually, isn't the return value of these 3 method
fdoray
2017/04/26 17:20:33
Done.
| |
| 60 return GetValueFromArgList(CallFirstTag(), getter, args...); | |
| 61 } | |
| 62 | |
| 63 // Overload 3: Get value from first argument. Check that no argument in |args| | |
|
gab
2017/04/25 17:48:15
Since the intent is for this one to match first an
fdoray
2017/04/26 17:20:33
Done.
| |
| 64 // has the same type as |first_arg|. | |
| 65 template <class GetterType, | |
| 66 class FirstArgType, | |
| 67 class... ArgTypes, | |
| 68 class Instantiation = decltype( | |
| 69 std::declval<GetterType>()(std::declval<FirstArgType>()))> | |
|
gab
2017/04/25 17:48:15
Document in meta-comment of this file what GetterT
fdoray
2017/04/26 17:20:33
Done.
| |
| 70 constexpr typename GetterType::ValueType GetValueFromArgList( | |
| 71 CallFirstTag, | |
| 72 GetterType getter, | |
| 73 const FirstArgType& first_arg, | |
| 74 const ArgTypes&... args) { | |
| 75 // CheckNoArgOfType() is invoked as part of a comma operator statement to | |
| 76 // avoid an unused return value warning. | |
| 77 return CheckNoArgOfType<FirstArgType>(args...), getter(first_arg); | |
| 78 } | |
| 79 | |
| 80 template <typename ArgType> | |
| 81 struct BooleanArgGetter { | |
| 82 using ValueType = bool; | |
| 83 constexpr ValueType operator()(ArgType) const { return true; } | |
| 84 constexpr ValueType operator()() const { return false; } | |
| 85 }; | |
| 86 | |
| 87 template <typename ArgType, ArgType DefaultValue> | |
| 88 struct EnumArgGetter { | |
| 89 using ValueType = ArgType; | |
| 90 constexpr ValueType operator()(ArgType arg) const { return arg; } | |
| 91 constexpr ValueType operator()() const { return DefaultValue; } | |
| 92 }; | |
| 93 | |
| 94 } // namespace internal | |
| 95 } // namespace base | |
| 96 | |
| 97 #endif // BASE_TASK_SCHEDULER_TASK_TRAITS_DETAILS_H_ | |
| OLD | NEW |