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

Unified Diff: base/task_scheduler/task_traits_details.h

Issue 2829083002: Add constexpr TaskTraits constructor. (Closed)
Patch Set: CR gab 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..52f23c3a2f12b3d4a5bebf039caa514f11bd30a4
--- /dev/null
+++ b/base/task_scheduler/task_traits_details.h
@@ -0,0 +1,127 @@
+// 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<CheckedType, ArgTypes...>>::type {};
+
+// When the following call is made:
+// GetValueFromArgListImpl(CallFirstTag(), GetterType(), args...);
+// The compiler prefers using the first overload of GetValueFromArgListImpl(),
+// 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) isn't defined, 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 GetValueFromArgListImpl() with CallFirstTag() as first argument. The third
+// overload returns getter.GetDefaultValue().
+
+// Tag dispatching.
+struct CallSecondTag {};
+struct CallFirstTag : CallSecondTag {};
+
+// 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 GetValueFromArgListImpl(
+ 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 GetValueFromArgListImpl(
+ CallSecondTag,
+ GetterType getter,
+ const FirstArgType&,
+ const ArgTypes&... args) {
+ return GetValueFromArgListImpl(CallFirstTag(), getter, args...);
+}
+
+// Overload 3: Default value.
+template <class GetterType>
+constexpr typename GetterType::ValueType GetValueFromArgListImpl(
+ CallFirstTag,
gab 2017/04/28 19:00:31 I meant to reorder this to be Overload 1 so that l
fdoray 2017/05/01 17:13:10 Done.
+ GetterType getter) {
+ return getter.GetDefaultValue();
+}
+
+// If there is an argument |arg_of_type| of type Getter::ArgType in |args|,
+// returns getter.GetValueFromArg(arg_of_type). If there are more than one
+// argument of type Getter::ArgType in |args|, generates a compile-time error.
+// Otherwise, returns getter.GetDefaultValue().
+//
+// |getter| must provide:
+//
+// ValueType:
+// The return type of GetValueFromArgListImpl().
+//
+// ArgType:
+// The type of the argument from which GetValueFromArgListImpl() derives its
+// return value.
+//
+// ValueType GetValueFromArg(ArgType):
+// Converts an argument of type ArgType into a value returned by
+// GetValueFromArgListImpl().
+//
+// ValueType GetDefaultValue():
+// Returns the value returned by GetValueFromArgListImpl() if none of its
+// arguments is of type ArgType.
+template <class GetterType, class... ArgTypes>
+constexpr typename GetterType::ValueType GetValueFromArgList(
+ GetterType getter,
+ const ArgTypes&... args) {
+ return GetValueFromArgListImpl(CallFirstTag(), getter, args...);
+}
+
+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; }
+};
+
+// Allows instantiation of multiple types in one statement. Used to prevent
+// instantiation of the constructor of TaskTraits with inappropriate argument
+// types.
+template <class...>
+struct InitTypes {};
+
+} // namespace internal
+} // namespace base
+
+#endif // BASE_TASK_SCHEDULER_TASK_TRAITS_DETAILS_H_

Powered by Google App Engine
This is Rietveld 408576698