aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2016-01-05 14:59:40 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-01-05 14:59:40 -0800
commit221524de3be1fc343ad328c5e99562f32b5cad9c (patch)
treed9b791db0ff48921388d2b7443fd5fc58f0b9583 /include
parent3c1468188924ede1e6589cddee84031c16782226 (diff)
Start using <type_traits> and <utility> (C++11).
SkUtility.h and SkTLogic.h implement a number of type traits now available through <type_traits> and <utility>. This removes SkUtility.h, replacing it with <utility>, and moves a number of traits in SkTLogic.h to use the std:: equivelents. This change only uses C++11 parts of the standard library; SkTLogic.h will continue to provide C++14 and beyond for now in the skstd namespace. The changes to SkTLogic.h are being done gradually so that safe changes may be landed confidently, with more risky changes in the future. Review URL: https://codereview.chromium.org/1561683002
Diffstat (limited to 'include')
-rw-r--r--include/core/SkTArray.h3
-rw-r--r--include/core/SkTLazy.h3
-rw-r--r--include/private/SkTLogic.h138
-rw-r--r--include/private/SkTemplates.h1
-rw-r--r--include/private/SkUniquePtr.h47
-rw-r--r--include/private/SkUtility.h32
6 files changed, 77 insertions, 147 deletions
diff --git a/include/core/SkTArray.h b/include/core/SkTArray.h
index 9f1bfa1ac1..17cbc5c05c 100644
--- a/include/core/SkTArray.h
+++ b/include/core/SkTArray.h
@@ -12,6 +12,7 @@
#include "SkTypes.h"
#include <new>
+#include <utility>
template <typename T, bool MEM_COPY = false> class SkTArray;
@@ -198,7 +199,7 @@ public:
*/
template<class... Args> T& emplace_back(Args&&... args) {
T* newT = reinterpret_cast<T*>(this->push_back_raw(1));
- return *new (newT) T(skstd::forward<Args>(args)...);
+ return *new (newT) T(std::forward<Args>(args)...);
}
/**
diff --git a/include/core/SkTLazy.h b/include/core/SkTLazy.h
index 60d816147f..c8ae3178f7 100644
--- a/include/core/SkTLazy.h
+++ b/include/core/SkTLazy.h
@@ -11,6 +11,7 @@
#include "../private/SkTemplates.h"
#include "SkTypes.h"
#include <new>
+#include <utility>
/**
* Efficient way to defer allocating/initializing a class until it is needed
@@ -50,7 +51,7 @@ public:
if (this->isValid()) {
fPtr->~T();
}
- fPtr = new (SkTCast<T*>(fStorage.get())) T(skstd::forward<Args>(args)...);
+ fPtr = new (SkTCast<T*>(fStorage.get())) T(std::forward<Args>(args)...);
return fPtr;
}
diff --git a/include/private/SkTLogic.h b/include/private/SkTLogic.h
index 9c21db6756..8d07ba1d38 100644
--- a/include/private/SkTLogic.h
+++ b/include/private/SkTLogic.h
@@ -5,9 +5,10 @@
* found in the LICENSE file.
*
*
- * This header provides some of the helpers (std::integral_constant) and
- * type transformations (std::conditional) which will become available with
- * C++11 in the type_traits header.
+ * This header provides some of the helpers (like std::enable_if_t) which will
+ * become available with C++14 in the type_traits header (in the skstd
+ * namespace). This header also provides several Skia specific additions such
+ * as SK_WHEN and the sknonstd namespace.
*/
#ifndef SkTLogic_DEFINED
@@ -17,77 +18,46 @@
#include <stddef.h>
#include <stdint.h>
+#include <type_traits>
+#include <utility>
namespace skstd {
-using nullptr_t = decltype(nullptr);
+template <bool B> using bool_constant = std::integral_constant<bool, B>;
-template <typename T, T v> struct integral_constant {
- static const/*expr*/ T value = v;
- using value_type = T;
- using type = integral_constant<T, v>;
- //constexpr operator value_type() const noexcept { return value; }
- //constexpr value_type operator()() const noexcept { return value; }
-};
-
-template <bool B> using bool_constant = integral_constant<bool, B>;
-
-using true_type = bool_constant<true>;
-using false_type = bool_constant<false>;
-
-template <bool B, typename T, typename F> struct conditional { using type = T; };
-template <typename T, typename F> struct conditional<false, T, F> { using type = F; };
-template <bool B, typename T, typename F> using conditional_t = typename conditional<B, T, F>::type;
-
-template <bool B, typename T = void> struct enable_if { using type = T; };
-template <typename T> struct enable_if<false, T> {};
-template <bool B, typename T = void> using enable_if_t = typename enable_if<B, T>::type;
-
-template <typename T> struct remove_const { using type = T; };
-template <typename T> struct remove_const<const T> { using type = T; };
-template <typename T> using remove_const_t = typename remove_const<T>::type;
-
-template <typename T> struct remove_volatile { using type = T; };
-template <typename T> struct remove_volatile<volatile T> { using type = T; };
-template <typename T> using remove_volatile_t = typename remove_volatile<T>::type;
+template <bool B, typename T, typename F> using conditional_t = typename std::conditional<B, T, F>::type;
+template <bool B, typename T = void> using enable_if_t = typename std::enable_if<B, T>::type;
-template <typename T> struct remove_cv { using type = remove_volatile_t<remove_const_t<T>>; };
-template <typename T> using remove_cv_t = typename remove_cv<T>::type;
+template <typename T> using remove_const_t = typename std::remove_const<T>::type;
+template <typename T> using remove_volatile_t = typename std::remove_volatile<T>::type;
+template <typename T> using remove_cv_t = typename std::remove_cv<T>::type;
+template <typename T> using remove_reference_t = typename std::remove_reference<T>::type;
+template <typename T> using remove_extent_t = typename std::remove_extent<T>::type;
-template <typename T> struct remove_reference { using type = T; };
-template <typename T> struct remove_reference<T&> { using type = T; };
-template <typename T> struct remove_reference<T&&> { using type = T; };
-template <typename T> using remove_reference_t = typename remove_reference<T>::type;
-
-template <typename T> struct remove_extent { using type = T; };
-template <typename T> struct remove_extent<T[]> { using type = T; };
-template <typename T, size_t N> struct remove_extent<T[N]> { using type = T;};
-template <typename T> using remove_extent_t = typename remove_extent<T>::type;
-
-template <typename T, typename U> struct is_same : false_type {};
-template <typename T> struct is_same<T, T> : true_type {};
+template <typename T, typename U> struct is_same : std::false_type {};
+template <typename T> struct is_same<T, T> : std::true_type {};
template <typename T> struct is_void : is_same<void, remove_cv_t<T>> {};
-template <typename T> struct is_const : false_type {};
-template <typename T> struct is_const<const T> : true_type {};
+template <typename T> struct is_const : std::false_type {};
+template <typename T> struct is_const<const T> : std::true_type {};
-template <typename T> struct is_volatile : false_type {};
-template <typename T> struct is_volatile<volatile T> : true_type {};
+template <typename T> struct is_volatile : std::false_type {};
+template <typename T> struct is_volatile<volatile T> : std::true_type {};
-template <typename T> struct is_pointer_detector : false_type {};
-template <typename T> struct is_pointer_detector<T*> : true_type {};
+template <typename T> struct is_pointer_detector : std::false_type {};
+template <typename T> struct is_pointer_detector<T*> : std::true_type {};
template <typename T> struct is_pointer : is_pointer_detector<remove_cv_t<T>> {};
-template <typename T> struct is_reference : false_type {};
-template <typename T> struct is_reference<T&> : true_type {};
-template <typename T> struct is_reference<T&&> : true_type {};
+template <typename T> struct is_reference : std::false_type {};
+template <typename T> struct is_reference<T&> : std::true_type {};
+template <typename T> struct is_reference<T&&> : std::true_type {};
-template <typename T> struct is_lvalue_reference : false_type {};
-template <typename T> struct is_lvalue_reference<T&> : true_type {};
+template <typename T> struct is_lvalue_reference : std::false_type {};
+template <typename T> struct is_lvalue_reference<T&> : std::true_type {};
-template <typename T> struct is_rvalue_reference : false_type {};
-template <typename T> struct is_rvalue_reference<T&&> : true_type {};
+template <typename T> struct is_rvalue_reference : std::false_type {};
+template <typename T> struct is_rvalue_reference<T&&> : std::true_type {};
template <typename T> struct is_class_detector {
using yes_type = uint8_t;
@@ -107,47 +77,40 @@ template <typename T> struct is_empty_detector<T, false> {
};
template <typename T> struct is_empty : bool_constant<is_empty_detector<T>::value> {};
-template <typename T> struct is_array : false_type {};
-template <typename T> struct is_array<T[]> : true_type {};
-template <typename T, size_t N> struct is_array<T[N]> : true_type {};
+template <typename T> struct is_array : std::false_type {};
+template <typename T> struct is_array<T[]> : std::true_type {};
+template <typename T, size_t N> struct is_array<T[N]> : std::true_type {};
// template<typename R, typename... Args> struct is_function<
-// R [calling-convention] (Args...[, ...]) [const] [volatile] [&|&&]> : true_type {};
+// R [calling-convention] (Args...[, ...]) [const] [volatile] [&|&&]> : std::true_type {};
// The cv and ref-qualified versions are strange types we're currently avoiding, so not supported.
// On all platforms, variadic functions only exist in the c calling convention.
-template <typename> struct is_function : false_type { };
+template <typename> struct is_function : std::false_type {};
#if !defined(SK_BUILD_FOR_WIN)
-template <typename R, typename... Args> struct is_function<R(Args...)> : true_type {};
+template <typename R, typename... Args> struct is_function<R(Args...)> : std::true_type {};
#else
#if defined(_M_IX86)
-template <typename R, typename... Args> struct is_function<R __cdecl (Args...)> : true_type {};
-template <typename R, typename... Args> struct is_function<R __stdcall (Args...)> : true_type {};
-template <typename R, typename... Args> struct is_function<R __fastcall (Args...)> : true_type {};
+template <typename R, typename... Args> struct is_function<R __cdecl (Args...)> : std::true_type {};
+template <typename R, typename... Args> struct is_function<R __stdcall (Args...)> : std::true_type {};
+template <typename R, typename... Args> struct is_function<R __fastcall (Args...)> : std::true_type {};
#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
-template <typename R, typename... Args> struct is_function<R __vectorcall (Args...)> : true_type {};
+template <typename R, typename... Args> struct is_function<R __vectorcall (Args...)> : std::true_type {};
#endif
#else
-template <typename R, typename... Args> struct is_function<R __cdecl (Args...)> : true_type {};
-template <typename R, typename... Args> struct is_function<R __vectorcall (Args...)> : true_type {};
+template <typename R, typename... Args> struct is_function<R __cdecl (Args...)> : std::true_type {};
+template <typename R, typename... Args> struct is_function<R __vectorcall (Args...)> : std::true_type {};
#endif
#endif
-template <typename R, typename... Args> struct is_function<R(Args..., ...)> : true_type {};
-
-template <typename T> struct add_const { using type = const T; };
-template <typename T> using add_const_t = typename add_const<T>::type;
+template <typename R, typename... Args> struct is_function<R(Args..., ...)> : std::true_type {};
-template <typename T> struct add_volatile { using type = volatile T; };
-template <typename T> using add_volatile_t = typename add_volatile<T>::type;
-
-template <typename T> struct add_cv { using type = add_volatile_t<add_const_t<T>>; };
-template <typename T> using add_cv_t = typename add_cv<T>::type;
-
-template <typename T> struct add_pointer { using type = remove_reference_t<T>*; };
-template <typename T> using add_pointer_t = typename add_pointer<T>::type;
+template <typename T> using add_const_t = typename std::add_const<T>::type;
+template <typename T> using add_volatile_t = typename std::add_volatile<T>::type;
+template <typename T> using add_cv_t = typename std::add_cv<T>::type;
+template <typename T> using add_pointer_t = typename std::add_pointer<T>::type;
template <typename T, bool=is_void<T>::value> struct add_lvalue_reference_init { using type = T; };
template <typename T> struct add_lvalue_reference_init<T, false> { using type = T&; };
-template <typename T> struct add_lvalue_reference : add_lvalue_reference_init<T> { };
+template <typename T> struct add_lvalue_reference : add_lvalue_reference_init<T> {};
template <typename T> using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
template <typename T, bool=is_void<T>::value> struct add_rvalue_reference_init { using type = T; };
@@ -155,9 +118,6 @@ template <typename T> struct add_rvalue_reference_init<T, false> { using type =
template <typename T> struct add_rvalue_reference : add_rvalue_reference_init<T> {};
template <typename T> using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
-/* This is 'just' a forward declaration. */
-template <typename T> add_rvalue_reference_t<T> declval() /*noexcept*/;
-
template <typename S, typename D, bool=is_void<S>::value||is_function<D>::value||is_array<D>::value>
struct is_convertible_detector {
static const/*expr*/ bool value = is_void<D>::value;
@@ -169,14 +129,14 @@ template <typename S, typename D> struct is_convertible_detector<S, D, false> {
template <typename To> static void param_convertable_to(To);
template <typename From, typename To>
- static decltype(param_convertable_to<To>(declval<From>()), yes_type()) convertible(int);
+ static decltype(param_convertable_to<To>(std::declval<From>()), yes_type()) convertible(int);
template <typename, typename> static no_type convertible(...);
static const/*expr*/ bool value = sizeof(convertible<S, D>(0)) == sizeof(yes_type);
};
template<typename S, typename D> struct is_convertible
- : bool_constant<is_convertible_detector<S, D>::value> { };
+ : bool_constant<is_convertible_detector<S, D>::value> {};
template <typename T> struct decay {
using U = remove_reference_t<T>;
diff --git a/include/private/SkTemplates.h b/include/private/SkTemplates.h
index c1fd4cbca6..496cf42733 100644
--- a/include/private/SkTemplates.h
+++ b/include/private/SkTemplates.h
@@ -14,7 +14,6 @@
#include "SkTLogic.h"
#include "SkTypes.h"
#include "SkUniquePtr.h"
-#include "SkUtility.h"
#include <limits.h>
#include <new>
diff --git a/include/private/SkUniquePtr.h b/include/private/SkUniquePtr.h
index 5d6e722658..a824639855 100644
--- a/include/private/SkUniquePtr.h
+++ b/include/private/SkUniquePtr.h
@@ -9,7 +9,8 @@
#define SkUniquePtr_DEFINED
#include "SkTLogic.h"
-#include "SkUtility.h"
+#include <cstddef>
+#include <utility>
namespace skstd {
@@ -51,7 +52,7 @@ private:
struct compressed_base : private B {
/*constexpr*/ compressed_base() : B() {}
/*constexpr*/ compressed_base(const B& b) : B(b) {}
- /*constexpr*/ compressed_base(const B&& b) : B(move(b)) {}
+ /*constexpr*/ compressed_base(B&& b) : B(std::move(b)) {}
/*constexpr*/ B& get() /*noexcept*/ { return *this; }
/*constexpr*/ B const& get() const /*noexcept*/ { return *this; }
void swap(compressed_base&) /*noexcept*/ { }
@@ -61,7 +62,7 @@ private:
B fb;
/*constexpr*/ compressed_base() : B() {}
/*constexpr*/ compressed_base(const B& b) : fb(b) {}
- /*constexpr*/ compressed_base(const B&& b) : fb(move(b)) {}
+ /*constexpr*/ compressed_base(B&& b) : fb(std::move(b)) {}
/*constexpr*/ B& get() /*noexcept*/ { return fb; }
/*constexpr*/ B const& get() const /*noexcept*/ { return fb; }
void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); }
@@ -75,7 +76,7 @@ private:
template <typename U1, typename U2, typename = enable_if_t<
is_convertible<U1, pointer>::value && is_convertible<U2, deleter_type>::value
>> /*constexpr*/ compressed_data(U1&& ptr, U2&& d)
- : compressed_base<deleter_type>(skstd::forward<U2>(d)), fPtr(skstd::forward<U1>(ptr)) {}
+ : compressed_base<deleter_type>(std::forward<U2>(d)), fPtr(std::forward<U1>(ptr)) {}
/*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; }
/*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fPtr; }
/*constexpr*/ deleter_type& getDeleter() /*noexcept*/ {
@@ -96,7 +97,7 @@ public:
static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr function pointer!");
}
- /*constexpr*/ unique_ptr(skstd::nullptr_t) /*noexcept*/ : unique_ptr() { }
+ /*constexpr*/ unique_ptr(std::nullptr_t) /*noexcept*/ : unique_ptr() { }
explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) {
static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr function pointer!");
@@ -108,7 +109,7 @@ public:
{}
unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/
- : data(move(ptr), move(d))
+ : data(std::move(ptr), std::move(d))
{
static_assert(!is_reference<deleter_type>::value,
"Binding an rvalue reference deleter as an lvalue reference deleter is not allowed.");
@@ -116,7 +117,7 @@ public:
unique_ptr(unique_ptr&& that) /*noexcept*/
- : data(that.release(), forward<deleter_type>(that.get_deleter()))
+ : data(that.release(), std::forward<deleter_type>(that.get_deleter()))
{}
template <typename U, typename ThatD, typename = enable_if_t<
@@ -124,7 +125,7 @@ public:
!is_array<U>::value &&
conditional_t<is_reference<D>::value, is_same<ThatD, D>, is_convertible<ThatD, D>>::value>>
unique_ptr(unique_ptr<U, ThatD>&& that) /*noexcept*/
- : data(that.release(), forward<ThatD>(that.get_deleter()))
+ : data(that.release(), std::forward<ThatD>(that.get_deleter()))
{}
~unique_ptr() /*noexcept*/ {
@@ -137,7 +138,7 @@ public:
unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ {
reset(that.release());
- get_deleter() = forward<deleter_type>(that.get_deleter());
+ get_deleter() = std::forward<deleter_type>(that.get_deleter());
return *this;
}
@@ -146,11 +147,11 @@ public:
!is_array<U>::value,
unique_ptr&> operator=(unique_ptr<U, ThatD>&& that) /*noexcept*/ {
reset(that.release());
- get_deleter() = forward<ThatD>(that.get_deleter());
+ get_deleter() = std::forward<ThatD>(that.get_deleter());
return *this;
}
- unique_ptr& operator=(skstd::nullptr_t) /*noexcept*/ {
+ unique_ptr& operator=(std::nullptr_t) /*noexcept*/ {
reset();
return *this;
}
@@ -221,7 +222,7 @@ private:
struct compressed_base : private B {
/*constexpr*/ compressed_base() : B() {}
/*constexpr*/ compressed_base(const B& b) : B(b) {}
- /*constexpr*/ compressed_base(const B&& b) : B(move(b)) {}
+ /*constexpr*/ compressed_base(B&& b) : B(std::move(b)) {}
/*constexpr*/ B& get() /*noexcept*/ { return *this; }
/*constexpr*/ B const& get() const /*noexcept*/ { return *this; }
void swap(compressed_base&) /*noexcept*/ { }
@@ -231,7 +232,7 @@ private:
B fb;
/*constexpr*/ compressed_base() : B() {}
/*constexpr*/ compressed_base(const B& b) : fb(b) {}
- /*constexpr*/ compressed_base(const B&& b) : fb(move(b)) {}
+ /*constexpr*/ compressed_base(B&& b) : fb(std::move(b)) {}
/*constexpr*/ B& get() /*noexcept*/ { return fb; }
/*constexpr*/ B const& get() const /*noexcept*/ { return fb; }
void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); }
@@ -245,7 +246,7 @@ private:
template <typename U1, typename U2, typename = enable_if_t<
is_convertible<U1, pointer>::value && is_convertible<U2, deleter_type>::value
>> /*constexpr*/ compressed_data(U1&& ptr, U2&& d)
- : compressed_base<deleter_type>(skstd::forward<U2>(d)), fPtr(skstd::forward<U1>(ptr)) {}
+ : compressed_base<deleter_type>(std::forward<U2>(d)), fPtr(std::forward<U1>(ptr)) {}
/*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; }
/*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fPtr; }
/*constexpr*/ deleter_type& getDeleter() /*noexcept*/ {
@@ -266,7 +267,7 @@ public:
static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr function pointer!");
}
- /*constexpr*/ unique_ptr(skstd::nullptr_t) /*noexcept*/ : unique_ptr() { }
+ /*constexpr*/ unique_ptr(std::nullptr_t) /*noexcept*/ : unique_ptr() { }
explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) {
static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr function pointer!");
@@ -278,14 +279,14 @@ public:
{}
unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/
- : data(move(ptr), move(d))
+ : data(std::move(ptr), std::move(d))
{
static_assert(!is_reference<deleter_type>::value,
"Binding an rvalue reference deleter as an lvalue reference deleter is not allowed.");
}
unique_ptr(unique_ptr&& that) /*noexcept*/
- : data(that.release(), forward<deleter_type>(that.get_deleter()))
+ : data(that.release(), std::forward<deleter_type>(that.get_deleter()))
{}
~unique_ptr() {
@@ -298,11 +299,11 @@ public:
unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ {
reset(that.release());
- get_deleter() = forward<deleter_type>(that.get_deleter());
+ get_deleter() = std::forward<deleter_type>(that.get_deleter());
return *this;
}
- unique_ptr& operator=(skstd::nullptr_t) /*noexcept*/ {
+ unique_ptr& operator=(std::nullptr_t) /*noexcept*/ {
reset();
return *this;
}
@@ -363,13 +364,13 @@ inline bool operator==(const unique_ptr<T, D>& a, const unique_ptr<U, ThatD>& b)
}
template <typename T, typename D>
-inline bool operator==(const unique_ptr<T, D>& a, skstd::nullptr_t) /*noexcept*/ {
+inline bool operator==(const unique_ptr<T, D>& a, std::nullptr_t) /*noexcept*/ {
//return !a;
return !a.is_attached();
}
template <typename T, typename D>
-inline bool operator==(skstd::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
+inline bool operator==(std::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
//return !b;
return !b.is_attached();
}
@@ -380,13 +381,13 @@ inline bool operator!=(const unique_ptr<T, D>& a, const unique_ptr<U, ThatD>& b)
}
template <typename T, typename D>
-inline bool operator!=(const unique_ptr<T, D>& a, skstd::nullptr_t) /*noexcept*/ {
+inline bool operator!=(const unique_ptr<T, D>& a, std::nullptr_t) /*noexcept*/ {
//return (bool)a;
return a.is_attached();
}
template <typename T, typename D>
-inline bool operator!=(skstd::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
+inline bool operator!=(std::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
//return (bool)b;
return b.is_attached();
}
diff --git a/include/private/SkUtility.h b/include/private/SkUtility.h
deleted file mode 100644
index a96e8fe292..0000000000
--- a/include/private/SkUtility.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkUtility_DEFINED
-#define SkUtility_DEFINED
-
-#include "SkTLogic.h"
-
-namespace skstd {
-
-template <typename T> inline remove_reference_t<T>&& move(T&& t) {
- return static_cast<remove_reference_t<T>&&>(t);
-}
-
-template <typename T> inline T&& forward(remove_reference_t<T>& t) /*noexcept*/ {
- return static_cast<T&&>(t);
-}
-template <typename T> inline T&& forward(remove_reference_t<T>&& t) /*noexcept*/ {
- static_assert(!is_lvalue_reference<T>::value,
- "Forwarding an rvalue reference as an lvalue reference is not allowed.");
- return static_cast<T&&>(t);
-}
-
-template <typename T> add_rvalue_reference_t<T> declval();
-
-} // namespace skstd
-
-#endif