/*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#pragma once
+#include <cstdint>
#include <type_traits>
#include <utility>
noexcept(typename std::decay<T>::type(std::forward<T>(value)))) {
return std::forward<T>(value);
}
+
+/**
+ * A simple helper for getting a constant reference to an object.
+ *
+ * Example:
+ *
+ * std::vector<int> v{1,2,3};
+ * // The following two lines are equivalent:
+ * auto a = const_cast<const std::vector<int>&>(v).begin();
+ * auto b = folly::as_const(v).begin();
+ *
+ * Like C++17's std::as_const. See http://wg21.link/p0007
+ */
+#if __cpp_lib_as_const || _MSC_VER
+
+/* using override */ using std::as_const;
+
+#else
+
+template <class T>
+constexpr T const& as_const(T& t) noexcept {
+ return t;
+}
+
+template <class T>
+void as_const(T const&&) = delete;
+
+#endif
+
+#if __cpp_lib_integer_sequence || _MSC_VER
+
+/* using override */ using std::integer_sequence;
+/* using override */ using std::index_sequence;
+/* using override */ using std::make_index_sequence;
+
+#else
+
+template <class T, T... Ints>
+struct integer_sequence {
+ using value_type = T;
+
+ static constexpr std::size_t size() noexcept {
+ return sizeof...(Ints);
+ }
+};
+
+template <std::size_t... Ints>
+using index_sequence = folly::integer_sequence<std::size_t, Ints...>;
+
+namespace detail {
+template <std::size_t N, std::size_t... Ints>
+struct make_index_sequence
+ : detail::make_index_sequence<N - 1, N - 1, Ints...> {};
+
+template <std::size_t... Ints>
+struct make_index_sequence<0, Ints...> : folly::index_sequence<Ints...> {};
+}
+
+template <std::size_t N>
+using make_index_sequence = detail::make_index_sequence<N>;
+
+#endif
+
+/**
+ * A simple function object that passes its argument through unchanged.
+ *
+ * Example:
+ *
+ * int i = 42;
+ * int &j = Identity()(i);
+ * assert(&i == &j);
+ *
+ * Warning: passing a prvalue through Identity turns it into an xvalue,
+ * which can effect whether lifetime extension occurs or not. For instance:
+ *
+ * auto&& x = std::make_unique<int>(42);
+ * cout << *x ; // OK, x refers to a valid unique_ptr.
+ *
+ * auto&& y = Identity()(std::make_unique<int>(42));
+ * cout << *y ; // ERROR: y did not lifetime-extend the unique_ptr. It
+ * // is no longer valid
+ */
+struct Identity {
+ using is_transparent = void;
+ template <class T>
+ constexpr T&& operator()(T&& x) const noexcept {
+ return static_cast<T&&>(x);
+ }
+};
}