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

Unified Diff: base/task_scheduler/task_traits_details.h

Issue 2829083002: Add constexpr TaskTraits constructor. (Closed)
Patch Set: CR-robliao-28-add-details-file 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 side-by-side diff with in-line comments
Download patch
Index: base/task_scheduler/task_traits_details.h
diff --git a/base/task_scheduler/task_traits_details.h b/base/task_scheduler/task_traits_details.h
new file mode 100644
index 0000000000000000000000000000000000000000..62507773c320ec937db0d33949db9a1b1643424d
--- /dev/null
+++ b/base/task_scheduler/task_traits_details.h
@@ -0,0 +1,97 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_TASK_SCHEDULER_TASK_TRAITS_DETAILS_H_
+#define BASE_TASK_SCHEDULER_TASK_TRAITS_DETAILS_H_
+
+#include <type_traits>
+#include <utility>
+
+namespace base {
+
gab 2017/04/25 17:48:15 Remove this empty line (consistent with EOF)
fdoray 2017/04/26 17:20:33 Done.
+namespace internal {
+
+// CheckNoArgOfType() generates a compile-time error if it receives an argument
+// of type UnwantedType. The second overload checks the type of the first
+// argument and makes a recursive call with the remaining arguments. The first
+// overload takes no argument and is used to end the recursion. Both overloads
+// return a bool because it is invalid for a constexpr function to return void.
+template <class UnwantedType>
+constexpr bool CheckNoArgOfType() {
+ return true;
+}
+
+template <class UnwantedType, class FirstArgType, class... ArgTypes>
+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.
+ 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
+ "Multiple arguments of the same type were provided to the "
+ "constructor of TaskTraits.");
+ return CheckNoArgOfType<UnwantedType>(args...);
+}
+
+// When the following call is made:
+// GetValueFromArgList(CallFirstTag(), GetterType(), args...);
+// The compiler prefers using the 3rd overload of GetValueFromArgList(), because
+// the type of the first argument matches exactly. That overload uses
+// Getter::operator()(FirstArgType) to extract a value from |first_arg|. If
+// Getter::operator()(FirstArgType) isn't defined, the compiler uses the first
+// or the second overload instead (depending on whether |args| is empty). The
+// first overload returns a default value obtained from Getter::operator()().
+// The second overload discards |first_arg| and calls back GetValueFromArgList()
+// with CallFirstTag() as first argument.
+struct CallSecondTag {};
+struct CallFirstTag : CallSecondTag {};
+
+// Overload 1: Default value.
+template <class GetterType>
+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.
+ -> decltype(getter()) {
+ return getter();
+}
+
+// Overload 2: Discard first argument.
+template <class GetterType, class FirstArgType, class... ArgTypes>
+constexpr auto GetValueFromArgList(CallSecondTag,
+ GetterType getter,
+ const FirstArgType&,
+ const ArgTypes&... args)
+ -> 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.
+ return GetValueFromArgList(CallFirstTag(), getter, args...);
+}
+
+// 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.
+// has the same type as |first_arg|.
+template <class GetterType,
+ class FirstArgType,
+ class... ArgTypes,
+ class Instantiation = decltype(
+ 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.
+constexpr typename GetterType::ValueType GetValueFromArgList(
+ CallFirstTag,
+ GetterType getter,
+ const FirstArgType& first_arg,
+ const ArgTypes&... args) {
+ // CheckNoArgOfType() is invoked as part of a comma operator statement to
+ // avoid an unused return value warning.
+ return CheckNoArgOfType<FirstArgType>(args...), getter(first_arg);
+}
+
+template <typename ArgType>
+struct BooleanArgGetter {
+ using ValueType = bool;
+ constexpr ValueType operator()(ArgType) const { return true; }
+ constexpr ValueType operator()() const { return false; }
+};
+
+template <typename ArgType, ArgType DefaultValue>
+struct EnumArgGetter {
+ using ValueType = ArgType;
+ constexpr ValueType operator()(ArgType arg) const { return arg; }
+ constexpr ValueType operator()() const { return DefaultValue; }
+};
+
+} // namespace internal
+} // namespace base
+
+#endif // BASE_TASK_SCHEDULER_TASK_TRAITS_DETAILS_H_

Powered by Google App Engine
This is Rietveld 408576698