Enable and require C++17 compilation

Updates build files to specify using the C++17 standard.

Add a usage of the C++17 exclusive [[maybe_unused]] attribute as a test.
Also unconditionally use <filesystem> in Reactor unit tests.

C++17 deprecates things like std::unary_function<>, which were present
in Subzero's LLVM headers, but the functionality was unused so it has
been deleted.

Bug: b/174843857
Bug: b/155971541
Change-Id: Ib167726535399b0b12751a3d93feaa9db762cd5d
Signed-off-by: Nicolas Capens <capn@google.com>
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/51948
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index a03b732..a0faf9e 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -21,7 +21,7 @@
                 "${workspaceFolder}/third_party/SPIRV-Tools/include"
             ],
             "cStandard": "c11",
-            "cppStandard": "c++14"
+            "cppStandard": "c++17"
         },
         {
             "name": "Mac",
@@ -44,7 +44,7 @@
                 "${workspaceFolder}/third_party/SPIRV-Tools/include"
             ],
             "cStandard": "c11",
-            "cppStandard": "c++14"
+            "cppStandard": "c++17"
         },
         {
             "name": "Win32",
@@ -66,7 +66,7 @@
                 "${workspaceFolder}/third_party/SPIRV-Tools/include"
             ],
             "cStandard": "c11",
-            "cppStandard": "c++14"
+            "cppStandard": "c++17"
         }
     ],
     "version": 4
diff --git a/Android.bp b/Android.bp
index 248a1c6..94c173e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -32,7 +32,7 @@
         "-DVK_USE_PLATFORM_ANDROID_KHR",
         "-DVK_EXPORT= ",
     ],
-    cpp_std: "c++14",
+    cpp_std: "c++17",
 
     target: {
         host: {
diff --git a/BUILD.gn b/BUILD.gn
index a527912..2e02016 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -60,12 +60,14 @@
         "/wd4309", # Truncation of constant value. See PixelRoutine.cpp casts of signed shorts.
       ]
     }
