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

Unified Diff: base/task_scheduler/task_traits_details.h

Issue 2829083002: Add constexpr TaskTraits constructor. (Closed)
Patch Set: remove-comma 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
« no previous file with comments | « base/task_scheduler/task_traits.cc ('k') | base/task_scheduler/task_traits_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..05fb60568b193babe5c3364cacb8171327920e25
--- /dev/null
+++ b/base/task_scheduler/task_traits_details.h
@@ -0,0 +1,128 @@
+// 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...);
+// If |args| is empty, the compiler selects the first overload. This overload
+// returns getter.GetDefaultValue(). If |args| is not empty, the compiler
+// prefers using the second overload 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 third
+// overload instead. This overload discards the first argument in |args| and
+// makes a recursive call to GetValueFromArgListImpl() with CallFirstTag() as
+// first argument.
+
+// Tag dispatching.
+struct CallSecondTag {};
+struct CallFirstTag : CallSecondTag {};
+
+// Overload 1: Default value.
+template <class GetterType>
+constexpr typename GetterType::ValueType GetValueFromArgListImpl(
+ CallFirstTag,
+ GetterType getter) {
+ return getter.GetDefaultValue();
+}
+
+// Overload 2: 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 3: 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...);
+}
+
+// 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_
« no previous file with comments | « base/task_scheduler/task_traits.cc ('k') | base/task_scheduler/task_traits_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698