Revert "Do not enforce a specific C++ standard"

This reverts commit d839b77928b3f9bebbbd18a1095ea2af890f3c34.

Reason for revert: Breaks the BUILD on macOS

Change-Id: I49f448ed4942cc88df9e4ad3b78d56f6be04351d
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fa110a9..69432f7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,14 +29,47 @@
 # Authors: keir@google.com (Keir Mierle)
 #          alexs.mac@gmail.com (Alex Stewart)
 
-cmake_minimum_required(VERSION 3.10)
-
-if (POLICY CMP0074) # Added in CMake 3.12
+cmake_minimum_required(VERSION 3.5)
+cmake_policy(VERSION 3.5)
+if (POLICY CMP0074)
   # FindTBB.cmake uses TBB_ROOT in a way that is historical, but also compliant
   # with CMP0074 so suppress the legacy compatibility warning and allow its use.
   cmake_policy(SET CMP0074 NEW)
 endif()
 
+# Set the C++ version when compiling Ceres.
+#
+# Reflect a user-specified (via -D) CMAKE_CXX_STANDARD if present, otherwise
+# default to C++14.
+set(DEFAULT_CXX_STANDARD ${CMAKE_CXX_STANDARD})
+if (NOT DEFAULT_CXX_STANDARD)
+  set(DEFAULT_CXX_STANDARD 14)
+endif()
+set(CMAKE_CXX_STANDARD ${DEFAULT_CXX_STANDARD} CACHE STRING
+  "C++ standard (minimum 14)" FORCE)
+# Restrict CMAKE_CXX_STANDARD to the valid versions permitted and ensure that
+# if one was forced via -D that it is in the valid set.
+set(ALLOWED_CXX_STANDARDS 14 17 20)
+set_property(CACHE CMAKE_CXX_STANDARD PROPERTY STRINGS ${ALLOWED_CXX_STANDARDS})
+list(FIND ALLOWED_CXX_STANDARDS ${CMAKE_CXX_STANDARD} POSITION)
+if (POSITION LESS 0)
+  message(FATAL_ERROR "Invalid CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}. "
+    "Must be one of: ${ALLOWED_CXX_STANDARDS}")
+endif()
+# Specify the standard as a hard requirement, otherwise CMAKE_CXX_STANDARD is
+# interpreted as a suggestion that can decay *back* to lower versions.
+set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE BOOL "")
+mark_as_advanced(CMAKE_CXX_STANDARD_REQUIRED)
+
+# MSVC versions < 2015 did not fully support >= C++14, and technically even
+# 2015 did not support a couple of smaller features
+if (CMAKE_CXX_COMPILER_ID MATCHES MSVC AND
+    CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0)
+  message(FATAL_ERROR "Invalid CMAKE_CXX_COMPILER_VERSION: "
+    "${CMAKE_CXX_COMPILER_VERSION}. Ceres requires at least MSVC 2015 for "
+    "C++14 support.")
+endif()
+
 # On macOS, add the Homebrew prefix (with appropriate suffixes) to the
 # respective HINTS directories (after any user-specified locations).  This
 # handles Homebrew installations into non-standard locations (not /usr/local).
@@ -204,6 +237,7 @@
 endif (IOS)
 
 unset(CERES_COMPILE_OPTIONS)
+message("-- Building with C++${CMAKE_CXX_STANDARD}")
 
 # Eigen.
 # Eigen delivers Eigen3Config.cmake since v3.3.3
@@ -457,7 +491,6 @@
   mark_as_advanced(benchmark_DIR)
 endif()
 
-# TODO Report features using the FeatureSummary CMake module
 if (BUILD_SHARED_LIBS)
   message("-- Building Ceres as a shared library.")
 else (BUILD_SHARED_LIBS)
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 5606804..f57c2e8 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -314,10 +314,17 @@
 target_compile_options(ceres_internal PUBLIC $<TARGET_PROPERTY:ceres,COMPILE_OPTIONS>)
 target_compile_definitions(ceres_internal PRIVATE ceres_EXPORTS)
 
-# Ensure the minimum required C++ language version is fulfilled as our
-# requirement by downstream clients. Consumers can choose the same or a newer
-# language standard revision.
-target_compile_features(ceres PUBLIC cxx_std_14)
+# The ability to specify a minimum language version via cxx_std_[11,14,17]
+# requires CMake >= 3.8.  Prior to that we have to specify the compiler features
+# we require.
+if (CMAKE_VERSION VERSION_LESS 3.8)
+  set(REQUIRED_PUBLIC_CXX_FEATURES cxx_alignas cxx_alignof cxx_constexpr)
+else()
+  # Forward whatever C++ version Ceres was compiled with as our requirement
+  # for downstream clients.
+  set(REQUIRED_PUBLIC_CXX_FEATURES cxx_std_${CMAKE_CXX_STANDARD})
+endif()
+target_compile_features(ceres PUBLIC ${REQUIRED_PUBLIC_CXX_FEATURES})
 
 set_target_properties(ceres PROPERTIES
   VERSION ${CERES_VERSION}