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

Unified Diff: base/task_scheduler/task_traits_details.h

Issue 2829083002: Add constexpr TaskTraits constructor. (Closed)
Patch Set: CR-etipdoray-gab-36-38 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..e728fa64565163b537bace8de66916cf38aaad84
--- /dev/null
+++ b/base/task_scheduler/task_traits_details.h
@@ -0,0 +1,121 @@
+// 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 {
+namespace internal {
+
+// HasArgOfType<CheckedType, ArgTypes...>::value is true iff a type in ArgTypes
+// matches CheckedType.
+template <class...>
+struct HasArgOfType : std::false_type {};
+template <class CheckedType, class FirstArgType, class... ArgTypes>
+struct HasArgOfType<CheckedType, FirstArgType, ArgTypes...>
+ : std::conditional<std::is_same<CheckedType, FirstArgType>::value,
+ std::true_type,
+ HasArgOfType<ArgTypes...>>::type {};
+
+// ArgsAreConvertible<CheckedType, ArgTypes...>::value is true iff all types in
+// ArgTypes are convertible to CheckedType.
+template <class...>
+struct ArgsAreConvertible : std::true_type {};
+template <class CheckedType, class FirstArgType, class... ArgTypes>
+struct ArgsAreConvertible<CheckedType, FirstArgType, ArgTypes...>
+ : std::conditional<std::is_convertible<FirstArgType, CheckedType>::value,
+ ArgsAreConvertible<CheckedType, ArgTypes...>,
+ std::false_type>::type {};
+
+// When the following call is made:
+// GetValueFromArgList(CallFirstTag(), GetterType(), args...);
+// The compiler prefers using the first overload of GetValueFromArgList(),
+// because the type of the first argument matches exactly. This overload returns
+// getter.GetValueFromArg(first_arg), where |first_arg| is the first element in
+// |args|. If getter.GetValueFromArg(first_arg) can't be called, the compiler
+// uses the second or the third overload instead (depending on whether |args| is
+// empty). The second overload discards |first_arg| and makes a recursive call
+// to GetValueFromArgList() with CallFirstTag() as first argument. The third
+// overload returns getter.GetDefaultValue(). GetValueFromArgList() generates a
+// compile-time error if more than one of its arguments match the type of the
+// argument of getter.GetValueFromArg().
+//
+// |getter| must provide:
+//
+// ValueType:
+// The return type of GetValueFromArgList().
+//
+// ArgType:
+// The type of the argument from which GetValueFromArgList() derives its
+// return value.
+//
+// ValueType GetValueFromArg(ArgType):
+// Converts an argument of type ArgType into a value returned by
+// GetValueFromArgList().
+//
+// ValueType GetDefaultValue():
+// Returns the value returned by GetValueFromArgList() if none of its
+// arguments is of type ArgType.
+
+struct CallSecondTag {};
+struct CallFirstTag : CallSecondTag {};
robliao 2017/04/26 19:45:54 To make sure I understand this correctly, these ar
fdoray 2017/04/26 20:25:14 Done.
+
+// Overload 1: Get value from first argument. Check that no argument in |args|
+// has the same type as |first_arg|.
+template <class GetterType,
+ class FirstArgType,
+ class... ArgTypes,
+ class TestGetValueFromArgDefined =
+ decltype(std::declval<GetterType>().GetValueFromArg(
+ std::declval<FirstArgType>()))>
+constexpr typename GetterType::ValueType GetValueFromArgList(
+ CallFirstTag,
+ GetterType getter,
+ const FirstArgType& first_arg,
+ const ArgTypes&... args) {
+ static_assert(!HasArgOfType<FirstArgType, ArgTypes...>::value,
+ "Multiple arguments of the same type were provided to the "
+ "constructor of TaskTraits.");
+ return getter.GetValueFromArg(first_arg);
+}
+
+// Overload 2: Discard first argument.
+template <class GetterType, class FirstArgType, class... ArgTypes>
+constexpr typename GetterType::ValueType GetValueFromArgList(
+ CallSecondTag,
+ GetterType getter,
+ const FirstArgType&,
+ const ArgTypes&... args) {
+ return GetValueFromArgList(CallFirstTag(), getter, args...);
+}
+
+// Overload 3: Default value.
+template <class GetterType>
+constexpr typename GetterType::ValueType GetValueFromArgList(
+ CallSecondTag,
+ GetterType getter) {
+ return getter.GetDefaultValue();
+}
+
+template <typename ArgType>
+struct BooleanArgGetter {
+ using ValueType = bool;
+ constexpr ValueType GetValueFromArg(ArgType) const { return true; }
+ constexpr ValueType GetDefaultValue() const { return false; }
+};
+
+template <typename ArgType, ArgType DefaultValue>
+struct EnumArgGetter {
+ using ValueType = ArgType;
+ constexpr ValueType GetValueFromArg(ArgType arg) const { return arg; }
+ constexpr ValueType GetDefaultValue() const { return DefaultValue; }
+};
+
+} // namespace internal
+} // namespace base
+
+#endif // BASE_TASK_SCHEDULER_TASK_TRAITS_DETAILS_H_

Powered by Google App Engine
This is Rietveld 408576698