blob: 079104420b5ba7e82f0c22d59cd589e2ceb4e0e4 [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Check C++ capabilities.
include(CheckCXXSourceCompiles)
macro (cxx_test prog name)
check_cxx_source_compiles("${prog}" HAS_${name})
if (HAS_${name})
list(APPEND CPP_DEFINITIONS "HAS_${name}")
else()
set(CPP_TEST_FAILED True)
endif()
endmacro()
set(CPP_DEFINITIONS "")
set(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} ${CXX_WARNING_FLAGS}")
cxx_test("#if defined(__cplusplus) && __cplusplus >= 201103\nint main(int, char**) { return 0; }\n#endif" CPP11)
# Don't need to check individual flags if compiler claims to be C++11 or later as they will be set automatically
if (NOT HAS_CPP11)
set(CPP_TEST_FAILED False)
cxx_test("long long ll; int main(int, char**) { return 0; }" LONG_LONG_TYPE)
cxx_test("int* x = nullptr; int main(int, char**) { return 0; }" NULLPTR)
cxx_test("#include <string>\nvoid blah(std::string&&) {} int main(int, char**) { blah(\"hello\"); return 0; }" RVALUE_REFERENCES)
cxx_test("class x {explicit operator int(); }; int main(int, char**) { return 0; }" EXPLICIT_CONVERSIONS)
cxx_test("class x {x()=default; }; int main(int, char**) { return 0; }" DEFAULTED_FUNCTIONS)
cxx_test("class x {x(x&&)=default; }; int main(int, char**) { return 0; }" DEFAULTED_MOVE_INITIALIZERS)
cxx_test("class x {x()=delete; }; int main(int, char**) { return 0; }" DELETED_FUNCTIONS)
cxx_test("struct x {x() {}}; int main(int, char**) { static thread_local x foo; return 0; }" THREAD_LOCAL)
cxx_test("int main(int, char**) { int a=[](){return 42;}(); return a; }" LAMBDAS)
cxx_test("template <class... X> void x(X... a) {} int main(int, char**) { x(1); x(43, \"\"); return 0; }" VARIADIC_TEMPLATES)
cxx_test("#include <random>\nint main(int, char**) { return 0; }" HEADER_RANDOM)
cxx_test("#include <memory>\nstd::unique_ptr<int> u; int main(int, char**) { return 0; }" STD_UNIQUE_PTR)
cxx_test("#include <thread>\nstd::thread t; int main(int, char**) { return 0; }" STD_THREAD)
cxx_test("#include <mutex>\nstd::mutex m; int main(int, char**) { return 0; }" STD_MUTEX)
cxx_test("#include <atomic>\nstd::atomic<int> a; int main(int, char**) { return 0; }" STD_ATOMIC)
# If all the tests passed this is the same as if we have C++11 for the purposes of compilation
# (this shortens the compile command line for VS 2017 significantly)
if (NOT CPP_TEST_FAILED)
set(CPP_DEFINITIONS "HAS_CPP11")
endif()
endif()
unset(CMAKE_REQUIRED_FLAGS) # Don't contaminate later C tests with C++ flags