+
+    cflags_cc = [ "/std:c++17" ]
   } else {
     cflags = [
-      "-std=c++14",
       "-fno-exceptions",
       "-fno-operator-names",
     ]
+    cflags_cc = [ "-std=c++17" ]
 
     defines += [
       "__STDC_CONSTANT_MACROS",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a880c50..ec8544c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,7 +16,7 @@
 
 project(SwiftShader C CXX ASM)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
 set(CXX_STANDARD_REQUIRED ON)
 # MSVC doesn't define __cplusplus by default
 if(MSVC)
diff --git a/src/Device/Blitter.cpp b/src/Device/Blitter.cpp
index 4926469..abd5a91 100644
--- a/src/Device/Blitter.cpp
+++ b/src/Device/Blitter.cpp
@@ -2066,7 +2066,7 @@
 	uint8_t *source2 = source1 + slice;
 	uint8_t *source3 = source2 + slice;
 
-	const bool SSE2 = CPUID::supportsSSE2();
+	[[maybe_unused]] const bool SSE2 = CPUID::supportsSSE2();
 
 	if(format == VK_FORMAT_R8G8B8A8_UNORM || format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_A8B8G8R8_UNORM_PACK32)
 	{
diff --git a/src/System/Build.cpp b/src/System/Build.cpp
index 002bbeb..68d8ab9 100644
--- a/src/System/Build.cpp
+++ b/src/System/Build.cpp
@@ -25,15 +25,15 @@
 #endif
 
 // The template and unused function below verifies the compiler is using at least
-// C++14. It will print an error message containing the actual C++ version if
-// the version is < 14.
+// C++17. It will print an error message containing the actual C++ version if
+// the version is < 17.
 
 namespace {
 
 template<int version>
 class cpp
 {
-	static_assert(version >= 2014, "SwiftShader requires at least C++14");
+	static_assert(version >= 2017, "SwiftShader requires at least C++17");
 };
 
 void check_cpp_version()
diff --git a/tests/ReactorUnitTests/ReactorUnitTests.cpp b/tests/ReactorUnitTests/ReactorUnitTests.cpp
index 3a42695..1f01e7c 100644
--- a/tests/ReactorUnitTests/ReactorUnitTests.cpp
+++ b/tests/ReactorUnitTests/ReactorUnitTests.cpp
@@ -20,19 +20,11 @@
 
 #include <array>
 #include <cmath>
+#include <filesystem>
 #include <fstream>
 #include <thread>
 #include <tuple>
 
-// TODO(b/174843857): Remove once we upgrade to C++17
-#if(__cplusplus >= 201703L)
-#	define HAS_STD_FILESYSTEM
-#endif
-
-#if(defined(HAS_STD_FILESYSTEM))
-#	include <filesystem>
-#endif
-
 using namespace rr;
 
 std::string testName()
@@ -3293,7 +3285,7 @@
 	EXPECT_EQ(result, expected);
 }
 
-#if defined(ENABLE_RR_EMIT_ASM_FILE) && defined(HAS_STD_FILESYSTEM)
+#if defined(ENABLE_RR_EMIT_ASM_FILE)
 TEST(ReactorUnitTests, EmitAsm)
 {
 	// Only supported by LLVM for now
diff --git a/third_party/llvm-subzero/include/llvm/ADT/STLExtras.h b/third_party/llvm-subzero/include/llvm/ADT/STLExtras.h
index 4435b46..e69bb6c 100644
--- a/third_party/llvm-subzero/include/llvm/ADT/STLExtras.h
+++ b/third_party/llvm-subzero/include/llvm/ADT/STLExtras.h
@@ -45,34 +45,6 @@
 
 } // End detail namespace
 
-//===----------------------------------------------------------------------===//
-//     Extra additions to <functional>
-//===----------------------------------------------------------------------===//
-
-template<class Ty>
-struct identity : public std::unary_function<Ty, Ty> {
-  Ty &operator()(Ty &self) const {
-    return self;
-  }
-  const Ty &operator()(const Ty &self) const {
-    return self;
-  }
-};
-
-template<class Ty>
-struct less_ptr : public std::binary_function<Ty, Ty, bool> {
-  bool operator()(const Ty* left, const Ty* right) const {
-    return *left < *right;
-  }
-};
-
-template<class Ty>
-struct greater_ptr : public std::binary_function<Ty, Ty, bool> {
-  bool operator()(const Ty* left, const Ty* right) const {
-    return *right < *left;
-  }
-};
-
 /// An efficient, type-erasing, non-owning reference to a callable. This is
 /// intended for use as the type of a function parameter that is not used
 /// after the function in question returns.
@@ -346,95 +318,6 @@
                     FilterIteratorT(std::end(std::forward<RangeT>(Range))));
 }
 
-// forward declarations required by zip_shortest/zip_first
-template <typename R, typename UnaryPredicate>
-bool all_of(R &&range, UnaryPredicate P);
-
-template <size_t... I> struct index_sequence;
-
-template <class... Ts> struct index_sequence_for;
-
-namespace detail {
-template <typename... Iters> class zip_first {
-public:
-  typedef std::input_iterator_tag iterator_category;
-  typedef std::tuple<decltype(*std::declval<Iters>())...> value_type;
-  std::tuple<Iters...> iterators;
-
-private:
-  template <size_t... Ns> value_type deres(index_sequence<Ns...>) {
-    return value_type(*std::get<Ns>(iterators)...);
-  }
-
-  template <size_t... Ns> decltype(iterators) tup_inc(index_sequence<Ns...>) {
-    return std::tuple<Iters...>(std::next(std::get<Ns>(iterators))...);
-  }
-
-public:
-  value_type operator*() { return deres(index_sequence_for<Iters...>{}); }
-
-  void operator++() { iterators = tup_inc(index_sequence_for<Iters...>{}); }
-
-  bool operator!=(const zip_first<Iters...> &other) const {
-    return std::get<0>(iterators) != std::get<0>(other.iterators);
-  }
-  zip_first(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {}
-};
-
-template <typename... Iters> class zip_shortest : public zip_first<Iters...> {
-  template <size_t... Ns>
-  bool test(const zip_first<Iters...> &other, index_sequence<Ns...>) const {
-    return all_of(std::initializer_list<bool>{std::get<Ns>(this->iterators) !=
-                                              std::get<Ns>(other.iterators)...},
-                  identity<bool>{});
-  }
-
-public:
-  bool operator!=(const zip_first<Iters...> &other) const {
-    return test(other, index_sequence_for<Iters...>{});
-  }
-  zip_shortest(Iters &&... ts)
-      : zip_first<Iters...>(std::forward<Iters>(ts)...) {}
-};
-
-template <template <typename...> class ItType, typename... Args> class zippy {
-public:
-  typedef ItType<decltype(std::begin(std::declval<Args>()))...> iterator;
-
-private:
-  std::tuple<Args...> ts;
-
-  template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) {
-    return iterator(std::begin(std::get<Ns>(ts))...);
-  }
-  template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) {
-    return iterator(std::end(std::get<Ns>(ts))...);
-  }
-
-public:
-  iterator begin() { return begin_impl(index_sequence_for<Args...>{}); }
-  iterator end() { return end_impl(index_sequence_for<Args...>{}); }
-  zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {}
-};
-} // End detail namespace
-
-/// zip iterator for two or more iteratable types.
-template <typename T, typename U, typename... Args>
-detail::zippy<detail::zip_shortest, T, U, Args...> zip(T &&t, U &&u,
-                                                       Args &&... args) {
-  return detail::zippy<detail::zip_shortest, T, U, Args...>(
-      std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
-}
-
-/// zip iterator that, for the sake of efficiency, assumes the first iteratee to
-/// be the shortest.
-template <typename T, typename U, typename... Args>
-detail::zippy<detail::zip_first, T, U, Args...> zip_first(T &&t, U &&u,
-                                                          Args &&... args) {
-  return detail::zippy<detail::zip_first, T, U, Args...>(
-      std::forward<T>(t), std::forward<U>(u), std::forward<Args>(args)...);
-}
-
 //===----------------------------------------------------------------------===//
 //     Extra additions to <utility>
 //===----------------------------------------------------------------------===//