diff --git a/base/module.mk b/base/module.mk index f12a710920b2..fc0430fda114 100644 --- a/base/module.mk +++ b/base/module.mk @@ -1,6 +1,7 @@ MODULE := base MODULE_OBJS := \ + test_new_standards.o \ main.o \ commandLine.o \ plugins.o \ diff --git a/base/test_new_standards.cpp b/base/test_new_standards.cpp new file mode 100644 index 000000000000..fbc534e16647 --- /dev/null +++ b/base/test_new_standards.cpp @@ -0,0 +1,271 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +// This file does nothing functional! +// It test support for main C++11 features +// In the future, it might be extended to test also C++14, C++17, C++20 and any future standard +// +// In order to enable the tests, we have to `define ENABLE_TEST_CPP_11` (and of course, compile this file) +// Then it should print "Testing C++11" *during compilation* +// If the message is printed, and there are no compilation errors - great, C++11 is supported on this platform +// If there are errors, each one of the tests can be disabled, by defining the relevant DONT_TEST_* +// It's important to disable failing tests, because we might decide to support only specific subset of C++11 +// +// Note: there are 3 warnings in my GCC run, they have no signficance + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#ifdef ENABLE_TEST_CPP_11 +#pragma message("Testing C++11") +// The tests are based on https://blog.petrzemek.net/2014/12/07/improving-cpp98-code-with-cpp11/ +// See there for further links and explanations +// +// We're not testing `nullptr` and `override`, since they're defined in common/c++11-compat.h + +// INITIALIZIER_LIST1 test disabled: +// it fails in my VS 2019 and in GCC 4.8.5 (from 2015) +// TODO: maybe it's my syntax problem, maybe Common::Array need to be changed to support this syntax? +#define DONT_TEST_INITIALIZIER_LIST1 + +#include "common/array.h" +#include "common/hashmap.h" +#include "common/hash-str.h" +#include "common/rect.h" + +#ifndef DONT_TEST_CLASS_ENUM +// ---------------------------------- +// Scoped/Strongly Typed Enumerations +// ---------------------------------- +enum class MyEnum { + VAL1, + VAL2, + VAL3 +}; +#endif + +#ifndef DONT_TEST_FINAL_CLASS +// ---------------------------------- +// Non-Inheritable Classes (final) +// ---------------------------------- +// C++11 +class TestNewStandards final { +#else +class TestNewStandards { +#endif +private: + void do_nothing(const int &i) { + // don't do anything with i + }; + +#ifndef DONT_TEST_FINAL_FUNCTION + // ---------------------------------- + // Non-Overridable Member Functions (final) + // ---------------------------------- + virtual void f() final {} +#endif + +#ifndef DONT_TEST_VARIADIC_TEMPLATES + // ------------------------ + // Variadic Templates + // ------------------------ + template + void variadic_function(const T &value) { + do_nothing(value); + } + + template + void variadic_function(const U &head, const T &... tail) { + do_nothing(head); + variadic_function(tail...); + } +#endif + +#ifndef DONT_TEST_TYPE_ALIASES + // ------------------------ + // Type Aliases + // * note - this test has another bunch of code below + // ------------------------ + // C++98 + template + struct Dictionary_98 { + typedef Common::HashMap type; + }; + // Usage: + Dictionary_98::type d98; + + // C++11 + template + using Dictionary_11 = Common::HashMap; + // Usage: + Dictionary_11 d11; +#endif + + void test_cpp11() { +#ifdef DONT_TEST_INITIALIZIER_LIST1 + // ------------------------ + // Initializer list + // ------------------------ + // C++98 + Common::Array arr; + arr.push_back(1); + arr.push_back(2); + arr.push_back(3); +#else + // C++11 + Common::Array arr = {1, 2, 3}; +#endif + +#ifndef DONT_TEST_INITIALIZIER_LIST2 + // C++11 + Common::Point arr3[] = {{0, 0}, {1, 1}}; +#endif + +#ifndef DONT_TEST_AUTO_TYPE_INFERENCE + // ------------------------ + // Automatic Type Inference + // ------------------------ + // C++98 + for (Common::Array::iterator i = arr.begin(), e = arr.end(); i != e; ++i) + ; + + // C++11 + for (auto i = arr.begin(), e = arr.end(); i != e; ++i) + ; +#endif + +#ifndef DONT_TEST_RANGE_BASED_FOR_LOOP + // ------------------------ + // Range based for loop + // ------------------------ + // C++98 + for (Common::Array::iterator i = arr.begin(), e = arr.end(); i != e; ++i) + do_nothing(*i); + + // C++11 + for (int &i : arr) + do_nothing(i); +#endif + +#ifndef DONT_TEST_LAMBDA_FUNCTIONS + // ------------------------ + // Lambda functions + // ------------------------ + // C++98 + // the following isn't working in VS, but it's not really important to debug... + // Common::for_each(arr.begin(), arr.end(), do_nothing); + + // C++11 + Common::for_each(arr.begin(), arr.end(), + [](int i) { + // don't do anything with i + } + ); +#endif + +#ifndef DONT_TEST_VARIADIC_TEMPLATES + variadic_function(1, 1, 2, 3, 5, 8, 13, 21, 34); +#endif + +#ifndef DONT_TEST_GET_RID_OF_SPACE_IN_NESTED_TEMPLATES + // ------------------------ + // No Need For an Extra Space In Nested Template Declarations + // ------------------------ + // C++98 + Common::Array > v_98; + + // C++11 + Common::Array> v_11; +#endif + +#ifndef DONT_TEST_TYPE_ALIASES + // ------------------------ + // Type Aliases + // * note - this test has another bunch of code above + // ------------------------ + // C++98 + typedef void (*fp_98)(int, int); + + // C++11 + using fp_11 = void (*)(int, int); +#endif + + }; + +#ifndef DONT_TEST_ALT_FUNCTION_SYNTAX + // ------------------------ + // Alternative Function Syntax + // ------------------------ + // C++98 + int f_98(int x, int y) {return x;} + + // C++11 + auto f_11(int x, int y) -> int {return x;} +#endif + +#ifndef DONT_TEST_NON_STATIC_INIT + // ------------------------ + // Non-Static Data Member Initializers + // ------------------------ + int j = 3; + Common::String s = "non static init"; +#endif + +#ifndef DONT_TEST_EXPLICIT + // ------------------------ + // Explicit Conversion Operators + // ------------------------ + explicit operator bool() const {return true;} +#endif + + +public: + TestNewStandards() { + test_cpp11(); + } + +#ifndef DONT_TEST_MOVE_SEMANTICS + // ------------------------ + // Move semantics + // Note: this test hasn't been taken from the aforementioned web page + // ------------------------ + TestNewStandards(TestNewStandards&& t) { + // I'm not convinced that it's a good example of move sematics, it's a complicated topic. But just checking the syntax. + } +#endif + + +#ifndef DONT_TEST_DELETED_FUNCTIONS + // ------------------------ + // Explicitly Deleted Functions + // (useful for non copyable classes, + // particularly for our Singleton class) + // ------------------------ + TestNewStandards &operator=(const TestNewStandards &) = delete; +#endif + +}; + +static TestNewStandards test = TestNewStandards(); + +#endif diff --git a/configure b/configure index a2ca0d425688..259eb2a87daa 100755 --- a/configure +++ b/configure @@ -169,6 +169,7 @@ _iconv=auto _tts=auto _gtk=auto _fribidi=auto +_test_cpp11=no # Default option behavior yes/no _debug_build=auto _release_build=auto @@ -260,6 +261,7 @@ add_feature vorbis "Vorbis file support" "_vorbis _tremor" add_feature zlib "zlib" "_zlib" add_feature lua "lua" "_lua" add_feature fribidi "FriBidi" "_fribidi" +add_feature test_cpp11 "Test C++11" "_test_cpp11" # Directories for installing ScummVM. # This list is closely based on what GNU autoconf does, @@ -1240,6 +1242,8 @@ for ac_option in $@; do --disable-mad) _mad=no ;; --enable-fribidi) _fribidi=yes ;; --disable-fribidi) _fribidi=no ;; + --enable-test-cpp11) _test_cpp11=yes ;; + --disable-test-cpp11) _test_cpp11=no ;; --enable-zlib) _zlib=yes ;; --disable-zlib) _zlib=no ;; --enable-sparkle) _sparkle=yes ;; @@ -5557,6 +5561,12 @@ fi define_in_config_if_yes "$_fribidi" 'USE_FRIBIDI' echo "$_fribidi" +# +# Test C++11 Compatibility +# +define_in_config_if_yes "$_test_cpp11" 'ENABLE_TEST_CPP_11' +echo_n "Test C+11 Compatibility in compilation? " +echo "$_test_cpp11" # Default to plain text output for pandoc if test -z "$_pandocformat" -o "$_pandocformat" = "default"; then