summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2016-10-07 14:43:09 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2016-10-07 14:43:09 +0200
commit377472a6dd2c9bdff4d5667f5789c49aee2abb4c (patch)
treea0ce4d6fc3db1524609efc61307d48448e703f38 /3rdparty
parent1335933ce00cf6095e403a24d0b1dd9e0b565650 (diff)
Added sol2 header only library as future replacement for luabridge (nw)
Diffstat (limited to '3rdparty')
-rw-r--r--3rdparty/sol2/.gitignore71
-rw-r--r--3rdparty/sol2/.gitmodules6
-rw-r--r--3rdparty/sol2/.travis.yml186
-rw-r--r--3rdparty/sol2/CONTRIBUTING.md58
-rw-r--r--3rdparty/sol2/Catch/.gitignore22
-rw-r--r--3rdparty/sol2/Catch/.travis.yml163
-rw-r--r--3rdparty/sol2/Catch/LICENSE_1_0.txt23
-rw-r--r--3rdparty/sol2/Catch/README.md22
-rw-r--r--3rdparty/sol2/Catch/catch-logo-small.pngbin0 -> 51470 bytes
-rw-r--r--3rdparty/sol2/Catch/docs/Readme.md20
-rw-r--r--3rdparty/sol2/Catch/docs/assertions.md82
-rw-r--r--3rdparty/sol2/Catch/docs/build-systems.md86
-rw-r--r--3rdparty/sol2/Catch/docs/command-line.md220
-rw-r--r--3rdparty/sol2/Catch/docs/configuration.md73
-rw-r--r--3rdparty/sol2/Catch/docs/contributing.md23
-rw-r--r--3rdparty/sol2/Catch/docs/logging.md52
-rw-r--r--3rdparty/sol2/Catch/docs/own-main.md68
-rw-r--r--3rdparty/sol2/Catch/docs/slow-compiles.md22
-rw-r--r--3rdparty/sol2/Catch/docs/test-cases-and-sections.md86
-rw-r--r--3rdparty/sol2/Catch/docs/test-fixtures.md32
-rw-r--r--3rdparty/sol2/Catch/docs/tostring.md70
-rw-r--r--3rdparty/sol2/Catch/docs/tutorial.md249
-rw-r--r--3rdparty/sol2/Catch/docs/why-catch.md42
-rw-r--r--3rdparty/sol2/Catch/projects/CMake/CMakeLists.txt48
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/ApproxTests.cpp112
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/BDDTests.cpp103
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.std.approved.txt835
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.sw.approved.txt9050
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.swa4.approved.txt491
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/Baselines/junit.sw.approved.txt684
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/Baselines/xml.sw.approved.txt9511
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/ClassTests.cpp57
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/CmdLineTests.cpp264
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/ConditionTests.cpp335
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/EnumToString.cpp76
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/ExceptionTests.cpp203
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/GeneratorTests.cpp42
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/MessageTests.cpp133
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/MiscTests.cpp480
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/PartTrackerTests.cpp328
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_common.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_console_colour.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_debugger.cpp2
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_capture.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_config.cpp2
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_exception.cpp2
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_generators.cpp1
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_registry_hub.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_reporter.cpp2
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_runner.cpp1
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_testcase.cpp2
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_message.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_option.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_ptr.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_stream.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_streambuf.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_xmlwriter.cpp4
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/TagAliasTests.cpp41
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/TestMain.cpp461
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/ToStringPair.cpp47
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/ToStringTuple.cpp59
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/ToStringVector.cpp77
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/ToStringWhich.cpp68
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/TrickyTests.cpp401
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/VariadicMacrosTests.cpp31
-rw-r--r--3rdparty/sol2/Catch/projects/SelfTest/makefile30
-rw-r--r--3rdparty/sol2/Catch/projects/VS2008/TestCatch/TestCatch/TestCatch.cpp8
-rw-r--r--3rdparty/sol2/Catch/projects/VS2008/TestCatch/TestCatch/TestCatch.vcproj390
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj742
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest/CatchSelfTest.179
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest/catch_text.cpp3
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle.xcodeproj/project.pbxproj258
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle/dummy.txt0
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest.xcodeproj/project.pbxproj265
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/CatchOCTestCase.h25
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/CatchOCTestCase.mm83
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/Main.mm2
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/OCTest.179
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/OCTest.mm28
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/TestObj.h28
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/TestObj.m25
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest.xcodeproj/project.pbxproj299
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/OCTest.mm27
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/TestObj.h25
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/TestObj.m18
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/en.lproj/InfoPlist.strings2
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/iOSTest-Info.plist47
-rw-r--r--3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/iOSTest-Prefix.pch14
-rw-r--r--3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerAppDelegate.h114
-rw-r--r--3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerMainView.h189
-rw-r--r--3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerReporter.h115
-rw-r--r--3rdparty/sol2/Catch/projects/runners/iTchRunner/itChRunnerMain.mm27
-rw-r--r--3rdparty/sol2/Catch/projects/runners/iTchRunner/readme6
-rw-r--r--3rdparty/sol2/Catch/scripts/approvalTests.py115
-rw-r--r--3rdparty/sol2/Catch/scripts/approve.py31
-rw-r--r--3rdparty/sol2/Catch/scripts/developBuild.py9
-rw-r--r--3rdparty/sol2/Catch/scripts/fixTrailingWhitespace.py46
-rw-r--r--3rdparty/sol2/Catch/scripts/generateSingleHeader.py103
-rw-r--r--3rdparty/sol2/Catch/scripts/majorRelease.py9
-rw-r--r--3rdparty/sol2/Catch/scripts/minorRelease.py9
-rw-r--r--3rdparty/sol2/Catch/scripts/patchRelease.py9
-rw-r--r--3rdparty/sol2/Catch/scripts/releaseCommon.py89
-rw-r--r--3rdparty/sol2/Catch/scripts/releaseNotes.py62
-rw-r--r--3rdparty/sol2/Catch/scripts/scriptCommon.py21
-rw-r--r--3rdparty/sol2/Catch/single_include/catch.hpp10359
-rw-r--r--3rdparty/sol2/LICENSE.txt20
-rw-r--r--3rdparty/sol2/Optional/CMakeLists.txt11
-rw-r--r--3rdparty/sol2/Optional/LICENSE_1_0.txt23
-rw-r--r--3rdparty/sol2/Optional/README.md39
-rw-r--r--3rdparty/sol2/Optional/copyright.txt10
-rw-r--r--3rdparty/sol2/Optional/optional.hpp1064
-rw-r--r--3rdparty/sol2/Optional/test_optional.cpp1459
-rw-r--r--3rdparty/sol2/Optional/test_type_traits.cpp66
-rw-r--r--3rdparty/sol2/README.md75
-rw-r--r--3rdparty/sol2/bootstrap.py206
-rw-r--r--3rdparty/sol2/docs/Makefile216
-rw-r--r--3rdparty/sol2/docs/make.bat263
-rw-r--r--3rdparty/sol2/docs/source/api/api-top.rst46
-rw-r--r--3rdparty/sol2/docs/source/api/as_function.rst67
-rw-r--r--3rdparty/sol2/docs/source/api/as_table.rst24
-rw-r--r--3rdparty/sol2/docs/source/api/c_call.rst71
-rw-r--r--3rdparty/sol2/docs/source/api/compatibility.rst16
-rw-r--r--3rdparty/sol2/docs/source/api/coroutine.rst109
-rw-r--r--3rdparty/sol2/docs/source/api/error.rst15
-rw-r--r--3rdparty/sol2/docs/source/api/function.rst89
-rw-r--r--3rdparty/sol2/docs/source/api/make_reference.rst26
-rw-r--r--3rdparty/sol2/docs/source/api/metatable_key.rst154
-rw-r--r--3rdparty/sol2/docs/source/api/object.rst70
-rw-r--r--3rdparty/sol2/docs/source/api/optional.rst6
-rw-r--r--3rdparty/sol2/docs/source/api/overload.rst89
-rw-r--r--3rdparty/sol2/docs/source/api/property.rst64
-rw-r--r--3rdparty/sol2/docs/source/api/protect.rst33
-rw-r--r--3rdparty/sol2/docs/source/api/protected_function.rst185
-rw-r--r--3rdparty/sol2/docs/source/api/proxy.rst201
-rw-r--r--3rdparty/sol2/docs/source/api/readonly.rst11
-rw-r--r--3rdparty/sol2/docs/source/api/reference.rst75
-rw-r--r--3rdparty/sol2/docs/source/api/resolve.rst39
-rw-r--r--3rdparty/sol2/docs/source/api/simple_usertype.rst16
-rw-r--r--3rdparty/sol2/docs/source/api/stack.rst199
-rw-r--r--3rdparty/sol2/docs/source/api/stack_reference.rst8
-rw-r--r--3rdparty/sol2/docs/source/api/state.rst121
-rw-r--r--3rdparty/sol2/docs/source/api/table.rst208
-rw-r--r--3rdparty/sol2/docs/source/api/this_state.rst31
-rw-r--r--3rdparty/sol2/docs/source/api/thread.rst52
-rw-r--r--3rdparty/sol2/docs/source/api/tie.rst26
-rw-r--r--3rdparty/sol2/docs/source/api/types.rst207
-rw-r--r--3rdparty/sol2/docs/source/api/unique_usertype_traits.rst44
-rw-r--r--3rdparty/sol2/docs/source/api/user.rst19
-rw-r--r--3rdparty/sol2/docs/source/api/userdata.rst13
-rw-r--r--3rdparty/sol2/docs/source/api/usertype.rst329
-rw-r--r--3rdparty/sol2/docs/source/api/usertype_memory.rst47
-rw-r--r--3rdparty/sol2/docs/source/api/var.rst49
-rw-r--r--3rdparty/sol2/docs/source/api/variadic_args.rst49
-rw-r--r--3rdparty/sol2/docs/source/benchmarks.rst94
-rw-r--r--3rdparty/sol2/docs/source/cmake.rst54
-rw-r--r--3rdparty/sol2/docs/source/codecvt.rst8
-rw-r--r--3rdparty/sol2/docs/source/conf.py291
-rw-r--r--3rdparty/sol2/docs/source/eevee_code_after.jpgbin0 -> 9593 bytes
-rw-r--r--3rdparty/sol2/docs/source/eevee_code_before.jpgbin0 -> 59507 bytes
-rw-r--r--3rdparty/sol2/docs/source/exceptions.rst51
-rw-r--r--3rdparty/sol2/docs/source/features.rst258
-rw-r--r--3rdparty/sol2/docs/source/index.rst123
-rw-r--r--3rdparty/sol2/docs/source/licenses.rst47
-rw-r--r--3rdparty/sol2/docs/source/mentions.rst50
-rw-r--r--3rdparty/sol2/docs/source/origin.rst28
-rw-r--r--3rdparty/sol2/docs/source/performance.rst15
-rw-r--r--3rdparty/sol2/docs/source/rtti.rst14
-rw-r--r--3rdparty/sol2/docs/source/safety.rst22
-rw-r--r--3rdparty/sol2/docs/source/sol.pngbin0 -> 14482 bytes
-rw-r--r--3rdparty/sol2/docs/source/sol.psdbin0 -> 121930 bytes
-rw-r--r--3rdparty/sol2/docs/source/tutorial/all-the-things.rst606
-rw-r--r--3rdparty/sol2/docs/source/tutorial/customization.rst114
-rw-r--r--3rdparty/sol2/docs/source/tutorial/cxx-in-lua.rst138
-rw-r--r--3rdparty/sol2/docs/source/tutorial/existing.rst27
-rw-r--r--3rdparty/sol2/docs/source/tutorial/functions.rst341
-rw-r--r--3rdparty/sol2/docs/source/tutorial/getting-started.rst84
-rw-r--r--3rdparty/sol2/docs/source/tutorial/ownership.rst94
-rw-r--r--3rdparty/sol2/docs/source/tutorial/tutorial-top.rst21
-rw-r--r--3rdparty/sol2/docs/source/tutorial/variables.rst202
-rw-r--r--3rdparty/sol2/examples/any_return.cpp46
-rw-r--r--3rdparty/sol2/examples/basic.cpp19
-rw-r--r--3rdparty/sol2/examples/config.cpp39
-rw-r--r--3rdparty/sol2/examples/config.lua3
-rw-r--r--3rdparty/sol2/examples/customization.cpp91
-rw-r--r--3rdparty/sol2/examples/functions.cpp110
-rw-r--r--3rdparty/sol2/examples/namespacing.cpp33
-rw-r--r--3rdparty/sol2/examples/player_script.lua29
-rw-r--r--3rdparty/sol2/examples/protected_functions.cpp47
-rw-r--r--3rdparty/sol2/examples/require.cpp47
-rw-r--r--3rdparty/sol2/examples/self_call.cpp35
-rw-r--r--3rdparty/sol2/examples/static_variables.cpp61
-rw-r--r--3rdparty/sol2/examples/tables.cpp59
-rw-r--r--3rdparty/sol2/examples/usertype.cpp109
-rw-r--r--3rdparty/sol2/examples/usertype_advanced.cpp121
-rw-r--r--3rdparty/sol2/examples/usertype_initializers.cpp67
-rw-r--r--3rdparty/sol2/examples/usertype_simple.cpp95
-rw-r--r--3rdparty/sol2/examples/usertype_special_functions.cpp70
-rw-r--r--3rdparty/sol2/examples/usertype_var.cpp45
-rw-r--r--3rdparty/sol2/examples/variables.cpp37
-rw-r--r--3rdparty/sol2/examples/variadic_args.cpp40
-rw-r--r--3rdparty/sol2/install.deps.sh96
-rw-r--r--3rdparty/sol2/ninja_syntax.py156
-rw-r--r--3rdparty/sol2/single.py165
-rw-r--r--3rdparty/sol2/single/sol/sol.hpp12323
-rw-r--r--3rdparty/sol2/sol.hpp50
-rw-r--r--3rdparty/sol2/sol/bind_traits.hpp243
-rw-r--r--3rdparty/sol2/sol/call.hpp573
-rw-r--r--3rdparty/sol2/sol/compatibility.hpp47
-rw-r--r--3rdparty/sol2/sol/compatibility/5.0.0.h44
-rw-r--r--3rdparty/sol2/sol/compatibility/5.1.0.h175
-rw-r--r--3rdparty/sol2/sol/compatibility/5.x.x.h57
-rw-r--r--3rdparty/sol2/sol/compatibility/5.x.x.inl707
-rw-r--r--3rdparty/sol2/sol/compatibility/version.hpp121
-rw-r--r--3rdparty/sol2/sol/container_usertype_metatable.hpp412
-rw-r--r--3rdparty/sol2/sol/coroutine.hpp119
-rw-r--r--3rdparty/sol2/sol/debug.hpp54
-rw-r--r--3rdparty/sol2/sol/demangle.hpp158
-rw-r--r--3rdparty/sol2/sol/deprecate.hpp44
-rw-r--r--3rdparty/sol2/sol/error.hpp55
-rw-r--r--3rdparty/sol2/sol/function.hpp151
-rw-r--r--3rdparty/sol2/sol/function_result.hpp88
-rw-r--r--3rdparty/sol2/sol/function_types.hpp342
-rw-r--r--3rdparty/sol2/sol/function_types_core.hpp39
-rw-r--r--3rdparty/sol2/sol/function_types_overloaded.hpp59
-rw-r--r--3rdparty/sol2/sol/function_types_stateful.hpp103
-rw-r--r--3rdparty/sol2/sol/function_types_stateless.hpp163
-rw-r--r--3rdparty/sol2/sol/function_types_templated.hpp132
-rw-r--r--3rdparty/sol2/sol/in_place.hpp50
-rw-r--r--3rdparty/sol2/sol/inheritance.hpp117
-rw-r--r--3rdparty/sol2/sol/load_result.hpp139
-rw-r--r--3rdparty/sol2/sol/object.hpp152
-rw-r--r--3rdparty/sol2/sol/optional.hpp43
-rw-r--r--3rdparty/sol2/sol/overload.hpp45
-rw-r--r--3rdparty/sol2/sol/property.hpp105
-rw-r--r--3rdparty/sol2/sol/protect.hpp51
-rw-r--r--3rdparty/sol2/sol/protected_function.hpp190
-rw-r--r--3rdparty/sol2/sol/protected_function_result.hpp130
-rw-r--r--3rdparty/sol2/sol/proxy.hpp175
-rw-r--r--3rdparty/sol2/sol/proxy_base.hpp51
-rw-r--r--3rdparty/sol2/sol/raii.hpp132
-rw-r--r--3rdparty/sol2/sol/reference.hpp174
-rw-r--r--3rdparty/sol2/sol/resolve.hpp96
-rw-r--r--3rdparty/sol2/sol/simple_usertype_metatable.hpp494
-rw-r--r--3rdparty/sol2/sol/stack.hpp226
-rw-r--r--3rdparty/sol2/sol/stack_check.hpp350
-rw-r--r--3rdparty/sol2/sol/stack_check_get.hpp114
-rw-r--r--3rdparty/sol2/sol/stack_core.hpp410
-rw-r--r--3rdparty/sol2/sol/stack_field.hpp261
-rw-r--r--3rdparty/sol2/sol/stack_get.hpp537
-rw-r--r--3rdparty/sol2/sol/stack_guard.hpp63
-rw-r--r--3rdparty/sol2/sol/stack_pop.hpp49
-rw-r--r--3rdparty/sol2/sol/stack_probe.hpp87
-rw-r--r--3rdparty/sol2/sol/stack_proxy.hpp124
-rw-r--r--3rdparty/sol2/sol/stack_push.hpp693
-rw-r--r--3rdparty/sol2/sol/stack_reference.hpp84
-rw-r--r--3rdparty/sol2/sol/state.hpp59
-rw-r--r--3rdparty/sol2/sol/state_view.hpp460
-rw-r--r--3rdparty/sol2/sol/string_shim.hpp64
-rw-r--r--3rdparty/sol2/sol/table.hpp31
-rw-r--r--3rdparty/sol2/sol/table_core.hpp462
-rw-r--r--3rdparty/sol2/sol/table_iterator.hpp120
-rw-r--r--3rdparty/sol2/sol/thread.hpp77
-rw-r--r--3rdparty/sol2/sol/tie.hpp101
-rw-r--r--3rdparty/sol2/sol/traits.hpp425
-rw-r--r--3rdparty/sol2/sol/tuple.hpp80
-rw-r--r--3rdparty/sol2/sol/types.hpp756
-rw-r--r--3rdparty/sol2/sol/userdata.hpp82
-rw-r--r--3rdparty/sol2/sol/usertype.hpp97
-rw-r--r--3rdparty/sol2/sol/usertype_metatable.hpp583
-rw-r--r--3rdparty/sol2/sol/usertype_traits.hpp55
-rw-r--r--3rdparty/sol2/sol/variadic_args.hpp236
-rw-r--r--3rdparty/sol2/sol/wrapper.hpp233
-rw-r--r--3rdparty/sol2/test_containers.cpp310
-rw-r--r--3rdparty/sol2/test_coroutines.cpp64
-rw-r--r--3rdparty/sol2/test_customizations.cpp86
-rw-r--r--3rdparty/sol2/test_functions.cpp949
-rw-r--r--3rdparty/sol2/test_inheritance.cpp247
-rw-r--r--3rdparty/sol2/test_operators.cpp83
-rw-r--r--3rdparty/sol2/test_overflow.cpp47
-rw-r--r--3rdparty/sol2/test_simple_usertypes.cpp459
-rw-r--r--3rdparty/sol2/test_stack_guard.hpp11
-rw-r--r--3rdparty/sol2/test_strings.cpp122
-rw-r--r--3rdparty/sol2/test_tables.cpp548
-rw-r--r--3rdparty/sol2/test_usertypes.cpp1425
-rw-r--r--3rdparty/sol2/tests.cpp680
290 files changed, 80392 insertions, 0 deletions
diff --git a/3rdparty/sol2/.gitignore b/3rdparty/sol2/.gitignore
new file mode 100644
index 00000000000..242803c126c
--- /dev/null
+++ b/3rdparty/sol2/.gitignore
@@ -0,0 +1,71 @@
+# Python (Bytecode)
+*.pyc
+
+# ninja files
+*.ninja
+
+# Visual Studio
+*.props
+*.user
+.vs/
+Debug/
+Release/
+x64/
+*.vcxproj
+*.vcxproj.filters
+*.tlog
+*.lastbuildstate
+*.idb
+*.sln
+*.gitattributes
+
+# VSCode
+.vscode/
+
+# Compiler outputs
+obj/*
+bin/*
+
+# Dropbox interference
+.dropbox*
+
+# QtCreator
+*.creator.user.*
+*.config
+*.creator
+*.files
+*.includes
+
+# Scratchpad Files
+main2.cpp
+main.cpp
+
+# Local Lua Testbeds
+lua-5.3.2/
+lua-5.3.1/
+lua-5.3.0/
+lua-5.2.4/
+lua-5.2.2/
+lua-5.2.3/
+lua-5.1.5/
+luajit-2.0.4/
+luajit-2.0.3/
+include/
+liblua.a
+lib/liblua5.2.a
+
+# Windows Crap
+desktop.ini
+*.sublime-workspace
+docs/build/
+*.sublime-project
+m.lua
+single/sol.hpp
+*.db
+lua53.dll
+main.exe
+main.o
+lua-5.3.3/
+*.pdf
+main.lua
+LuaJIT-2.1.0/
diff --git a/3rdparty/sol2/.gitmodules b/3rdparty/sol2/.gitmodules
new file mode 100644
index 00000000000..f6ae162a2f3
--- /dev/null
+++ b/3rdparty/sol2/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "Catch"]
+ path = Catch
+ url = https://github.com/philsquared/Catch.git
+[submodule "Optional"]
+ path = Optional
+ url = https://github.com/ThePhD/Optional.git
diff --git a/3rdparty/sol2/.travis.yml b/3rdparty/sol2/.travis.yml
new file mode 100644
index 00000000000..aa6677ef55f
--- /dev/null
+++ b/3rdparty/sol2/.travis.yml
@@ -0,0 +1,186 @@
+language: cpp
+sudo: required
+dist: trusty
+
+git:
+ depth: 5
+
+before_install:
+- source ./install.deps.sh
+
+install:
+- install_os_deps
+
+script:
+- echo "Configuration info:"
+- export_compiler_vars
+- ninja --version
+- ./bootstrap.py --ci && ninja
+
+notifications:
+ email:
+ on_success: change
+ on_failure: change
+
+matrix:
+ include:
+ - os: linux
+ env: COMPILER=g++-4.9 LUA_VERSION=lua52
+ compiler: gcc
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - gcc-4.9
+ - g++-4.9
+ - ninja-build
+ - liblua5.2-dev
+
+ # gcc-5
+ - os: linux
+ env: COMPILER=g++-4.9 LUA_VERSION=luajit51
+ compiler: gcc
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - gcc-4.9
+ - g++-4.9
+ - ninja-build
+ - libluajit-5.1-dev
+
+ # gcc-5
+ - os: linux
+ env: COMPILER=g++-5 LUA_VERSION=lua52
+ compiler: gcc
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - gcc-5
+ - g++-5
+ - ninja-build
+ - liblua5.2-dev
+
+ # gcc-5
+ - os: linux
+ env: COMPILER=g++-5 LUA_VERSION=luajit51
+ compiler: gcc
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - gcc-5
+ - g++-5
+ - ninja-build
+ - libluajit-5.1-dev
+
+ # clang
+ - os: linux
+ env:
+ - LLVM_VERSION=3.5.0
+ - LLVM_ARCHIVE_PATH=$HOME/clang+llvm.tar.xz
+ - COMPILER=clang++
+ - CPPFLAGS="-I $HOME/clang-$LLVM_VERSION/include/c++/v1"
+ - CXXFLAGS=-lc++
+ - PATH=$HOME/clang-$LLVM_VERSION/bin:$PATH
+ - LD_LIBRARY_PATH=$HOME/clang-$LLVM_VERSION/lib:$LD_LIBRARY_PATH
+ - LUA_VERSION=lua52
+ before_install:
+ - wget http://llvm.org/releases/$LLVM_VERSION/clang+llvm-$LLVM_VERSION-x86_64-linux-gnu-ubuntu-14.04.tar.xz -O $LLVM_ARCHIVE_PATH
+ - mkdir $HOME/clang-$LLVM_VERSION
+ - tar xf $LLVM_ARCHIVE_PATH -C $HOME/clang-$LLVM_VERSION --strip-components 1
+ - export PATH=$HOME/clang+llvm/bin:$PATH
+ - source ./install.deps.sh
+ compiler: clang
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - gcc-4.9
+ - g++-4.9
+ - ninja-build
+ - liblua5.2-dev
+
+ - os: linux
+ env:
+ - LLVM_VERSION=3.6.0
+ - LLVM_ARCHIVE_PATH=$HOME/clang+llvm.tar.xz
+ - COMPILER=clang++
+ - CPPFLAGS="-I $HOME/clang-$LLVM_VERSION/include/c++/v1"
+ - CXXFLAGS=-lc++
+ - PATH=$HOME/clang-$LLVM_VERSION/bin:$PATH
+ - LD_LIBRARY_PATH=$HOME/clang-$LLVM_VERSION/lib:$LD_LIBRARY_PATH
+ - LUA_VERSION=lua52
+ before_install:
+ - wget http://llvm.org/releases/$LLVM_VERSION/clang+llvm-$LLVM_VERSION-x86_64-linux-gnu-ubuntu-14.04.tar.xz -O $LLVM_ARCHIVE_PATH
+ - mkdir $HOME/clang-$LLVM_VERSION
+ - tar xf $LLVM_ARCHIVE_PATH -C $HOME/clang-$LLVM_VERSION --strip-components 1
+ - export PATH=$HOME/clang+llvm/bin:$PATH
+ - source ./install.deps.sh
+ compiler: clang
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - gcc-4.9
+ - g++-4.9
+ - ninja-build
+ - liblua5.2-dev
+
+ - os: linux
+ env:
+ - LLVM_VERSION=3.6.0
+ - LLVM_ARCHIVE_PATH=$HOME/clang+llvm.tar.xz
+ - COMPILER=clang++
+ - CPPFLAGS="-I $HOME/clang-$LLVM_VERSION/include/c++/v1"
+ - CXXFLAGS=-lc++
+ - PATH=$HOME/clang-$LLVM_VERSION/bin:$PATH
+ - LD_LIBRARY_PATH=$HOME/clang-$LLVM_VERSION/lib:$LD_LIBRARY_PATH
+ - LUA_VERSION=luajit51
+ before_install:
+ - wget http://llvm.org/releases/$LLVM_VERSION/clang+llvm-$LLVM_VERSION-x86_64-linux-gnu-ubuntu-14.04.tar.xz -O $LLVM_ARCHIVE_PATH
+ - mkdir $HOME/clang-$LLVM_VERSION
+ - tar xf $LLVM_ARCHIVE_PATH -C $HOME/clang-$LLVM_VERSION --strip-components 1
+ - export PATH=$HOME/clang+llvm/bin:$PATH
+ - source ./install.deps.sh
+ compiler: clang
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - gcc-4.9
+ - g++-4.9
+ - ninja-build
+ - libluajit-5.1-dev
+
+ - os: osx
+ osx_image: xcode7
+ compiler: gcc
+ env: COMPILER=g++-4.9 LUA_VERSION=lua53
+
+ - os: osx
+ osx_image: xcode7
+ compiler: gcc
+ env: COMPILER=g++-5 LUA_VERSION=lua53
+
+ - os: osx
+ osx_image: xcode7
+ compiler: gcc
+ env: COMPILER=g++-5 LUA_VERSION=luajit
+
+ - os: osx
+ osx_image: xcode7
+ compiler: clang
+ env: COMPILER=appleclang LUA_VERSION=lua53
+
+ allow_failures:
+ - os: osx
+ compiler: clang
diff --git a/3rdparty/sol2/CONTRIBUTING.md b/3rdparty/sol2/CONTRIBUTING.md
new file mode 100644
index 00000000000..e7a4147a648
--- /dev/null
+++ b/3rdparty/sol2/CONTRIBUTING.md
@@ -0,0 +1,58 @@
+## Contributing to Sol
+
+Looking to contribute to Sol? Well, first thing I want to mention is thank you!
+Second of all, this is probably where you should look :)
+
+## Reporting Issues
+
+If you found a bug, please make sure to make an issue in the issue tracker.
+
+The guidelines for reporting a bug are relatively simple and are as follows:
+
+1. Produce a simple, short, compilable test case that reproduces your problem.
+2. Make a descriptive title that summarises the bug as a whole.
+3. Explain the bug in as much detail as you can in the body of the issue.
+
+If you have all of those requirements set, then your issue reporting is golden.
+
+## Submitting a pull request
+
+Submitting a pull request is fairly simple, just make sure it focuses on a single aspect and doesn't
+manage to have scope creep and it's probably good to go. It would be incredibly lovely if the style is
+consistent to those found in the repository.
+
+They are as follows (more will be added as they come up):
+
+- No spaces between parentheses. e.g. `f(g())` not `f ( g ( ) )`.
+- Tabs for indentation, spaces for alignment.
+- Bracing style is
+
+```cpp
+if(my_bool) {
+
+}
+else if(my_other_bool) {
+
+}
+else {
+
+}
+```
+
+- Variable names follow those in the C++ standard, basically snake_case.
+- Maximum column length is 125
+- Trailing return type will always be in the same line. Even if it goes off the column length. e.g.
+`auto f() -> decltype(/* my long expression */) {`
+- Since this is a header-only library, all free functions must be marked `inline`.
+- Use braces in optional contexts like `if`, `for`, `else`, `while`, etc. e.g.
+
+```cpp
+if(x > 12) {
+ return x * 2;
+}
+```
+
+- Use `typename` instead of `class` for template parameters. e.g. `template<typename T>`.
+
+If you don't meet all of these style guidelines, don't fret. I'll probably fix it. But please
+do make an effort to actually meet them. Otherwise I'm more likely to reject the pull request.
diff --git a/3rdparty/sol2/Catch/.gitignore b/3rdparty/sol2/Catch/.gitignore
new file mode 100644
index 00000000000..3ca4b5c555c
--- /dev/null
+++ b/3rdparty/sol2/Catch/.gitignore
@@ -0,0 +1,22 @@
+*.build
+*.pbxuser
+*.mode1v3
+*.ncb
+*.suo
+Debug
+Release
+*.user
+*.xcuserstate
+.DS_Store
+xcuserdata
+CatchSelfTest.xcscheme
+Breakpoints.xcbkptlist
+projects/VS2010/TestCatch/_UpgradeReport_Files/
+projects/VS2010/TestCatch/TestCatch/TestCatch.vcxproj.filters
+projects/VisualStudio/TestCatch/UpgradeLog.XML
+UpgradeLog.XML
+Resources/DWARF
+projects/XCode/iOSTest/Build
+*.pyc
+DerivedData
+*.xccheckout
diff --git a/3rdparty/sol2/Catch/.travis.yml b/3rdparty/sol2/Catch/.travis.yml
new file mode 100644
index 00000000000..e63a76a36ef
--- /dev/null
+++ b/3rdparty/sol2/Catch/.travis.yml
@@ -0,0 +1,163 @@
+language: cpp
+sudo: false
+
+cache:
+ ccache: true
+ directories:
+ - $HOME/.ccache
+
+env:
+ global:
+ - USE_CCACHE=1
+ - CCACHE_COMPRESS=1
+ - CCACHE_MAXSIZE=200M
+ - CCACHE_CPP2=1
+
+
+matrix:
+ include:
+
+ # 1/ Linux Clang Builds
+ - os: linux
+ compiler: clang
+ addons: &clang35
+ apt:
+ sources: ['llvm-toolchain-precise-3.5', 'ubuntu-toolchain-r-test']
+ packages: ['clang-3.5']
+ env: COMPILER='ccache clang++-3.5' BUILD_TYPE='Release'
+
+ - os: linux
+ compiler: clang
+ addons: *clang35
+ env: COMPILER='ccache clang++-3.5' BUILD_TYPE='Debug'
+
+
+ - os: linux
+ compiler: clang
+ addons: &clang36
+ apt:
+ sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test']
+ packages: ['clang-3.6']
+ env: COMPILER='ccache clang++-3.6' BUILD_TYPE='Release'
+
+ - os: linux
+ compiler: clang
+ addons: *clang36
+ env: COMPILER='ccache clang++-3.6' BUILD_TYPE='Debug'
+
+
+ - os: linux
+ compiler: clang
+ addons: &clang37
+ apt:
+ sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test']
+ packages: ['clang-3.7']
+ env: COMPILER='ccache clang++-3.7' BUILD_TYPE='Release'
+
+ - os: linux
+ compiler: clang
+ addons: *clang37
+ env: COMPILER='ccache clang++-3.7' BUILD_TYPE='Debug'
+
+
+ - os: linux
+ compiler: clang
+ addons: &clang38
+ apt:
+ sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test']
+ packages: ['clang-3.8']
+ env: COMPILER='ccache clang++-3.8' BUILD_TYPE='Release'
+
+ - os: linux
+ compiler: clang
+ addons: *clang38
+ env: COMPILER='ccache clang++-3.8' BUILD_TYPE='Debug'
+
+
+ # 2/ Linux GCC Builds
+ - os: linux
+ compiler: gcc
+ addons: &gcc48
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['g++-4.8']
+ env: COMPILER='ccache g++-4.8' BUILD_TYPE='Release'
+
+ - os: linux
+ compiler: gcc
+ addons: *gcc48
+ env: COMPILER='ccache g++-4.8' BUILD_TYPE='Debug'
+
+
+ - os: linux
+ compiler: gcc
+ addons: &gcc49
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['g++-4.9']
+ env: COMPILER='ccache g++-4.9' BUILD_TYPE='Release'
+
+ - os: linux
+ compiler: gcc
+ addons: *gcc49
+ env: COMPILER='ccache g++-4.9' BUILD_TYPE='Debug'
+
+
+ - os: linux
+ compiler: gcc
+ addons: &gcc5
+ apt:
+ sources: ['ubuntu-toolchain-r-test']
+ packages: ['g++-5']
+ env: COMPILER='ccache g++-5' BUILD_TYPE='Release'
+
+ - os: linux
+ compiler: gcc
+ addons: *gcc5
+ env: COMPILER='ccache g++-5' BUILD_TYPE='Debug'
+
+
+ # 3/ OSX Clang Builds
+ - os: osx
+ osx_image: xcode6.4
+ compiler: clang
+ env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
+
+ - os: osx
+ osx_image: xcode6.4
+ compiler: clang
+ env: COMPILER='ccache clang++' BUILD_TYPE='Release'
+
+
+ - os: osx
+ osx_image: xcode7
+ compiler: clang
+ env: COMPILER='ccache clang++' BUILD_TYPE='Debug'
+
+ - os: osx
+ osx_image: xcode7
+ compiler: clang
+ env: COMPILER='ccache clang++' BUILD_TYPE='Release'
+
+
+install:
+ - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
+ - mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
+ - |
+ if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
+ CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz"
+ mkdir cmake && travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
+ export PATH=${DEPS_DIR}/cmake/bin:${PATH}
+ elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
+ brew install cmake ccache
+ fi
+
+before_script:
+ - export CXX=${COMPILER}
+ - cd ${TRAVIS_BUILD_DIR}
+ - cmake -Hprojects/CMake -BBuild -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
+ - cd Build
+
+script:
+ - make -j 2
+ - ctest -V -j 2
diff --git a/3rdparty/sol2/Catch/LICENSE_1_0.txt b/3rdparty/sol2/Catch/LICENSE_1_0.txt
new file mode 100644
index 00000000000..36b7cd93cdf
--- /dev/null
+++ b/3rdparty/sol2/Catch/LICENSE_1_0.txt
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/3rdparty/sol2/Catch/README.md b/3rdparty/sol2/Catch/README.md
new file mode 100644
index 00000000000..33d124135c9
--- /dev/null
+++ b/3rdparty/sol2/Catch/README.md
@@ -0,0 +1,22 @@
+![catch logo](catch-logo-small.png)
+
+*v1.3.4*
+
+Build status (on Travis CI) [![Build Status](https://travis-ci.org/philsquared/Catch.png)](https://travis-ci.org/philsquared/Catch)
+
+<a href="https://raw.githubusercontent.com/philsquared/Catch/master/single_include/catch.hpp">The latest, single header, version can be downloaded directly using this link</a>
+
+## What's the Catch?
+
+Catch stands for C++ Automated Test Cases in Headers and is a multi-paradigm automated test framework for C++ and Objective-C (and, maybe, C). It is implemented entirely in a set of header files, but is packaged up as a single header for extra convenience.
+
+## How to use it
+This documentation comprises these three parts:
+
+* [Why do we need yet another C++ Test Framework?](docs/why-catch.md)
+* [Tutorial](docs/tutorial.md) - getting started
+* [Reference section](docs/Readme.md) - all the details
+
+## More
+* Issues and bugs can be raised on the [Issue tracker on GitHub](https://github.com/philsquared/Catch/issues)
+* For discussion or questions please use [the dedicated Google Groups forum](https://groups.google.com/forum/?fromgroups#!forum/catch-forum)
diff --git a/3rdparty/sol2/Catch/catch-logo-small.png b/3rdparty/sol2/Catch/catch-logo-small.png
new file mode 100644
index 00000000000..a4e74e8a27e
--- /dev/null
+++ b/3rdparty/sol2/Catch/catch-logo-small.png
Binary files differ
diff --git a/3rdparty/sol2/Catch/docs/Readme.md b/3rdparty/sol2/Catch/docs/Readme.md
new file mode 100644
index 00000000000..74b876de33b
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/Readme.md
@@ -0,0 +1,20 @@
+These are the currently documented areas of the framework. There is more to come.
+
+Before looking at this material be sure to read the [tutorial](tutorial.md)
+
+* [Assertion macros](assertions.md)
+* [Logging macros](logging.md)
+* [Test cases and sections](test-cases-and-sections.md)
+* [Test fixtures](test-fixtures.md)
+* [Command line](command-line.md)
+* [Build systems](build-systems.md)
+* [Supplying your own main()](own-main.md)
+* [Configuration](configuration.md)
+* [String Conversions](tostring.md)
+* [Why are my tests slow to compile?](slow-compiles.md)
+
+Other
+
+* [Why Catch?](why-catch.md)
+* [What's changed](whats-changed.md)
+* [Contributing](contributing.md)
diff --git a/3rdparty/sol2/Catch/docs/assertions.md b/3rdparty/sol2/Catch/docs/assertions.md
new file mode 100644
index 00000000000..82bb96a3447
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/assertions.md
@@ -0,0 +1,82 @@
+# Assertion Macros
+
+Most test frameworks have a large collection of assertion macros to capture all possible conditional forms (```_EQUALS```, ```_NOTEQUALS```, ```_GREATER_THAN``` etc).
+
+Catch is different. Because it decomposes natural C-style conditional expressions most of these forms are reduced to one or two that you will use all the time. That said there are a rich set of auxilliary macros as well. We'll describe all of these here.
+
+Most of these macros come in two forms:
+
+## Natural Expressions
+
+The ```REQUIRE``` family of macros tests an expression and aborts the test case if it fails.
+The ```CHECK``` family are equivalent but execution continues in the same test case even if the assertion fails. This is useful if you have a series of essentially orthogonal assertions and it is useful to see all the results rather than stopping at the first failure.
+
+* **REQUIRE(** _expression_ **)** and
+* **CHECK(** _expression_ **)**
+
+Evaluates the expression and records the result. If an exception is thrown it is caught, reported, and counted as a failure. These are the macros you will use most of the time
+
+Examples:
+```
+CHECK( str == "string value" );
+CHECK( thisReturnsTrue() );
+REQUIRE( i == 42 );
+```
+
+* **REQUIRE_FALSE(** _expression_ **)** and
+* **CHECK_FALSE(** _expression_ **)**
+
+Evaluates the expression and records the _logical NOT_ of the result. If an exception is thrown it is caught, reported, and counted as a failure.
+(these forms exist as a workaround for the fact that ! prefixed expressions cannot be decomposed).
+
+Example:
+```
+REQUIRE_FALSE( thisReturnsFalse() );
+```
+
+### Floating point comparisons
+
+When comparing floating point numbers - especially if at least one of them has been computed - great care must be taken to allow for rounding errors and inexact representations.
+
+Catch provides a way to perform tolerant comparisons of floating point values through use of a wrapper class called ```Approx```. ```Approx``` can be used on either side of a comparison expression. It overloads the comparisons operators to take a tolerance into account. Here's a simple example:
+
+```
+REQUIRE( performComputation() == Approx( 2.1 ) );
+```
+
+By default a small epsilon value is used that covers many simple cases of rounding errors. When this is insufficent the epsilon value (the amount within which a difference either way is ignored) can be specified by calling the ```epsilon()``` method on the ```Approx``` instance. e.g.:
+
+```
+REQUIRE( 22/7 == Approx( 3.141 ).epsilon( 0.01 ) );
+```
+
+When dealing with very large or very small numbers it can be useful to specify a scale, which can be achieved by calling the ```scale()``` method on the ```Approx``` instance.
+
+## Exceptions
+
+* **REQUIRE_THROWS(** _expression_ **)** and
+* **CHECK_THROWS(** _expression_ **)**
+
+Expects that an exception (of any type) is be thrown during evaluation of the expression.
+
+* **REQUIRE_THROWS_AS(** _expression_, _exception type_ **)** and
+* **CHECK_THROWS_AS(** _expression_, _exception type_ **)**
+
+Expects that an exception of the _specified type_ is thrown during evaluation of the expression.
+
+* **REQUIRE_NOTHROW(** _expression_ **)** and
+* **CHECK_NOTHROW(** _expression_ **)**
+
+Expects that no exception is thrown during evaluation of the expression.
+
+## Matcher expressions
+
+To support Matchers a slightly different form is used. Matchers will be more fully documented elsewhere. *Note that Matchers are still at early stage development and are subject to change.*
+
+* **REQUIRE_THAT(** _lhs_, _matcher call_ **)** and
+* **CHECK_THAT(** _lhs_, _matcher call_ **)**
+
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/docs/build-systems.md b/3rdparty/sol2/Catch/docs/build-systems.md
new file mode 100644
index 00000000000..b001dc19d99
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/build-systems.md
@@ -0,0 +1,86 @@
+# Integration with build systems
+
+Build Systems may refer to low-level tools, like CMake, or larger systems that run on servers, like Jenkins or TeamCity. This page will talk about both.
+
+# Continuous Integration systems
+
+Probably the most important aspect to using Catch with a build server is the use of different reporters. Catch comes bundled with three reporters that should cover the majority of build servers out there - although adding more for better integration with some is always a possibility (as has been done with TeamCity).
+
+Two of these reporters are built in (XML and JUnit) and the third (TeamCity) is included as a separate header. It's possible that the other two may be split out in the future too - as that would make the core of Catch smaller for those that don't need them.
+
+## XML Reporter
+```-r xml```
+
+The XML Reporter writes in an XML format that is specific to Catch.
+
+The advantage of this format is that it corresponds well to the way Catch works (especially the more unusual features, such as nested sections) and is a fully streaming format - that is it writes output as it goes, without having to store up all its results before it can start writing.
+
+The disadvantage is that, being specific to Catch, no existing build servers understand the format natively. It can be used as input to an XSLT transformation that could covert it to, say, HTML - although this loses the streaming advantage, of course.
+
+## JUnit Reporter
+```-r junit```
+
+The JUnit Reporter writes in an XML format that mimics the JUnit ANT schema.
+
+The advantage of this format is that the JUnit Ant schema is widely understood by most build servers and so can usually be consumed with no additional work.
+
+The disadvantage is that this schema was designed to correspond to how JUnit works - and there is a significant mismatch with how Catch works. Additionally the format is not streamable (because opening elements hold counts of failed and passing tests as attributes) - so the whole test run must complete before it can be written.
+
+## TeamCity Reporter
+```-r teamcity```
+
+The TeamCity Reporter writes TeamCity service messages to stdout. In order to be able to use this reporter an additional header must also be included.
+
+```catch_reporter_teamcity.hpp``` can be found in the ```include\reporters``` directory. It should be included in the same file that ```#define```s ```CATCH_CONFIG_MAIN``` or ```CATCH_CONFIG_RUNNER```. The ```#include``` should be placed after ```#include```ing Catch itself.
+
+e.g.:
+
+```
+#define CATCH_CONFIG_MAIN
+#include "catch.hpp"
+#include "catch_reporter_teamcity.hpp"
+```
+
+Being specific to TeamCity this is the best reporter to use with it - but it is completely unsuitable for any other purpose. It is a streaming format (it writes as it goes) - although test results don't appear in the TeamCity interface until the completion of a suite (usually the whole test run).
+
+# Low-level tools
+
+## CMake
+
+You can use the following CMake script to automatically fetch Catch from github and configure it as an external project:
+
+```CMake
+cmake_minimum_required(VERSION 2.8.8)
+project(catch_builder CXX)
+include(ExternalProject)
+find_package(Git REQUIRED)
+
+ExternalProject_Add(
+ catch
+ PREFIX ${CMAKE_BINARY_DIR}/catch
+ GIT_REPOSITORY https://github.com/philsquared/Catch.git
+ TIMEOUT 10
+ UPDATE_COMMAND ${GIT_EXECUTABLE} pull
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ LOG_DOWNLOAD ON
+ )
+
+# Expose required variable (CATCH_INCLUDE_DIR) to parent scope
+ExternalProject_Get_Property(catch source_dir)
+set(CATCH_INCLUDE_DIR ${source_dir}/include CACHE INTERNAL "Path to include folder for Catch")
+```
+
+If you put it in, e.g., `${PROJECT_SRC_DIR}/${EXT_PROJECTS_DIR}/catch/`, you can use it in your project by adding the following to your root CMake file:
+
+```CMake
+# Includes Catch in the project:
+add_subdirectory(${EXT_PROJECTS_DIR}/catch)
+include_directories(${CATCH_INCLUDE_DIR} ${COMMON_INCLUDES})
+enable_testing(true) # Enables unit-testing.
+```
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/docs/command-line.md b/3rdparty/sol2/Catch/docs/command-line.md
new file mode 100644
index 00000000000..d1d4bd4a614
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/command-line.md
@@ -0,0 +1,220 @@
+Catch works quite nicely without any command line options at all - but for those times when you want greater control the following options are available.
+Click one of the followings links to take you straight to that option - or scroll on to browse the available options.
+
+<a href="#specifying-which-tests-to-run"> ` <test-spec> ...`</a><br />
+<a href="#usage"> ` -h, -?, --help`</a><br />
+<a href="#listing-available-tests-tags-or-reporters"> ` -l, --list-tests`</a><br />
+<a href="#listing-available-tests-tags-or-reporters"> ` -t, --list-tags`</a><br />
+<a href="#showing-results-for-successful-tests"> ` -s, --success`</a><br />
+<a href="#breaking-into-the-debugger"> ` -b, --break`</a><br />
+<a href="#eliding-assertions-expected-to-throw"> ` -e, --nothrow`</a><br />
+<a href="#invisibles"> ` -i, --invisibles`</a><br />
+<a href="#sending-output-to-a-file"> ` -o, --out`</a><br />
+<a href="#choosing-a-reporter-to-use"> ` -r, --reporter`</a><br />
+<a href="#naming-a-test-run"> ` -n, --name`</a><br />
+<a href="#aborting-after-a-certain-number-of-failures"> ` -a, --abort`</a><br />
+<a href="#aborting-after-a-certain-number-of-failures"> ` -x, --abortx`</a><br />
+<a href="#warnings"> ` -w, --warn`</a><br />
+<a href="#reporting-timings"> ` -d, --durations`</a><br />
+<a href="#input-file"> ` -f, --input-file`</a><br />
+
+</br>
+
+<a href="#list-test-names-only"> ` --list-test-names-only`</a><br />
+<a href="#listing-available-tests-tags-or-reporters"> ` --list-reporters`</a><br />
+<a href="#order"> ` --order`</a><br />
+<a href="#rng-seed"> ` --rng-seed`</a><br />
+
+</br>
+
+
+
+<a id="specifying-which-tests-to-run"></a>
+## Specifying which tests to run
+
+<pre>&lt;test-spec> ...</pre>
+
+Test cases, wildcarded test cases, tags and tag expressions are all passed directly as arguments. Tags are distinguished by being enclosed in square brackets.
+
+If no test specs are supplied then all test cases, except "hidden" tests, are run.
+A test is hidden by giving it any tag starting with (or just) a period (```.```) - or, in the deprecated case, tagged ```[hide]``` or given name starting with `'./'`. To specify hidden tests from the command line ```[.]``` or ```[hide]``` can be used *regardless of how they were declared*.
+
+Specs must be enclosed in quotes if they contain spaces. If they do not contain spaces the quotes are optional.
+
+Wildcards consist of the `*` character at the beginning and/or end of test case names and can substitute for any number of any characters (including none).
+
+Test specs are case insensitive.
+
+If a spec is prefixed with `exclude:` or the `~` character then the pattern matches an exclusion. This means that tests matching the pattern are excluded from the set - even if a prior inclusion spec included them. Subsequent inclusion specs will take precendence, however.
+Inclusions and exclusions are evaluated in left-to-right order.
+
+Test case examples:
+
+<pre>thisTestOnly Matches the test case called, 'thisTestOnly'
+"this test only" Matches the test case called, 'this test only'
+these* Matches all cases starting with 'these'
+exclude:notThis Matches all tests except, 'notThis'
+~notThis Matches all tests except, 'notThis'
+~*private* Matches all tests except those that contain 'private'
+a* ~ab* abc Matches all tests that start with 'a', except those that
+ start with 'ab', except 'abc', which is included
+</pre>
+
+Names within square brackets are interpreted as tags.
+A series of tags form an AND expression wheras a comma-separated sequence forms an OR expression. e.g.:
+
+<pre>[one][two],[three]</pre>
+This matches all tests tagged `[one]` and `[two]`, as well as all tests tagged `[three]`
+
+
+<a id="choosing-a-reporter-to-use"></a>
+## Choosing a reporter to use
+
+<pre>-r, --reporter &lt;reporter></pre>
+
+A reporter is an object that formats and structures the output of running tests, and potentially summarises the results. By default a console reporter is used that writes, IDE friendly, textual output. Catch comes bundled with some alternative reporters, but more can be added in client code.<br />
+The bundled reporters are:
+
+<pre>-r console
+-r compact
+-r xml
+-r junit
+</pre>
+
+The JUnit reporter is an xml format that follows the structure of the JUnit XML Report ANT task, as consumed by a number of third-party tools, including Continuous Integration servers such as Hudson. If not otherwise needed, the standard XML reporter is preferred as this is a streaming reporter, whereas the Junit reporter needs to hold all its results until the end so it can write the overall results into attributes of the root node.
+
+<a id="breaking-into-the-debugger"></a>
+## Breaking into the debugger
+<pre>-b, --break</pre>
+
+In some IDEs (currently XCode and Visual Studio) it is possible for Catch to break into the debugger on a test failure. This can be very helpful during debug sessions - especially when there is more than one path through a particular test.
+In addition to the command line option, ensure you have built your code with the DEBUG preprocessor symbol
+
+<a id="showing-results-for-successful-tests"></a>
+## Showing results for successful tests
+<pre>-s, --success</pre>
+
+Usually you only want to see reporting for failed tests. Sometimes it's useful to see *all* the output (especially when you don't trust that that test you just added worked first time!).
+To see successful, as well as failing, test results just pass this option. Note that each reporter may treat this option differently. The Junit reporter, for example, logs all results regardless.
+
+<a id="aborting-after-a-certain-number-of-failures"></a>
+## Aborting after a certain number of failures
+<pre>-a, --abort
+-x, --abortx [&lt;failure threshold>]
+</pre>
+
+If a ```REQUIRE``` assertion fails the test case aborts, but subsequent test cases are still run.
+If a ```CHECK``` assertion fails even the current test case is not aborted.
+
+Sometimes this results in a flood of failure messages and you'd rather just see the first few. Specifying ```-a``` or ```--abort``` on its own will abort the whole test run on the first failed assertion of any kind. Use ```-x``` or ```--abortx``` followed by a number to abort after that number of assertion failures.
+
+<a id="listing-available-tests-tags-or-reporters"></a>
+## Listing available tests, tags or reporters
+<pre>-l, --list-tests
+-t, --list-tags
+--list-reporters
+</pre>
+
+```-l``` or ```--list-tests`` will list all registered tests, along with any tags.
+If one or more test-specs have been supplied too then only the matching tests will be listed.
+
+```-t``` or ```--list-tags``` lists all available tags, along with the number of test cases they match. Again, supplying test specs limits the tags that match.
+
+```--list-reporters``` lists the available reporters.
+
+<a id="sending-output-to-a-file"></a>
+## Sending output to a file
+<pre>-o, --out &lt;filename>
+</pre>
+
+Use this option to send all output to a file. By default output is sent to stdout (note that uses of stdout and stderr *from within test cases* are redirected and included in the report - so even stderr will effectively end up on stdout).
+
+<a id="naming-a-test-run"></a>
+## Naming a test run
+<pre>-n, --name &lt;name for test run></pre>
+
+If a name is supplied it will be used by the reporter to provide an overall name for the test run. This can be useful if you are sending to a file, for example, and need to distinguish different test runs - either from different Catch executables or runs of the same executable with different options. If not supplied the name is defaulted to the name of the executable.
+
+<a id="eliding-assertions-expected-to-throw"></a>
+## Eliding assertions expected to throw
+<pre>-e, --nothrow</pre>
+
+Skips all assertions that test that an exception is thrown, e.g. ```REQUIRE_THROWS```.
+
+These can be a nuisance in certain debugging environments that may break when exceptions are thrown (while this is usually optional for handled exceptions, it can be useful to have enabled if you are trying to track down something unexpected).
+
+Sometimes exceptions are expected outside of one of the assertions that tests for them (perhaps thrown and caught within the code-under-test). The whole test case can be skipped when using ```-e``` by marking it with the ```[!throws]``` tag.
+
+When running with this option any throw checking assertions are skipped so as not to contribute additional noise. Be careful if this affects the behaviour of subsequent tests.
+
+<a id="invisibles"></a>
+## Make whitespace visible
+<pre>-i, --invisibles</pre>
+
+If a string comparison fails due to differences in whitespace - especially leading or trailing whitespace - it can be hard to see what's going on.
+This option transforms tabs and newline characters into ```\t``` and ```\n``` respectively when printing.
+
+<a id="warnings"></a>
+## Warnings
+<pre>-w, --warn &lt;warning name></pre>
+
+Enables reporting of warnings (only one, at time of this writing). If a warning is issued it fails the test.
+
+The ony available warning, presently, is ```NoAssertions```. This warning fails a test case, or (leaf) section if no assertions (```REQUIRE```/ ```CHECK``` etc) are encountered.
+
+<a id="reporting-timings"></a>
+## Reporting timings
+<pre>-d, --durations &lt;yes/no></pre>
+
+When set to ```yes``` Catch will report the duration of each test case, in milliseconds. Note that it does this regardless of whether a test case passes or fails. Note, also, the certain reporters (e.g. Junit) always report test case durations regardless of this option being set or not.
+
+<a id="input-file"></a>
+## Load test names to run from a file
+<pre>-f, --input-file &lt;filename></pre>
+
+Provide the name of a file that contains a list of test case names - one per line. Blank lines are skipped and anything after the comment character, ```#```, is ignored.
+
+A useful way to generate an initial instance of this file is to use the <a href="#list-test-names-only">list-test-names-only</a> option. This can then be manually curated to specify a specific subset of tests - or in a specific order.
+
+<a id="list-test-names-only"></a>
+## Just test names
+<pre>--list-test-names-only</pre>
+
+This option lists all available tests in a non-indented form, one on each line. This makes it ideal for saving to a file and feeding back into the <a href="#input-file">```-f``` or ```--input-file```</a> option.
+
+
+<a id="order"></a>
+## Specify the order test cases are run
+<pre>--order &lt;decl|lex|rand&gt;</pre>
+
+Test cases are ordered one of three ways:
+
+
+### decl
+Declaration order. The order the tests were originally declared in. Note that ordering between files is not guaranteed and is implementation dependent.
+
+### lex
+Lexicographically sorted. Tests are sorted, alpha-numerically, by name.
+
+### rand
+Randomly sorted. Test names are sorted using ```std::random_shuffle()```. By default the random number generator is seeded with 0 - and so the order is repeatable. To control the random seed see <a href="#rng-seed">rng-seed</a>.
+
+<a id="rng-seed"></a>
+## Specify a seed for the Random Number Generator
+<pre>--rng-seed &lt;'time'|number&gt;</pre>
+
+Sets a seed for the random number generator using ```std::srand()```.
+If a number is provided this is used directly as the seed so the random pattern is repeatable.
+Alternatively if the keyword ```time``` is provided then the result of calling ```std::time(0)``` is used and so the pattern becomes unpredictable.
+
+In either case the actual value for the seed is printed as part of Catch's output so if an issue is discovered that is sensitive to test ordering the ordering can be reproduced - even if it was originally seeded from ```std::time(0)```.
+
+<a id="usage"></a>
+## Usage
+<pre>-h, -?, --help</pre>
+
+Prints the command line arguments to stdout
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/docs/configuration.md b/3rdparty/sol2/Catch/docs/configuration.md
new file mode 100644
index 00000000000..33052190cf3
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/configuration.md
@@ -0,0 +1,73 @@
+Catch is designed to "just work" as much as possible. For most people the only configuration needed is telling Catch which source file should host all the implementation code (```CATCH_CONFIG_MAIN```).
+
+Nonetheless there are still some occasions where finer control is needed. For these occasions Catch exposes a small set of macros for configuring how it is built.
+
+# main()/ implementation
+
+ CATCH_CONFIG_MAIN // Designates this as implementation file and defines main()
+ CATCH_CONFIG_RUNNER // Designates this as implementation file
+
+Although Catch is header only it still, internally, maintains a distinction between interface headers and headers that contain implementation. Only one source file in your test project should compile the implementation headers and this is controlled through the use of one of these macros - one of these identifiers should be defined before including Catch in *exactly one implementation file in your project*.
+
+# Prefixing Catch macros
+
+ CATCH_CONFIG_PREFIX_ALL
+
+To keep test code clean and uncluttered Catch uses short macro names (e.g. ```TEST_CASE``` and ```REQUIRE```). Occasionally these may conflict with identifiers from platform headers or the system under test. In this case the above identifier can be defined. This will cause all the Catch user macros to be prefixed with ```CATCH_``` (e.g. ```CATCH_TEST_CASE``` and ```CATCH_REQUIRE```).
+
+
+# Terminal colour
+
+ CATCH_CONFIG_COLOUR_NONE // completely disables all text colouring
+ CATCH_CONFIG_COLOUR_WINDOWS // forces the Win32 console API to be used
+ CATCH_CONFIG_COLOUR_ANSI // forces ANSI colour codes to be used
+
+Yes, I am English, so I will continue to spell "colour" with a 'u'.
+
+When sending output to the terminal, if it detects that it can, Catch will use colourised text. On Windows the Win32 API, ```SetConsoleTextAttribute```, is used. On POSIX systems ANSI colour escape codes are inserted into the stream.
+
+For finer control you can define one of the above identifiers (these are mutually exclusive - but that is not checked so may behave unexpectedly if you mix them):
+
+Note that when ANSI colour codes are used "unistd.h" must be includable - along with a definition of ```isatty()```
+
+Typically you should place the ```#define``` before #including "catch.hpp" in your main source file - but if you prefer you can define it for your whole project by whatever your IDE or build system provides for you to do so.
+
+# Console width
+
+ CATCH_CONFIG_CONSOLE_WIDTH = x // where x is a number
+
+Catch formats output intended for the console to fit within a fixed number of characters. This is especially important as indentation is used extensively and uncontrolled line wraps break this.
+By default a console width of 80 is assumed but this can be controlled by defining the above identifier to be a different value.
+
+# stdout
+
+ CATCH_CONFIG_NOSTDOUT
+
+Catch does not use ```std::cout``` and ```std::cerr``` directly but gets them from ```Catch::cout()``` and ```Catch::cerr()``` respectively. If the above identifier is defined these functions are left unimplemented and you must implement them yourself. Their signatures are:
+
+ std::ostream& cout();
+ std::ostream& cerr();
+
+This can be useful on certain platforms that do not provide ```std::cout``` and ```std::cerr```, such as certain embedded systems.
+
+# C++ conformance toggles
+
+ CATCH_CONFIG_CPP11_NULLPTR // nullptr is supported?
+ CATCH_CONFIG_CPP11_NOEXCEPT // noexcept is supported?
+ CATCH_CONFIG_CPP11_GENERATED_METHODS // delete and default keywords for methods
+ CATCH_CONFIG_CPP11_IS_ENUM // std::is_enum is supported?
+ CATCH_CONFIG_CPP11_TUPLE // std::tuple is supported
+ CATCH_CONFIG_VARIADIC_MACROS // Usually pre-C++11 compiler extensions are sufficient
+ CATCH_CONFIG_CPP11_LONG_LONG // generates overloads for the long long type
+ CATCH_CONFIG_CPP11_OVERRIDE // CATCH_OVERRIDE expands to override (for virtual function implementations)
+ CATCH_CONFIG_CPP11_UNIQUE_PTR // Use std::unique_ptr instead of std::auto_ptr
+
+Catch has some basic compiler detection that will attempt to select the appropriate mix of these macros. However being incomplete - and often without access to the respective compilers - this detection tends to be conservative.
+So overriding control is given to the user. If a compiler supports a feature (and Catch does not already detect it) then one or more of these may be defined to enable it (or suppress it, in some cases). If you do do this please raise an issue, specifying your compiler version (ideally with an idea of how to detect it) and stating that it has such support.
+You may also suppress any of these features by using the `_NO_` form, e.g. `CATCH_CONFIG_CPP11_NO_NULLPTR`.
+
+All C++11 support can be disabled with `CATCH_CONFIG_NO_CPP11`
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/docs/contributing.md b/3rdparty/sol2/Catch/docs/contributing.md
new file mode 100644
index 00000000000..49a663c042b
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/contributing.md
@@ -0,0 +1,23 @@
+# Contributing to Catch
+
+So you want to contribute something to Catch? That's great! Whether it's a bug fix, a new feature, support for additional compilers - or just a fix to the documentation - all contributions are very welcome and very much appreciated. Of course so are bug reports and other comments and questions.
+
+If you are contributing to the code base there are a few simple guidelines to keep in mind. This also includes notes to help you find your way around. As this is liable to drift out of date please raise an issue or, better still, a pull request for this file, if you notice that.
+
+## Branches
+
+Ongoing development is on the "develop" branch (if there is one, currently), or on feature branches that are branched off of develop. Please target any pull requests at develop, or, for larger chunks of work, a branch off of develop.
+
+## Directory structure
+
+Users of Catch primarily use the single header version. Maintainers should work with the full source (which is still, primarily, in headers). This can be found in the ```include``` folder, but you may prefer to use one of the IDE project files (for MSVC or XCode). These can be found under ```projects/```*IDE Name*```/```*project name*. A number of contributors have proposed make files, and submitted their own versions. At some point these should be made available too.
+
+In addition to the include files and IDE projects there are a number of tests in cpp files. These can all be found in ```projects/SelfTest```. You'll also see a ```SurrogateCpps``` directory in there. This contains a set of cpp files that each ```#include``` a single header. While these files are not essential to compilation they help to keep the implementation headers self-contained. At time of writing this set is not complete but has reasonable coverage. If you add additional headers please try to remember to add a surrogate cpp for it.
+
+The other directories are ```scripts``` which contains a set of python scripts to help in testing Catch as well as generating the single include, and docs, which contains the documentation as a set of markdown files.
+
+ *this document is in-progress...*
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/docs/logging.md b/3rdparty/sol2/Catch/docs/logging.md
new file mode 100644
index 00000000000..a659b3e8e81
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/logging.md
@@ -0,0 +1,52 @@
+# Logging macros
+
+Additional messages can be logged during a test case.
+
+## Streaming macros
+
+All these macros allow heterogenous sequences of values to be streaming using the insertion operator (```<<```) in the same way that std::ostream, std::cout, etc support it.
+
+E.g.:
+```c++
+INFO( "The number is " << i );
+```
+
+(Note that there is no initial ```<<``` - instead the insertion sequence is placed in parentheses.)
+These macros come in three forms:
+
+**INFO(** _message expression_ **)**
+
+The message is logged to a buffer, but only reported with the next assertion that is logged. This allows you to log contextual information in case of failures which is not shown during a successful test run (for the console reporter, without -s). Messages are removed from the buffer at the end of their scope, so may be used, for example, in loops.
+
+**WARN(** _message expression_ **)**
+
+The message is always reported but does not fail the test.
+
+**FAIL(** _message expression_ **)**
+
+The message is reported and the test case fails.
+
+## Quickly capture a variable value
+
+**CAPTURE(** _expression_ **)**
+
+Sometimes you just want to log the name and value of a variable. While you can easily do this with the INFO macro, above, as a convenience the CAPTURE macro handles the stringising of the variable name for you (actually it works with any expression, not just variables).
+
+E.g.
+```c++
+CAPTURE( theAnswer );
+```
+
+This would log something like:
+
+<pre>"theAnswer := 42"</pre>
+
+## Deprecated macros
+
+**SCOPED_INFO and SCOPED_CAPTURE**
+
+These macros are now deprecated and are just aliases for INFO and CAPTURE (which were not previously scoped).
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/docs/own-main.md b/3rdparty/sol2/Catch/docs/own-main.md
new file mode 100644
index 00000000000..f8c836e6f27
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/own-main.md
@@ -0,0 +1,68 @@
+# Supplying main() yourself
+
+The easiest way to use Catch is to let it supply ```main()``` for you and handle configuring itself from the command line.
+
+This is achieved by writing ```#define CATCH_CONFIG_MAIN``` before the ```#include "catch.hpp"``` in *exactly one* source file.
+
+Sometimes, though, you need to write your own version of main(). You can do this by writing ```#define CATCH_CONFIG_RUNNER``` instead. Now you are free to write ```main()``` as normal and call into Catch yourself manually.
+
+You now have a lot of flexibility - but here are three recipes to get your started:
+
+## Let Catch take full control of args and config
+
+If you just need to have code that executes before and/ or after Catch this is the simplest option.
+
+```c++
+#define CATCH_CONFIG_RUNNER
+#include "catch.hpp"
+
+int main( int argc, char* const argv[] )
+{
+ // global setup...
+
+ int result = Catch::Session().run( argc, argv );
+
+ // global clean-up...
+
+ return result;
+}
+```
+
+## Amending the config
+
+If you still want Catch to process the command line, but you want to programatically tweak the config, you can do so in one of two ways:
+
+```c++
+#define CATCH_CONFIG_RUNNER
+#include "catch.hpp"
+
+int main( int argc, char* const argv[] )
+{
+ Catch::Session session; // There must be exactly once instance
+
+ // writing to session.configData() here sets defaults
+ // this is the preferred way to set them
+
+ int returnCode = session.applyCommandLine( argc, argv );
+ if( returnCode != 0 ) // Indicates a command line error
+ return returnCode;
+
+ // writing to session.configData() or session.Config() here
+ // overrides command line args
+ // only do this if you know you need to
+
+ return session.run();
+}
+```
+
+Take a look at the definitions of Config and ConfigData to see what you can do with them.
+
+To take full control of the config simply omit the call to ```applyCommandLine()```.
+
+## Adding your own command line options
+
+Catch embeds a powerful command line parser which you can also use to parse your own options out. This capability is still in active development but will be documented here when it is ready.
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/docs/slow-compiles.md b/3rdparty/sol2/Catch/docs/slow-compiles.md
new file mode 100644
index 00000000000..5291aeccc1d
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/slow-compiles.md
@@ -0,0 +1,22 @@
+# Why do my tests take so long to compile?
+
+Several people have reported that test code written with Catch takes much longer to compile than they would expect. Why is that?
+
+Catch is implemented entirely in headers. There is a little overhead due to this - but not as much as you might think - and you can minimise it simply by organising your test code as follows:
+
+## Short answer
+Exactly one source file must ```#define``` either ```CATCH_CONFIG_MAIN``` or ```CATCH_CONFIG_RUNNER``` before ```#include```-ing Catch. In this file *do not write any test cases*! In most cases that means this file will just contain two lines (the ```#define``` and the ```#include```).
+
+## Long answer
+
+Usually C++ code is split between a header file, containing declarations and prototypes, and an implementation file (.cpp) containing the definition, or implementation, code. Each implementation file, along with all the headers that it includes (and which those headers include, etc), is expanded into a single entity called a translation unit - which is then passed to the compiler and compiled down to an object file.
+
+But functions and methods can also be written inline in header files. The downside to this is that these definitions will then be compiled in *every* translation unit that includes the header.
+
+Because Catch is implemented *entirely* in headers you might think that the whole of Catch must be compiled into every translation unit that uses it! Actually it's not quite as bad as that. Catch mitigates this situation by effectively maintaining the traditional separation between the implementation code and declarations. Internally the implementation code is protected by ```#ifdef```s and is conditionally compiled into only one translation unit. This translation unit is that one that ```#define```s ```CATCH_CONFIG_MAIN``` or ```CATCH_CONFIG_RUNNER```. Let's call this the main source file.
+
+As a result the main source file *does* compile the whole of Catch every time! So it makes sense to dedicate this file to *only* ```#define```-ing the identifier and ```#include```-ing Catch (and implementing the runner code, if you're doing that). Keep all your test cases in other files. This way you won't pay the recompilation cost for the whole of Catch
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/docs/test-cases-and-sections.md b/3rdparty/sol2/Catch/docs/test-cases-and-sections.md
new file mode 100644
index 00000000000..86644f006cd
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/test-cases-and-sections.md
@@ -0,0 +1,86 @@
+# Test cases and sections
+
+While Catch fully supports the traditional, xUnit, style of class-based fixtures containing test case methods this is not the preferred style.
+
+Instead Catch provides a powerful mechanism for nesting test case sections within a test case. For a more detailed discussion see the [tutorial](tutorial.md#testCasesAndSections).
+
+Test cases and sections are very easy to use in practice:
+
+* **TEST_CASE(** _test name_ \[, _tags_ \] **)**
+* **SECTION(** _section name_ **)**
+
+_test name_ and _section name_ are free form, quoted, strings. The optional _tags_ argument is a quoted string containing one or more tags enclosed in square brackets. Tags are discussed below. Test names must be unique within the Catch executable.
+
+For examples see the [Tutorial](tutorial.md)
+
+## Tags
+
+Tags allow an arbitrary number of additional strings to be associated with a test case. Test cases can be selected (for running, or just for listing) by tag - or even by an expression that combines several tags. At their most basic level they provide a simple way to group several related tests together.
+
+As an example - given the following test cases:
+
+ TEST_CASE( "A", "[widget]" ) { /* ... */ }
+ TEST_CASE( "B", "[widget]" ) { /* ... */ }
+ TEST_CASE( "C", "[gadget]" ) { /* ... */ }
+ TEST_CASE( "D", "[widget][gadget]" ) { /* ... */ }
+
+The tag expression, ```"[widget]"``` selects A, B & D. ```"[gadget]"``` selects C & D. ```"[widget][gadget]"``` selects just D and ```"[widget],[gadget]"``` selects all four test cases.
+
+For more detail on command line selection see [the command line docs](command-line.md#specifying-which-tests-to-run)
+
+Tag names are not case sensitive.
+
+### Special Tags
+
+All tag names beginning with non-alphanumeric characters are reserved by Catch. Catch defines a number of "special" tags, which have meaning to the test runner itself. These special tags all begin with a symbol character. Following is a list of currently defined special tags and their meanings.
+
+* `[!hide]` or `[.]` (or, for legacy reasons, `[hide]`) - causes test cases to be skipped from the default list (ie when no test cases have been explicitly selected through tag expressions or name wildcards). The hide tag is often combined with another, user, tag (for example `[.][integration]` - so all integration tests are excluded from the default run but can be run by passing `[integration]` on the command line). As a short-cut you can combine these by simply prefixing your user tag with a `.` - e.g. `[.integration]`. Because the hide tag has evolved to have several forms, all forms are added as tags if you use one of them.
+
+* `[!throws]` - lets Catch know that this test is likely to throw an exception even if successful. This causes the test to be exluded when running with `-e` or `--nothrow`.
+
+* `[!shouldfail]` - reverse the failing logic of the test: if the test is successful if it fails, and vice-versa.
+
+* `[!mayfail]` - doesn't fail the test if any given assertion fails (but still reports it). This can be useful to flag a work-in-progress, or a known issue that you don't want to immediately fix but still want to track in the your tests.
+
+* `[#<filename>]` - running with `-#` or `--filenames-as-tags` causes Catch to add the filename, prefixed with `#` (and with any extension stripped) as a tag. e.g. tests in testfile.cpp would all be tagged `[#testfile]`.
+
+* `[@<alias>]` - tag aliases all begin with `@` (see below).
+
+## Tag aliases
+
+Between tag expressions and wildcarded test names (as well as combinations of the two) quite complex patterns can be constructed to direct which test cases are run. If a complex pattern is used often it is convenient to be able to create an alias for the expression. this can be done, in code, using the following form:
+
+ CATCH_REGISTER_TAG_ALIAS( <alias string>, <tag expression> )
+
+Aliases must begining with the `@` character. An example of a tag alias is:
+
+ CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
+
+Now when `[@nhf]` is used on the command line this matches all tests that are tagged `[failing]`, but which are not also hidden.
+
+## BDD-style test cases
+
+In addition to Catch's take on the classic style of test cases, Catch supports an alternative syntax that allow tests to be written as "executable specifications" (one of the early goals of [Behaviour Driven Development](http://dannorth.net/introducing-bdd/)). This set of macros map on to ```TEST_CASE```s and ```SECTION```s, with a little internal support to make them smoother to work with.
+
+* **SCENARIO(** _scenario name_ \[, _tags_ \] **)**
+
+This macro maps onto ```TEST_CASE``` and works in the same way, except that the test case name will be prefixed by "Scenario: "
+
+* **GIVEN(** _something_ **)**
+* **WHEN(** _something_ **)**
+* **THEN(** _something_ **)**
+
+These macros map onto ```SECTION```s except that the section names are the _something_s prefixed by "given: ", "when: " or "then: " respectively.
+
+* **AND_WHEN(** _something_ **)**
+* **AND_THEN(** _something_ **)**
+
+Similar to ```WHEN``` and ```THEN``` except that the prefixes start with "and ". These are used to chain ```WHEN```s and ```THEN```s together.
+
+When any of these macros are used the console reporter recognises them and formats the test case header such that the Givens, Whens and Thens are aligned to aid readability.
+
+Other than the additional prefixes and the formatting in the console reporter these macros behave exactly as ```TEST_CASE```s and ```SECTION```s. As such there is nothing enforcing the correct sequencing of these macros - that's up to the programmer!
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/docs/test-fixtures.md b/3rdparty/sol2/Catch/docs/test-fixtures.md
new file mode 100644
index 00000000000..6bef762b8e3
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/test-fixtures.md
@@ -0,0 +1,32 @@
+Although Catch allows you to group tests together as sections within a test case, it can still convenient, sometimes, to group them using a more traditional test fixture. Catch fully supports this too. You define the test fixture as a simple structure:
+
+```c++
+class UniqueTestsFixture {
+ private:
+ static int uniqueID;
+ protected:
+ DBConnection conn;
+ public:
+ UniqueTestsFixture() : conn(DBConnection::createConnection("myDB")) {
+ }
+ protected:
+ int getID() {
+ return ++uniqueID;
+ }
+ };
+
+ int UniqueTestsFixture::uniqueID = 0;
+
+ TEST_CASE_METHOD(UniqueTestsFixture, "Create Employee/No Name", "[create]") {
+ REQUIRE_THROWS(conn.executeSQL("INSERT INTO employee (id, name) VALUES (?, ?)", getID(), ""));
+ }
+ TEST_CASE_METHOD(UniqueTestsFixture, "Create Employee/Normal", "[create]") {
+ REQUIRE(conn.executeSQL("INSERT INTO employee (id, name) VALUES (?, ?)", getID(), "Joe Bloggs"));
+ }
+```
+
+The two test cases here will create uniquely-named derived classes of UniqueTestsFixture and thus can access the `getID()` protected method and `conn` member variables. This ensures that both the test cases are able to create a DBConnection using the same method (DRY principle) and that any ID's created are unique such that the order that tests are executed does not matter.
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/docs/tostring.md b/3rdparty/sol2/Catch/docs/tostring.md
new file mode 100644
index 00000000000..dbb6cb8d5d0
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/tostring.md
@@ -0,0 +1,70 @@
+# String conversions
+
+Catch needs to be able to convert types you use in assertions and logging expressions into strings (for logging and reporting purposes).
+Most built-in or std types are supported out of the box but there are three ways that you can tell Catch how to convert your own types (or other, third-party types) into strings.
+
+## operator << overload for std::ostream
+
+This is the standard way of providing string conversions in C++ - and the chances are you may already provide this for your own purposes. If you're not familiar with this idiom it involves writing a free function of the form:
+
+```
+std::ostream& operator << ( std::ostream& os, T const& value ) {
+ os << convertMyTypeToString( value );
+ return os;
+}
+```
+
+(where ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable - it doesn't have to be in another function).
+
+You should put this function in the same namespace as your type.
+
+Alternatively you may prefer to write it as a member function:
+
+```
+std::ostream& T::operator << ( std::ostream& os ) const {
+ os << convertMyTypeToString( *this );
+ return os;
+}
+```
+
+## Catch::toString overload
+
+If you don't want to provide an ```operator <<``` overload, or you want to convert your type differently for testing purposes, you can provide an overload for ```Catch::toString()``` for your type.
+
+```
+namespace Catch {
+ std::string toString( T const& value ) {
+ return convertMyTypeToString( value );
+ }
+}
+```
+
+Again ```T``` is your type and ```convertMyTypeToString``` is where you'll write whatever code is necessary to make your type printable. Note that the function must be in the Catch namespace, which itself must be in the global namespace.
+
+## Catch::StringMaker<T> specialisation
+
+There are some cases where overloading toString does not work as expected. Specialising StringMaker<T> gives you more precise, and reliable, control - but at the cost of slightly more code and complexity:
+
+```
+namespace Catch {
+ template<> struct StringMaker<T> {
+ static std::string convert( T const& value ) {
+ return convertMyTypeToString( value );
+ }
+ };
+}
+```
+
+## Exceptions
+
+By default all exceptions deriving from `std::exception` will be translated to strings by calling the `what()` method. For exception types that do not derive from `std::exception` - or if `what()` does not return a suitable string - use `CATCH_TRANSLATE_EXCEPTION`. This defines a function that takes your exception type, by reference, and returns a string. It can appear anywhere in the code - it doesn't have to be in the same translation unit. For example:
+
+```
+CATCH_TRANSLATE_EXCEPTION( MyType& ex ) {
+ return ex.message();
+}
+```
+
+---
+
+[Home](Readme.md)
diff --git a/3rdparty/sol2/Catch/docs/tutorial.md b/3rdparty/sol2/Catch/docs/tutorial.md
new file mode 100644
index 00000000000..0fdaff9bbe3
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/tutorial.md
@@ -0,0 +1,249 @@
+# Getting Catch
+
+The simplest way to get Catch is to download the single header version from [http://builds.catch-lib.net](http://builds.catch-lib.net). Don't be put off by the word "builds" there. The single header is generated by merging a set of individual headers but it is still just normal source code in a header file.
+
+The full source for Catch, including test projects, documentation, and other things, is hosted on GitHub. [http://catch-lib.net](http://catch-lib.net) will redirect you there.
+
+
+## Where to put it?
+
+Catch is header only. All you need to do is drop the file(s) somewhere reachable from your project - either in some central location you can set your header search path to find, or directly into your project tree itself! This is a particularly good option for other Open-Source projects that want to use Catch for their test suite. See [this blog entry for more on that](http://www.levelofindirection.com/journal/2011/5/27/unit-testing-in-c-and-objective-c-just-got-ridiculously-easi.html).
+
+The rest of this tutorial will assume that the Catch single-include header (or the include folder) is available unqualified - but you may need to prefix it with a folder name if necessary.
+
+# Writing tests
+
+Let's start with a really simple example. Say you have written a function to calculate factorials and now you want to test it (let's leave aside TDD for now).
+
+```c++
+unsigned int Factorial( unsigned int number ) {
+ return number <= 1 ? number : Factorial(number-1)*number;
+}
+```
+
+To keep things simple we'll put everything in a single file (<a href="#scaling-up">see later for more on how to structure your test files</a>)
+
+```c++
+#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
+#include "catch.hpp"
+
+unsigned int Factorial( unsigned int number ) {
+ return number <= 1 ? number : Factorial(number-1)*number;
+}
+
+TEST_CASE( "Factorials are computed", "[factorial]" ) {
+ REQUIRE( Factorial(1) == 1 );
+ REQUIRE( Factorial(2) == 2 );
+ REQUIRE( Factorial(3) == 6 );
+ REQUIRE( Factorial(10) == 3628800 );
+}
+```
+
+This will compile to a complete executable which responds to [command line arguments](command-line.md). If you just run it with no arguments it will execute all test cases (in this case there is just one), report any failures, report a summary of how many tests passed and failed and return the number of failed tests (useful for if you just want a yes/ no answer to: "did it work").
+
+If you run this as written it will pass. Everything is good. Right?
+Well, there is still a bug here. In fact the first version of this tutorial I posted here genuinely had the bug in! So it's not completely contrived (thanks to Daryle Walker (```@CTMacUser```) for pointing this out).
+
+What is the bug? Well what is the factorial of zero?
+[The factorial of zero is one](http://mathforum.org/library/drmath/view/57128.html) - which is just one of those things you have to know (and remember!).
+
+Let's add that to the test case:
+
+```c++
+TEST_CASE( "Factorials are computed", "[factorial]" ) {
+ REQUIRE( Factorial(0) == 1 );
+ REQUIRE( Factorial(1) == 1 );
+ REQUIRE( Factorial(2) == 2 );
+ REQUIRE( Factorial(3) == 6 );
+ REQUIRE( Factorial(10) == 3628800 );
+}
+```
+
+Now we get a failure - something like:
+
+```
+Example.cpp:9: FAILED:
+ REQUIRE( Factorial(0) == 1 )
+with expansion:
+ 0 == 1
+```
+
+Note that we get the actual return value of Factorial(0) printed for us (0) - even though we used a natural expression with the == operator. That let's us immediately see what the problem is.
+
+Let's change the factorial function to:
+
+```c++
+unsigned int Factorial( unsigned int number ) {
+ return number > 1 ? Factorial(number-1)*number : 1;
+}
+```
+
+Now all the tests pass.
+
+Of course there are still more issues to do deal with. For example we'll hit problems when the return value starts to exceed the range of an unsigned int. With factorials that can happen quite quickly. You might want to add tests for such cases and decide how to handle them. We'll stop short of doing that here.
+
+## What did we do here?
+
+Although this was a simple test it's been enough to demonstrate a few things about how Catch is used. Let's take moment to consider those before we move on.
+
+1. All we did was ```#define``` one identifier and ```#include``` one header and we got everything - even an implementation of ```main()``` that will [respond to command line arguments](command-line.md). You can only use that ```#define``` in one implementation file, for (hopefully) obvious reasons. Once you have more than one file with unit tests in you'll just ```#include "catch.hpp"``` and go. Usually it's a good idea to have a dedicated implementation file that just has ```#define CATCH_CONFIG_MAIN``` and ```#include "catch.hpp"```. You can also provide your own implementation of main and drive Catch yourself (see [Supplying-your-own-main()](own-main.md)).
+2. We introduce test cases with the ```TEST_CASE``` macro. This macro takes one or two arguments - a free form test name and, optionally, one or more tags (for more see <a href="#test-cases-and-sections">Test cases and Sections</a>, ). The test name must be unique. You can run sets of tests by specifying a wildcarded test name or a tag expression. See the [command line docs](command-line.md) for more information on running tests.
+3. The name and tags arguments are just strings. We haven't had to declare a function or method - or explicitly register the test case anywhere. Behind the scenes a function with a generated name is defined for you, and automatically registered using static registry classes. By abstracting the function name away we can name our tests without the constraints of identifier names.
+4. We write our individual test assertions using the ```REQUIRE``` macro. Rather than a separate macro for each type of condition we express the condition naturally using C/C++ syntax. Behind the scenes a simple set of expression templates captures the left-hand-side and right-hand-side of the expression so we can display the values in our test report. As we'll see later there _are_ other assertion macros - but because of this technique the number of them is drastically reduced.
+
+<a id="test-cases-and-sections"></a>
+## Test cases and sections
+
+Most test frameworks have a class-based fixture mechanism. That is, test cases map to methods on a class and common setup and teardown can be performed in ```setup()``` and ```teardown()``` methods (or constructor/ destructor in languages, like C++, that support deterministic destruction).
+
+While Catch fully supports this way of working there are a few problems with the approach. In particular the way your code must be split up, and the blunt granularity of it, may cause problems. You can only have one setup/ teardown pair across a set of methods, but sometimes you want slightly different setup in each method, or you may even want several levels of setup (a concept which we will clarify later on in this tutorial). It was <a href="http://jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html">problems like these</a> that led James Newkirk, who led the team that built NUnit, to start again from scratch and <a href="http://jamesnewkirk.typepad.com/posts/2007/09/announcing-xuni.html">build xUnit</a>).
+
+Catch takes a different approach (to both NUnit and xUnit) that is a more natural fit for C++ and the C family of languages. This is best explained through an example:
+
+```c++
+TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
+
+ std::vector<int> v( 5 );
+
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 5 );
+
+ SECTION( "resizing bigger changes size and capacity" ) {
+ v.resize( 10 );
+
+ REQUIRE( v.size() == 10 );
+ REQUIRE( v.capacity() >= 10 );
+ }
+ SECTION( "resizing smaller changes size but not capacity" ) {
+ v.resize( 0 );
+
+ REQUIRE( v.size() == 0 );
+ REQUIRE( v.capacity() >= 5 );
+ }
+ SECTION( "reserving bigger changes capacity but not size" ) {
+ v.reserve( 10 );
+
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 10 );
+ }
+ SECTION( "reserving smaller does not change size or capacity" ) {
+ v.reserve( 0 );
+
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 5 );
+ }
+}
+```
+
+For each ```SECTION``` the ```TEST_CASE``` is executed from the start - so as we enter each section we know that size is 5 and capacity is at least 5. We enforced those requirements with the ```REQUIRE```s at the top level so we can be confident in them.
+This works because the ```SECTION``` macro contains an if statement that calls back into Catch to see if the section should be executed. One leaf section is executed on each run through a ```TEST_CASE```. The other sections are skipped. Next time through the next section is executed, and so on until no new sections are encountered.
+
+So far so good - this is already an improvement on the setup/teardown approach because now we see our setup code inline and use the stack.
+
+The power of sections really shows, however, when we need to execute a sequence of, checked, operations. Continuing the vector example, we might want to verify that attempting to reserve a capacity smaller than the current capacity of the vector changes nothing. We can do that, naturally, like so:
+
+```c++
+ SECTION( "reserving bigger changes capacity but not size" ) {
+ v.reserve( 10 );
+
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 10 );
+
+ SECTION( "reserving smaller again does not change capacity" ) {
+ v.reserve( 7 );
+
+ REQUIRE( v.capacity() >= 10 );
+ }
+ }
+```
+
+Sections can be nested to an arbitrary depth (limited only by your stack size). Each leaf section (i.e. a section that contains no nested sections) will be executed exactly once, on a separate path of execution from any other leaf section (so no leaf section can interfere with another). A failure in a parent section will prevent nested sections from running - but then that's the idea.
+
+## BDD-Style
+
+If you name your test cases and sections appropriately you can achieve a BDD-style specification structure. This became such a useful way of working that first class support has been added to Catch. Scenarios can be specified using ```SCENARIO```, ```GIVEN```, ```WHEN``` and ```THEN``` macros, which map on to ```TEST_CASE```s and ```SECTION```s, respectively. For more details see [Test cases and sections](test-cases-and-sections.md).
+
+The vector example can be adjusted to use these macros like so:
+
+```c++
+SCENARIO( "vectors can be sized and resized", "[vector]" ) {
+
+ GIVEN( "A vector with some items" ) {
+ std::vector<int> v( 5 );
+
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 5 );
+
+ WHEN( "the size is increased" ) {
+ v.resize( 10 );
+
+ THEN( "the size and capacity change" ) {
+ REQUIRE( v.size() == 10 );
+ REQUIRE( v.capacity() >= 10 );
+ }
+ }
+ WHEN( "the size is reduced" ) {
+ v.resize( 0 );
+
+ THEN( "the size changes but not capacity" ) {
+ REQUIRE( v.size() == 0 );
+ REQUIRE( v.capacity() >= 5 );
+ }
+ }
+ WHEN( "more capacity is reserved" ) {
+ v.reserve( 10 );
+
+ THEN( "the capacity changes but not the size" ) {
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 10 );
+ }
+ }
+ WHEN( "less capacity is reserved" ) {
+ v.reserve( 0 );
+
+ THEN( "neither size nor capacity are changed" ) {
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 5 );
+ }
+ }
+ }
+}
+```
+
+Conveniently, these tests will be reported as follows when run:
+
+```
+Scenario: vectors can be sized and resized
+ Given: A vector with some items
+ When: more capacity is reserved
+ Then: the capacity changes but not the size
+```
+
+<a id="scaling-up"></a>
+## Scaling up
+
+To keep the tutorial simple we put all our code in a single file. This is fine to get started - and makes jumping into Catch even quicker and easier. As you write more real-world tests, though, this is not really the best approach.
+
+The requirement is that the following block of code ([or equivalent](own-main.md)):
+
+```c++
+#define CATCH_CONFIG_MAIN
+#include "catch.hpp"
+```
+
+appears in _exactly one_ source file. Use as many additional cpp files (or whatever you call your implementation files) as you need for your tests, partitioned however makes most sense for your way of working. Each additional file need only ```#include "catch.hpp"``` - do not repeat the ```#define```!
+
+In fact it is usually a good idea to put the block with the ```#define``` [in it's own source file](slow-compiles.md).
+
+Do not write your tests in header files!
+
+
+## Next steps
+
+This has been a brief introduction to get you up and running with Catch, and to point out some of the key differences between Catch and other frameworks you may already be familiar with. This will get you going quite far already and you are now in a position to dive in and write some tests.
+
+Of course there is more to learn - most of which you should be able to page-fault in as you go. Please see the ever-growing [Reference section](Readme.md) for what's available.
+
+---
+
+[Home](Readme.md)
diff --git a/3rdparty/sol2/Catch/docs/why-catch.md b/3rdparty/sol2/Catch/docs/why-catch.md
new file mode 100644
index 00000000000..93488d2291d
--- /dev/null
+++ b/3rdparty/sol2/Catch/docs/why-catch.md
@@ -0,0 +1,42 @@
+# Why do we need yet another C++ test framework?
+
+Good question. For C++ there are quite a number of established frameworks, including (but not limited to), [CppUnit](http://sourceforge.net/apps/mediawiki/cppunit/index.php?title=Main_Page), [Google Test](http://code.google.com/p/googletest/), [Boost.Test](http://www.boost.org/doc/libs/1_49_0/libs/test/doc/html/index.html), [Aeryn](https://launchpad.net/aeryn), [Cute](http://r2.ifs.hsr.ch/cute), [Fructose](http://fructose.sourceforge.net/) and [many, many more](http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B). Even for Objective-C there are a few, including OCUnit - which now comes bundled with XCode.
+
+So what does Catch bring to the party that differentiates it from these? Apart from a Catchy name, of course.
+
+## Key Features
+
+* Really easy to get started. Just download catch.hpp, #include it and you're away.
+* No external dependencies. As long as you can compile C++98 and have a C++ standard library available.
+* Write test cases as, self-registering, functions or methods.
+* Divide test cases into sections, each of which is run in isolation (eliminates the need for fixtures!)
+* Use BDD-style Given-When-Then sections as well as traditional unit test cases.
+* Only one core assertion macro for comparisons. Standard C/C++ operators are used for the comparison - yet the full expression is decomposed and lhs and rhs values are logged.
+
+## Other core features
+
+* Tests are named using free-form strings - no more couching names in legal identifiers.
+* Tests can be tagged for easily running ad-hoc groups of tests.
+* Failures can (optionally) break into the debugger on Windows and Mac.
+* Output is through modular reporter objects. Basic textual and XML reporters are included. Custom reporters can easily be added.
+* JUnit xml output is supported for integration with third-party tools, such as CI servers.
+* A default main() function is provided (in a header), but you can supply your own for complete control (e.g. integration into your own test runner GUI).
+* A command line parser is provided and can still be used if you choose to provided your own main() function.
+* Catch can test itself.
+* Alternative assertion macro(s) report failures but don't abort the test case
+* Floating point tolerance comparisons are built in using an expressive Approx() syntax.
+* Internal and friendly macros are isolated so name clashes can be managed
+* Support for Matchers (early stages)
+
+## Objective-C-specific features
+
+* Automatically detects if you are using it from an Objective-C project
+* Works with and without ARC with no additional configuration
+* Implement test fixtures using Obj-C classes too (like OCUnit)
+* Additional built in matchers that work with Obj-C types (e.g. string matchers)
+
+See the [tutorial](tutorial.md) to get more of a taste of using CATCH in practice
+
+---
+
+[Home](Readme.md) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/projects/CMake/CMakeLists.txt b/3rdparty/sol2/Catch/projects/CMake/CMakeLists.txt
new file mode 100644
index 00000000000..960d9fb1fcb
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/CMake/CMakeLists.txt
@@ -0,0 +1,48 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(Catch)
+
+# define some folders
+get_filename_component(CATCH_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
+get_filename_component(CATCH_DIR "${CATCH_DIR}" PATH)
+set(SELF_TEST_DIR ${CATCH_DIR}/projects/SelfTest)
+if(USE_CPP11)
+ ## We can't turn this on by default, since it breaks on travis
+ message(STATUS "Enabling C++11")
+ set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
+endif()
+
+# define the sources of the self test
+set(SOURCES
+ ${SELF_TEST_DIR}/ApproxTests.cpp
+ ${SELF_TEST_DIR}/BDDTests.cpp
+ ${SELF_TEST_DIR}/ClassTests.cpp
+ ${SELF_TEST_DIR}/ConditionTests.cpp
+ ${SELF_TEST_DIR}/ExceptionTests.cpp
+ ${SELF_TEST_DIR}/GeneratorTests.cpp
+ ${SELF_TEST_DIR}/MessageTests.cpp
+ ${SELF_TEST_DIR}/MiscTests.cpp
+ ${SELF_TEST_DIR}/PartTrackerTests.cpp
+ ${SELF_TEST_DIR}/TestMain.cpp
+ ${SELF_TEST_DIR}/TrickyTests.cpp
+ ${SELF_TEST_DIR}/VariadicMacrosTests.cpp
+ ${SELF_TEST_DIR}/EnumToString.cpp
+ ${SELF_TEST_DIR}/ToStringPair.cpp
+ ${SELF_TEST_DIR}/ToStringVector.cpp
+ ${SELF_TEST_DIR}/ToStringWhich.cpp
+ ${SELF_TEST_DIR}/ToStringTuple.cpp
+)
+
+# configure the executable
+include_directories(${CATCH_DIR}/include)
+add_executable(SelfTest ${SOURCES})
+
+# configure unit tests via CTest
+enable_testing()
+add_test(NAME RunTests COMMAND SelfTest)
+
+add_test(NAME ListTests COMMAND SelfTest --list-tests)
+set_tests_properties(ListTests PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ test cases")
+
+add_test(NAME ListTags COMMAND SelfTest --list-tags)
+set_tests_properties(ListTags PROPERTIES PASS_REGULAR_EXPRESSION "[0-9]+ tags")
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/ApproxTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/ApproxTests.cpp
new file mode 100644
index 00000000000..53656596c0a
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/ApproxTests.cpp
@@ -0,0 +1,112 @@
+/*
+ * Created by Phil on 28/04/2011.
+ * Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "catch.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "Some simple comparisons between doubles",
+ "[Approx]"
+)
+{
+ double d = 1.23;
+
+ REQUIRE( d == Approx( 1.23 ) );
+ REQUIRE( d != Approx( 1.22 ) );
+ REQUIRE( d != Approx( 1.24 ) );
+
+ REQUIRE( Approx( d ) == 1.23 );
+ REQUIRE( Approx( d ) != 1.22 );
+ REQUIRE( Approx( d ) != 1.24 );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "Approximate comparisons with different epsilons",
+ "[Approx]"
+ )
+{
+ double d = 1.23;
+
+ REQUIRE( d != Approx( 1.231 ) );
+ REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "Approximate comparisons with floats",
+ "[Approx]"
+)
+{
+ REQUIRE( 1.23f == Approx( 1.23f ) );
+ REQUIRE( 0.0f == Approx( 0.0f ) );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "Approximate comparisons with ints",
+ "[Approx]"
+)
+{
+ REQUIRE( 1 == Approx( 1 ) );
+ REQUIRE( 0 == Approx( 0 ) );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "Approximate comparisons with mixed numeric types",
+ "[Approx]"
+)
+{
+ const double dZero = 0;
+ const double dSmall = 0.00001;
+ const double dMedium = 1.234;
+
+ REQUIRE( 1.0f == Approx( 1 ) );
+ REQUIRE( 0 == Approx( dZero) );
+ REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) );
+ REQUIRE( 1.234f == Approx( dMedium ) );
+ REQUIRE( dMedium == Approx( 1.234f ) );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "Use a custom approx",
+ "[Approx][custom]"
+)
+{
+ double d = 1.23;
+
+ Approx approx = Approx::custom().epsilon( 0.005 );
+
+ REQUIRE( d == approx( 1.23 ) );
+ REQUIRE( d == approx( 1.22 ) );
+ REQUIRE( d == approx( 1.24 ) );
+ REQUIRE( d != approx( 1.25 ) );
+
+ REQUIRE( approx( d ) == 1.23 );
+ REQUIRE( approx( d ) == 1.22 );
+ REQUIRE( approx( d ) == 1.24 );
+ REQUIRE( approx( d ) != 1.25 );
+}
+
+inline double divide( double a, double b ) {
+ return a/b;
+}
+
+TEST_CASE( "Approximate PI", "[Approx][PI]" )
+{
+ REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) );
+ REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) );
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/BDDTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/BDDTests.cpp
new file mode 100644
index 00000000000..2c8bc2495b0
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/BDDTests.cpp
@@ -0,0 +1,103 @@
+/*
+ * Created by Phil on 29/11/2010.
+ * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "catch.hpp"
+
+inline bool itDoesThis(){ return true; }
+inline bool itDoesThat(){ return true; }
+
+SCENARIO( "Do that thing with the thing", "[Tags]" ) {
+ GIVEN( "This stuff exists" ) {
+ // make stuff exist
+ WHEN( "I do this" ) {
+ // do this
+ THEN( "it should do this")
+ {
+ REQUIRE( itDoesThis() );
+ AND_THEN( "do that")
+ REQUIRE( itDoesThat() );
+ }
+ }
+ }
+}
+
+SCENARIO( "Vector resizing affects size and capacity", "[vector][bdd][size][capacity]" ) {
+ GIVEN( "an empty vector" ) {
+ std::vector<int> v;
+ REQUIRE( v.size() == 0 );
+
+ WHEN( "it is made larger" ) {
+ v.resize( 10 );
+ THEN( "the size and capacity go up" ) {
+ REQUIRE( v.size() == 10 );
+ REQUIRE( v.capacity() >= 10 );
+
+ AND_WHEN( "it is made smaller again" ) {
+ v.resize( 5 );
+ THEN( "the size goes down but the capacity stays the same" ) {
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 10 );
+ }
+ }
+ }
+ }
+
+ WHEN( "we reserve more space" ) {
+ v.reserve( 10 );
+ THEN( "The capacity is increased but the size remains the same" ) {
+ REQUIRE( v.capacity() >= 10 );
+ REQUIRE( v.size() == 0 );
+ }
+ }
+ }
+}
+
+SCENARIO( "This is a really long scenario name to see how the list command deals with wrapping",
+ "[very long tags][lots][long][tags][verbose]"
+ "[one very long tag name that should cause line wrapping writing out using the list command]"
+ "[anotherReallyLongTagNameButThisOneHasNoObviousWrapPointsSoShouldSplitWithinAWordUsingADashCharacter]" ) {
+ GIVEN( "A section name that is so long that it cannot fit in a single console width" )
+ WHEN( "The test headers are printed as part of the normal running of the scenario" )
+ THEN( "The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent" )
+ SUCCEED("boo!");
+}
+
+namespace {
+
+// a trivial fixture example to support SCENARIO_METHOD tests
+struct Fixture
+{
+ Fixture()
+ : d_counter(0)
+ {
+ }
+
+ int counter()
+ {
+ return d_counter++;
+ }
+
+ int d_counter;
+};
+
+}
+
+SCENARIO_METHOD(Fixture,
+ "BDD tests requiring Fixtures to provide commonly-accessed data or methods",
+ "[bdd][fixtures]") {
+ const int before(counter());
+ GIVEN("No operations precede me") {
+ REQUIRE(before == 0);
+ WHEN("We get the count") {
+ const int after(counter());
+ THEN("Subsequently values are higher") {
+ REQUIRE(after > before);
+ }
+ }
+ }
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.std.approved.txt b/3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.std.approved.txt
new file mode 100644
index 00000000000..7bbae96e57b
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.std.approved.txt
@@ -0,0 +1,835 @@
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CatchSelfTest is a <version> host application.
+Run with -? for options
+
+-------------------------------------------------------------------------------
+A METHOD_AS_TEST_CASE based test run that fails
+-------------------------------------------------------------------------------
+ClassTests.cpp:<line number>
+...............................................................................
+
+ClassTests.cpp:<line number>: FAILED:
+ REQUIRE( s == "world" )
+with expansion:
+ "hello" == "world"
+
+-------------------------------------------------------------------------------
+A TEST_CASE_METHOD based test run that fails
+-------------------------------------------------------------------------------
+ClassTests.cpp:<line number>
+...............................................................................
+
+ClassTests.cpp:<line number>: FAILED:
+ REQUIRE( m_a == 2 )
+with expansion:
+ 1 == 2
+
+-------------------------------------------------------------------------------
+Equality checks that should fail
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven == 6 )
+with expansion:
+ 7 == 6
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven == 8 )
+with expansion:
+ 7 == 8
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven == 0 )
+with expansion:
+ 7 == 0
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one == Approx( 9.11f ) )
+with expansion:
+ 9.1f == Approx( 9.1099996567 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one == Approx( 9.0f ) )
+with expansion:
+ 9.1f == Approx( 9.0 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one == Approx( 1 ) )
+with expansion:
+ 9.1f == Approx( 1.0 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one == Approx( 0 ) )
+with expansion:
+ 9.1f == Approx( 0.0 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.double_pi == Approx( 3.1415 ) )
+with expansion:
+ 3.1415926535 == Approx( 3.1415 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello == "goodbye" )
+with expansion:
+ "hello" == "goodbye"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello == "hell" )
+with expansion:
+ "hello" == "hell"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello == "hello1" )
+with expansion:
+ "hello" == "hello1"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello.size() == 6 )
+with expansion:
+ 5 == 6
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( x == Approx( 1.301 ) )
+with expansion:
+ 1.3 == Approx( 1.301 )
+
+-------------------------------------------------------------------------------
+Inequality checks that should fail
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven != 7 )
+with expansion:
+ 7 != 7
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one != Approx( 9.1f ) )
+with expansion:
+ 9.1f != Approx( 9.1000003815 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.double_pi != Approx( 3.1415926535 ) )
+with expansion:
+ 3.1415926535 != Approx( 3.1415926535 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello != "hello" )
+with expansion:
+ "hello" != "hello"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello.size() != 5 )
+with expansion:
+ 5 != 5
+
+-------------------------------------------------------------------------------
+Ordering comparison checks that should fail
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven > 7 )
+with expansion:
+ 7 > 7
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven < 7 )
+with expansion:
+ 7 < 7
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven > 8 )
+with expansion:
+ 7 > 8
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven < 6 )
+with expansion:
+ 7 < 6
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven < 0 )
+with expansion:
+ 7 < 0
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven < -1 )
+with expansion:
+ 7 < -1
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven >= 8 )
+with expansion:
+ 7 >= 8
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven <= 6 )
+with expansion:
+ 7 <= 6
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one < 9 )
+with expansion:
+ 9.1f < 9
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one > 10 )
+with expansion:
+ 9.1f > 10
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one > 9.2 )
+with expansion:
+ 9.1f > 9.2
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello > "hello" )
+with expansion:
+ "hello" > "hello"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello < "hello" )
+with expansion:
+ "hello" < "hello"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello > "hellp" )
+with expansion:
+ "hello" > "hellp"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello > "z" )
+with expansion:
+ "hello" > "z"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello < "hellm" )
+with expansion:
+ "hello" < "hellm"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello < "a" )
+with expansion:
+ "hello" < "a"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello >= "z" )
+with expansion:
+ "hello" >= "z"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello <= "a" )
+with expansion:
+ "hello" <= "a"
+
+-------------------------------------------------------------------------------
+'Not' checks that should fail
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( false != false )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( true != true )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( !true )
+with expansion:
+ false
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK_FALSE( true )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( !trueValue )
+with expansion:
+ false
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK_FALSE( trueValue )
+with expansion:
+ !true
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( !(1 == 1) )
+with expansion:
+ false
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK_FALSE( 1 == 1 )
+with expansion:
+ !(1 == 1)
+
+-------------------------------------------------------------------------------
+Expected exceptions that don't throw or unexpected exceptions fail the test
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ CHECK_THROWS_AS( thisThrows() )
+due to unexpected exception with message:
+ expected exception
+
+ExceptionTests.cpp:<line number>: FAILED:
+ CHECK_THROWS_AS( thisDoesntThrow() )
+because no exception was thrown where one was expected:
+
+ExceptionTests.cpp:<line number>: FAILED:
+ CHECK_NOTHROW( thisThrows() )
+due to unexpected exception with message:
+ expected exception
+
+-------------------------------------------------------------------------------
+When unchecked exceptions are thrown directly they are always failures
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+ unexpected exception
+
+-------------------------------------------------------------------------------
+An unchecked exception reports the line of the last assertion
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ {Unknown expression after the reported line}
+due to unexpected exception with message:
+ unexpected exception
+
+-------------------------------------------------------------------------------
+When unchecked exceptions are thrown from sections they are always failures
+ section name
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+ unexpected exception
+
+-------------------------------------------------------------------------------
+When unchecked exceptions are thrown from functions they are always failures
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ CHECK( thisThrows() == 0 )
+due to unexpected exception with message:
+ expected exception
+
+-------------------------------------------------------------------------------
+When unchecked exceptions are thrown during a REQUIRE the test should abort
+fail
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ REQUIRE( thisThrows() == 0 )
+due to unexpected exception with message:
+ expected exception
+
+-------------------------------------------------------------------------------
+When unchecked exceptions are thrown during a CHECK the test should abort and
+fail
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ CHECK( thisThrows() == 0 )
+due to unexpected exception with message:
+ expected exception
+
+-------------------------------------------------------------------------------
+Non-std exceptions can be translated
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+ custom exception
+
+-------------------------------------------------------------------------------
+Custom std-exceptions can be custom translated
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+ custom std exception
+
+-------------------------------------------------------------------------------
+Custom exceptions can be translated when testing for nothrow
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ REQUIRE_NOTHROW( throwCustom() )
+due to unexpected exception with message:
+ custom exception - not std
+
+-------------------------------------------------------------------------------
+Custom exceptions can be translated when testing for throwing as something else
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ REQUIRE_THROWS_AS( throwCustom() )
+due to unexpected exception with message:
+ custom exception - not std
+
+-------------------------------------------------------------------------------
+Unexpected exceptions can be translated
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+ 3.14
+
+-------------------------------------------------------------------------------
+Mismatching exception messages failing the test
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ REQUIRE_THROWS_WITH( thisThrows(), "should fail" )
+with expansion:
+ expected exception
+
+-------------------------------------------------------------------------------
+INFO and WARN do not abort tests
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>:
+warning:
+ this is a warning
+
+-------------------------------------------------------------------------------
+INFO gets logged on failure
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+ REQUIRE( a == 1 )
+with expansion:
+ 2 == 1
+with messages:
+ this message should be logged
+ so should this
+
+-------------------------------------------------------------------------------
+INFO gets logged on failure, even if captured before successful assertions
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+ CHECK( a == 1 )
+with expansion:
+ 2 == 1
+with messages:
+ this message may be logged later
+ this message should be logged
+
+MessageTests.cpp:<line number>: FAILED:
+ CHECK( a == 0 )
+with expansion:
+ 2 == 0
+with message:
+ and this, but later
+
+-------------------------------------------------------------------------------
+FAIL aborts the test
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+explicitly with message:
+ This is a failure
+
+-------------------------------------------------------------------------------
+FAIL does not require an argument
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+
+-------------------------------------------------------------------------------
+Output from all sections is reported
+ one
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+explicitly with message:
+ Message from section one
+
+-------------------------------------------------------------------------------
+Output from all sections is reported
+ two
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+explicitly with message:
+ Message from section two
+
+Message from section one
+Message from section two
+-------------------------------------------------------------------------------
+SCOPED_INFO is reset for each loop
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+ REQUIRE( i < 10 )
+with expansion:
+ 10 < 10
+with messages:
+ current counter 10
+ i := 10
+
+-------------------------------------------------------------------------------
+just failure
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+explicitly with message:
+ Previous info should not be seen
+
+-------------------------------------------------------------------------------
+sends information to INFO
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with messages:
+ hi
+ i := 7
+
+-------------------------------------------------------------------------------
+Pointers can be converted to strings
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>:
+warning:
+ actual address of p: 0x<hex digits>
+
+MessageTests.cpp:<line number>:
+warning:
+ toString(p): 0x<hex digits>
+
+-------------------------------------------------------------------------------
+more nested SECTION tests
+ s1
+ s2
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ REQUIRE( a == b )
+with expansion:
+ 1 == 2
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+ s1
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( b > a )
+with expansion:
+ 0 > 1
+
+-------------------------------------------------------------------------------
+looped tests
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[0] (1) is even
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[1] (1) is even
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[3] (3) is even
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[4] (5) is even
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[6] (13) is even
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[7] (21) is even
+
+A string sent directly to stdout
+A string sent directly to stderr
+-------------------------------------------------------------------------------
+checkedIf, failing
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECKED_IF( flag )
+with expansion:
+ false
+
+MiscTests.cpp:<line number>: FAILED:
+ REQUIRE( testCheckedIf( false ) )
+with expansion:
+ false
+
+-------------------------------------------------------------------------------
+checkedElse, failing
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECKED_ELSE( flag )
+with expansion:
+ false
+
+MiscTests.cpp:<line number>: FAILED:
+ REQUIRE( testCheckedElse( false ) )
+with expansion:
+ false
+
+-------------------------------------------------------------------------------
+send a single char to INFO
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ 3
+
+-------------------------------------------------------------------------------
+Contains string matcher
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), Contains( "not there" ) )
+with expansion:
+ "this string contains 'abc' as a substring" contains: "not there"
+
+-------------------------------------------------------------------------------
+StartsWith string matcher
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), StartsWith( "string" ) )
+with expansion:
+ "this string contains 'abc' as a substring" starts with: "string"
+
+-------------------------------------------------------------------------------
+EndsWith string matcher
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), EndsWith( "this" ) )
+with expansion:
+ "this string contains 'abc' as a substring" ends with: "this"
+
+-------------------------------------------------------------------------------
+Equals string matcher
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), Equals( "something else" ) )
+with expansion:
+ "this string contains 'abc' as a substring" equals: "something else"
+
+-------------------------------------------------------------------------------
+Matchers can be composed with both && and || - failing
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) )
+with expansion:
+ "this string contains 'abc' as a substring" ( ( contains: "string" or
+ contains: "different" ) and contains: "random" )
+
+-------------------------------------------------------------------------------
+Matchers can be negated (Not) with the ! operator - failing
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), !Contains( "substring" ) )
+with expansion:
+ "this string contains 'abc' as a substring" not contains: "substring"
+
+-------------------------------------------------------------------------------
+Nice descriptive name
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+warning:
+ This one ran
+
+-------------------------------------------------------------------------------
+A couple of nested sections followed by a failure
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+explicitly with message:
+ to infinity and beyond
+
+-------------------------------------------------------------------------------
+Tabs and newlines show in output
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( s1 == s2 )
+with expansion:
+ "if ($b == 10) {
+ $a= 20;
+ }"
+ ==
+ "if ($b == 10) {
+ $a = 20;
+ }
+ "
+
+hello
+hello
+-------------------------------------------------------------------------------
+Where there is more to the expression after the RHS
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+warning:
+ Uncomment the code in this test to check that it gives a sensible compiler
+ error
+
+-------------------------------------------------------------------------------
+Where the LHS is not a simple value
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+warning:
+ Uncomment the code in this test to check that it gives a sensible compiler
+ error
+
+-------------------------------------------------------------------------------
+A failing expression with a non streamable type is still captured
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>: FAILED:
+ CHECK( &o1 == &o2 )
+with expansion:
+ 0x<hex digits> == 0x<hex digits>
+
+TrickyTests.cpp:<line number>: FAILED:
+ CHECK( o1 == o2 )
+with expansion:
+ {?} == {?}
+
+-------------------------------------------------------------------------------
+string literals of different sizes can be compared
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>: FAILED:
+ REQUIRE( std::string( "first" ) == "second" )
+with expansion:
+ "first" == "second"
+
+===============================================================================
+test cases: 167 | 124 passed | 42 failed | 1 failed as expected
+assertions: 914 | 818 passed | 83 failed | 13 failed as expected
+
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.sw.approved.txt b/3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.sw.approved.txt
new file mode 100644
index 00000000000..d8c0b9b910a
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.sw.approved.txt
@@ -0,0 +1,9050 @@
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CatchSelfTest is a <version> host application.
+Run with -? for options
+
+-------------------------------------------------------------------------------
+toString(enum)
+-------------------------------------------------------------------------------
+EnumToString.cpp:<line number>
+...............................................................................
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e0) == "0" )
+with expansion:
+ "0" == "0"
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e1) == "1" )
+with expansion:
+ "1" == "1"
+
+-------------------------------------------------------------------------------
+toString(enum w/operator<<)
+-------------------------------------------------------------------------------
+EnumToString.cpp:<line number>
+...............................................................................
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e0) == "E2{0}" )
+with expansion:
+ "E2{0}" == "E2{0}"
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e1) == "E2{1}" )
+with expansion:
+ "E2{1}" == "E2{1}"
+
+-------------------------------------------------------------------------------
+toString(enum class)
+-------------------------------------------------------------------------------
+EnumToString.cpp:<line number>
+...............................................................................
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e0) == "0" )
+with expansion:
+ "0" == "0"
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e1) == "1" )
+with expansion:
+ "1" == "1"
+
+-------------------------------------------------------------------------------
+toString(enum class w/operator<<)
+-------------------------------------------------------------------------------
+EnumToString.cpp:<line number>
+...............................................................................
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e0) == "E2/V0" )
+with expansion:
+ "E2/V0" == "E2/V0"
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e1) == "E2/V1" )
+with expansion:
+ "E2/V1" == "E2/V1"
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e3) == "Unknown enum value 10" )
+with expansion:
+ "Unknown enum value 10"
+ ==
+ "Unknown enum value 10"
+
+-------------------------------------------------------------------------------
+Some simple comparisons between doubles
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d == Approx( 1.23 ) )
+with expansion:
+ 1.23 == Approx( 1.23 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d != Approx( 1.22 ) )
+with expansion:
+ 1.23 != Approx( 1.22 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d != Approx( 1.24 ) )
+with expansion:
+ 1.23 != Approx( 1.24 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Approx( d ) == 1.23 )
+with expansion:
+ Approx( 1.23 ) == 1.23
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Approx( d ) != 1.22 )
+with expansion:
+ Approx( 1.23 ) != 1.22
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Approx( d ) != 1.24 )
+with expansion:
+ Approx( 1.23 ) != 1.24
+
+-------------------------------------------------------------------------------
+Approximate comparisons with different epsilons
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d != Approx( 1.231 ) )
+with expansion:
+ 1.23 != Approx( 1.231 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) )
+with expansion:
+ 1.23 == Approx( 1.231 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with floats
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 1.23f == Approx( 1.23f ) )
+with expansion:
+ 1.23f == Approx( 1.2300000191 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 0.0f == Approx( 0.0f ) )
+with expansion:
+ 0.0f == Approx( 0.0 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with ints
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 1 == Approx( 1 ) )
+with expansion:
+ 1 == Approx( 1.0 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 0 == Approx( 0 ) )
+with expansion:
+ 0 == Approx( 0.0 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with mixed numeric types
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 1.0f == Approx( 1 ) )
+with expansion:
+ 1.0f == Approx( 1.0 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 0 == Approx( dZero) )
+with expansion:
+ 0 == Approx( 0.0 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) )
+with expansion:
+ 0 == Approx( 0.00001 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 1.234f == Approx( dMedium ) )
+with expansion:
+ 1.234f == Approx( 1.234 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( dMedium == Approx( 1.234f ) )
+with expansion:
+ 1.234 == Approx( 1.2339999676 )
+
+-------------------------------------------------------------------------------
+Use a custom approx
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d == approx( 1.23 ) )
+with expansion:
+ 1.23 == Approx( 1.23 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d == approx( 1.22 ) )
+with expansion:
+ 1.23 == Approx( 1.22 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d == approx( 1.24 ) )
+with expansion:
+ 1.23 == Approx( 1.24 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d != approx( 1.25 ) )
+with expansion:
+ 1.23 != Approx( 1.25 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( approx( d ) == 1.23 )
+with expansion:
+ Approx( 1.23 ) == 1.23
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( approx( d ) == 1.22 )
+with expansion:
+ Approx( 1.23 ) == 1.22
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( approx( d ) == 1.24 )
+with expansion:
+ Approx( 1.23 ) == 1.24
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( approx( d ) != 1.25 )
+with expansion:
+ Approx( 1.23 ) != 1.25
+
+-------------------------------------------------------------------------------
+Approximate PI
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) )
+with expansion:
+ 3.1428571429 == Approx( 3.141 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) )
+with expansion:
+ 3.1428571429 != Approx( 3.141 )
+
+-------------------------------------------------------------------------------
+A METHOD_AS_TEST_CASE based test run that succeeds
+-------------------------------------------------------------------------------
+ClassTests.cpp:<line number>
+...............................................................................
+
+ClassTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s == "hello" )
+with expansion:
+ "hello" == "hello"
+
+-------------------------------------------------------------------------------
+A METHOD_AS_TEST_CASE based test run that fails
+-------------------------------------------------------------------------------
+ClassTests.cpp:<line number>
+...............................................................................
+
+ClassTests.cpp:<line number>: FAILED:
+ REQUIRE( s == "world" )
+with expansion:
+ "hello" == "world"
+
+-------------------------------------------------------------------------------
+A TEST_CASE_METHOD based test run that succeeds
+-------------------------------------------------------------------------------
+ClassTests.cpp:<line number>
+...............................................................................
+
+ClassTests.cpp:<line number>:
+PASSED:
+ REQUIRE( m_a == 1 )
+with expansion:
+ 1 == 1
+
+-------------------------------------------------------------------------------
+A TEST_CASE_METHOD based test run that fails
+-------------------------------------------------------------------------------
+ClassTests.cpp:<line number>
+...............................................................................
+
+ClassTests.cpp:<line number>: FAILED:
+ REQUIRE( m_a == 2 )
+with expansion:
+ 1 == 2
+
+-------------------------------------------------------------------------------
+Equality checks that should succeed
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven == 7 )
+with expansion:
+ 7 == 7
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one == Approx( 9.1f ) )
+with expansion:
+ 9.1f == Approx( 9.1000003815 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.double_pi == Approx( 3.1415926535 ) )
+with expansion:
+ 3.1415926535 == Approx( 3.1415926535 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello == "hello" )
+with expansion:
+ "hello" == "hello"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( "hello" == data.str_hello )
+with expansion:
+ "hello" == "hello"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello.size() == 5 )
+with expansion:
+ 5 == 5
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( x == Approx( 1.3 ) )
+with expansion:
+ 1.3 == Approx( 1.3 )
+
+-------------------------------------------------------------------------------
+Equality checks that should fail
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven == 6 )
+with expansion:
+ 7 == 6
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven == 8 )
+with expansion:
+ 7 == 8
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven == 0 )
+with expansion:
+ 7 == 0
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one == Approx( 9.11f ) )
+with expansion:
+ 9.1f == Approx( 9.1099996567 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one == Approx( 9.0f ) )
+with expansion:
+ 9.1f == Approx( 9.0 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one == Approx( 1 ) )
+with expansion:
+ 9.1f == Approx( 1.0 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one == Approx( 0 ) )
+with expansion:
+ 9.1f == Approx( 0.0 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.double_pi == Approx( 3.1415 ) )
+with expansion:
+ 3.1415926535 == Approx( 3.1415 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello == "goodbye" )
+with expansion:
+ "hello" == "goodbye"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello == "hell" )
+with expansion:
+ "hello" == "hell"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello == "hello1" )
+with expansion:
+ "hello" == "hello1"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello.size() == 6 )
+with expansion:
+ 5 == 6
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( x == Approx( 1.301 ) )
+with expansion:
+ 1.3 == Approx( 1.301 )
+
+-------------------------------------------------------------------------------
+Inequality checks that should succeed
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven != 6 )
+with expansion:
+ 7 != 6
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven != 8 )
+with expansion:
+ 7 != 8
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one != Approx( 9.11f ) )
+with expansion:
+ 9.1f != Approx( 9.1099996567 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one != Approx( 9.0f ) )
+with expansion:
+ 9.1f != Approx( 9.0 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one != Approx( 1 ) )
+with expansion:
+ 9.1f != Approx( 1.0 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one != Approx( 0 ) )
+with expansion:
+ 9.1f != Approx( 0.0 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.double_pi != Approx( 3.1415 ) )
+with expansion:
+ 3.1415926535 != Approx( 3.1415 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello != "goodbye" )
+with expansion:
+ "hello" != "goodbye"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello != "hell" )
+with expansion:
+ "hello" != "hell"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello != "hello1" )
+with expansion:
+ "hello" != "hello1"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello.size() != 6 )
+with expansion:
+ 5 != 6
+
+-------------------------------------------------------------------------------
+Inequality checks that should fail
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven != 7 )
+with expansion:
+ 7 != 7
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one != Approx( 9.1f ) )
+with expansion:
+ 9.1f != Approx( 9.1000003815 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.double_pi != Approx( 3.1415926535 ) )
+with expansion:
+ 3.1415926535 != Approx( 3.1415926535 )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello != "hello" )
+with expansion:
+ "hello" != "hello"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello.size() != 5 )
+with expansion:
+ 5 != 5
+
+-------------------------------------------------------------------------------
+Ordering comparison checks that should succeed
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven < 8 )
+with expansion:
+ 7 < 8
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven > 6 )
+with expansion:
+ 7 > 6
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven > 0 )
+with expansion:
+ 7 > 0
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven > -1 )
+with expansion:
+ 7 > -1
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven >= 7 )
+with expansion:
+ 7 >= 7
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven >= 6 )
+with expansion:
+ 7 >= 6
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven <= 7 )
+with expansion:
+ 7 <= 7
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven <= 8 )
+with expansion:
+ 7 <= 8
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one > 9 )
+with expansion:
+ 9.1f > 9
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one < 10 )
+with expansion:
+ 9.1f < 10
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one < 9.2 )
+with expansion:
+ 9.1f < 9.2
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello <= "hello" )
+with expansion:
+ "hello" <= "hello"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello >= "hello" )
+with expansion:
+ "hello" >= "hello"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello < "hellp" )
+with expansion:
+ "hello" < "hellp"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello < "zebra" )
+with expansion:
+ "hello" < "zebra"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello > "hellm" )
+with expansion:
+ "hello" > "hellm"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello > "a" )
+with expansion:
+ "hello" > "a"
+
+-------------------------------------------------------------------------------
+Ordering comparison checks that should fail
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven > 7 )
+with expansion:
+ 7 > 7
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven < 7 )
+with expansion:
+ 7 < 7
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven > 8 )
+with expansion:
+ 7 > 8
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven < 6 )
+with expansion:
+ 7 < 6
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven < 0 )
+with expansion:
+ 7 < 0
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven < -1 )
+with expansion:
+ 7 < -1
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven >= 8 )
+with expansion:
+ 7 >= 8
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven <= 6 )
+with expansion:
+ 7 <= 6
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one < 9 )
+with expansion:
+ 9.1f < 9
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one > 10 )
+with expansion:
+ 9.1f > 10
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one > 9.2 )
+with expansion:
+ 9.1f > 9.2
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello > "hello" )
+with expansion:
+ "hello" > "hello"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello < "hello" )
+with expansion:
+ "hello" < "hello"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello > "hellp" )
+with expansion:
+ "hello" > "hellp"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello > "z" )
+with expansion:
+ "hello" > "z"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello < "hellm" )
+with expansion:
+ "hello" < "hellm"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello < "a" )
+with expansion:
+ "hello" < "a"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello >= "z" )
+with expansion:
+ "hello" >= "z"
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.str_hello <= "a" )
+with expansion:
+ "hello" <= "a"
+
+-------------------------------------------------------------------------------
+Comparisons with int literals don't warn when mixing signed/ unsigned
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i == 1 )
+with expansion:
+ 1 == 1
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ui == 2 )
+with expansion:
+ 2 == 2
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( l == 3 )
+with expansion:
+ 3 == 3
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ul == 4 )
+with expansion:
+ 4 == 4
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( c == 5 )
+with expansion:
+ 5 == 5
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( uc == 6 )
+with expansion:
+ 6 == 6
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 1 == i )
+with expansion:
+ 1 == 1
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 2 == ui )
+with expansion:
+ 2 == 2
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 3 == l )
+with expansion:
+ 3 == 3
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 4 == ul )
+with expansion:
+ 4 == 4
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 5 == c )
+with expansion:
+ 5 == 5
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 6 == uc )
+with expansion:
+ 6 == 6
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( (std::numeric_limits<unsigned long>::max)() > ul )
+with expansion:
+ 18446744073709551615 (0x<hex digits>)
+ >
+ 4
+
+-------------------------------------------------------------------------------
+comparisons between int variables
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( long_var == unsigned_char_var )
+with expansion:
+ 1 == 1
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( long_var == unsigned_short_var )
+with expansion:
+ 1 == 1
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( long_var == unsigned_int_var )
+with expansion:
+ 1 == 1
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( long_var == unsigned_long_var )
+with expansion:
+ 1 == 1
+
+-------------------------------------------------------------------------------
+comparisons between const int variables
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( unsigned_char_var == 1 )
+with expansion:
+ 1 == 1
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( unsigned_short_var == 1 )
+with expansion:
+ 1 == 1
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( unsigned_int_var == 1 )
+with expansion:
+ 1 == 1
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( unsigned_long_var == 1 )
+with expansion:
+ 1 == 1
+
+-------------------------------------------------------------------------------
+Comparisons between unsigned ints and negative signed ints match c++ standard
+behaviour
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ CHECK( ( -1 > 2u ) )
+with expansion:
+ true
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ CHECK( -1 > 2u )
+with expansion:
+ -1 > 2
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ CHECK( ( 2u < -1 ) )
+with expansion:
+ true
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ CHECK( 2u < -1 )
+with expansion:
+ 2 < -1
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ CHECK( ( minInt > 2u ) )
+with expansion:
+ true
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ CHECK( minInt > 2u )
+with expansion:
+ -2147483648 > 2
+
+-------------------------------------------------------------------------------
+Comparisons between ints where one side is computed
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ CHECK( 54 == 6*9 )
+with expansion:
+ 54 == 54
+
+-------------------------------------------------------------------------------
+Pointers can be compared to null
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( p == nullptr )
+with expansion:
+ NULL == nullptr
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( p == pNULL )
+with expansion:
+ NULL == NULL
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( p != nullptr )
+with expansion:
+ 0x<hex digits> != nullptr
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( cp != nullptr )
+with expansion:
+ 0x<hex digits> != nullptr
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( cpc != nullptr )
+with expansion:
+ 0x<hex digits> != nullptr
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( returnsNull() == nullptr )
+with expansion:
+ {null string} == nullptr
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( returnsConstNull() == nullptr )
+with expansion:
+ {null string} == nullptr
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( nullptr != p )
+with expansion:
+ nullptr != 0x<hex digits>
+
+-------------------------------------------------------------------------------
+'Not' checks that should succeed
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( false == false )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( true == true )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( !false )
+with expansion:
+ true
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_FALSE( false )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( !falseValue )
+with expansion:
+ true
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_FALSE( falseValue )
+with expansion:
+ !false
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( !(1 == 2) )
+with expansion:
+ true
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_FALSE( 1 == 2 )
+with expansion:
+ !(1 == 2)
+
+-------------------------------------------------------------------------------
+'Not' checks that should fail
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( false != false )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( true != true )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( !true )
+with expansion:
+ false
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK_FALSE( true )
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( !trueValue )
+with expansion:
+ false
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK_FALSE( trueValue )
+with expansion:
+ !true
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( !(1 == 1) )
+with expansion:
+ false
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK_FALSE( 1 == 1 )
+with expansion:
+ !(1 == 1)
+
+-------------------------------------------------------------------------------
+When checked exceptions are thrown they can be expected or unexpected
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THROWS_AS( thisThrows() )
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_NOTHROW( thisDoesntThrow() )
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THROWS( thisThrows() )
+
+-------------------------------------------------------------------------------
+Expected exceptions that don't throw or unexpected exceptions fail the test
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ CHECK_THROWS_AS( thisThrows() )
+due to unexpected exception with message:
+ expected exception
+
+ExceptionTests.cpp:<line number>: FAILED:
+ CHECK_THROWS_AS( thisDoesntThrow() )
+because no exception was thrown where one was expected:
+
+ExceptionTests.cpp:<line number>: FAILED:
+ CHECK_NOTHROW( thisThrows() )
+due to unexpected exception with message:
+ expected exception
+
+-------------------------------------------------------------------------------
+When unchecked exceptions are thrown directly they are always failures
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+ unexpected exception
+
+-------------------------------------------------------------------------------
+An unchecked exception reports the line of the last assertion
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ CHECK( 1 == 1 )
+
+ExceptionTests.cpp:<line number>: FAILED:
+ {Unknown expression after the reported line}
+due to unexpected exception with message:
+ unexpected exception
+
+-------------------------------------------------------------------------------
+When unchecked exceptions are thrown from sections they are always failures
+ section name
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+ unexpected exception
+
+-------------------------------------------------------------------------------
+When unchecked exceptions are thrown from functions they are always failures
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ CHECK( thisThrows() == 0 )
+due to unexpected exception with message:
+ expected exception
+
+-------------------------------------------------------------------------------
+When unchecked exceptions are thrown during a REQUIRE the test should abort
+fail
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ REQUIRE( thisThrows() == 0 )
+due to unexpected exception with message:
+ expected exception
+
+-------------------------------------------------------------------------------
+When unchecked exceptions are thrown during a CHECK the test should abort and
+fail
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ CHECK( thisThrows() == 0 )
+due to unexpected exception with message:
+ expected exception
+
+-------------------------------------------------------------------------------
+Non-std exceptions can be translated
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+ custom exception
+
+-------------------------------------------------------------------------------
+Custom std-exceptions can be custom translated
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+ custom std exception
+
+-------------------------------------------------------------------------------
+Custom exceptions can be translated when testing for nothrow
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ REQUIRE_NOTHROW( throwCustom() )
+due to unexpected exception with message:
+ custom exception - not std
+
+-------------------------------------------------------------------------------
+Custom exceptions can be translated when testing for throwing as something else
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+ REQUIRE_THROWS_AS( throwCustom() )
+due to unexpected exception with message:
+ custom exception - not std
+
+-------------------------------------------------------------------------------
+Unexpected exceptions can be translated
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>: FAILED:
+due to unexpected exception with message:
+ 3.14
+
+-------------------------------------------------------------------------------
+NotImplemented exception
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THROWS( thisFunctionNotImplemented( 7 ) )
+
+-------------------------------------------------------------------------------
+Exception messages can be tested for
+ exact match
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THROWS_WITH( thisThrows(), "expected exception" )
+
+-------------------------------------------------------------------------------
+Exception messages can be tested for
+ different case
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THROWS_WITH( thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) )
+
+-------------------------------------------------------------------------------
+Exception messages can be tested for
+ wildcarded
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THROWS_WITH( thisThrows(), StartsWith( "expected" ) )
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THROWS_WITH( thisThrows(), EndsWith( "exception" ) )
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THROWS_WITH( thisThrows(), Contains( "except" ) )
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THROWS_WITH( thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) )
+
+-------------------------------------------------------------------------------
+Mismatching exception messages failing the test
+-------------------------------------------------------------------------------
+ExceptionTests.cpp:<line number>
+...............................................................................
+
+ExceptionTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THROWS_WITH( thisThrows(), "expected exception" )
+
+ExceptionTests.cpp:<line number>: FAILED:
+ REQUIRE_THROWS_WITH( thisThrows(), "should fail" )
+with expansion:
+ expected exception
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 2 == 2
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 200 == 200
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 4 == 4
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 200 == 200
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 6 == 6
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 200 == 200
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 8 == 8
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 200 == 200
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 10 == 10
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 200 == 200
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 30 == 30
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 200 == 200
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 40 == 40
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 200 == 200
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 42 == 42
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 200 == 200
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 72 == 72
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 200 == 200
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 2 == 2
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 202 == 202
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 4 == 4
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 202 == 202
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 6 == 6
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 202 == 202
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 8 == 8
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 202 == 202
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 10 == 10
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 202 == 202
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 30 == 30
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 202 == 202
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 40 == 40
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 202 == 202
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 42 == 42
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 202 == 202
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 72 == 72
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 202 == 202
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 2 == 2
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 204 == 204
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 4 == 4
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 204 == 204
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 6 == 6
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 204 == 204
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 8 == 8
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 204 == 204
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 10 == 10
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 204 == 204
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 30 == 30
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 204 == 204
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 40 == 40
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 204 == 204
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 42 == 42
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 204 == 204
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 72 == 72
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 204 == 204
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 2 == 2
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 206 == 206
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 4 == 4
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 206 == 206
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 6 == 6
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 206 == 206
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 8 == 8
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 206 == 206
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 10 == 10
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 206 == 206
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 30 == 30
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 206 == 206
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 40 == 40
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 206 == 206
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 42 == 42
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 206 == 206
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 72 == 72
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 206 == 206
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 2 == 2
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 208 == 208
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 4 == 4
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 208 == 208
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 6 == 6
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 208 == 208
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 8 == 8
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 208 == 208
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 10 == 10
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 208 == 208
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 30 == 30
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 208 == 208
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 40 == 40
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 208 == 208
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 42 == 42
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 208 == 208
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 72 == 72
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 208 == 208
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 2 == 2
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 210 == 210
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 4 == 4
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 210 == 210
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 6 == 6
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 210 == 210
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 8 == 8
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 210 == 210
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 10 == 10
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 210 == 210
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 30 == 30
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 210 == 210
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 40 == 40
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 210 == 210
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 42 == 42
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 210 == 210
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 72 == 72
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 210 == 210
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 2 == 2
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 212 == 212
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 4 == 4
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 212 == 212
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 6 == 6
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 212 == 212
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 8 == 8
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 212 == 212
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 10 == 10
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 212 == 212
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 30 == 30
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 212 == 212
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 40 == 40
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 212 == 212
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 42 == 42
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 212 == 212
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 72 == 72
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 212 == 212
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 2 == 2
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 214 == 214
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 4 == 4
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 214 == 214
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 6 == 6
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 214 == 214
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 8 == 8
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 214 == 214
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 10 == 10
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 214 == 214
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 30 == 30
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 214 == 214
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 40 == 40
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 214 == 214
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 42 == 42
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 214 == 214
+
+-------------------------------------------------------------------------------
+Generators over two ranges
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 )
+with expansion:
+ 72 == 72
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 )
+with expansion:
+ 214 == 214
+
+-------------------------------------------------------------------------------
+Generator over a range of pairs
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( i->first == i->second-1 )
+with expansion:
+ 0 == 0
+
+-------------------------------------------------------------------------------
+Generator over a range of pairs
+-------------------------------------------------------------------------------
+GeneratorTests.cpp:<line number>
+...............................................................................
+
+GeneratorTests.cpp:<line number>:
+PASSED:
+ CATCH_REQUIRE( i->first == i->second-1 )
+with expansion:
+ 2 == 2
+
+-------------------------------------------------------------------------------
+INFO and WARN do not abort tests
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>:
+warning:
+ this is a message
+ this is a warning
+
+-------------------------------------------------------------------------------
+SUCCEED counts as a test pass
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>:
+PASSED:
+with message:
+ this is a success
+
+-------------------------------------------------------------------------------
+INFO gets logged on failure
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+ REQUIRE( a == 1 )
+with expansion:
+ 2 == 1
+with messages:
+ this message should be logged
+ so should this
+
+-------------------------------------------------------------------------------
+INFO gets logged on failure, even if captured before successful assertions
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>:
+PASSED:
+ CHECK( a == 2 )
+with expansion:
+ 2 == 2
+with message:
+ this message may be logged later
+
+MessageTests.cpp:<line number>: FAILED:
+ CHECK( a == 1 )
+with expansion:
+ 2 == 1
+with message:
+ this message should be logged
+
+MessageTests.cpp:<line number>: FAILED:
+ CHECK( a == 0 )
+with expansion:
+ 2 == 0
+with message:
+ and this, but later
+
+MessageTests.cpp:<line number>:
+PASSED:
+ CHECK( a == 2 )
+with expansion:
+ 2 == 2
+with message:
+ but not this
+
+-------------------------------------------------------------------------------
+FAIL aborts the test
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+explicitly with message:
+ This is a failure
+
+-------------------------------------------------------------------------------
+FAIL does not require an argument
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+
+-------------------------------------------------------------------------------
+SUCCESS does not require an argument
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+Output from all sections is reported
+ one
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+explicitly with message:
+ Message from section one
+
+-------------------------------------------------------------------------------
+Output from all sections is reported
+ two
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+explicitly with message:
+ Message from section two
+
+Message from section one
+-------------------------------------------------------------------------------
+Standard output from all sections is reported
+ one
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+
+No assertions in section 'one'
+
+Message from section two
+-------------------------------------------------------------------------------
+Standard output from all sections is reported
+ two
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+
+No assertions in section 'two'
+
+-------------------------------------------------------------------------------
+SCOPED_INFO is reset for each loop
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i < 10 )
+with expansion:
+ 0 < 10
+with messages:
+ current counter 0
+ i := 0
+
+MessageTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i < 10 )
+with expansion:
+ 1 < 10
+with messages:
+ current counter 1
+ i := 1
+
+MessageTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i < 10 )
+with expansion:
+ 2 < 10
+with messages:
+ current counter 2
+ i := 2
+
+MessageTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i < 10 )
+with expansion:
+ 3 < 10
+with messages:
+ current counter 3
+ i := 3
+
+MessageTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i < 10 )
+with expansion:
+ 4 < 10
+with messages:
+ current counter 4
+ i := 4
+
+MessageTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i < 10 )
+with expansion:
+ 5 < 10
+with messages:
+ current counter 5
+ i := 5
+
+MessageTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i < 10 )
+with expansion:
+ 6 < 10
+with messages:
+ current counter 6
+ i := 6
+
+MessageTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i < 10 )
+with expansion:
+ 7 < 10
+with messages:
+ current counter 7
+ i := 7
+
+MessageTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i < 10 )
+with expansion:
+ 8 < 10
+with messages:
+ current counter 8
+ i := 8
+
+MessageTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i < 10 )
+with expansion:
+ 9 < 10
+with messages:
+ current counter 9
+ i := 9
+
+MessageTests.cpp:<line number>: FAILED:
+ REQUIRE( i < 10 )
+with expansion:
+ 10 < 10
+with messages:
+ current counter 10
+ i := 10
+
+-------------------------------------------------------------------------------
+The NO_FAIL macro reports a failure but does not fail the test
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>:
+FAILED - but was ok:
+ CHECK_NOFAIL( 1 == 2 )
+
+-------------------------------------------------------------------------------
+just failure
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+explicitly with message:
+ Previous info should not be seen
+
+-------------------------------------------------------------------------------
+sends information to INFO
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with messages:
+ hi
+ i := 7
+
+-------------------------------------------------------------------------------
+Pointers can be converted to strings
+-------------------------------------------------------------------------------
+MessageTests.cpp:<line number>
+...............................................................................
+
+MessageTests.cpp:<line number>:
+warning:
+ actual address of p: 0x<hex digits>
+
+MessageTests.cpp:<line number>:
+warning:
+ toString(p): 0x<hex digits>
+
+-------------------------------------------------------------------------------
+random SECTION tests
+ s1
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( a != b )
+with expansion:
+ 1 != 2
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( b != a )
+with expansion:
+ 2 != 1
+
+-------------------------------------------------------------------------------
+random SECTION tests
+ s2
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( a != b )
+with expansion:
+ 1 != 2
+
+-------------------------------------------------------------------------------
+nested SECTION tests
+ s1
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( a != b )
+with expansion:
+ 1 != 2
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( b != a )
+with expansion:
+ 2 != 1
+
+-------------------------------------------------------------------------------
+nested SECTION tests
+ s1
+ s2
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( a != b )
+with expansion:
+ 1 != 2
+
+-------------------------------------------------------------------------------
+more nested SECTION tests
+ s1
+ s2
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ REQUIRE( a == b )
+with expansion:
+ 1 == 2
+
+-------------------------------------------------------------------------------
+more nested SECTION tests
+ s1
+ s3
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( a != b )
+with expansion:
+ 1 != 2
+
+-------------------------------------------------------------------------------
+more nested SECTION tests
+ s1
+ s4
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( a < b )
+with expansion:
+ 1 < 2
+
+-------------------------------------------------------------------------------
+even more nested SECTION tests
+ c
+ d (leaf)
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+even more nested SECTION tests
+ c
+ e (leaf)
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+even more nested SECTION tests
+ f (leaf)
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+looped SECTION tests
+ s1
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( b > a )
+with expansion:
+ 0 > 1
+
+-------------------------------------------------------------------------------
+looped tests
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[0] (1) is even
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[1] (1) is even
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 0 == 0
+with message:
+ Testing if fib[2] (2) is even
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[3] (3) is even
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[4] (5) is even
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 0 == 0
+with message:
+ Testing if fib[5] (8) is even
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[6] (13) is even
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( ( fib[i] % 2 ) == 0 )
+with expansion:
+ 1 == 0
+with message:
+ Testing if fib[7] (21) is even
+
+A string sent directly to stdout
+A string sent directly to stderr
+-------------------------------------------------------------------------------
+null strings
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( makeString( false ) != static_cast<char*>(nullptr) )
+with expansion:
+ "valid string" != {null string}
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( makeString( true ) == static_cast<char*>(nullptr) )
+with expansion:
+ {null string} == {null string}
+
+-------------------------------------------------------------------------------
+checkedIf
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECKED_IF( flag )
+with expansion:
+ true
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCheckedIf( true ) )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+checkedIf, failing
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECKED_IF( flag )
+with expansion:
+ false
+
+MiscTests.cpp:<line number>: FAILED:
+ REQUIRE( testCheckedIf( false ) )
+with expansion:
+ false
+
+-------------------------------------------------------------------------------
+checkedElse
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECKED_ELSE( flag )
+with expansion:
+ true
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCheckedElse( true ) )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+checkedElse, failing
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECKED_ELSE( flag )
+with expansion:
+ false
+
+MiscTests.cpp:<line number>: FAILED:
+ REQUIRE( testCheckedElse( false ) )
+with expansion:
+ false
+
+-------------------------------------------------------------------------------
+xmlentitycheck
+ embedded xml
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+xmlentitycheck
+ encoded chars
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+send a single char to INFO
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ REQUIRE( false )
+with message:
+ 3
+
+-------------------------------------------------------------------------------
+atomic if
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( x == 0 )
+with expansion:
+ 0 == 0
+
+-------------------------------------------------------------------------------
+String matchers
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THAT( testStringForMatching(), Contains( "string" ) )
+with expansion:
+ "this string contains 'abc' as a substring" contains: "string"
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), Contains( "abc" ) )
+with expansion:
+ "this string contains 'abc' as a substring" contains: "abc"
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), StartsWith( "this" ) )
+with expansion:
+ "this string contains 'abc' as a substring" starts with: "this"
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) )
+with expansion:
+ "this string contains 'abc' as a substring" ends with: "substring"
+
+-------------------------------------------------------------------------------
+Contains string matcher
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), Contains( "not there" ) )
+with expansion:
+ "this string contains 'abc' as a substring" contains: "not there"
+
+-------------------------------------------------------------------------------
+StartsWith string matcher
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), StartsWith( "string" ) )
+with expansion:
+ "this string contains 'abc' as a substring" starts with: "string"
+
+-------------------------------------------------------------------------------
+EndsWith string matcher
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), EndsWith( "this" ) )
+with expansion:
+ "this string contains 'abc' as a substring" ends with: "this"
+
+-------------------------------------------------------------------------------
+Equals string matcher
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), Equals( "something else" ) )
+with expansion:
+ "this string contains 'abc' as a substring" equals: "something else"
+
+-------------------------------------------------------------------------------
+Equals string matcher, with NULL
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE_THAT( "", Equals(nullptr) )
+with expansion:
+ "" equals: ""
+
+-------------------------------------------------------------------------------
+AllOf matcher
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) )
+with expansion:
+ "this string contains 'abc' as a substring" ( contains: "string" and
+ contains: "abc" )
+
+-------------------------------------------------------------------------------
+AnyOf matcher
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) )
+with expansion:
+ "this string contains 'abc' as a substring" ( contains: "string" or contains:
+ "not there" )
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) )
+with expansion:
+ "this string contains 'abc' as a substring" ( contains: "not there" or
+ contains: "string" )
+
+-------------------------------------------------------------------------------
+Equals
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) )
+with expansion:
+ "this string contains 'abc' as a substring" equals: "this string contains
+ 'abc' as a substring"
+
+-------------------------------------------------------------------------------
+Matchers can be (AllOf) composed with the && operator
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), Contains( "string" ) && Contains( "abc" ) && Contains( "substring" ) && Contains( "contains" ) )
+with expansion:
+ "this string contains 'abc' as a substring" ( contains: "string" and
+ contains: "abc" and contains: "substring" and contains: "contains" )
+
+-------------------------------------------------------------------------------
+Matchers can be (AnyOf) composed with the || operator
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) )
+with expansion:
+ "this string contains 'abc' as a substring" ( contains: "string" or contains:
+ "different" or contains: "random" )
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) )
+with expansion:
+ "some completely different text that contains one common word" ( contains:
+ "string" or contains: "different" or contains: "random" )
+
+-------------------------------------------------------------------------------
+Matchers can be composed with both && and ||
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) )
+with expansion:
+ "this string contains 'abc' as a substring" ( ( contains: "string" or
+ contains: "different" ) and contains: "substring" )
+
+-------------------------------------------------------------------------------
+Matchers can be composed with both && and || - failing
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) )
+with expansion:
+ "this string contains 'abc' as a substring" ( ( contains: "string" or
+ contains: "different" ) and contains: "random" )
+
+-------------------------------------------------------------------------------
+Matchers can be negated (Not) with the ! operator
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( testStringForMatching(), !Contains( "different" ) )
+with expansion:
+ "this string contains 'abc' as a substring" not contains: "different"
+
+-------------------------------------------------------------------------------
+Matchers can be negated (Not) with the ! operator - failing
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK_THAT( testStringForMatching(), !Contains( "substring" ) )
+with expansion:
+ "this string contains 'abc' as a substring" not contains: "substring"
+
+-------------------------------------------------------------------------------
+Factorials are computed
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Factorial(0) == 1 )
+with expansion:
+ 1 == 1
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Factorial(1) == 1 )
+with expansion:
+ 1 == 1
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Factorial(2) == 2 )
+with expansion:
+ 2 == 2
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Factorial(3) == 6 )
+with expansion:
+ 6 == 6
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Factorial(10) == 3628800 )
+with expansion:
+ 3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
+
+-------------------------------------------------------------------------------
+Nice descriptive name
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+warning:
+ This one ran
+
+-------------------------------------------------------------------------------
+vectors can be sized and resized
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 5 )
+with expansion:
+ 5 == 5
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 5 )
+with expansion:
+ 5 >= 5
+
+-------------------------------------------------------------------------------
+vectors can be sized and resized
+ resizing bigger changes size and capacity
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 10 )
+with expansion:
+ 10 == 10
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 10 )
+with expansion:
+ 10 >= 10
+
+-------------------------------------------------------------------------------
+vectors can be sized and resized
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 5 )
+with expansion:
+ 5 == 5
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 5 )
+with expansion:
+ 5 >= 5
+
+-------------------------------------------------------------------------------
+vectors can be sized and resized
+ resizing smaller changes size but not capacity
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 0 )
+with expansion:
+ 0 == 0
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 5 )
+with expansion:
+ 5 >= 5
+
+-------------------------------------------------------------------------------
+vectors can be sized and resized
+ resizing smaller changes size but not capacity
+ We can use the 'swap trick' to reset the capacity
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() == 0 )
+with expansion:
+ 0 == 0
+
+-------------------------------------------------------------------------------
+vectors can be sized and resized
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 5 )
+with expansion:
+ 5 == 5
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 5 )
+with expansion:
+ 5 >= 5
+
+-------------------------------------------------------------------------------
+vectors can be sized and resized
+ reserving bigger changes capacity but not size
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 5 )
+with expansion:
+ 5 == 5
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 10 )
+with expansion:
+ 10 >= 10
+
+-------------------------------------------------------------------------------
+vectors can be sized and resized
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 5 )
+with expansion:
+ 5 == 5
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 5 )
+with expansion:
+ 5 >= 5
+
+-------------------------------------------------------------------------------
+vectors can be sized and resized
+ reserving smaller does not change size or capacity
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 5 )
+with expansion:
+ 5 == 5
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 5 )
+with expansion:
+ 5 >= 5
+
+-------------------------------------------------------------------------------
+A couple of nested sections followed by a failure
+ Outer
+ Inner
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+with message:
+ that's not flying - that's failing in style
+
+-------------------------------------------------------------------------------
+A couple of nested sections followed by a failure
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+explicitly with message:
+ to infinity and beyond
+
+-------------------------------------------------------------------------------
+not allowed
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+Tabs and newlines show in output
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>: FAILED:
+ CHECK( s1 == s2 )
+with expansion:
+ "if ($b == 10) {
+ $a= 20;
+ }"
+ ==
+ "if ($b == 10) {
+ $a = 20;
+ }
+ "
+
+-------------------------------------------------------------------------------
+toString on const wchar_t const pointer returns the string contents
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK( result == "\"wide load\"" )
+with expansion:
+ ""wide load"" == ""wide load""
+
+-------------------------------------------------------------------------------
+toString on const wchar_t pointer returns the string contents
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK( result == "\"wide load\"" )
+with expansion:
+ ""wide load"" == ""wide load""
+
+-------------------------------------------------------------------------------
+toString on wchar_t const pointer returns the string contents
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK( result == "\"wide load\"" )
+with expansion:
+ ""wide load"" == ""wide load""
+
+-------------------------------------------------------------------------------
+toString on wchar_t returns the string contents
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ CHECK( result == "\"wide load\"" )
+with expansion:
+ ""wide load"" == ""wide load""
+
+-------------------------------------------------------------------------------
+XmlEncode
+ normal string
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( encode( "normal string" ) == "normal string" )
+with expansion:
+ "normal string" == "normal string"
+
+-------------------------------------------------------------------------------
+XmlEncode
+ empty string
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( encode( "" ) == "" )
+with expansion:
+ "" == ""
+
+-------------------------------------------------------------------------------
+XmlEncode
+ string with ampersand
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( encode( "smith & jones" ) == "smith &amp; jones" )
+with expansion:
+ "smith &amp; jones" == "smith &amp; jones"
+
+-------------------------------------------------------------------------------
+XmlEncode
+ string with less-than
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( encode( "smith < jones" ) == "smith &lt; jones" )
+with expansion:
+ "smith &lt; jones" == "smith &lt; jones"
+
+-------------------------------------------------------------------------------
+XmlEncode
+ string with greater-than
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( encode( "smith > jones" ) == "smith > jones" )
+with expansion:
+ "smith > jones" == "smith > jones"
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( encode( "smith ]]> jones" ) == "smith ]]&gt; jones" )
+with expansion:
+ "smith ]]&gt; jones"
+ ==
+ "smith ]]&gt; jones"
+
+-------------------------------------------------------------------------------
+XmlEncode
+ string with quotes
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( encode( stringWithQuotes ) == stringWithQuotes )
+with expansion:
+ "don't "quote" me on that"
+ ==
+ "don't "quote" me on that"
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't &quot;quote&quot; me on that" )
+with expansion:
+ "don't &quot;quote&quot; me on that"
+ ==
+ "don't &quot;quote&quot; me on that"
+
+-------------------------------------------------------------------------------
+XmlEncode
+ string with control char (1)
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( encode( "[\x01]" ) == "[&#x1]" )
+with expansion:
+ "[&#x1]" == "[&#x1]"
+
+-------------------------------------------------------------------------------
+XmlEncode
+ string with control char (x7F)
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( encode( "[\x7F]" ) == "[&#x7F]" )
+with expansion:
+ "[&#x7F]" == "[&#x7F]"
+
+-------------------------------------------------------------------------------
+long long
+-------------------------------------------------------------------------------
+MiscTests.cpp:<line number>
+...............................................................................
+
+MiscTests.cpp:<line number>:
+PASSED:
+ REQUIRE( l == std::numeric_limits<long long>::max() )
+with expansion:
+ 9223372036854775807 (0x<hex digits>)
+ ==
+ 9223372036854775807 (0x<hex digits>)
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ default - no arguments
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( config.shouldDebugBreak == false )
+with expansion:
+ false == false
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( config.abortAfter == -1 )
+with expansion:
+ -1 == -1
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( config.noThrow == false )
+with expansion:
+ false == false
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( config.reporterNames.empty() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ test lists
+ 1 test
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false )
+with expansion:
+ false == false
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ test lists
+ Specify one test case exclusion using exclude:
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false )
+with expansion:
+ false == false
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ test lists
+ Specify one test case exclusion using ~
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false )
+with expansion:
+ false == false
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ reporter
+ -r/console
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.reporterNames[0] == "console" )
+with expansion:
+ "console" == "console"
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ reporter
+ -r/xml
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.reporterNames[0] == "xml" )
+with expansion:
+ "xml" == "xml"
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ reporter
+ -r xml and junit
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.reporterNames.size() == 2 )
+with expansion:
+ 2 == 2
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.reporterNames[0] == "xml" )
+with expansion:
+ "xml" == "xml"
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.reporterNames[1] == "junit" )
+with expansion:
+ "junit" == "junit"
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ reporter
+ --reporter/junit
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.reporterNames[0] == "junit" )
+with expansion:
+ "junit" == "junit"
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ debugger
+ -b
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.shouldDebugBreak == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ debugger
+ --break
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.shouldDebugBreak )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ abort
+ -a aborts after first failure
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.abortAfter == 1 )
+with expansion:
+ 1 == 1
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ abort
+ -x 2 aborts after two failures
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.abortAfter == 2 )
+with expansion:
+ 2 == 2
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ abort
+ -x must be greater than zero
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "greater than zero" ) )
+with expansion:
+ "Value after -x or --abortAfter must be greater than zero
+ - while parsing: (-x, --abortx <no. failures>)" contains: "greater than zero"
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ abort
+ -x must be numeric
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) )
+with expansion:
+ "Unable to convert oops to destination type
+ - while parsing: (-x, --abortx <no. failures>)" contains: "-x"
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ nothrow
+ -e
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.noThrow == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ nothrow
+ --nothrow
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.noThrow == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ output filename
+ -o filename
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.outputFilename == "filename.ext" )
+with expansion:
+ "filename.ext" == "filename.ext"
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ output filename
+ --out
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.outputFilename == "filename.ext" )
+with expansion:
+ "filename.ext" == "filename.ext"
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ combinations
+ Single character flags can be combined
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( config.abortAfter == 1 )
+with expansion:
+ 1 == 1
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( config.shouldDebugBreak )
+with expansion:
+ true
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( config.noThrow == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ force-colour
+ --force-colour
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( config.forceColour )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Process can be configured on command line
+ force-colour
+ without --force-colour
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) )
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( !config.forceColour )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ plain string
+ No wrapping
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString )
+with expansion:
+ "one two three four"
+ ==
+ "one two three four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString )
+with expansion:
+ "one two three four"
+ ==
+ "one two three four"
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ plain string
+ Wrapped once
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" )
+with expansion:
+ "one two three
+ four"
+ ==
+ "one two three
+ four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" )
+with expansion:
+ "one two three
+ four"
+ ==
+ "one two three
+ four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" )
+with expansion:
+ "one two three
+ four"
+ ==
+ "one two three
+ four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" )
+with expansion:
+ "one two three
+ four"
+ ==
+ "one two three
+ four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" )
+with expansion:
+ "one two
+ three four"
+ ==
+ "one two
+ three four"
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ plain string
+ Wrapped twice
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" )
+with expansion:
+ "one two
+ three
+ four"
+ ==
+ "one two
+ three
+ four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" )
+with expansion:
+ "one two
+ three
+ four"
+ ==
+ "one two
+ three
+ four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" )
+with expansion:
+ "one two
+ three
+ four"
+ ==
+ "one two
+ three
+ four"
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ plain string
+ Wrapped three times
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" )
+with expansion:
+ "one
+ two
+ three
+ four"
+ ==
+ "one
+ two
+ three
+ four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" )
+with expansion:
+ "one
+ two
+ three
+ four"
+ ==
+ "one
+ two
+ three
+ four"
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ plain string
+ Short wrap
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" )
+with expansion:
+ "abc-
+ def"
+ ==
+ "abc-
+ def"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" )
+with expansion:
+ "abc-
+ defg"
+ ==
+ "abc-
+ defg"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" )
+with expansion:
+ "abc-
+ def-
+ gh"
+ ==
+ "abc-
+ def-
+ gh"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" )
+with expansion:
+ "one
+ two
+ thr-
+ ee
+ four"
+ ==
+ "one
+ two
+ thr-
+ ee
+ four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" )
+with expansion:
+ "one
+ two
+ th-
+ ree
+ fo-
+ ur"
+ ==
+ "one
+ two
+ th-
+ ree
+ fo-
+ ur"
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ plain string
+ As container
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ REQUIRE( text.size() == 4 )
+with expansion:
+ 4 == 4
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( text[0] == "one" )
+with expansion:
+ "one" == "one"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( text[1] == "two" )
+with expansion:
+ "two" == "two"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( text[2] == "three" )
+with expansion:
+ "three" == "three"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( text[3] == "four" )
+with expansion:
+ "four" == "four"
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ plain string
+ Indent first line differently
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( text.toString() == " one two\n three\n four" )
+with expansion:
+ " one two
+ three
+ four"
+ ==
+ " one two
+ three
+ four"
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ With newlines
+ No wrapping
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString )
+with expansion:
+ "one two
+ three four"
+ ==
+ "one two
+ three four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString )
+with expansion:
+ "one two
+ three four"
+ ==
+ "one two
+ three four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString )
+with expansion:
+ "one two
+ three four"
+ ==
+ "one two
+ three four"
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ With newlines
+ Trailing newline
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef\n" )
+with expansion:
+ "abcdef
+ "
+ ==
+ "abcdef
+ "
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" )
+with expansion:
+ "abcdef" == "abcdef"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef\n" )
+with expansion:
+ "abcdef
+ "
+ ==
+ "abcdef
+ "
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ With newlines
+ Wrapped once
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" )
+with expansion:
+ "one two
+ three
+ four"
+ ==
+ "one two
+ three
+ four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" )
+with expansion:
+ "one two
+ three
+ four"
+ ==
+ "one two
+ three
+ four"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" )
+with expansion:
+ "one two
+ three
+ four"
+ ==
+ "one two
+ three
+ four"
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ With newlines
+ Wrapped twice
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" )
+with expansion:
+ "one
+ two
+ three
+ four"
+ ==
+ "one
+ two
+ three
+ four"
+
+-------------------------------------------------------------------------------
+Long strings can be wrapped
+ With tabs
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( testString, TextAttributes().setWidth( 15 ) ).toString() == "one two three\n four\n five\n six" )
+with expansion:
+ "one two three
+ four
+ five
+ six"
+ ==
+ "one two three
+ four
+ five
+ six"
+
+-------------------------------------------------------------------------------
+replaceInPlace
+ replace single char
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( replaceInPlace( letters, "b", "z" ) )
+with expansion:
+ true
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( letters == "azcdefcg" )
+with expansion:
+ "azcdefcg" == "azcdefcg"
+
+-------------------------------------------------------------------------------
+replaceInPlace
+ replace two chars
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( replaceInPlace( letters, "c", "z" ) )
+with expansion:
+ true
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( letters == "abzdefzg" )
+with expansion:
+ "abzdefzg" == "abzdefzg"
+
+-------------------------------------------------------------------------------
+replaceInPlace
+ replace first char
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( replaceInPlace( letters, "a", "z" ) )
+with expansion:
+ true
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( letters == "zbcdefcg" )
+with expansion:
+ "zbcdefcg" == "zbcdefcg"
+
+-------------------------------------------------------------------------------
+replaceInPlace
+ replace last char
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( replaceInPlace( letters, "g", "z" ) )
+with expansion:
+ true
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( letters == "abcdefcz" )
+with expansion:
+ "abcdefcz" == "abcdefcz"
+
+-------------------------------------------------------------------------------
+replaceInPlace
+ replace all chars
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( replaceInPlace( letters, letters, "replaced" ) )
+with expansion:
+ true
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( letters == "replaced" )
+with expansion:
+ "replaced" == "replaced"
+
+-------------------------------------------------------------------------------
+replaceInPlace
+ replace no chars
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_FALSE( replaceInPlace( letters, "x", "z" ) )
+with expansion:
+ !false
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( letters == letters )
+with expansion:
+ "abcdefcg" == "abcdefcg"
+
+-------------------------------------------------------------------------------
+replaceInPlace
+ escape '
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( replaceInPlace( s, "'", "|'" ) )
+with expansion:
+ true
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( s == "didn|'t" )
+with expansion:
+ "didn|'t" == "didn|'t"
+
+hello
+hello
+-------------------------------------------------------------------------------
+Text can be formatted using the Text class
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( "hi there" ).toString() == "hi there" )
+with expansion:
+ "hi there" == "hi there"
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" )
+with expansion:
+ "hi
+ there"
+ ==
+ "hi
+ there"
+
+-------------------------------------------------------------------------------
+Long text is truncted
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+ CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) )
+with expansion:
+ "***************************************************************************-
+ ***-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+ ****************************************************************************-
+ **-
+ ****************************************************************************-
+ **-
+ ************************
+... message truncated due to excessive size
+
+-------------------------------------------------------------------------------
+ManuallyRegistered
+-------------------------------------------------------------------------------
+TestMain.cpp:<line number>
+...............................................................................
+
+TestMain.cpp:<line number>:
+PASSED:
+with message:
+ was called
+
+-------------------------------------------------------------------------------
+Parsing a std::pair
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( (std::pair<int, int>( 1, 2 )) == aNicePair )
+with expansion:
+ std::pair( 1, 2 ) == std::pair( 1, 2 )
+
+-------------------------------------------------------------------------------
+Where there is more to the expression after the RHS
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+warning:
+ Uncomment the code in this test to check that it gives a sensible compiler
+ error
+
+-------------------------------------------------------------------------------
+Where the LHS is not a simple value
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+warning:
+ Uncomment the code in this test to check that it gives a sensible compiler
+ error
+
+-------------------------------------------------------------------------------
+A failing expression with a non streamable type is still captured
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>: FAILED:
+ CHECK( &o1 == &o2 )
+with expansion:
+ 0x<hex digits> == 0x<hex digits>
+
+TrickyTests.cpp:<line number>: FAILED:
+ CHECK( o1 == o2 )
+with expansion:
+ {?} == {?}
+
+-------------------------------------------------------------------------------
+string literals of different sizes can be compared
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>: FAILED:
+ REQUIRE( std::string( "first" ) == "second" )
+with expansion:
+ "first" == "second"
+
+-------------------------------------------------------------------------------
+An expression with side-effects should only be evaluated once
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i++ == 7 )
+with expansion:
+ 7 == 7
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( i++ == 8 )
+with expansion:
+ 8 == 8
+
+-------------------------------------------------------------------------------
+Operators at different namespace levels not hijacked by Koenig lookup
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 0x<hex digits> == o )
+with expansion:
+ 3221225472 (0x<hex digits>) == {?}
+
+-------------------------------------------------------------------------------
+Demonstrate that a non-const == is not used
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( t == 1u )
+with expansion:
+ {?} == 1
+
+-------------------------------------------------------------------------------
+Test enum bit values
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 0x<hex digits> == bit30and31 )
+with expansion:
+ 3221225472 (0x<hex digits>) == 3221225472
+
+-------------------------------------------------------------------------------
+boolean member
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( obj.prop != nullptr )
+with expansion:
+ 0x<hex digits> != nullptr
+
+-------------------------------------------------------------------------------
+(unimplemented) static bools can be evaluated
+ compare to true
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( is_true<true>::value == true )
+with expansion:
+ true == true
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( true == is_true<true>::value )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+(unimplemented) static bools can be evaluated
+ compare to false
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( is_true<false>::value == false )
+with expansion:
+ false == false
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( false == is_true<false>::value )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+(unimplemented) static bools can be evaluated
+ negation
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( !is_true<false>::value )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+(unimplemented) static bools can be evaluated
+ double negation
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( !!is_true<true>::value )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+(unimplemented) static bools can be evaluated
+ direct
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( is_true<true>::value )
+with expansion:
+ true
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE_FALSE( is_true<false>::value )
+with expansion:
+ !false
+
+-------------------------------------------------------------------------------
+Objects that evaluated in boolean contexts can be checked
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ CHECK( True )
+with expansion:
+ true
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ CHECK( !False )
+with expansion:
+ true
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ CHECK_FALSE( False )
+with expansion:
+ !false
+
+-------------------------------------------------------------------------------
+Assertions then sections
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::alwaysTrue() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Assertions then sections
+ A section
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::alwaysTrue() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Assertions then sections
+ A section
+ Another section
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::alwaysTrue() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Assertions then sections
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::alwaysTrue() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Assertions then sections
+ A section
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::alwaysTrue() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Assertions then sections
+ A section
+ Another other section
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::alwaysTrue() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+non streamable - with conv. op
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s == "7" )
+with expansion:
+ "7" == "7"
+
+-------------------------------------------------------------------------------
+Comparing function pointers
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( a )
+with expansion:
+ true
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( a == &foo )
+with expansion:
+ 0x<hex digits> == 0x<hex digits>
+
+-------------------------------------------------------------------------------
+Comparing member function pointers
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ CHECK( m == &S::f )
+with expansion:
+ 0x<hex digits>
+ ==
+ 0x<hex digits>
+
+-------------------------------------------------------------------------------
+pointer to class
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( p == 0 )
+with expansion:
+ NULL == 0
+
+-------------------------------------------------------------------------------
+null_ptr
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ptr.get() == nullptr )
+with expansion:
+ NULL == nullptr
+
+-------------------------------------------------------------------------------
+X/level/0/a
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+X/level/0/b
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+X/level/1/a
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+X/level/1/b
+-------------------------------------------------------------------------------
+TrickyTests.cpp:<line number>
+...............................................................................
+
+TrickyTests.cpp:<line number>:
+PASSED:
+
+-------------------------------------------------------------------------------
+toString( has_toString )
+-------------------------------------------------------------------------------
+ToStringWhich.cpp:<line number>
+...............................................................................
+
+ToStringWhich.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString( item ) == "toString( has_toString )" )
+with expansion:
+ "toString( has_toString )"
+ ==
+ "toString( has_toString )"
+
+-------------------------------------------------------------------------------
+toString( has_maker )
+-------------------------------------------------------------------------------
+ToStringWhich.cpp:<line number>
+...............................................................................
+
+ToStringWhich.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString( item ) == "StringMaker<has_maker>" )
+with expansion:
+ "StringMaker<has_maker>"
+ ==
+ "StringMaker<has_maker>"
+
+-------------------------------------------------------------------------------
+toString( has_maker_and_toString )
+-------------------------------------------------------------------------------
+ToStringWhich.cpp:<line number>
+...............................................................................
+
+ToStringWhich.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString( item ) == "toString( has_maker_and_toString )" )
+with expansion:
+ "toString( has_maker_and_toString )"
+ ==
+ "toString( has_maker_and_toString )"
+
+-------------------------------------------------------------------------------
+toString( vectors<has_toString )
+-------------------------------------------------------------------------------
+ToStringWhich.cpp:<line number>
+...............................................................................
+
+ToStringWhich.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString( v ) == "{ {?} }" )
+with expansion:
+ "{ {?} }" == "{ {?} }"
+
+-------------------------------------------------------------------------------
+toString( vectors<has_maker )
+-------------------------------------------------------------------------------
+ToStringWhich.cpp:<line number>
+...............................................................................
+
+ToStringWhich.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString( v ) == "{ StringMaker<has_maker> }" )
+with expansion:
+ "{ StringMaker<has_maker> }"
+ ==
+ "{ StringMaker<has_maker> }"
+
+-------------------------------------------------------------------------------
+toString( vectors<has_maker_and_toString )
+-------------------------------------------------------------------------------
+ToStringWhich.cpp:<line number>
+...............................................................................
+
+ToStringWhich.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString( v ) == "{ StringMaker<has_maker_and_toString> }" )
+with expansion:
+ "{ StringMaker<has_maker_and_toString> }"
+ ==
+ "{ StringMaker<has_maker_and_toString> }"
+
+-------------------------------------------------------------------------------
+Tracker
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isOpen() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+ successfully close one section
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isSuccessfullyCompleted() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ctx.completedCycle() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isSuccessfullyCompleted() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isOpen() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+ fail one section
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isSuccessfullyCompleted() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ctx.completedCycle() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isSuccessfullyCompleted() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ fail one section
+ re-enter after failed section
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1b.isOpen() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ctx.completedCycle() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isSuccessfullyCompleted() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isOpen() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+ fail one section
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isSuccessfullyCompleted() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ctx.completedCycle() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isSuccessfullyCompleted() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ fail one section
+ re-enter after failed section and find next section
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1b.isOpen() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ctx.completedCycle() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isSuccessfullyCompleted() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isOpen() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+ successfully close one section, then find another
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2.isOpen() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ successfully close one section, then find another
+ Re-enter - skips S1 and enters S2
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1b.isOpen() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2b.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ctx.completedCycle() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ successfully close one section, then find another
+ Re-enter - skips S1 and enters S2
+ Successfully close S2
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ctx.completedCycle() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2b.isSuccessfullyCompleted() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isSuccessfullyCompleted() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isOpen() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+ successfully close one section, then find another
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2.isOpen() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ successfully close one section, then find another
+ Re-enter - skips S1 and enters S2
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1b.isOpen() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2b.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ctx.completedCycle() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ successfully close one section, then find another
+ Re-enter - skips S1 and enters S2
+ fail S2
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( ctx.completedCycle() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2b.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2b.isSuccessfullyCompleted() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isSuccessfullyCompleted() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase3.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1c.isOpen() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2c.isOpen() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase3.isSuccessfullyCompleted() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isOpen() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+ open a nested section
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isOpen() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+ start a generator
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1.index() == 0 )
+with expansion:
+ 0 == 0
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ start a generator
+ close outer section
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isSuccessfullyCompleted() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ start a generator
+ close outer section
+ Re-enter for second generation
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1b.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1b.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1b.index() == 1 )
+with expansion:
+ 1 == 1
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1b.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1b.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isComplete() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isOpen() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+ start a generator
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1.index() == 0 )
+with expansion:
+ 0 == 0
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ start a generator
+ Start a new inner section
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ start a generator
+ Start a new inner section
+ Re-enter for second generation
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1b.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1b.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1b.index() == 1 )
+with expansion:
+ 1 == 1
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2b.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2b.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1b.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1b.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isComplete() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isOpen() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Tracker
+ start a generator
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1.index() == 0 )
+with expansion:
+ 0 == 0
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ start a generator
+ Fail an inner section
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2.isSuccessfullyCompleted() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase.isComplete() == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Tracker
+ start a generator
+ Fail an inner section
+ Re-enter for second generation
+-------------------------------------------------------------------------------
+PartTrackerTests.cpp:<line number>
+...............................................................................
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1b.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1b.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1b.index() == 0 )
+with expansion:
+ 0 == 0
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2b.isOpen() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1b.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1b.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase2.isComplete() == false )
+with expansion:
+ false == false
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase3.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1c.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1c.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1c.index() == 1 )
+with expansion:
+ 1 == 1
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2c.isOpen() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s2c.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( g1c.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s1c.isComplete() )
+with expansion:
+ true
+
+PartTrackerTests.cpp:<line number>:
+PASSED:
+ REQUIRE( testCase3.isComplete() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+std::pair<int,std::string> -> toString
+-------------------------------------------------------------------------------
+ToStringPair.cpp:<line number>
+...............................................................................
+
+ToStringPair.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString( value ) == "{ 34, \"xyzzy\" }" )
+with expansion:
+ "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }"
+
+-------------------------------------------------------------------------------
+std::pair<int,const std::string> -> toString
+-------------------------------------------------------------------------------
+ToStringPair.cpp:<line number>
+...............................................................................
+
+ToStringPair.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(value) == "{ 34, \"xyzzy\" }" )
+with expansion:
+ "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }"
+
+-------------------------------------------------------------------------------
+std::vector<std::pair<std::string,int> > -> toString
+-------------------------------------------------------------------------------
+ToStringPair.cpp:<line number>
+...............................................................................
+
+ToStringPair.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString( pr ) == "{ { \"green\", 55 } }" )
+with expansion:
+ "{ { "green", 55 } }"
+ ==
+ "{ { "green", 55 } }"
+
+-------------------------------------------------------------------------------
+pair<pair<int,const char *,pair<std::string,int> > -> toString
+-------------------------------------------------------------------------------
+ToStringPair.cpp:<line number>
+...............................................................................
+
+ToStringPair.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" )
+with expansion:
+ "{ { 42, "Arthur" }, { "Ford", 24 } }"
+ ==
+ "{ { 42, "Arthur" }, { "Ford", 24 } }"
+
+-------------------------------------------------------------------------------
+vector<int> -> toString
+-------------------------------------------------------------------------------
+ToStringVector.cpp:<line number>
+...............................................................................
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(vv) == "{ }" )
+with expansion:
+ "{ }" == "{ }"
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(vv) == "{ 42 }" )
+with expansion:
+ "{ 42 }" == "{ 42 }"
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(vv) == "{ 42, 250 }" )
+with expansion:
+ "{ 42, 250 }" == "{ 42, 250 }"
+
+-------------------------------------------------------------------------------
+vector<string> -> toString
+-------------------------------------------------------------------------------
+ToStringVector.cpp:<line number>
+...............................................................................
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(vv) == "{ }" )
+with expansion:
+ "{ }" == "{ }"
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(vv) == "{ \"hello\" }" )
+with expansion:
+ "{ "hello" }" == "{ "hello" }"
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(vv) == "{ \"hello\", \"world\" }" )
+with expansion:
+ "{ "hello", "world" }"
+ ==
+ "{ "hello", "world" }"
+
+-------------------------------------------------------------------------------
+vector<int,allocator> -> toString
+-------------------------------------------------------------------------------
+ToStringVector.cpp:<line number>
+...............................................................................
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(vv) == "{ }" )
+with expansion:
+ "{ }" == "{ }"
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(vv) == "{ 42 }" )
+with expansion:
+ "{ 42 }" == "{ 42 }"
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(vv) == "{ 42, 250 }" )
+with expansion:
+ "{ 42, 250 }" == "{ 42, 250 }"
+
+-------------------------------------------------------------------------------
+vec<vec<string,alloc>> -> toString
+-------------------------------------------------------------------------------
+ToStringVector.cpp:<line number>
+...............................................................................
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(v) == "{ }" )
+with expansion:
+ "{ }" == "{ }"
+
+ToStringVector.cpp:<line number>:
+PASSED:
+ REQUIRE( Catch::toString(v) == "{ { \"hello\" }, { \"world\" } }" )
+with expansion:
+ "{ { "hello" }, { "world" } }"
+ ==
+ "{ { "hello" }, { "world" } }"
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Empty test spec should have no filters
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Test spec from empty string should have no filters
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches(tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Test spec from just a comma should have no filters
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Test spec from name should have one filter
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Test spec from quoted name should have one filter
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Test spec from name should have one filter
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Wildcard at the start
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( parseTestSpec( "*a" ).matches( tcA ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Wildcard at the end
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( parseTestSpec( "a*" ).matches( tcA ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Wildcard at both ends
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( parseTestSpec( "*a*" ).matches( tcA ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Redundant wildcard at the start
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Redundant wildcard at the end
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Redundant wildcard at both ends
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Wildcard at both ends, redundant at start
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Just wildcard
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Single tag
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Single tag, two matches
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Two tags
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Two tags, spare separated
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Wildcarded name and tag
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ Single tag exclusion
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ One tag exclusion and one tag inclusion
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ One tag exclusion and one wldcarded name inclusion
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ One tag exclusion, using exclude:, and one wldcarded name inclusion
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ name exclusion
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ wildcarded name exclusion
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ wildcarded name exclusion with tag inclusion
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ wildcarded name exclusion, using exclude:, with tag inclusion
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ two wildcarded names
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ empty tag
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ empty quoted name
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == false )
+with expansion:
+ false == false
+
+-------------------------------------------------------------------------------
+Parse test names and tags
+ quoted string followed by tag exclusion
+-------------------------------------------------------------------------------
+CmdLineTests.cpp:<line number>
+...............................................................................
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.hasFilters() == true )
+with expansion:
+ true == true
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcA ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcB ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcC ) == false )
+with expansion:
+ false == false
+
+CmdLineTests.cpp:<line number>:
+PASSED:
+ CHECK( spec.matches( tcD ) == true )
+with expansion:
+ true == true
+
+-------------------------------------------------------------------------------
+tuple<>
+-------------------------------------------------------------------------------
+ToStringTuple.cpp:<line number>
+...............................................................................
+
+ToStringTuple.cpp:<line number>:
+PASSED:
+ CHECK( "{ }" == Catch::toString(type{}) )
+with expansion:
+ "{ }" == "{ }"
+
+ToStringTuple.cpp:<line number>:
+PASSED:
+ CHECK( "{ }" == Catch::toString(value) )
+with expansion:
+ "{ }" == "{ }"
+
+-------------------------------------------------------------------------------
+tuple<int>
+-------------------------------------------------------------------------------
+ToStringTuple.cpp:<line number>
+...............................................................................
+
+ToStringTuple.cpp:<line number>:
+PASSED:
+ CHECK( "{ 0 }" == Catch::toString(type{0}) )
+with expansion:
+ "{ 0 }" == "{ 0 }"
+
+-------------------------------------------------------------------------------
+tuple<float,int>
+-------------------------------------------------------------------------------
+ToStringTuple.cpp:<line number>
+...............................................................................
+
+ToStringTuple.cpp:<line number>:
+PASSED:
+ CHECK( "1.2f" == Catch::toString(float(1.2)) )
+with expansion:
+ "1.2f" == "1.2f"
+
+ToStringTuple.cpp:<line number>:
+PASSED:
+ CHECK( "{ 1.2f, 0 }" == Catch::toString(type{1.2,0}) )
+with expansion:
+ "{ 1.2f, 0 }" == "{ 1.2f, 0 }"
+
+-------------------------------------------------------------------------------
+tuple<string,string>
+-------------------------------------------------------------------------------
+ToStringTuple.cpp:<line number>
+...............................................................................
+
+ToStringTuple.cpp:<line number>:
+PASSED:
+ CHECK( "{ \"hello\", \"world\" }" == Catch::toString(type{"hello","world"}) )
+with expansion:
+ "{ "hello", "world" }"
+ ==
+ "{ "hello", "world" }"
+
+-------------------------------------------------------------------------------
+tuple<tuple<int>,tuple<>,float>
+-------------------------------------------------------------------------------
+ToStringTuple.cpp:<line number>
+...............................................................................
+
+ToStringTuple.cpp:<line number>:
+PASSED:
+ CHECK( "{ { 42 }, { }, 1.2f }" == Catch::toString(value) )
+with expansion:
+ "{ { 42 }, { }, 1.2f }"
+ ==
+ "{ { 42 }, { }, 1.2f }"
+
+-------------------------------------------------------------------------------
+tuple<nullptr,int,const char *>
+-------------------------------------------------------------------------------
+ToStringTuple.cpp:<line number>
+...............................................................................
+
+ToStringTuple.cpp:<line number>:
+PASSED:
+ CHECK( "{ nullptr, 42, \"Catch me\" }" == Catch::toString(value) )
+with expansion:
+ "{ nullptr, 42, "Catch me" }"
+ ==
+ "{ nullptr, 42, "Catch me" }"
+
+-------------------------------------------------------------------------------
+Tag alias can be registered against tag patterns
+ The same tag alias can only be registered once
+-------------------------------------------------------------------------------
+TagAliasTests.cpp:<line number>
+...............................................................................
+
+TagAliasTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( what, Contains( "[@zzz]" ) )
+with expansion:
+ "error: tag alias, "[@zzz]" already registered.
+ First seen at file:2
+ Redefined at file:10" contains: "
+ [@zzz]"
+
+TagAliasTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( what, Contains( "file" ) )
+with expansion:
+ "error: tag alias, "[@zzz]" already registered.
+ First seen at file:2
+ Redefined at file:10" contains:
+ "file"
+
+TagAliasTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( what, Contains( "2" ) )
+with expansion:
+ "error: tag alias, "[@zzz]" already registered.
+ First seen at file:2
+ Redefined at file:10" contains:
+ "2"
+
+TagAliasTests.cpp:<line number>:
+PASSED:
+ CHECK_THAT( what, Contains( "10" ) )
+with expansion:
+ "error: tag alias, "[@zzz]" already registered.
+ First seen at file:2
+ Redefined at file:10" contains:
+ "10"
+
+-------------------------------------------------------------------------------
+Tag alias can be registered against tag patterns
+ Tag aliases must be of the form [@name]
+-------------------------------------------------------------------------------
+TagAliasTests.cpp:<line number>
+...............................................................................
+
+TagAliasTests.cpp:<line number>:
+PASSED:
+ CHECK_THROWS( registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) )
+
+TagAliasTests.cpp:<line number>:
+PASSED:
+ CHECK_THROWS( registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) )
+
+TagAliasTests.cpp:<line number>:
+PASSED:
+ CHECK_THROWS( registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) )
+
+TagAliasTests.cpp:<line number>:
+PASSED:
+ CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) )
+
+-------------------------------------------------------------------------------
+Anonymous test case 1
+-------------------------------------------------------------------------------
+VariadicMacrosTests.cpp:<line number>
+...............................................................................
+
+VariadicMacrosTests.cpp:<line number>:
+PASSED:
+with message:
+ anonymous test case
+
+-------------------------------------------------------------------------------
+Test case with one argument
+-------------------------------------------------------------------------------
+VariadicMacrosTests.cpp:<line number>
+...............................................................................
+
+VariadicMacrosTests.cpp:<line number>:
+PASSED:
+with message:
+ no assertions
+
+-------------------------------------------------------------------------------
+Variadic macros
+ Section with one argument
+-------------------------------------------------------------------------------
+VariadicMacrosTests.cpp:<line number>
+...............................................................................
+
+VariadicMacrosTests.cpp:<line number>:
+PASSED:
+with message:
+ no assertions
+
+-------------------------------------------------------------------------------
+Scenario: Do that thing with the thing
+ Given: This stuff exists
+ When: I do this
+ Then: it should do this
+-------------------------------------------------------------------------------
+BDDTests.cpp:<line number>
+...............................................................................
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( itDoesThis() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Scenario: Do that thing with the thing
+ Given: This stuff exists
+ When: I do this
+ Then: it should do this
+ And: do that
+-------------------------------------------------------------------------------
+BDDTests.cpp:<line number>
+...............................................................................
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( itDoesThat() )
+with expansion:
+ true
+
+-------------------------------------------------------------------------------
+Scenario: Vector resizing affects size and capacity
+ Given: an empty vector
+-------------------------------------------------------------------------------
+BDDTests.cpp:<line number>
+...............................................................................
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 0 )
+with expansion:
+ 0 == 0
+
+-------------------------------------------------------------------------------
+Scenario: Vector resizing affects size and capacity
+ Given: an empty vector
+ When: it is made larger
+ Then: the size and capacity go up
+-------------------------------------------------------------------------------
+BDDTests.cpp:<line number>
+...............................................................................
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 10 )
+with expansion:
+ 10 == 10
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 10 )
+with expansion:
+ 10 >= 10
+
+-------------------------------------------------------------------------------
+Scenario: Vector resizing affects size and capacity
+ Given: an empty vector
+ When: it is made larger
+ Then: the size and capacity go up
+ And when: it is made smaller again
+ Then: the size goes down but the capacity stays the same
+-------------------------------------------------------------------------------
+BDDTests.cpp:<line number>
+...............................................................................
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 5 )
+with expansion:
+ 5 == 5
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 10 )
+with expansion:
+ 10 >= 10
+
+-------------------------------------------------------------------------------
+Scenario: Vector resizing affects size and capacity
+ Given: an empty vector
+-------------------------------------------------------------------------------
+BDDTests.cpp:<line number>
+...............................................................................
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 0 )
+with expansion:
+ 0 == 0
+
+-------------------------------------------------------------------------------
+Scenario: Vector resizing affects size and capacity
+ Given: an empty vector
+ When: we reserve more space
+ Then: The capacity is increased but the size remains the same
+-------------------------------------------------------------------------------
+BDDTests.cpp:<line number>
+...............................................................................
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.capacity() >= 10 )
+with expansion:
+ 10 >= 10
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( v.size() == 0 )
+with expansion:
+ 0 == 0
+
+-------------------------------------------------------------------------------
+Scenario: This is a really long scenario name to see how the list command deals
+ with wrapping
+ Given: A section name that is so long that it cannot fit in a single
+ console width
+ When: The test headers are printed as part of the normal running of the
+ scenario
+ Then: The, deliberately very long and overly verbose (you see what I did
+ there?) section names must wrap, along with an indent
+-------------------------------------------------------------------------------
+BDDTests.cpp:<line number>
+...............................................................................
+
+BDDTests.cpp:<line number>:
+PASSED:
+with message:
+ boo!
+
+-------------------------------------------------------------------------------
+Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or
+ methods
+ Given: No operations precede me
+-------------------------------------------------------------------------------
+BDDTests.cpp:<line number>
+...............................................................................
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( before == 0 )
+with expansion:
+ 0 == 0
+
+-------------------------------------------------------------------------------
+Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or
+ methods
+ Given: No operations precede me
+ When: We get the count
+ Then: Subsequently values are higher
+-------------------------------------------------------------------------------
+BDDTests.cpp:<line number>
+...............................................................................
+
+BDDTests.cpp:<line number>:
+PASSED:
+ REQUIRE( after > before )
+with expansion:
+ 1 > 0
+
+===============================================================================
+test cases: 167 | 123 passed | 43 failed | 1 failed as expected
+assertions: 916 | 818 passed | 85 failed | 13 failed as expected
+
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.swa4.approved.txt b/3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.swa4.approved.txt
new file mode 100644
index 00000000000..0793f1d1eed
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/Baselines/console.swa4.approved.txt
@@ -0,0 +1,491 @@
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CatchSelfTest is a <version> host application.
+Run with -? for options
+
+-------------------------------------------------------------------------------
+toString(enum)
+-------------------------------------------------------------------------------
+EnumToString.cpp:<line number>
+...............................................................................
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e0) == "0" )
+with expansion:
+ "0" == "0"
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e1) == "1" )
+with expansion:
+ "1" == "1"
+
+-------------------------------------------------------------------------------
+toString(enum w/operator<<)
+-------------------------------------------------------------------------------
+EnumToString.cpp:<line number>
+...............................................................................
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e0) == "E2{0}" )
+with expansion:
+ "E2{0}" == "E2{0}"
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e1) == "E2{1}" )
+with expansion:
+ "E2{1}" == "E2{1}"
+
+-------------------------------------------------------------------------------
+toString(enum class)
+-------------------------------------------------------------------------------
+EnumToString.cpp:<line number>
+...............................................................................
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e0) == "0" )
+with expansion:
+ "0" == "0"
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e1) == "1" )
+with expansion:
+ "1" == "1"
+
+-------------------------------------------------------------------------------
+toString(enum class w/operator<<)
+-------------------------------------------------------------------------------
+EnumToString.cpp:<line number>
+...............................................................................
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e0) == "E2/V0" )
+with expansion:
+ "E2/V0" == "E2/V0"
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e1) == "E2/V1" )
+with expansion:
+ "E2/V1" == "E2/V1"
+
+EnumToString.cpp:<line number>:
+PASSED:
+ CHECK( Catch::toString(e3) == "Unknown enum value 10" )
+with expansion:
+ "Unknown enum value 10"
+ ==
+ "Unknown enum value 10"
+
+-------------------------------------------------------------------------------
+Some simple comparisons between doubles
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d == Approx( 1.23 ) )
+with expansion:
+ 1.23 == Approx( 1.23 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d != Approx( 1.22 ) )
+with expansion:
+ 1.23 != Approx( 1.22 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d != Approx( 1.24 ) )
+with expansion:
+ 1.23 != Approx( 1.24 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Approx( d ) == 1.23 )
+with expansion:
+ Approx( 1.23 ) == 1.23
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Approx( d ) != 1.22 )
+with expansion:
+ Approx( 1.23 ) != 1.22
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( Approx( d ) != 1.24 )
+with expansion:
+ Approx( 1.23 ) != 1.24
+
+-------------------------------------------------------------------------------
+Approximate comparisons with different epsilons
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d != Approx( 1.231 ) )
+with expansion:
+ 1.23 != Approx( 1.231 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d == Approx( 1.231 ).epsilon( 0.1 ) )
+with expansion:
+ 1.23 == Approx( 1.231 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with floats
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 1.23f == Approx( 1.23f ) )
+with expansion:
+ 1.23f == Approx( 1.2300000191 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 0.0f == Approx( 0.0f ) )
+with expansion:
+ 0.0f == Approx( 0.0 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with ints
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 1 == Approx( 1 ) )
+with expansion:
+ 1 == Approx( 1.0 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 0 == Approx( 0 ) )
+with expansion:
+ 0 == Approx( 0.0 )
+
+-------------------------------------------------------------------------------
+Approximate comparisons with mixed numeric types
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 1.0f == Approx( 1 ) )
+with expansion:
+ 1.0f == Approx( 1.0 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 0 == Approx( dZero) )
+with expansion:
+ 0 == Approx( 0.0 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 0 == Approx( dSmall ).epsilon( 0.001 ) )
+with expansion:
+ 0 == Approx( 0.00001 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( 1.234f == Approx( dMedium ) )
+with expansion:
+ 1.234f == Approx( 1.234 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( dMedium == Approx( 1.234f ) )
+with expansion:
+ 1.234 == Approx( 1.2339999676 )
+
+-------------------------------------------------------------------------------
+Use a custom approx
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d == approx( 1.23 ) )
+with expansion:
+ 1.23 == Approx( 1.23 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d == approx( 1.22 ) )
+with expansion:
+ 1.23 == Approx( 1.22 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d == approx( 1.24 ) )
+with expansion:
+ 1.23 == Approx( 1.24 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( d != approx( 1.25 ) )
+with expansion:
+ 1.23 != Approx( 1.25 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( approx( d ) == 1.23 )
+with expansion:
+ Approx( 1.23 ) == 1.23
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( approx( d ) == 1.22 )
+with expansion:
+ Approx( 1.23 ) == 1.22
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( approx( d ) == 1.24 )
+with expansion:
+ Approx( 1.23 ) == 1.24
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( approx( d ) != 1.25 )
+with expansion:
+ Approx( 1.23 ) != 1.25
+
+-------------------------------------------------------------------------------
+Approximate PI
+-------------------------------------------------------------------------------
+ApproxTests.cpp:<line number>
+...............................................................................
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 ) )
+with expansion:
+ 3.1428571429 == Approx( 3.141 )
+
+ApproxTests.cpp:<line number>:
+PASSED:
+ REQUIRE( divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 ) )
+with expansion:
+ 3.1428571429 != Approx( 3.141 )
+
+-------------------------------------------------------------------------------
+A METHOD_AS_TEST_CASE based test run that succeeds
+-------------------------------------------------------------------------------
+ClassTests.cpp:<line number>
+...............................................................................
+
+ClassTests.cpp:<line number>:
+PASSED:
+ REQUIRE( s == "hello" )
+with expansion:
+ "hello" == "hello"
+
+-------------------------------------------------------------------------------
+A METHOD_AS_TEST_CASE based test run that fails
+-------------------------------------------------------------------------------
+ClassTests.cpp:<line number>
+...............................................................................
+
+ClassTests.cpp:<line number>: FAILED:
+ REQUIRE( s == "world" )
+with expansion:
+ "hello" == "world"
+
+-------------------------------------------------------------------------------
+A TEST_CASE_METHOD based test run that succeeds
+-------------------------------------------------------------------------------
+ClassTests.cpp:<line number>
+...............................................................................
+
+ClassTests.cpp:<line number>:
+PASSED:
+ REQUIRE( m_a == 1 )
+with expansion:
+ 1 == 1
+
+-------------------------------------------------------------------------------
+A TEST_CASE_METHOD based test run that fails
+-------------------------------------------------------------------------------
+ClassTests.cpp:<line number>
+...............................................................................
+
+ClassTests.cpp:<line number>: FAILED:
+ REQUIRE( m_a == 2 )
+with expansion:
+ 1 == 2
+
+-------------------------------------------------------------------------------
+Equality checks that should succeed
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven == 7 )
+with expansion:
+ 7 == 7
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one == Approx( 9.1f ) )
+with expansion:
+ 9.1f == Approx( 9.1000003815 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.double_pi == Approx( 3.1415926535 ) )
+with expansion:
+ 3.1415926535 == Approx( 3.1415926535 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello == "hello" )
+with expansion:
+ "hello" == "hello"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( "hello" == data.str_hello )
+with expansion:
+ "hello" == "hello"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello.size() == 5 )
+with expansion:
+ 5 == 5
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( x == Approx( 1.3 ) )
+with expansion:
+ 1.3 == Approx( 1.3 )
+
+-------------------------------------------------------------------------------
+Equality checks that should fail
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven == 6 )
+with expansion:
+ 7 == 6
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven == 8 )
+with expansion:
+ 7 == 8
+
+-------------------------------------------------------------------------------
+Inequality checks that should succeed
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven != 6 )
+with expansion:
+ 7 != 6
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.int_seven != 8 )
+with expansion:
+ 7 != 8
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one != Approx( 9.11f ) )
+with expansion:
+ 9.1f != Approx( 9.1099996567 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one != Approx( 9.0f ) )
+with expansion:
+ 9.1f != Approx( 9.0 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one != Approx( 1 ) )
+with expansion:
+ 9.1f != Approx( 1.0 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.float_nine_point_one != Approx( 0 ) )
+with expansion:
+ 9.1f != Approx( 0.0 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.double_pi != Approx( 3.1415 ) )
+with expansion:
+ 3.1415926535 != Approx( 3.1415 )
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello != "goodbye" )
+with expansion:
+ "hello" != "goodbye"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello != "hell" )
+with expansion:
+ "hello" != "hell"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello != "hello1" )
+with expansion:
+ "hello" != "hello1"
+
+ConditionTests.cpp:<line number>:
+PASSED:
+ REQUIRE( data.str_hello.size() != 6 )
+with expansion:
+ 5 != 6
+
+-------------------------------------------------------------------------------
+Inequality checks that should fail
+-------------------------------------------------------------------------------
+ConditionTests.cpp:<line number>
+...............................................................................
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.int_seven != 7 )
+with expansion:
+ 7 != 7
+
+ConditionTests.cpp:<line number>: FAILED:
+ CHECK( data.float_nine_point_one != Approx( 9.1f ) )
+with expansion:
+ 9.1f != Approx( 9.1000003815 )
+
+===============================================================================
+test cases: 19 | 15 passed | 3 failed | 1 failed as expected
+assertions: 62 | 56 passed | 4 failed | 2 failed as expected
+
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/Baselines/junit.sw.approved.txt b/3rdparty/sol2/Catch/projects/SelfTest/Baselines/junit.sw.approved.txt
new file mode 100644
index 00000000000..18792059a7e
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/Baselines/junit.sw.approved.txt
@@ -0,0 +1,684 @@
+<testsuites>
+ <testsuite name="CatchSelfTest" errors="13" failures="72" tests="916" hostname="tbd" time="{duration}" timestamp="tbd">
+ <testcase classname="global" name="toString(enum)" time="{duration}"/>
+ <testcase classname="global" name="toString(enum w/operator&lt;&lt;)" time="{duration}"/>
+ <testcase classname="global" name="toString(enum class)" time="{duration}"/>
+ <testcase classname="global" name="toString(enum class w/operator&lt;&lt;)" time="{duration}"/>
+ <testcase classname="global" name="Some simple comparisons between doubles" time="{duration}"/>
+ <testcase classname="global" name="Approximate comparisons with different epsilons" time="{duration}"/>
+ <testcase classname="global" name="Approximate comparisons with floats" time="{duration}"/>
+ <testcase classname="global" name="Approximate comparisons with ints" time="{duration}"/>
+ <testcase classname="global" name="Approximate comparisons with mixed numeric types" time="{duration}"/>
+ <testcase classname="global" name="Use a custom approx" time="{duration}"/>
+ <testcase classname="global" name="Approximate PI" time="{duration}"/>
+ <testcase classname="TestClass" name="A METHOD_AS_TEST_CASE based test run that succeeds" time="{duration}"/>
+ <testcase classname="TestClass" name="A METHOD_AS_TEST_CASE based test run that fails" time="{duration}">
+ <failure message="&quot;hello&quot; == &quot;world&quot;" type="REQUIRE">
+ClassTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="Fixture" name="A TEST_CASE_METHOD based test run that succeeds" time="{duration}"/>
+ <testcase classname="Fixture" name="A TEST_CASE_METHOD based test run that fails" time="{duration}">
+ <failure message="1 == 2" type="REQUIRE">
+ClassTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Equality checks that should succeed" time="{duration}"/>
+ <testcase classname="global" name="Equality checks that should fail" time="{duration}">
+ <failure message="7 == 6" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="7 == 8" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="7 == 0" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="9.1f == Approx( 9.1099996567 )" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="9.1f == Approx( 9.0 )" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="9.1f == Approx( 1.0 )" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="9.1f == Approx( 0.0 )" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="3.1415926535 == Approx( 3.1415 )" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; == &quot;goodbye&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; == &quot;hell&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; == &quot;hello1&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="5 == 6" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="1.3 == Approx( 1.301 )" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Inequality checks that should succeed" time="{duration}"/>
+ <testcase classname="global" name="Inequality checks that should fail" time="{duration}">
+ <failure message="7 != 7" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="9.1f != Approx( 9.1000003815 )" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="3.1415926535 != Approx( 3.1415926535 )" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; != &quot;hello&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="5 != 5" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Ordering comparison checks that should succeed" time="{duration}"/>
+ <testcase classname="global" name="Ordering comparison checks that should fail" time="{duration}">
+ <failure message="7 > 7" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="7 &lt; 7" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="7 > 8" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="7 &lt; 6" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="7 &lt; 0" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="7 &lt; -1" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="7 >= 8" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="7 &lt;= 6" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="9.1f &lt; 9" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="9.1f > 10" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="9.1f > 9.2" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; > &quot;hello&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; &lt; &quot;hello&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; > &quot;hellp&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; > &quot;z&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; &lt; &quot;hellm&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; &lt; &quot;a&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; >= &quot;z&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="&quot;hello&quot; &lt;= &quot;a&quot;" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Comparisons with int literals don't warn when mixing signed/ unsigned" time="{duration}"/>
+ <testcase classname="global" name="comparisons between int variables" time="{duration}"/>
+ <testcase classname="global" name="comparisons between const int variables" time="{duration}"/>
+ <testcase classname="global" name="Comparisons between unsigned ints and negative signed ints match c++ standard behaviour" time="{duration}"/>
+ <testcase classname="global" name="Comparisons between ints where one side is computed" time="{duration}"/>
+ <testcase classname="global" name="Pointers can be compared to null" time="{duration}"/>
+ <testcase classname="global" name="'Not' checks that should succeed" time="{duration}"/>
+ <testcase classname="global" name="'Not' checks that should fail" time="{duration}">
+ <failure message="false != false" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="true != true" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="false" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="!true" type="CHECK_FALSE">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="false" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="!true" type="CHECK_FALSE">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="false" type="CHECK">
+ConditionTests.cpp:<line number>
+ </failure>
+ <failure message="!(1 == 1)" type="CHECK_FALSE">
+ConditionTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="When checked exceptions are thrown they can be expected or unexpected" time="{duration}"/>
+ <testcase classname="global" name="Expected exceptions that don't throw or unexpected exceptions fail the test" time="{duration}">
+ <error message="thisThrows()" type="CHECK_THROWS_AS">
+expected exception
+ExceptionTests.cpp:<line number>
+ </error>
+ <failure message="thisDoesntThrow()" type="CHECK_THROWS_AS">
+ExceptionTests.cpp:<line number>
+ </failure>
+ <error message="thisThrows()" type="CHECK_NOTHROW">
+expected exception
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="When unchecked exceptions are thrown directly they are always failures" time="{duration}">
+ <error type="TEST_CASE">
+unexpected exception
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="An unchecked exception reports the line of the last assertion" time="{duration}">
+ <error message="{Unknown expression after the reported line}">
+unexpected exception
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="When unchecked exceptions are thrown from sections they are always failures" name="section name" time="{duration}">
+ <error type="TEST_CASE">
+unexpected exception
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="When unchecked exceptions are thrown from functions they are always failures" time="{duration}">
+ <error message="thisThrows() == 0" type="CHECK">
+expected exception
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="When unchecked exceptions are thrown during a REQUIRE the test should abort fail" time="{duration}">
+ <error message="thisThrows() == 0" type="REQUIRE">
+expected exception
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="When unchecked exceptions are thrown during a CHECK the test should abort and fail" time="{duration}">
+ <error message="thisThrows() == 0" type="CHECK">
+expected exception
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="Non-std exceptions can be translated" time="{duration}">
+ <error type="TEST_CASE">
+custom exception
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="Custom std-exceptions can be custom translated" time="{duration}">
+ <error type="TEST_CASE">
+custom std exception
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="Custom exceptions can be translated when testing for nothrow" time="{duration}">
+ <error message="throwCustom()" type="REQUIRE_NOTHROW">
+custom exception - not std
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="Custom exceptions can be translated when testing for throwing as something else" time="{duration}">
+ <error message="throwCustom()" type="REQUIRE_THROWS_AS">
+custom exception - not std
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="Unexpected exceptions can be translated" time="{duration}">
+ <error type="TEST_CASE">
+3.14
+ExceptionTests.cpp:<line number>
+ </error>
+ </testcase>
+ <testcase classname="global" name="NotImplemented exception" time="{duration}"/>
+ <testcase classname="Exception messages can be tested for" name="exact match" time="{duration}"/>
+ <testcase classname="Exception messages can be tested for" name="different case" time="{duration}"/>
+ <testcase classname="Exception messages can be tested for" name="wildcarded" time="{duration}"/>
+ <testcase classname="global" name="Mismatching exception messages failing the test" time="{duration}">
+ <failure message="expected exception" type="REQUIRE_THROWS_WITH">
+ExceptionTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Generators over two ranges" time="{duration}"/>
+ <testcase classname="global" name="Generator over a range of pairs" time="{duration}"/>
+ <testcase classname="global" name="INFO and WARN do not abort tests" time="{duration}"/>
+ <testcase classname="global" name="SUCCEED counts as a test pass" time="{duration}"/>
+ <testcase classname="global" name="INFO gets logged on failure" time="{duration}">
+ <failure message="2 == 1" type="REQUIRE">
+this message should be logged
+so should this
+MessageTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="INFO gets logged on failure, even if captured before successful assertions" time="{duration}">
+ <failure message="2 == 1" type="CHECK">
+this message should be logged
+MessageTests.cpp:<line number>
+ </failure>
+ <failure message="2 == 0" type="CHECK">
+and this, but later
+MessageTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="FAIL aborts the test" time="{duration}">
+ <failure type="FAIL">
+This is a failure
+MessageTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="FAIL does not require an argument" time="{duration}">
+ <failure type="FAIL">
+MessageTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="SUCCESS does not require an argument" time="{duration}"/>
+ <testcase classname="Output from all sections is reported" name="one" time="{duration}">
+ <failure type="FAIL">
+Message from section one
+MessageTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="Output from all sections is reported" name="two" time="{duration}">
+ <failure type="FAIL">
+Message from section two
+MessageTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="Standard output from all sections is reported" name="two" time="{duration}">
+ <system-out>
+Message from section one
+Message from section two
+ </system-out>
+ </testcase>
+ <testcase classname="global" name="SCOPED_INFO is reset for each loop" time="{duration}">
+ <failure message="10 &lt; 10" type="REQUIRE">
+current counter 10
+i := 10
+MessageTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="The NO_FAIL macro reports a failure but does not fail the test" time="{duration}"/>
+ <testcase classname="global" name="just failure" time="{duration}">
+ <failure type="FAIL">
+Previous info should not be seen
+MessageTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="sends information to INFO" time="{duration}">
+ <failure message="false" type="REQUIRE">
+hi
+i := 7
+MessageTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Pointers can be converted to strings" time="{duration}"/>
+ <testcase classname="random SECTION tests" name="s1" time="{duration}"/>
+ <testcase classname="random SECTION tests" name="s2" time="{duration}"/>
+ <testcase classname="nested SECTION tests" name="s1" time="{duration}"/>
+ <testcase classname="nested SECTION tests" name="s1/s2" time="{duration}"/>
+ <testcase classname="more nested SECTION tests" name="s2/s1" time="{duration}">
+ <failure message="1 == 2" type="REQUIRE">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="more nested SECTION tests" name="s1/s3" time="{duration}"/>
+ <testcase classname="more nested SECTION tests" name="s1/s4" time="{duration}"/>
+ <testcase classname="even more nested SECTION tests" name="c/d (leaf)" time="{duration}"/>
+ <testcase classname="even more nested SECTION tests" name="c/e (leaf)" time="{duration}"/>
+ <testcase classname="even more nested SECTION tests" name="f (leaf)" time="{duration}"/>
+ <testcase classname="looped SECTION tests" name="s1" time="{duration}">
+ <failure message="0 > 1" type="CHECK">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="looped tests" time="{duration}">
+ <failure message="1 == 0" type="CHECK">
+Testing if fib[0] (1) is even
+MiscTests.cpp:<line number>
+ </failure>
+ <failure message="1 == 0" type="CHECK">
+Testing if fib[1] (1) is even
+MiscTests.cpp:<line number>
+ </failure>
+ <failure message="1 == 0" type="CHECK">
+Testing if fib[3] (3) is even
+MiscTests.cpp:<line number>
+ </failure>
+ <failure message="1 == 0" type="CHECK">
+Testing if fib[4] (5) is even
+MiscTests.cpp:<line number>
+ </failure>
+ <failure message="1 == 0" type="CHECK">
+Testing if fib[6] (13) is even
+MiscTests.cpp:<line number>
+ </failure>
+ <failure message="1 == 0" type="CHECK">
+Testing if fib[7] (21) is even
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Sends stuff to stdout and stderr" time="{duration}">
+ <system-out>
+A string sent directly to stdout
+ </system-out>
+ <system-err>
+A string sent directly to stderr
+ </system-err>
+ </testcase>
+ <testcase classname="global" name="null strings" time="{duration}"/>
+ <testcase classname="global" name="checkedIf" time="{duration}"/>
+ <testcase classname="global" name="checkedIf, failing" time="{duration}">
+ <failure message="false" type="CHECKED_IF">
+MiscTests.cpp:<line number>
+ </failure>
+ <failure message="false" type="REQUIRE">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="checkedElse" time="{duration}"/>
+ <testcase classname="global" name="checkedElse, failing" time="{duration}">
+ <failure message="false" type="CHECKED_ELSE">
+MiscTests.cpp:<line number>
+ </failure>
+ <failure message="false" type="REQUIRE">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="xmlentitycheck" name="embedded xml" time="{duration}"/>
+ <testcase classname="xmlentitycheck" name="encoded chars" time="{duration}"/>
+ <testcase classname="global" name="send a single char to INFO" time="{duration}">
+ <failure message="false" type="REQUIRE">
+3
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="atomic if" time="{duration}"/>
+ <testcase classname="global" name="String matchers" time="{duration}"/>
+ <testcase classname="global" name="Contains string matcher" time="{duration}">
+ <failure message="&quot;this string contains 'abc' as a substring&quot; contains: &quot;not there&quot;" type="CHECK_THAT">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="StartsWith string matcher" time="{duration}">
+ <failure message="&quot;this string contains 'abc' as a substring&quot; starts with: &quot;string&quot;" type="CHECK_THAT">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="EndsWith string matcher" time="{duration}">
+ <failure message="&quot;this string contains 'abc' as a substring&quot; ends with: &quot;this&quot;" type="CHECK_THAT">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Equals string matcher" time="{duration}">
+ <failure message="&quot;this string contains 'abc' as a substring&quot; equals: &quot;something else&quot;" type="CHECK_THAT">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Equals string matcher, with NULL" time="{duration}"/>
+ <testcase classname="global" name="AllOf matcher" time="{duration}"/>
+ <testcase classname="global" name="AnyOf matcher" time="{duration}"/>
+ <testcase classname="global" name="Equals" time="{duration}"/>
+ <testcase classname="global" name="Matchers can be (AllOf) composed with the &amp;&amp; operator" time="{duration}"/>
+ <testcase classname="global" name="Matchers can be (AnyOf) composed with the || operator" time="{duration}"/>
+ <testcase classname="global" name="Matchers can be composed with both &amp;&amp; and ||" time="{duration}"/>
+ <testcase classname="global" name="Matchers can be composed with both &amp;&amp; and || - failing" time="{duration}">
+ <failure message="&quot;this string contains 'abc' as a substring&quot; ( ( contains: &quot;string&quot; or contains: &quot;different&quot; ) and contains: &quot;random&quot; )" type="CHECK_THAT">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Matchers can be negated (Not) with the ! operator" time="{duration}"/>
+ <testcase classname="global" name="Matchers can be negated (Not) with the ! operator - failing" time="{duration}">
+ <failure message="&quot;this string contains 'abc' as a substring&quot; not contains: &quot;substring&quot;" type="CHECK_THAT">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="Factorials are computed" time="{duration}"/>
+ <testcase classname="global" name="Nice descriptive name" time="{duration}"/>
+ <testcase classname="vectors can be sized and resized" name="root" time="{duration}"/>
+ <testcase classname="vectors can be sized and resized" name="resizing bigger changes size and capacity" time="{duration}"/>
+ <testcase classname="vectors can be sized and resized" name="resizing smaller changes size but not capacity" time="{duration}"/>
+ <testcase classname="vectors can be sized and resized" name="resizing smaller changes size but not capacity/We can use the 'swap trick' to reset the capacity" time="{duration}"/>
+ <testcase classname="vectors can be sized and resized" name="reserving bigger changes capacity but not size" time="{duration}"/>
+ <testcase classname="vectors can be sized and resized" name="reserving smaller does not change size or capacity" time="{duration}"/>
+ <testcase classname="A couple of nested sections followed by a failure" name="root" time="{duration}">
+ <failure type="FAIL">
+to infinity and beyond
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="A couple of nested sections followed by a failure" name="Outer/Inner" time="{duration}"/>
+ <testcase classname="global" name="not allowed" time="{duration}"/>
+ <testcase classname="global" name="Tabs and newlines show in output" time="{duration}">
+ <failure message="&quot;if ($b == 10) {
+ $a = 20;
+}&quot;
+==
+&quot;if ($b == 10) {
+ $a = 20;
+}
+&quot;" type="CHECK">
+MiscTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="toString on const wchar_t const pointer returns the string contents" time="{duration}"/>
+ <testcase classname="global" name="toString on const wchar_t pointer returns the string contents" time="{duration}"/>
+ <testcase classname="global" name="toString on wchar_t const pointer returns the string contents" time="{duration}"/>
+ <testcase classname="global" name="toString on wchar_t returns the string contents" time="{duration}"/>
+ <testcase classname="XmlEncode" name="normal string" time="{duration}"/>
+ <testcase classname="XmlEncode" name="empty string" time="{duration}"/>
+ <testcase classname="XmlEncode" name="string with ampersand" time="{duration}"/>
+ <testcase classname="XmlEncode" name="string with less-than" time="{duration}"/>
+ <testcase classname="XmlEncode" name="string with greater-than" time="{duration}"/>
+ <testcase classname="XmlEncode" name="string with quotes" time="{duration}"/>
+ <testcase classname="XmlEncode" name="string with control char (1)" time="{duration}"/>
+ <testcase classname="XmlEncode" name="string with control char (x7F)" time="{duration}"/>
+ <testcase classname="global" name="long long" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="default - no arguments" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="test lists/1 test" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="test lists/Specify one test case exclusion using exclude:" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="test lists/Specify one test case exclusion using ~" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="reporter/-r/console" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="reporter/-r/xml" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="reporter/-r xml and junit" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="reporter/--reporter/junit" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="debugger/-b" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="debugger/--break" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="abort/-a aborts after first failure" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="abort/-x 2 aborts after two failures" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="abort/-x must be greater than zero" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="abort/-x must be numeric" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="nothrow/-e" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="nothrow/--nothrow" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="output filename/-o filename" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="output filename/--out" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="combinations/Single character flags can be combined" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="force-colour/--force-colour" time="{duration}"/>
+ <testcase classname="Process can be configured on command line" name="force-colour/without --force-colour" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="plain string/No wrapping" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="plain string/Wrapped once" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="plain string/Wrapped twice" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="plain string/Wrapped three times" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="plain string/Short wrap" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="plain string/As container" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="plain string/Indent first line differently" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="With newlines/No wrapping" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="With newlines/Trailing newline" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="With newlines/Wrapped once" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="With newlines/Wrapped twice" time="{duration}"/>
+ <testcase classname="Long strings can be wrapped" name="With tabs" time="{duration}"/>
+ <testcase classname="replaceInPlace" name="replace single char" time="{duration}"/>
+ <testcase classname="replaceInPlace" name="replace two chars" time="{duration}"/>
+ <testcase classname="replaceInPlace" name="replace first char" time="{duration}"/>
+ <testcase classname="replaceInPlace" name="replace last char" time="{duration}"/>
+ <testcase classname="replaceInPlace" name="replace all chars" time="{duration}"/>
+ <testcase classname="replaceInPlace" name="replace no chars" time="{duration}"/>
+ <testcase classname="replaceInPlace" name="escape '" time="{duration}"/>
+ <testcase classname="global" name="Strings can be rendered with colour" time="{duration}">
+ <system-out>
+hello
+hello
+ </system-out>
+ </testcase>
+ <testcase classname="global" name="Text can be formatted using the Text class" time="{duration}"/>
+ <testcase classname="global" name="Long text is truncted" time="{duration}"/>
+ <testcase classname="global" name="ManuallyRegistered" time="{duration}"/>
+ <testcase classname="global" name="Parsing a std::pair" time="{duration}"/>
+ <testcase classname="global" name="Where there is more to the expression after the RHS" time="{duration}"/>
+ <testcase classname="global" name="Where the LHS is not a simple value" time="{duration}"/>
+ <testcase classname="global" name="A failing expression with a non streamable type is still captured" time="{duration}">
+ <failure message="0x<hex digits> == 0x<hex digits>" type="CHECK">
+TrickyTests.cpp:<line number>
+ </failure>
+ <failure message="{?} == {?}" type="CHECK">
+TrickyTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="string literals of different sizes can be compared" time="{duration}">
+ <failure message="&quot;first&quot; == &quot;second&quot;" type="REQUIRE">
+TrickyTests.cpp:<line number>
+ </failure>
+ </testcase>
+ <testcase classname="global" name="An expression with side-effects should only be evaluated once" time="{duration}"/>
+ <testcase classname="global" name="Operators at different namespace levels not hijacked by Koenig lookup" time="{duration}"/>
+ <testcase classname="global" name="Demonstrate that a non-const == is not used" time="{duration}"/>
+ <testcase classname="global" name="Test enum bit values" time="{duration}"/>
+ <testcase classname="global" name="boolean member" time="{duration}"/>
+ <testcase classname="(unimplemented) static bools can be evaluated" name="compare to true" time="{duration}"/>
+ <testcase classname="(unimplemented) static bools can be evaluated" name="compare to false" time="{duration}"/>
+ <testcase classname="(unimplemented) static bools can be evaluated" name="negation" time="{duration}"/>
+ <testcase classname="(unimplemented) static bools can be evaluated" name="double negation" time="{duration}"/>
+ <testcase classname="(unimplemented) static bools can be evaluated" name="direct" time="{duration}"/>
+ <testcase classname="global" name="Objects that evaluated in boolean contexts can be checked" time="{duration}"/>
+ <testcase classname="Assertions then sections" name="root" time="{duration}"/>
+ <testcase classname="Assertions then sections" name="A section" time="{duration}"/>
+ <testcase classname="Assertions then sections" name="A section/Another section" time="{duration}"/>
+ <testcase classname="Assertions then sections" name="A section/Another other section" time="{duration}"/>
+ <testcase classname="global" name="non streamable - with conv. op" time="{duration}"/>
+ <testcase classname="global" name="Comparing function pointers" time="{duration}"/>
+ <testcase classname="global" name="Comparing member function pointers" time="{duration}"/>
+ <testcase classname="global" name="pointer to class" time="{duration}"/>
+ <testcase classname="global" name="null_ptr" time="{duration}"/>
+ <testcase classname="global" name="X/level/0/a" time="{duration}"/>
+ <testcase classname="global" name="X/level/0/b" time="{duration}"/>
+ <testcase classname="global" name="X/level/1/a" time="{duration}"/>
+ <testcase classname="global" name="X/level/1/b" time="{duration}"/>
+ <testcase classname="global" name="toString( has_toString )" time="{duration}"/>
+ <testcase classname="global" name="toString( has_maker )" time="{duration}"/>
+ <testcase classname="global" name="toString( has_maker_and_toString )" time="{duration}"/>
+ <testcase classname="global" name="toString( vectors&lt;has_toString )" time="{duration}"/>
+ <testcase classname="global" name="toString( vectors&lt;has_maker )" time="{duration}"/>
+ <testcase classname="global" name="toString( vectors&lt;has_maker_and_toString )" time="{duration}"/>
+ <testcase classname="Tracker" name="root" time="{duration}"/>
+ <testcase classname="Tracker" name="successfully close one section" time="{duration}"/>
+ <testcase classname="Tracker" name="fail one section" time="{duration}"/>
+ <testcase classname="Tracker" name="fail one section/re-enter after failed section" time="{duration}"/>
+ <testcase classname="Tracker" name="fail one section/re-enter after failed section and find next section" time="{duration}"/>
+ <testcase classname="Tracker" name="successfully close one section, then find another" time="{duration}"/>
+ <testcase classname="Tracker" name="successfully close one section, then find another/Re-enter - skips S1 and enters S2" time="{duration}"/>
+ <testcase classname="Tracker" name="successfully close one section, then find another/Re-enter - skips S1 and enters S2/Successfully close S2" time="{duration}"/>
+ <testcase classname="Tracker" name="successfully close one section, then find another/Re-enter - skips S1 and enters S2/fail S2" time="{duration}"/>
+ <testcase classname="Tracker" name="open a nested section" time="{duration}"/>
+ <testcase classname="Tracker" name="start a generator" time="{duration}"/>
+ <testcase classname="Tracker" name="start a generator/close outer section" time="{duration}"/>
+ <testcase classname="Tracker" name="start a generator/close outer section/Re-enter for second generation" time="{duration}"/>
+ <testcase classname="Tracker" name="start a generator/Start a new inner section" time="{duration}"/>
+ <testcase classname="Tracker" name="start a generator/Start a new inner section/Re-enter for second generation" time="{duration}"/>
+ <testcase classname="Tracker" name="start a generator/Fail an inner section" time="{duration}"/>
+ <testcase classname="Tracker" name="start a generator/Fail an inner section/Re-enter for second generation" time="{duration}"/>
+ <testcase classname="global" name="std::pair&lt;int,std::string> -> toString" time="{duration}"/>
+ <testcase classname="global" name="std::pair&lt;int,const std::string> -> toString" time="{duration}"/>
+ <testcase classname="global" name="std::vector&lt;std::pair&lt;std::string,int> > -> toString" time="{duration}"/>
+ <testcase classname="global" name="pair&lt;pair&lt;int,const char *,pair&lt;std::string,int> > -> toString" time="{duration}"/>
+ <testcase classname="global" name="vector&lt;int> -> toString" time="{duration}"/>
+ <testcase classname="global" name="vector&lt;string> -> toString" time="{duration}"/>
+ <testcase classname="global" name="vector&lt;int,allocator> -> toString" time="{duration}"/>
+ <testcase classname="global" name="vec&lt;vec&lt;string,alloc>> -> toString" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Empty test spec should have no filters" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Test spec from empty string should have no filters" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Test spec from just a comma should have no filters" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Test spec from name should have one filter" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Test spec from quoted name should have one filter" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Test spec from name should have one filter" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Wildcard at the start" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Wildcard at the end" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Wildcard at both ends" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Redundant wildcard at the start" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Redundant wildcard at the end" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Redundant wildcard at both ends" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Wildcard at both ends, redundant at start" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Just wildcard" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Single tag" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Single tag, two matches" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Two tags" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Two tags, spare separated" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Wildcarded name and tag" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="Single tag exclusion" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="One tag exclusion and one tag inclusion" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="One tag exclusion and one wldcarded name inclusion" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="One tag exclusion, using exclude:, and one wldcarded name inclusion" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="name exclusion" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="wildcarded name exclusion" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="wildcarded name exclusion with tag inclusion" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="wildcarded name exclusion, using exclude:, with tag inclusion" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="two wildcarded names" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="empty tag" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="empty quoted name" time="{duration}"/>
+ <testcase classname="Parse test names and tags" name="quoted string followed by tag exclusion" time="{duration}"/>
+ <testcase classname="global" name="tuple&lt;>" time="{duration}"/>
+ <testcase classname="global" name="tuple&lt;int>" time="{duration}"/>
+ <testcase classname="global" name="tuple&lt;float,int>" time="{duration}"/>
+ <testcase classname="global" name="tuple&lt;string,string>" time="{duration}"/>
+ <testcase classname="global" name="tuple&lt;tuple&lt;int>,tuple&lt;>,float>" time="{duration}"/>
+ <testcase classname="global" name="tuple&lt;nullptr,int,const char *>" time="{duration}"/>
+ <testcase classname="Tag alias can be registered against tag patterns" name="The same tag alias can only be registered once" time="{duration}"/>
+ <testcase classname="Tag alias can be registered against tag patterns" name="Tag aliases must be of the form [@name]" time="{duration}"/>
+ <testcase classname="global" name="Anonymous test case 1" time="{duration}"/>
+ <testcase classname="global" name="Test case with one argument" time="{duration}"/>
+ <testcase classname="Variadic macros" name="Section with one argument" time="{duration}"/>
+ <testcase classname="Scenario: Do that thing with the thing" name="Given: This stuff exists/When: I do this/Then: it should do this" time="{duration}"/>
+ <testcase classname="Scenario: Do that thing with the thing" name="Given: This stuff exists/When: I do this/Then: it should do this/And: do that" time="{duration}"/>
+ <testcase classname="Scenario: Vector resizing affects size and capacity" name="Given: an empty vector" time="{duration}"/>
+ <testcase classname="Scenario: Vector resizing affects size and capacity" name="Given: an empty vector/When: it is made larger/Then: the size and capacity go up" time="{duration}"/>
+ <testcase classname="Scenario: Vector resizing affects size and capacity" name="Given: an empty vector/When: it is made larger/Then: the size and capacity go up/And when: it is made smaller again/Then: the size goes down but the capacity stays the same" time="{duration}"/>
+ <testcase classname="Scenario: Vector resizing affects size and capacity" name="Given: an empty vector/When: we reserve more space/Then: The capacity is increased but the size remains the same" time="{duration}"/>
+ <testcase classname="Scenario: This is a really long scenario name to see how the list command deals with wrapping" name="Given: A section name that is so long that it cannot fit in a single console width/When: The test headers are printed as part of the normal running of the scenario/Then: The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent" time="{duration}"/>
+ <testcase classname="Fixture" name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me" time="{duration}"/>
+ <testcase classname="Fixture" name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me/When: We get the count/Then: Subsequently values are higher" time="{duration}"/>
+ <system-out>
+Message from section one
+Message from section two
+A string sent directly to stdout
+hello
+hello
+ </system-out>
+ <system-err>
+A string sent directly to stderr
+ </system-err>
+ </testsuite>
+</testsuites>
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/Baselines/xml.sw.approved.txt b/3rdparty/sol2/Catch/projects/SelfTest/Baselines/xml.sw.approved.txt
new file mode 100644
index 00000000000..e88e47ebc35
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/Baselines/xml.sw.approved.txt
@@ -0,0 +1,9511 @@
+<Catch name="CatchSelfTest">
+ <Group name="CatchSelfTest">
+ <TestCase name="toString(enum)">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/EnumToString.cpp" >
+ <Original>
+ Catch::toString(e0) == "0"
+ </Original>
+ <Expanded>
+ "0" == "0"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/EnumToString.cpp" >
+ <Original>
+ Catch::toString(e1) == "1"
+ </Original>
+ <Expanded>
+ "1" == "1"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString(enum w/operator&lt;&lt;)">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/EnumToString.cpp" >
+ <Original>
+ Catch::toString(e0) == "E2{0}"
+ </Original>
+ <Expanded>
+ "E2{0}" == "E2{0}"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/EnumToString.cpp" >
+ <Original>
+ Catch::toString(e1) == "E2{1}"
+ </Original>
+ <Expanded>
+ "E2{1}" == "E2{1}"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString(enum class)">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/EnumToString.cpp" >
+ <Original>
+ Catch::toString(e0) == "0"
+ </Original>
+ <Expanded>
+ "0" == "0"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/EnumToString.cpp" >
+ <Original>
+ Catch::toString(e1) == "1"
+ </Original>
+ <Expanded>
+ "1" == "1"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString(enum class w/operator&lt;&lt;)">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/EnumToString.cpp" >
+ <Original>
+ Catch::toString(e0) == "E2/V0"
+ </Original>
+ <Expanded>
+ "E2/V0" == "E2/V0"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/EnumToString.cpp" >
+ <Original>
+ Catch::toString(e1) == "E2/V1"
+ </Original>
+ <Expanded>
+ "E2/V1" == "E2/V1"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/EnumToString.cpp" >
+ <Original>
+ Catch::toString(e3) == "Unknown enum value 10"
+ </Original>
+ <Expanded>
+ "Unknown enum value 10"
+==
+"Unknown enum value 10"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Some simple comparisons between doubles">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ d == Approx( 1.23 )
+ </Original>
+ <Expanded>
+ 1.23 == Approx( 1.23 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ d != Approx( 1.22 )
+ </Original>
+ <Expanded>
+ 1.23 != Approx( 1.22 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ d != Approx( 1.24 )
+ </Original>
+ <Expanded>
+ 1.23 != Approx( 1.24 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ Approx( d ) == 1.23
+ </Original>
+ <Expanded>
+ Approx( 1.23 ) == 1.23
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ Approx( d ) != 1.22
+ </Original>
+ <Expanded>
+ Approx( 1.23 ) != 1.22
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ Approx( d ) != 1.24
+ </Original>
+ <Expanded>
+ Approx( 1.23 ) != 1.24
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Approximate comparisons with different epsilons">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ d != Approx( 1.231 )
+ </Original>
+ <Expanded>
+ 1.23 != Approx( 1.231 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ d == Approx( 1.231 ).epsilon( 0.1 )
+ </Original>
+ <Expanded>
+ 1.23 == Approx( 1.231 )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Approximate comparisons with floats">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ 1.23f == Approx( 1.23f )
+ </Original>
+ <Expanded>
+ 1.23f == Approx( 1.2300000191 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ 0.0f == Approx( 0.0f )
+ </Original>
+ <Expanded>
+ 0.0f == Approx( 0.0 )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Approximate comparisons with ints">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ 1 == Approx( 1 )
+ </Original>
+ <Expanded>
+ 1 == Approx( 1.0 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ 0 == Approx( 0 )
+ </Original>
+ <Expanded>
+ 0 == Approx( 0.0 )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Approximate comparisons with mixed numeric types">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ 1.0f == Approx( 1 )
+ </Original>
+ <Expanded>
+ 1.0f == Approx( 1.0 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ 0 == Approx( dZero)
+ </Original>
+ <Expanded>
+ 0 == Approx( 0.0 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ 0 == Approx( dSmall ).epsilon( 0.001 )
+ </Original>
+ <Expanded>
+ 0 == Approx( 0.00001 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ 1.234f == Approx( dMedium )
+ </Original>
+ <Expanded>
+ 1.234f == Approx( 1.234 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ dMedium == Approx( 1.234f )
+ </Original>
+ <Expanded>
+ 1.234 == Approx( 1.2339999676 )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Use a custom approx">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ d == approx( 1.23 )
+ </Original>
+ <Expanded>
+ 1.23 == Approx( 1.23 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ d == approx( 1.22 )
+ </Original>
+ <Expanded>
+ 1.23 == Approx( 1.22 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ d == approx( 1.24 )
+ </Original>
+ <Expanded>
+ 1.23 == Approx( 1.24 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ d != approx( 1.25 )
+ </Original>
+ <Expanded>
+ 1.23 != Approx( 1.25 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ approx( d ) == 1.23
+ </Original>
+ <Expanded>
+ Approx( 1.23 ) == 1.23
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ approx( d ) == 1.22
+ </Original>
+ <Expanded>
+ Approx( 1.23 ) == 1.22
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ approx( d ) == 1.24
+ </Original>
+ <Expanded>
+ Approx( 1.23 ) == 1.24
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ approx( d ) != 1.25
+ </Original>
+ <Expanded>
+ Approx( 1.23 ) != 1.25
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Approximate PI">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 )
+ </Original>
+ <Expanded>
+ 3.1428571429 == Approx( 3.141 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ApproxTests.cpp" >
+ <Original>
+ divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 )
+ </Original>
+ <Expanded>
+ 3.1428571429 != Approx( 3.141 )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="A METHOD_AS_TEST_CASE based test run that succeeds">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ClassTests.cpp" >
+ <Original>
+ s == "hello"
+ </Original>
+ <Expanded>
+ "hello" == "hello"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="A METHOD_AS_TEST_CASE based test run that fails">
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/ClassTests.cpp" >
+ <Original>
+ s == "world"
+ </Original>
+ <Expanded>
+ "hello" == "world"
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="A TEST_CASE_METHOD based test run that succeeds">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ClassTests.cpp" >
+ <Original>
+ m_a == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="A TEST_CASE_METHOD based test run that fails">
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/ClassTests.cpp" >
+ <Original>
+ m_a == 2
+ </Original>
+ <Expanded>
+ 1 == 2
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Equality checks that should succeed">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven == 7
+ </Original>
+ <Expanded>
+ 7 == 7
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one == Approx( 9.1f )
+ </Original>
+ <Expanded>
+ 9.1f == Approx( 9.1000003815 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.double_pi == Approx( 3.1415926535 )
+ </Original>
+ <Expanded>
+ 3.1415926535 == Approx( 3.1415926535 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello == "hello"
+ </Original>
+ <Expanded>
+ "hello" == "hello"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ "hello" == data.str_hello
+ </Original>
+ <Expanded>
+ "hello" == "hello"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello.size() == 5
+ </Original>
+ <Expanded>
+ 5 == 5
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ x == Approx( 1.3 )
+ </Original>
+ <Expanded>
+ 1.3 == Approx( 1.3 )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Equality checks that should fail">
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven == 6
+ </Original>
+ <Expanded>
+ 7 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven == 8
+ </Original>
+ <Expanded>
+ 7 == 8
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven == 0
+ </Original>
+ <Expanded>
+ 7 == 0
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one == Approx( 9.11f )
+ </Original>
+ <Expanded>
+ 9.1f == Approx( 9.1099996567 )
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one == Approx( 9.0f )
+ </Original>
+ <Expanded>
+ 9.1f == Approx( 9.0 )
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one == Approx( 1 )
+ </Original>
+ <Expanded>
+ 9.1f == Approx( 1.0 )
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one == Approx( 0 )
+ </Original>
+ <Expanded>
+ 9.1f == Approx( 0.0 )
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.double_pi == Approx( 3.1415 )
+ </Original>
+ <Expanded>
+ 3.1415926535 == Approx( 3.1415 )
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello == "goodbye"
+ </Original>
+ <Expanded>
+ "hello" == "goodbye"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello == "hell"
+ </Original>
+ <Expanded>
+ "hello" == "hell"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello == "hello1"
+ </Original>
+ <Expanded>
+ "hello" == "hello1"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello.size() == 6
+ </Original>
+ <Expanded>
+ 5 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ x == Approx( 1.301 )
+ </Original>
+ <Expanded>
+ 1.3 == Approx( 1.301 )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Inequality checks that should succeed">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven != 6
+ </Original>
+ <Expanded>
+ 7 != 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven != 8
+ </Original>
+ <Expanded>
+ 7 != 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one != Approx( 9.11f )
+ </Original>
+ <Expanded>
+ 9.1f != Approx( 9.1099996567 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one != Approx( 9.0f )
+ </Original>
+ <Expanded>
+ 9.1f != Approx( 9.0 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one != Approx( 1 )
+ </Original>
+ <Expanded>
+ 9.1f != Approx( 1.0 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one != Approx( 0 )
+ </Original>
+ <Expanded>
+ 9.1f != Approx( 0.0 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.double_pi != Approx( 3.1415 )
+ </Original>
+ <Expanded>
+ 3.1415926535 != Approx( 3.1415 )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello != "goodbye"
+ </Original>
+ <Expanded>
+ "hello" != "goodbye"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello != "hell"
+ </Original>
+ <Expanded>
+ "hello" != "hell"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello != "hello1"
+ </Original>
+ <Expanded>
+ "hello" != "hello1"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello.size() != 6
+ </Original>
+ <Expanded>
+ 5 != 6
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Inequality checks that should fail">
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven != 7
+ </Original>
+ <Expanded>
+ 7 != 7
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one != Approx( 9.1f )
+ </Original>
+ <Expanded>
+ 9.1f != Approx( 9.1000003815 )
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.double_pi != Approx( 3.1415926535 )
+ </Original>
+ <Expanded>
+ 3.1415926535 != Approx( 3.1415926535 )
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello != "hello"
+ </Original>
+ <Expanded>
+ "hello" != "hello"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello.size() != 5
+ </Original>
+ <Expanded>
+ 5 != 5
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Ordering comparison checks that should succeed">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven &lt; 8
+ </Original>
+ <Expanded>
+ 7 &lt; 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven > 6
+ </Original>
+ <Expanded>
+ 7 > 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven > 0
+ </Original>
+ <Expanded>
+ 7 > 0
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven > -1
+ </Original>
+ <Expanded>
+ 7 > -1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven >= 7
+ </Original>
+ <Expanded>
+ 7 >= 7
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven >= 6
+ </Original>
+ <Expanded>
+ 7 >= 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven &lt;= 7
+ </Original>
+ <Expanded>
+ 7 &lt;= 7
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven &lt;= 8
+ </Original>
+ <Expanded>
+ 7 &lt;= 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one > 9
+ </Original>
+ <Expanded>
+ 9.1f > 9
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one &lt; 10
+ </Original>
+ <Expanded>
+ 9.1f &lt; 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one &lt; 9.2
+ </Original>
+ <Expanded>
+ 9.1f &lt; 9.2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello &lt;= "hello"
+ </Original>
+ <Expanded>
+ "hello" &lt;= "hello"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello >= "hello"
+ </Original>
+ <Expanded>
+ "hello" >= "hello"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello &lt; "hellp"
+ </Original>
+ <Expanded>
+ "hello" &lt; "hellp"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello &lt; "zebra"
+ </Original>
+ <Expanded>
+ "hello" &lt; "zebra"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello > "hellm"
+ </Original>
+ <Expanded>
+ "hello" > "hellm"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello > "a"
+ </Original>
+ <Expanded>
+ "hello" > "a"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Ordering comparison checks that should fail">
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven > 7
+ </Original>
+ <Expanded>
+ 7 > 7
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven &lt; 7
+ </Original>
+ <Expanded>
+ 7 &lt; 7
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven > 8
+ </Original>
+ <Expanded>
+ 7 > 8
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven &lt; 6
+ </Original>
+ <Expanded>
+ 7 &lt; 6
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven &lt; 0
+ </Original>
+ <Expanded>
+ 7 &lt; 0
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven &lt; -1
+ </Original>
+ <Expanded>
+ 7 &lt; -1
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven >= 8
+ </Original>
+ <Expanded>
+ 7 >= 8
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.int_seven &lt;= 6
+ </Original>
+ <Expanded>
+ 7 &lt;= 6
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one &lt; 9
+ </Original>
+ <Expanded>
+ 9.1f &lt; 9
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one > 10
+ </Original>
+ <Expanded>
+ 9.1f > 10
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.float_nine_point_one > 9.2
+ </Original>
+ <Expanded>
+ 9.1f > 9.2
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello > "hello"
+ </Original>
+ <Expanded>
+ "hello" > "hello"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello &lt; "hello"
+ </Original>
+ <Expanded>
+ "hello" &lt; "hello"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello > "hellp"
+ </Original>
+ <Expanded>
+ "hello" > "hellp"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello > "z"
+ </Original>
+ <Expanded>
+ "hello" > "z"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello &lt; "hellm"
+ </Original>
+ <Expanded>
+ "hello" &lt; "hellm"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello &lt; "a"
+ </Original>
+ <Expanded>
+ "hello" &lt; "a"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello >= "z"
+ </Original>
+ <Expanded>
+ "hello" >= "z"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ data.str_hello &lt;= "a"
+ </Original>
+ <Expanded>
+ "hello" &lt;= "a"
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Comparisons with int literals don't warn when mixing signed/ unsigned">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ i == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ ui == 2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ l == 3
+ </Original>
+ <Expanded>
+ 3 == 3
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ ul == 4
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ c == 5
+ </Original>
+ <Expanded>
+ 5 == 5
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ uc == 6
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ 1 == i
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ 2 == ui
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ 3 == l
+ </Original>
+ <Expanded>
+ 3 == 3
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ 4 == ul
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ 5 == c
+ </Original>
+ <Expanded>
+ 5 == 5
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ 6 == uc
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ (std::numeric_limits&lt;unsigned long>::max)() > ul
+ </Original>
+ <Expanded>
+ 18446744073709551615 (0x<hex digits>)
+>
+4
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="comparisons between int variables">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ long_var == unsigned_char_var
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ long_var == unsigned_short_var
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ long_var == unsigned_int_var
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ long_var == unsigned_long_var
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="comparisons between const int variables">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ unsigned_char_var == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ unsigned_short_var == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ unsigned_int_var == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ unsigned_long_var == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Comparisons between unsigned ints and negative signed ints match c++ standard behaviour">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ ( -1 > 2u )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ -1 > 2u
+ </Original>
+ <Expanded>
+ -1 > 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ ( 2u &lt; -1 )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ 2u &lt; -1
+ </Original>
+ <Expanded>
+ 2 &lt; -1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ ( minInt > 2u )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ minInt > 2u
+ </Original>
+ <Expanded>
+ -2147483648 > 2
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Comparisons between ints where one side is computed">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ 54 == 6*9
+ </Original>
+ <Expanded>
+ 54 == 54
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Pointers can be compared to null">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ p == nullptr
+ </Original>
+ <Expanded>
+ NULL == nullptr
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ p == pNULL
+ </Original>
+ <Expanded>
+ NULL == NULL
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ p != nullptr
+ </Original>
+ <Expanded>
+ 0x<hex digits> != nullptr
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ cp != nullptr
+ </Original>
+ <Expanded>
+ 0x<hex digits> != nullptr
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ cpc != nullptr
+ </Original>
+ <Expanded>
+ 0x<hex digits> != nullptr
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ returnsNull() == nullptr
+ </Original>
+ <Expanded>
+ {null string} == nullptr
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ returnsConstNull() == nullptr
+ </Original>
+ <Expanded>
+ {null string} == nullptr
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ nullptr != p
+ </Original>
+ <Expanded>
+ nullptr != 0x<hex digits>
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="'Not' checks that should succeed">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ false == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ true == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !false
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE_FALSE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !false
+ </Original>
+ <Expanded>
+ !false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !falseValue
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE_FALSE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !falseValue
+ </Original>
+ <Expanded>
+ !false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !(1 == 2)
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE_FALSE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !1 == 2
+ </Original>
+ <Expanded>
+ !(1 == 2)
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="'Not' checks that should fail">
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ false != false
+ </Original>
+ <Expanded>
+ false != false
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ true != true
+ </Original>
+ <Expanded>
+ true != true
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !true
+ </Original>
+ <Expanded>
+ false
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK_FALSE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !true
+ </Original>
+ <Expanded>
+ !true
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !trueValue
+ </Original>
+ <Expanded>
+ false
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK_FALSE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !trueValue
+ </Original>
+ <Expanded>
+ !true
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !(1 == 1)
+ </Original>
+ <Expanded>
+ false
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK_FALSE" filename="projects/SelfTest/ConditionTests.cpp" >
+ <Original>
+ !1 == 1
+ </Original>
+ <Expanded>
+ !(1 == 1)
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="When checked exceptions are thrown they can be expected or unexpected">
+ <Expression success="true" type="REQUIRE_THROWS_AS" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows()
+ </Original>
+ <Expanded>
+ thisThrows()
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE_NOTHROW" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisDoesntThrow()
+ </Original>
+ <Expanded>
+ thisDoesntThrow()
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE_THROWS" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows()
+ </Original>
+ <Expanded>
+ thisThrows()
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Expected exceptions that don't throw or unexpected exceptions fail the test">
+ <Expression success="false" type="CHECK_THROWS_AS" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows()
+ </Original>
+ <Expanded>
+ thisThrows()
+ </Expanded>
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ expected exception
+ </Exception>
+ </Expression>
+ <Expression success="false" type="CHECK_THROWS_AS" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisDoesntThrow()
+ </Original>
+ <Expanded>
+ thisDoesntThrow()
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK_NOTHROW" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows()
+ </Original>
+ <Expanded>
+ thisThrows()
+ </Expanded>
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ expected exception
+ </Exception>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="When unchecked exceptions are thrown directly they are always failures">
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ unexpected exception
+ </Exception>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="An unchecked exception reports the line of the last assertion">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ 1 == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="false" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ {Unknown expression after the reported line}
+ </Original>
+ <Expanded>
+ {Unknown expression after the reported line}
+ </Expanded>
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ unexpected exception
+ </Exception>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="When unchecked exceptions are thrown from sections they are always failures">
+ <Section name="section name">
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ unexpected exception
+ </Exception>
+ <OverallResults successes="0" failures="1" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="When unchecked exceptions are thrown from functions they are always failures">
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows() == 0
+ </Original>
+ <Expanded>
+ thisThrows() == 0
+ </Expanded>
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ expected exception
+ </Exception>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="When unchecked exceptions are thrown during a REQUIRE the test should abort fail">
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows() == 0
+ </Original>
+ <Expanded>
+ thisThrows() == 0
+ </Expanded>
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ expected exception
+ </Exception>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="When unchecked exceptions are thrown during a CHECK the test should abort and fail">
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows() == 0
+ </Original>
+ <Expanded>
+ thisThrows() == 0
+ </Expanded>
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ expected exception
+ </Exception>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="When unchecked exceptions are thrown, but caught, they do not affect the test">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Non-std exceptions can be translated">
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ custom exception
+ </Exception>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Custom std-exceptions can be custom translated">
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ custom std exception
+ </Exception>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Custom exceptions can be translated when testing for nothrow">
+ <Expression success="false" type="REQUIRE_NOTHROW" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ throwCustom()
+ </Original>
+ <Expanded>
+ throwCustom()
+ </Expanded>
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ custom exception - not std
+ </Exception>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Custom exceptions can be translated when testing for throwing as something else">
+ <Expression success="false" type="REQUIRE_THROWS_AS" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ throwCustom()
+ </Original>
+ <Expanded>
+ throwCustom()
+ </Expanded>
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ custom exception - not std
+ </Exception>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Unexpected exceptions can be translated">
+ <Exception filename="projects/SelfTest/ExceptionTests.cpp" >
+ 3.14
+ </Exception>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="NotImplemented exception">
+ <Expression success="true" type="REQUIRE_THROWS" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisFunctionNotImplemented( 7 )
+ </Original>
+ <Expanded>
+ thisFunctionNotImplemented( 7 )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Exception messages can be tested for">
+ <Section name="exact match">
+ <Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows(), "expected exception"
+ </Original>
+ <Expanded>
+ thisThrows(), "expected exception"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="different case">
+ <Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No )
+ </Original>
+ <Expanded>
+ thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No )
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="wildcarded">
+ <Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows(), StartsWith( "expected" )
+ </Original>
+ <Expanded>
+ thisThrows(), StartsWith( "expected" )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows(), EndsWith( "exception" )
+ </Original>
+ <Expanded>
+ thisThrows(), EndsWith( "exception" )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows(), Contains( "except" )
+ </Original>
+ <Expanded>
+ thisThrows(), Contains( "except" )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows(), Contains( "exCept", Catch::CaseSensitive::No )
+ </Original>
+ <Expanded>
+ thisThrows(), Contains( "exCept", Catch::CaseSensitive::No )
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Mismatching exception messages failing the test">
+ <Expression success="true" type="REQUIRE_THROWS_WITH" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows(), "expected exception"
+ </Original>
+ <Expanded>
+ thisThrows(), "expected exception"
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="REQUIRE_THROWS_WITH" filename="projects/SelfTest/ExceptionTests.cpp" >
+ <Original>
+ thisThrows(), "should fail"
+ </Original>
+ <Expanded>
+ expected exception
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Generators over two ranges">
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 200 == 200
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 200 == 200
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 200 == 200
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 8 == 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 200 == 200
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 10 == 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 200 == 200
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 30 == 30
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 200 == 200
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 40 == 40
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 200 == 200
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 42 == 42
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 200 == 200
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 72 == 72
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 200 == 200
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 202 == 202
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 202 == 202
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 202 == 202
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 8 == 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 202 == 202
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 10 == 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 202 == 202
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 30 == 30
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 202 == 202
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 40 == 40
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 202 == 202
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 42 == 42
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 202 == 202
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 72 == 72
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 202 == 202
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 204 == 204
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 204 == 204
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 204 == 204
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 8 == 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 204 == 204
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 10 == 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 204 == 204
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 30 == 30
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 204 == 204
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 40 == 40
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 204 == 204
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 42 == 42
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 204 == 204
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 72 == 72
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 204 == 204
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 206 == 206
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 206 == 206
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 206 == 206
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 8 == 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 206 == 206
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 10 == 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 206 == 206
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 30 == 30
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 206 == 206
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 40 == 40
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 206 == 206
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 42 == 42
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 206 == 206
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 72 == 72
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 206 == 206
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 208 == 208
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 208 == 208
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 208 == 208
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 8 == 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 208 == 208
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 10 == 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 208 == 208
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 30 == 30
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 208 == 208
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 40 == 40
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 208 == 208
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 42 == 42
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 208 == 208
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 72 == 72
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 208 == 208
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 210 == 210
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 210 == 210
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 210 == 210
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 8 == 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 210 == 210
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 10 == 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 210 == 210
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 30 == 30
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 210 == 210
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 40 == 40
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 210 == 210
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 42 == 42
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 210 == 210
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 72 == 72
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 210 == 210
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 212 == 212
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 212 == 212
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 212 == 212
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 8 == 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 212 == 212
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 10 == 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 212 == 212
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 30 == 30
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 212 == 212
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 40 == 40
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 212 == 212
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 42 == 42
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 212 == 212
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 72 == 72
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 212 == 212
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 214 == 214
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 214 == 214
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 214 == 214
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 8 == 8
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 214 == 214
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 10 == 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 214 == 214
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 30 == 30
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 214 == 214
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 40 == 40
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 214 == 214
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 42 == 42
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 214 == 214
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( i, 2 ) == i*2
+ </Original>
+ <Expanded>
+ 72 == 72
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ multiply( j, 2 ) == j*2
+ </Original>
+ <Expanded>
+ 214 == 214
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Generator over a range of pairs">
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ i->first == i->second-1
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CATCH_REQUIRE" filename="projects/SelfTest/GeneratorTests.cpp" >
+ <Original>
+ i->first == i->second-1
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="INFO and WARN do not abort tests">
+ <Info>
+ this is a message
+ </Info>
+ <Warning>
+ this is a warning
+ </Warning>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="SUCCEED counts as a test pass">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="INFO gets logged on failure">
+ <Info>
+ this message should be logged
+ </Info>
+ <Info>
+ so should this
+ </Info>
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ a == 1
+ </Original>
+ <Expanded>
+ 2 == 1
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="INFO gets logged on failure, even if captured before successful assertions">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ a == 2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Info>
+ this message should be logged
+ </Info>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ a == 1
+ </Original>
+ <Expanded>
+ 2 == 1
+ </Expanded>
+ </Expression>
+ <Info>
+ and this, but later
+ </Info>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ a == 0
+ </Original>
+ <Expanded>
+ 2 == 0
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ a == 2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="FAIL aborts the test">
+ <Failure>
+ This is a failure
+ </Failure>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="FAIL does not require an argument">
+ <Failure/>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="SUCCESS does not require an argument">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Output from all sections is reported">
+ <Section name="one">
+ <Failure>
+ Message from section one
+ </Failure>
+ <OverallResults successes="0" failures="1" expectedFailures="0"/>
+ </Section>
+ <Section name="two">
+ <Failure>
+ Message from section two
+ </Failure>
+ <OverallResults successes="0" failures="1" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Standard output from all sections is reported">
+ <Section name="one">
+ <OverallResults successes="0" failures="1" expectedFailures="0"/>
+ </Section>
+ <Section name="two">
+ <OverallResults successes="0" failures="1" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="SCOPED_INFO is reset for each loop">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 0 &lt; 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 1 &lt; 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 2 &lt; 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 3 &lt; 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 4 &lt; 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 5 &lt; 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 6 &lt; 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 7 &lt; 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 8 &lt; 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 9 &lt; 10
+ </Expanded>
+ </Expression>
+ <Info>
+ current counter 10
+ </Info>
+ <Info>
+ i := 10
+ </Info>
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ i &lt; 10
+ </Original>
+ <Expanded>
+ 10 &lt; 10
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="The NO_FAIL macro reports a failure but does not fail the test">
+ <Expression success="false" type="CHECK_NOFAIL" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ 1 == 2
+ </Original>
+ <Expanded>
+ 1 == 2
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="just info">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="just failure">
+ <Failure>
+ Previous info should not be seen
+ </Failure>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="sends information to INFO">
+ <Info>
+ hi
+ </Info>
+ <Info>
+ i := 7
+ </Info>
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/MessageTests.cpp" >
+ <Original>
+ false
+ </Original>
+ <Expanded>
+ false
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Pointers can be converted to strings">
+ <Warning>
+ actual address of p: 0x<hex digits>
+ </Warning>
+ <Warning>
+ toString(p): 0x<hex digits>
+ </Warning>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="random SECTION tests">
+ <Section name="s1" description="doesn't equal">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ a != b
+ </Original>
+ <Expanded>
+ 1 != 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ b != a
+ </Original>
+ <Expanded>
+ 2 != 1
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="s2" description="not equal">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ a != b
+ </Original>
+ <Expanded>
+ 1 != 2
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="nested SECTION tests">
+ <Section name="s1" description="doesn't equal">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ a != b
+ </Original>
+ <Expanded>
+ 1 != 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ b != a
+ </Original>
+ <Expanded>
+ 2 != 1
+ </Expanded>
+ </Expression>
+ <Section name="s2" description="not equal">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ a != b
+ </Original>
+ <Expanded>
+ 1 != 2
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="more nested SECTION tests">
+ <Section name="s1" description="doesn't equal">
+ <Section name="s2" description="equal">
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ a == b
+ </Original>
+ <Expanded>
+ 1 == 2
+ </Expanded>
+ </Expression>
+ <OverallResults successes="0" failures="1" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="0" failures="1" expectedFailures="0"/>
+ </Section>
+ <Section name="s1" description="doesn't equal">
+ <Section name="s3" description="not equal">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ a != b
+ </Original>
+ <Expanded>
+ 1 != 2
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="s1" description="doesn't equal">
+ <Section name="s4" description="less than">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ a &lt; b
+ </Original>
+ <Expanded>
+ 1 &lt; 2
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="even more nested SECTION tests">
+ <Section name="c">
+ <Section name="d (leaf)">
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="c">
+ <Section name="e (leaf)">
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="f (leaf)">
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="looped SECTION tests">
+ <Section name="s1" description="b is currently: 0">
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ b > a
+ </Original>
+ <Expanded>
+ 0 > 1
+ </Expanded>
+ </Expression>
+ <OverallResults successes="0" failures="1" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="looped tests">
+ <Info>
+ Testing if fib[0] (1) is even
+ </Info>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ ( fib[i] % 2 ) == 0
+ </Original>
+ <Expanded>
+ 1 == 0
+ </Expanded>
+ </Expression>
+ <Info>
+ Testing if fib[1] (1) is even
+ </Info>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ ( fib[i] % 2 ) == 0
+ </Original>
+ <Expanded>
+ 1 == 0
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ ( fib[i] % 2 ) == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Info>
+ Testing if fib[3] (3) is even
+ </Info>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ ( fib[i] % 2 ) == 0
+ </Original>
+ <Expanded>
+ 1 == 0
+ </Expanded>
+ </Expression>
+ <Info>
+ Testing if fib[4] (5) is even
+ </Info>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ ( fib[i] % 2 ) == 0
+ </Original>
+ <Expanded>
+ 1 == 0
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ ( fib[i] % 2 ) == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Info>
+ Testing if fib[6] (13) is even
+ </Info>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ ( fib[i] % 2 ) == 0
+ </Original>
+ <Expanded>
+ 1 == 0
+ </Expanded>
+ </Expression>
+ <Info>
+ Testing if fib[7] (21) is even
+ </Info>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ ( fib[i] % 2 ) == 0
+ </Original>
+ <Expanded>
+ 1 == 0
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Sends stuff to stdout and stderr">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="null strings">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ makeString( false ) != static_cast&lt;char*>(nullptr)
+ </Original>
+ <Expanded>
+ "valid string" != {null string}
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ makeString( true ) == static_cast&lt;char*>(nullptr)
+ </Original>
+ <Expanded>
+ {null string} == {null string}
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="checkedIf">
+ <Expression success="true" type="CHECKED_IF" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ flag
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testCheckedIf( true )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="checkedIf, failing">
+ <Expression success="false" type="CHECKED_IF" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ flag
+ </Original>
+ <Expanded>
+ false
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testCheckedIf( false )
+ </Original>
+ <Expanded>
+ false
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="checkedElse">
+ <Expression success="true" type="CHECKED_ELSE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ flag
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testCheckedElse( true )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="checkedElse, failing">
+ <Expression success="false" type="CHECKED_ELSE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ flag
+ </Original>
+ <Expanded>
+ false
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testCheckedElse( false )
+ </Original>
+ <Expanded>
+ false
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="xmlentitycheck">
+ <Section name="embedded xml" description="&lt;test>it should be possible to embed xml characters, such as &lt;, &quot; or &amp;, or even whole &lt;xml>documents&lt;/xml> within an attribute&lt;/test>">
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="encoded chars" description="these should all be encoded: &amp;&amp;&amp;&quot;&quot;&quot;&lt;&lt;&lt;&amp;&quot;&lt;&lt;&amp;&quot;">
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="send a single char to INFO">
+ <Info>
+ 3
+ </Info>
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ false
+ </Original>
+ <Expanded>
+ false
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="atomic if">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ x == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="String matchers">
+ <Expression success="true" type="REQUIRE_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), Contains( "string" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" contains: "string"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), Contains( "abc" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" contains: "abc"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), StartsWith( "this" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" starts with: "this"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), EndsWith( "substring" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" ends with: "substring"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Contains string matcher">
+ <Expression success="false" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), Contains( "not there" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" contains: "not there"
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="StartsWith string matcher">
+ <Expression success="false" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), StartsWith( "string" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" starts with: "string"
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="EndsWith string matcher">
+ <Expression success="false" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), EndsWith( "this" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" ends with: "this"
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Equals string matcher">
+ <Expression success="false" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), Equals( "something else" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" equals: "something else"
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Equals string matcher, with NULL">
+ <Expression success="true" type="REQUIRE_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ "", Equals(nullptr)
+ </Original>
+ <Expanded>
+ "" equals: ""
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="AllOf matcher">
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" ( contains: "string" and contains: "abc" )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="AnyOf matcher">
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" ( contains: "string" or contains: "not there" )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" ( contains: "not there" or contains: "string" )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Equals">
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), Equals( "this string contains 'abc' as a substring" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" equals: "this string contains 'abc' as a substring"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Matchers can be (AllOf) composed with the &amp;&amp; operator">
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), Contains( "string" ) &amp;&amp; Contains( "abc" ) &amp;&amp; Contains( "substring" ) &amp;&amp; Contains( "contains" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" ( contains: "string" and contains: "abc" and contains: "substring" and contains: "contains" )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Matchers can be (AnyOf) composed with the || operator">
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" ( contains: "string" or contains: "different" or contains: "random" )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" )
+ </Original>
+ <Expanded>
+ "some completely different text that contains one common word" ( contains: "string" or contains: "different" or contains: "random" )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Matchers can be composed with both &amp;&amp; and ||">
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) &amp;&amp; Contains( "substring" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "substring" )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Matchers can be composed with both &amp;&amp; and || - failing">
+ <Expression success="false" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) &amp;&amp; Contains( "random" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" )
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Matchers can be negated (Not) with the ! operator">
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), !Contains( "different" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" not contains: "different"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Matchers can be negated (Not) with the ! operator - failing">
+ <Expression success="false" type="CHECK_THAT" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ testStringForMatching(), !Contains( "substring" )
+ </Original>
+ <Expanded>
+ "this string contains 'abc' as a substring" not contains: "substring"
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="Factorials are computed">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ Factorial(0) == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ Factorial(1) == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ Factorial(2) == 2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ Factorial(3) == 6
+ </Original>
+ <Expanded>
+ 6 == 6
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ Factorial(10) == 3628800
+ </Original>
+ <Expanded>
+ 3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="An empty test with no assertions">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Nice descriptive name">
+ <Warning>
+ This one ran
+ </Warning>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="first tag">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="second tag">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="vectors can be sized and resized">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.size() == 5
+ </Original>
+ <Expanded>
+ 5 == 5
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.capacity() >= 5
+ </Original>
+ <Expanded>
+ 5 >= 5
+ </Expanded>
+ </Expression>
+ <Section name="resizing bigger changes size and capacity">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.size() == 10
+ </Original>
+ <Expanded>
+ 10 == 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.capacity() >= 10
+ </Original>
+ <Expanded>
+ 10 >= 10
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.size() == 5
+ </Original>
+ <Expanded>
+ 5 == 5
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.capacity() >= 5
+ </Original>
+ <Expanded>
+ 5 >= 5
+ </Expanded>
+ </Expression>
+ <Section name="resizing smaller changes size but not capacity">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.size() == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.capacity() >= 5
+ </Original>
+ <Expanded>
+ 5 >= 5
+ </Expanded>
+ </Expression>
+ <Section name="We can use the 'swap trick' to reset the capacity">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.capacity() == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.size() == 5
+ </Original>
+ <Expanded>
+ 5 == 5
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.capacity() >= 5
+ </Original>
+ <Expanded>
+ 5 >= 5
+ </Expanded>
+ </Expression>
+ <Section name="reserving bigger changes capacity but not size">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.size() == 5
+ </Original>
+ <Expanded>
+ 5 == 5
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.capacity() >= 10
+ </Original>
+ <Expanded>
+ 10 >= 10
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.size() == 5
+ </Original>
+ <Expanded>
+ 5 == 5
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.capacity() >= 5
+ </Original>
+ <Expanded>
+ 5 >= 5
+ </Expanded>
+ </Expression>
+ <Section name="reserving smaller does not change size or capacity">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.size() == 5
+ </Original>
+ <Expanded>
+ 5 == 5
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ v.capacity() >= 5
+ </Original>
+ <Expanded>
+ 5 >= 5
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="A couple of nested sections followed by a failure">
+ <Section name="Outer">
+ <Section name="Inner">
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Failure>
+ to infinity and beyond
+ </Failure>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="not allowed">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Tabs and newlines show in output">
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ s1 == s2
+ </Original>
+ <Expanded>
+ "if ($b == 10) {
+ $a = 20;
+}"
+==
+"if ($b == 10) {
+ $a = 20;
+}
+"
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="toString on const wchar_t const pointer returns the string contents">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ result == "\"wide load\""
+ </Original>
+ <Expanded>
+ ""wide load"" == ""wide load""
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString on const wchar_t pointer returns the string contents">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ result == "\"wide load\""
+ </Original>
+ <Expanded>
+ ""wide load"" == ""wide load""
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString on wchar_t const pointer returns the string contents">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ result == "\"wide load\""
+ </Original>
+ <Expanded>
+ ""wide load"" == ""wide load""
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString on wchar_t returns the string contents">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ result == "\"wide load\""
+ </Original>
+ <Expanded>
+ ""wide load"" == ""wide load""
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="XmlEncode">
+ <Section name="normal string">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ encode( "normal string" ) == "normal string"
+ </Original>
+ <Expanded>
+ "normal string" == "normal string"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="empty string">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ encode( "" ) == ""
+ </Original>
+ <Expanded>
+ "" == ""
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="string with ampersand">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ encode( "smith &amp; jones" ) == "smith &amp;amp; jones"
+ </Original>
+ <Expanded>
+ "smith &amp;amp; jones" == "smith &amp;amp; jones"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="string with less-than">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ encode( "smith &lt; jones" ) == "smith &amp;lt; jones"
+ </Original>
+ <Expanded>
+ "smith &amp;lt; jones" == "smith &amp;lt; jones"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="string with greater-than">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ encode( "smith > jones" ) == "smith > jones"
+ </Original>
+ <Expanded>
+ "smith > jones" == "smith > jones"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ encode( "smith ]]&gt; jones" ) == "smith ]]&amp;gt; jones"
+ </Original>
+ <Expanded>
+ "smith ]]&amp;gt; jones"
+==
+"smith ]]&amp;gt; jones"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="string with quotes">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ encode( stringWithQuotes ) == stringWithQuotes
+ </Original>
+ <Expanded>
+ "don't "quote" me on that"
+==
+"don't "quote" me on that"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't &amp;quot;quote&amp;quot; me on that"
+ </Original>
+ <Expanded>
+ "don't &amp;quot;quote&amp;quot; me on that"
+==
+"don't &amp;quot;quote&amp;quot; me on that"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="string with control char (1)">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ encode( "[\x01]" ) == "[&amp;#x1]"
+ </Original>
+ <Expanded>
+ "[&amp;#x1]" == "[&amp;#x1]"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="string with control char (x7F)">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ encode( "[\x7F]" ) == "[&amp;#x7F]"
+ </Original>
+ <Expanded>
+ "[&amp;#x7F]" == "[&amp;#x7F]"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="long long">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/MiscTests.cpp" >
+ <Original>
+ l == std::numeric_limits&lt;long long>::max()
+ </Original>
+ <Expanded>
+ 9223372036854775807 (0x<hex digits>)
+==
+9223372036854775807 (0x<hex digits>)
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Process can be configured on command line">
+ <Section name="default - no arguments">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.shouldDebugBreak == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.abortAfter == -1
+ </Original>
+ <Expanded>
+ -1 == -1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.noThrow == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.reporterNames.empty()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="test lists">
+ <Section name="1 test" description="Specify one test case using">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ cfg.testSpec().matches( fakeTestCase( "test1" ) )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="test lists">
+ <Section name="Specify one test case exclusion using exclude:">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="test lists">
+ <Section name="Specify one test case exclusion using ~">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="reporter">
+ <Section name="-r/console">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.reporterNames[0] == "console"
+ </Original>
+ <Expanded>
+ "console" == "console"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="reporter">
+ <Section name="-r/xml">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.reporterNames[0] == "xml"
+ </Original>
+ <Expanded>
+ "xml" == "xml"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="reporter">
+ <Section name="-r xml and junit">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.reporterNames.size() == 2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.reporterNames[0] == "xml"
+ </Original>
+ <Expanded>
+ "xml" == "xml"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.reporterNames[1] == "junit"
+ </Original>
+ <Expanded>
+ "junit" == "junit"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="reporter">
+ <Section name="--reporter/junit">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.reporterNames[0] == "junit"
+ </Original>
+ <Expanded>
+ "junit" == "junit"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="debugger">
+ <Section name="-b">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.shouldDebugBreak == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="debugger">
+ <Section name="--break">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.shouldDebugBreak
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="abort">
+ <Section name="-a aborts after first failure">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.abortAfter == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="abort">
+ <Section name="-x 2 aborts after two failures">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.abortAfter == 2
+ </Original>
+ <Expanded>
+ 2 == 2
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="abort">
+ <Section name="-x must be greater than zero">
+ <Expression success="true" type="REQUIRE_THAT" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfigAndReturnError( argv, config ), Contains( "greater than zero" )
+ </Original>
+ <Expanded>
+ "Value after -x or --abortAfter must be greater than zero
+- while parsing: (-x, --abortx &lt;no. failures>)" contains: "greater than zero"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="abort">
+ <Section name="-x must be numeric">
+ <Expression success="true" type="REQUIRE_THAT" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfigAndReturnError( argv, config ), Contains( "-x" )
+ </Original>
+ <Expanded>
+ "Unable to convert oops to destination type
+- while parsing: (-x, --abortx &lt;no. failures>)" contains: "-x"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="nothrow">
+ <Section name="-e">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.noThrow == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="nothrow">
+ <Section name="--nothrow">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.noThrow == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="output filename">
+ <Section name="-o filename">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.outputFilename == "filename.ext"
+ </Original>
+ <Expanded>
+ "filename.ext" == "filename.ext"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="output filename">
+ <Section name="--out">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.outputFilename == "filename.ext"
+ </Original>
+ <Expanded>
+ "filename.ext" == "filename.ext"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="combinations">
+ <Section name="Single character flags can be combined">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.abortAfter == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.shouldDebugBreak
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.noThrow == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="force-colour">
+ <Section name="--force-colour">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ config.forceColour
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="force-colour">
+ <Section name="without --force-colour">
+ <Expression success="true" type="CHECK_NOTHROW" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ parseIntoConfig( argv, config )
+ </Original>
+ <Expanded>
+ parseIntoConfig( argv, config )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ !config.forceColour
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Long strings can be wrapped">
+ <Section name="plain string">
+ <Section name="No wrapping">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString
+ </Original>
+ <Expanded>
+ "one two three four"
+==
+"one two three four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString
+ </Original>
+ <Expanded>
+ "one two three four"
+==
+"one two three four"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="plain string">
+ <Section name="Wrapped once">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour"
+ </Original>
+ <Expanded>
+ "one two three
+four"
+==
+"one two three
+four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour"
+ </Original>
+ <Expanded>
+ "one two three
+four"
+==
+"one two three
+four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour"
+ </Original>
+ <Expanded>
+ "one two three
+four"
+==
+"one two three
+four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour"
+ </Original>
+ <Expanded>
+ "one two three
+four"
+==
+"one two three
+four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four"
+ </Original>
+ <Expanded>
+ "one two
+three four"
+==
+"one two
+three four"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="plain string">
+ <Section name="Wrapped twice">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour"
+ </Original>
+ <Expanded>
+ "one two
+three
+four"
+==
+"one two
+three
+four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour"
+ </Original>
+ <Expanded>
+ "one two
+three
+four"
+==
+"one two
+three
+four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour"
+ </Original>
+ <Expanded>
+ "one two
+three
+four"
+==
+"one two
+three
+four"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="plain string">
+ <Section name="Wrapped three times">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour"
+ </Original>
+ <Expanded>
+ "one
+two
+three
+four"
+==
+"one
+two
+three
+four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour"
+ </Original>
+ <Expanded>
+ "one
+two
+three
+four"
+==
+"one
+two
+three
+four"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="plain string">
+ <Section name="Short wrap">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef"
+ </Original>
+ <Expanded>
+ "abc-
+def"
+==
+"abc-
+def"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg"
+ </Original>
+ <Expanded>
+ "abc-
+defg"
+==
+"abc-
+defg"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh"
+ </Original>
+ <Expanded>
+ "abc-
+def-
+gh"
+==
+"abc-
+def-
+gh"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour"
+ </Original>
+ <Expanded>
+ "one
+two
+thr-
+ee
+four"
+==
+"one
+two
+thr-
+ee
+four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur"
+ </Original>
+ <Expanded>
+ "one
+two
+th-
+ree
+fo-
+ur"
+==
+"one
+two
+th-
+ree
+fo-
+ur"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="plain string">
+ <Section name="As container">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ text.size() == 4
+ </Original>
+ <Expanded>
+ 4 == 4
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ text[0] == "one"
+ </Original>
+ <Expanded>
+ "one" == "one"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ text[1] == "two"
+ </Original>
+ <Expanded>
+ "two" == "two"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ text[2] == "three"
+ </Original>
+ <Expanded>
+ "three" == "three"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ text[3] == "four"
+ </Original>
+ <Expanded>
+ "four" == "four"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="plain string">
+ <Section name="Indent first line differently">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ text.toString() == " one two\n three\n four"
+ </Original>
+ <Expanded>
+ " one two
+ three
+ four"
+==
+" one two
+ three
+ four"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="With newlines">
+ <Section name="No wrapping">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString
+ </Original>
+ <Expanded>
+ "one two
+three four"
+==
+"one two
+three four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString
+ </Original>
+ <Expanded>
+ "one two
+three four"
+==
+"one two
+three four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString
+ </Original>
+ <Expanded>
+ "one two
+three four"
+==
+"one two
+three four"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="With newlines">
+ <Section name="Trailing newline">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef\n"
+ </Original>
+ <Expanded>
+ "abcdef
+"
+==
+"abcdef
+"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef"
+ </Original>
+ <Expanded>
+ "abcdef" == "abcdef"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef\n"
+ </Original>
+ <Expanded>
+ "abcdef
+"
+==
+"abcdef
+"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="With newlines">
+ <Section name="Wrapped once">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour"
+ </Original>
+ <Expanded>
+ "one two
+three
+four"
+==
+"one two
+three
+four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour"
+ </Original>
+ <Expanded>
+ "one two
+three
+four"
+==
+"one two
+three
+four"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour"
+ </Original>
+ <Expanded>
+ "one two
+three
+four"
+==
+"one two
+three
+four"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="With newlines">
+ <Section name="Wrapped twice">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour"
+ </Original>
+ <Expanded>
+ "one
+two
+three
+four"
+==
+"one
+two
+three
+four"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="With tabs">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( testString, TextAttributes().setWidth( 15 ) ).toString() == "one two three\n four\n five\n six"
+ </Original>
+ <Expanded>
+ "one two three
+ four
+ five
+ six"
+==
+"one two three
+ four
+ five
+ six"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="replaceInPlace">
+ <Section name="replace single char">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ replaceInPlace( letters, "b", "z" )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ letters == "azcdefcg"
+ </Original>
+ <Expanded>
+ "azcdefcg" == "azcdefcg"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="replace two chars">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ replaceInPlace( letters, "c", "z" )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ letters == "abzdefzg"
+ </Original>
+ <Expanded>
+ "abzdefzg" == "abzdefzg"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="replace first char">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ replaceInPlace( letters, "a", "z" )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ letters == "zbcdefcg"
+ </Original>
+ <Expanded>
+ "zbcdefcg" == "zbcdefcg"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="replace last char">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ replaceInPlace( letters, "g", "z" )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ letters == "abcdefcz"
+ </Original>
+ <Expanded>
+ "abcdefcz" == "abcdefcz"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="replace all chars">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ replaceInPlace( letters, letters, "replaced" )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ letters == "replaced"
+ </Original>
+ <Expanded>
+ "replaced" == "replaced"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="replace no chars">
+ <Expression success="true" type="CHECK_FALSE" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ !replaceInPlace( letters, "x", "z" )
+ </Original>
+ <Expanded>
+ !false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ letters == letters
+ </Original>
+ <Expanded>
+ "abcdefcg" == "abcdefcg"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="escape '">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ replaceInPlace( s, "'", "|'" )
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ s == "didn|'t"
+ </Original>
+ <Expanded>
+ "didn|'t" == "didn|'t"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Strings can be rendered with colour">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Text can be formatted using the Text class">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( "hi there" ).toString() == "hi there"
+ </Original>
+ <Expanded>
+ "hi there" == "hi there"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ Text( "hi there", narrow ).toString() == "hi\nthere"
+ </Original>
+ <Expanded>
+ "hi
+there"
+==
+"hi
+there"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Long text is truncted">
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/TestMain.cpp" >
+ <Original>
+ t.toString(), EndsWith( "... message truncated due to excessive size" )
+ </Original>
+ <Expanded>
+ "******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+******************************************************************************-
+************************
+******************************************************************************-
+... message truncated due to excessive size" ends with: "... message truncated due to excessive size"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="ManuallyRegistered">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Parsing a std::pair">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ (std::pair&lt;int, int>( 1, 2 )) == aNicePair
+ </Original>
+ <Expanded>
+ std::pair( 1, 2 ) == std::pair( 1, 2 )
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Where there is more to the expression after the RHS">
+ <Warning>
+ Uncomment the code in this test to check that it gives a sensible compiler error
+ </Warning>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Where the LHS is not a simple value">
+ <Warning>
+ Uncomment the code in this test to check that it gives a sensible compiler error
+ </Warning>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="A failing expression with a non streamable type is still captured">
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ &amp;o1 == &amp;o2
+ </Original>
+ <Expanded>
+ 0x<hex digits> == 0x<hex digits>
+ </Expanded>
+ </Expression>
+ <Expression success="false" type="CHECK" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ o1 == o2
+ </Original>
+ <Expanded>
+ {?} == {?}
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="string literals of different sizes can be compared">
+ <Expression success="false" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ std::string( "first" ) == "second"
+ </Original>
+ <Expanded>
+ "first" == "second"
+ </Expanded>
+ </Expression>
+ <OverallResult success="false"/>
+ </TestCase>
+ <TestCase name="An expression with side-effects should only be evaluated once">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ i++ == 7
+ </Original>
+ <Expanded>
+ 7 == 7
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ i++ == 8
+ </Original>
+ <Expanded>
+ 8 == 8
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Operators at different namespace levels not hijacked by Koenig lookup">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ 0x<hex digits> == o
+ </Original>
+ <Expanded>
+ 3221225472 (0x<hex digits>) == {?}
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Demonstrate that a non-const == is not used">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ t == 1u
+ </Original>
+ <Expanded>
+ {?} == 1
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Test enum bit values">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ 0x<hex digits> == bit30and31
+ </Original>
+ <Expanded>
+ 3221225472 (0x<hex digits>) == 3221225472
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="boolean member">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ obj.prop != nullptr
+ </Original>
+ <Expanded>
+ 0x<hex digits> != nullptr
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="(unimplemented) static bools can be evaluated">
+ <Section name="compare to true">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ is_true&lt;true>::value == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ true == is_true&lt;true>::value
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="compare to false">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ is_true&lt;false>::value == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ false == is_true&lt;false>::value
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="negation">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ !is_true&lt;false>::value
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="double negation">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ !!is_true&lt;true>::value
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="direct">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ is_true&lt;true>::value
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE_FALSE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ !is_true&lt;false>::value
+ </Original>
+ <Expanded>
+ !false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Objects that evaluated in boolean contexts can be checked">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ True
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ !False
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_FALSE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ !False
+ </Original>
+ <Expanded>
+ !false
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Assertions then sections">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ Catch::alwaysTrue()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="A section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ Catch::alwaysTrue()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="Another section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ Catch::alwaysTrue()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ Catch::alwaysTrue()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="A section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ Catch::alwaysTrue()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="Another other section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ Catch::alwaysTrue()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="non streamable - with conv. op">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ s == "7"
+ </Original>
+ <Expanded>
+ "7" == "7"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Comparing function pointers">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ a
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ a == &amp;foo
+ </Original>
+ <Expanded>
+ 0x<hex digits> == 0x<hex digits>
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Comparing member function pointers">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ m == &amp;S::f
+ </Original>
+ <Expanded>
+ 0x<hex digits>
+==
+0x<hex digits>
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="pointer to class">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ p == 0
+ </Original>
+ <Expanded>
+ NULL == 0
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="null_ptr">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/TrickyTests.cpp" >
+ <Original>
+ ptr.get() == nullptr
+ </Original>
+ <Expanded>
+ NULL == nullptr
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="X/level/0/a">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="X/level/0/b">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="X/level/1/a">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="X/level/1/b">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString( has_toString )">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringWhich.cpp" >
+ <Original>
+ Catch::toString( item ) == "toString( has_toString )"
+ </Original>
+ <Expanded>
+ "toString( has_toString )"
+==
+"toString( has_toString )"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString( has_maker )">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringWhich.cpp" >
+ <Original>
+ Catch::toString( item ) == "StringMaker&lt;has_maker>"
+ </Original>
+ <Expanded>
+ "StringMaker&lt;has_maker>"
+==
+"StringMaker&lt;has_maker>"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString( has_maker_and_toString )">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringWhich.cpp" >
+ <Original>
+ Catch::toString( item ) == "toString( has_maker_and_toString )"
+ </Original>
+ <Expanded>
+ "toString( has_maker_and_toString )"
+==
+"toString( has_maker_and_toString )"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString( vectors&lt;has_toString )">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringWhich.cpp" >
+ <Original>
+ Catch::toString( v ) == "{ {?} }"
+ </Original>
+ <Expanded>
+ "{ {?} }" == "{ {?} }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString( vectors&lt;has_maker )">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringWhich.cpp" >
+ <Original>
+ Catch::toString( v ) == "{ StringMaker&lt;has_maker> }"
+ </Original>
+ <Expanded>
+ "{ StringMaker&lt;has_maker> }"
+==
+"{ StringMaker&lt;has_maker> }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="toString( vectors&lt;has_maker_and_toString )">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringWhich.cpp" >
+ <Original>
+ Catch::toString( v ) == "{ StringMaker&lt;has_maker_and_toString> }"
+ </Original>
+ <Expanded>
+ "{ StringMaker&lt;has_maker_and_toString> }"
+==
+"{ StringMaker&lt;has_maker_and_toString> }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Tracker">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="successfully close one section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isSuccessfullyCompleted()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ ctx.completedCycle()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isSuccessfullyCompleted()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="fail one section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isSuccessfullyCompleted() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ ctx.completedCycle()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isSuccessfullyCompleted() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="re-enter after failed section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1b.isOpen() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ ctx.completedCycle()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isSuccessfullyCompleted()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="10" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="fail one section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isSuccessfullyCompleted() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ ctx.completedCycle()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isSuccessfullyCompleted() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="re-enter after failed section and find next section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1b.isOpen() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ ctx.completedCycle()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isSuccessfullyCompleted()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="6" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="11" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="successfully close one section, then find another">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2.isOpen() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="Re-enter - skips S1 and enters S2">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1b.isOpen() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2b.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ ctx.completedCycle() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="Successfully close S2">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ ctx.completedCycle()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2b.isSuccessfullyCompleted()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isSuccessfullyCompleted()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="8" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="10" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="successfully close one section, then find another">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2.isOpen() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="Re-enter - skips S1 and enters S2">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1b.isOpen() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2b.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ ctx.completedCycle() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="fail S2">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ ctx.completedCycle()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2b.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2b.isSuccessfullyCompleted() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isSuccessfullyCompleted() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase3.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1c.isOpen() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2c.isOpen() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase3.isSuccessfullyCompleted()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="8" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="12" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="14" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="open a nested section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="6" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="start a generator">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1.index() == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="close outer section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isSuccessfullyCompleted() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="Re-enter for second generation">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1b.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1b.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1b.index() == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1b.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1b.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="8" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="10" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="14" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="start a generator">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1.index() == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="Start a new inner section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="Re-enter for second generation">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1b.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1b.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1b.index() == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2b.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2b.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1b.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1b.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="9" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="13" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="17" failures="0" expectedFailures="0"/>
+ </Section>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="start a generator">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1.index() == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="Fail an inner section">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2.isSuccessfullyCompleted() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Section name="Re-enter for second generation">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1b.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1b.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1b.index() == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2b.isOpen() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1b.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1b.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase2.isComplete() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase3.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1c.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1c.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1c.index() == 1
+ </Original>
+ <Expanded>
+ 1 == 1
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2c.isOpen()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s2c.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ g1c.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ s1c.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/PartTrackerTests.cpp" >
+ <Original>
+ testCase3.isComplete()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="17" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="22" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="26" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="std::pair&lt;int,std::string> -> toString">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringPair.cpp" >
+ <Original>
+ Catch::toString( value ) == "{ 34, \"xyzzy\" }"
+ </Original>
+ <Expanded>
+ "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="std::pair&lt;int,const std::string> -> toString">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringPair.cpp" >
+ <Original>
+ Catch::toString(value) == "{ 34, \"xyzzy\" }"
+ </Original>
+ <Expanded>
+ "{ 34, "xyzzy" }" == "{ 34, "xyzzy" }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="std::vector&lt;std::pair&lt;std::string,int> > -> toString">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringPair.cpp" >
+ <Original>
+ Catch::toString( pr ) == "{ { \"green\", 55 } }"
+ </Original>
+ <Expanded>
+ "{ { "green", 55 } }"
+==
+"{ { "green", 55 } }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="pair&lt;pair&lt;int,const char *,pair&lt;std::string,int> > -> toString">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringPair.cpp" >
+ <Original>
+ Catch::toString( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }"
+ </Original>
+ <Expanded>
+ "{ { 42, "Arthur" }, { "Ford", 24 } }"
+==
+"{ { 42, "Arthur" }, { "Ford", 24 } }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="vector&lt;int> -> toString">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(vv) == "{ }"
+ </Original>
+ <Expanded>
+ "{ }" == "{ }"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(vv) == "{ 42 }"
+ </Original>
+ <Expanded>
+ "{ 42 }" == "{ 42 }"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(vv) == "{ 42, 250 }"
+ </Original>
+ <Expanded>
+ "{ 42, 250 }" == "{ 42, 250 }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="vector&lt;string> -> toString">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(vv) == "{ }"
+ </Original>
+ <Expanded>
+ "{ }" == "{ }"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(vv) == "{ \"hello\" }"
+ </Original>
+ <Expanded>
+ "{ "hello" }" == "{ "hello" }"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(vv) == "{ \"hello\", \"world\" }"
+ </Original>
+ <Expanded>
+ "{ "hello", "world" }"
+==
+"{ "hello", "world" }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="vector&lt;int,allocator> -> toString">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(vv) == "{ }"
+ </Original>
+ <Expanded>
+ "{ }" == "{ }"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(vv) == "{ 42 }"
+ </Original>
+ <Expanded>
+ "{ 42 }" == "{ 42 }"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(vv) == "{ 42, 250 }"
+ </Original>
+ <Expanded>
+ "{ 42, 250 }" == "{ 42, 250 }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="vec&lt;vec&lt;string,alloc>> -> toString">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(v) == "{ }"
+ </Original>
+ <Expanded>
+ "{ }" == "{ }"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/ToStringVector.cpp" >
+ <Original>
+ Catch::toString(v) == "{ { \"hello\" }, { \"world\" } }"
+ </Original>
+ <Expanded>
+ "{ { "hello" }, { "world" } }"
+==
+"{ { "hello" }, { "world" } }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Parse test names and tags">
+ <Section name="Empty test spec should have no filters">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Test spec from empty string should have no filters">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches(tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Test spec from just a comma should have no filters">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Test spec from name should have one filter">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Test spec from quoted name should have one filter">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Test spec from name should have one filter">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Wildcard at the start">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ parseTestSpec( "*a" ).matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="6" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Wildcard at the end">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ parseTestSpec( "a*" ).matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="6" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Wildcard at both ends">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ parseTestSpec( "*a*" ).matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="6" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Redundant wildcard at the start">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Redundant wildcard at the end">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Redundant wildcard at both ends">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Wildcard at both ends, redundant at start">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Just wildcard">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Single tag">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Single tag, two matches">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Two tags">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Two tags, spare separated">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Wildcarded name and tag">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Single tag exclusion">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="One tag exclusion and one tag inclusion">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="One tag exclusion and one wldcarded name inclusion">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="One tag exclusion, using exclude:, and one wldcarded name inclusion">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="name exclusion">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="wildcarded name exclusion">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="wildcarded name exclusion with tag inclusion">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="wildcarded name exclusion, using exclude:, with tag inclusion">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="two wildcarded names">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="empty tag">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="empty quoted name">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="quoted string followed by tag exclusion">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.hasFilters() == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcA ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcB ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcC ) == false
+ </Original>
+ <Expanded>
+ false == false
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/CmdLineTests.cpp" >
+ <Original>
+ spec.matches( tcD ) == true
+ </Original>
+ <Expanded>
+ true == true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="tuple&lt;>">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ToStringTuple.cpp" >
+ <Original>
+ "{ }" == Catch::toString(type{})
+ </Original>
+ <Expanded>
+ "{ }" == "{ }"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ToStringTuple.cpp" >
+ <Original>
+ "{ }" == Catch::toString(value)
+ </Original>
+ <Expanded>
+ "{ }" == "{ }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="tuple&lt;int>">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ToStringTuple.cpp" >
+ <Original>
+ "{ 0 }" == Catch::toString(type{0})
+ </Original>
+ <Expanded>
+ "{ 0 }" == "{ 0 }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="tuple&lt;float,int>">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ToStringTuple.cpp" >
+ <Original>
+ "1.2f" == Catch::toString(float(1.2))
+ </Original>
+ <Expanded>
+ "1.2f" == "1.2f"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ToStringTuple.cpp" >
+ <Original>
+ "{ 1.2f, 0 }" == Catch::toString(type{1.2,0})
+ </Original>
+ <Expanded>
+ "{ 1.2f, 0 }" == "{ 1.2f, 0 }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="tuple&lt;string,string>">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ToStringTuple.cpp" >
+ <Original>
+ "{ \"hello\", \"world\" }" == Catch::toString(type{"hello","world"})
+ </Original>
+ <Expanded>
+ "{ "hello", "world" }"
+==
+"{ "hello", "world" }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="tuple&lt;tuple&lt;int>,tuple&lt;>,float>">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ToStringTuple.cpp" >
+ <Original>
+ "{ { 42 }, { }, 1.2f }" == Catch::toString(value)
+ </Original>
+ <Expanded>
+ "{ { 42 }, { }, 1.2f }"
+==
+"{ { 42 }, { }, 1.2f }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="tuple&lt;nullptr,int,const char *>">
+ <Expression success="true" type="CHECK" filename="projects/SelfTest/ToStringTuple.cpp" >
+ <Original>
+ "{ nullptr, 42, \"Catch me\" }" == Catch::toString(value)
+ </Original>
+ <Expanded>
+ "{ nullptr, 42, "Catch me" }"
+==
+"{ nullptr, 42, "Catch me" }"
+ </Expanded>
+ </Expression>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Tag alias can be registered against tag patterns">
+ <Section name="The same tag alias can only be registered once">
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/TagAliasTests.cpp" >
+ <Original>
+ what, Contains( "[@zzz]" )
+ </Original>
+ <Expanded>
+ "error: tag alias, "[@zzz]" already registered.
+ First seen at file:2
+ Redefined at file:10" contains: "[@zzz]"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/TagAliasTests.cpp" >
+ <Original>
+ what, Contains( "file" )
+ </Original>
+ <Expanded>
+ "error: tag alias, "[@zzz]" already registered.
+ First seen at file:2
+ Redefined at file:10" contains: "file"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/TagAliasTests.cpp" >
+ <Original>
+ what, Contains( "2" )
+ </Original>
+ <Expanded>
+ "error: tag alias, "[@zzz]" already registered.
+ First seen at file:2
+ Redefined at file:10" contains: "2"
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THAT" filename="projects/SelfTest/TagAliasTests.cpp" >
+ <Original>
+ what, Contains( "10" )
+ </Original>
+ <Expanded>
+ "error: tag alias, "[@zzz]" already registered.
+ First seen at file:2
+ Redefined at file:10" contains: "10"
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Tag aliases must be of the form [@name]">
+ <Expression success="true" type="CHECK_THROWS" filename="projects/SelfTest/TagAliasTests.cpp" >
+ <Original>
+ registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) )
+ </Original>
+ <Expanded>
+ registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THROWS" filename="projects/SelfTest/TagAliasTests.cpp" >
+ <Original>
+ registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
+ </Original>
+ <Expanded>
+ registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THROWS" filename="projects/SelfTest/TagAliasTests.cpp" >
+ <Original>
+ registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
+ </Original>
+ <Expanded>
+ registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="CHECK_THROWS" filename="projects/SelfTest/TagAliasTests.cpp" >
+ <Original>
+ registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) )
+ </Original>
+ <Expanded>
+ registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) )
+ </Expanded>
+ </Expression>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Anonymous test case 1">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Test case with one argument">
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Variadic macros">
+ <Section name="Section with one argument">
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Scenario: Do that thing with the thing">
+ <Section name="Given: This stuff exists">
+ <Section name="When: I do this">
+ <Section name="Then: it should do this">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ itDoesThis()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <Section name="And: do that">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ itDoesThat()
+ </Original>
+ <Expanded>
+ true
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Scenario: Vector resizing affects size and capacity">
+ <Section name="Given: an empty vector">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ v.size() == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Section name="When: it is made larger">
+ <Section name="Then: the size and capacity go up">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ v.size() == 10
+ </Original>
+ <Expanded>
+ 10 == 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ v.capacity() >= 10
+ </Original>
+ <Expanded>
+ 10 >= 10
+ </Expanded>
+ </Expression>
+ <Section name="And when: it is made smaller again">
+ <Section name="Then: the size goes down but the capacity stays the same">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ v.size() == 5
+ </Original>
+ <Expanded>
+ 5 == 5
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ v.capacity() >= 10
+ </Original>
+ <Expanded>
+ 10 >= 10
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="4" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="5" failures="0" expectedFailures="0"/>
+ </Section>
+ <Section name="Given: an empty vector">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ v.size() == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Section name="When: we reserve more space">
+ <Section name="Then: The capacity is increased but the size remains the same">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ v.capacity() >= 10
+ </Original>
+ <Expanded>
+ 10 >= 10
+ </Expanded>
+ </Expression>
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ v.size() == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="3" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Scenario: This is a really long scenario name to see how the list command deals with wrapping">
+ <Section name="Given: A section name that is so long that it cannot fit in a single console width">
+ <Section name="When: The test headers are printed as part of the normal running of the scenario">
+ <Section name="Then: The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent">
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <TestCase name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods">
+ <Section name="Given: No operations precede me">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ before == 0
+ </Original>
+ <Expanded>
+ 0 == 0
+ </Expanded>
+ </Expression>
+ <Section name="When: We get the count">
+ <Section name="Then: Subsequently values are higher">
+ <Expression success="true" type="REQUIRE" filename="projects/SelfTest/BDDTests.cpp" >
+ <Original>
+ after > before
+ </Original>
+ <Expanded>
+ 1 > 0
+ </Expanded>
+ </Expression>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="1" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResults successes="2" failures="0" expectedFailures="0"/>
+ </Section>
+ <OverallResult success="true"/>
+ </TestCase>
+ <OverallResults successes="818" failures="85" expectedFailures="13"/>
+ </Group>
+ <OverallResults successes="818" failures="85" expectedFailures="13"/>
+</Catch>
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/ClassTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/ClassTests.cpp
new file mode 100644
index 00000000000..a4707849bb9
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/ClassTests.cpp
@@ -0,0 +1,57 @@
+/*
+ * Created by Phil on 09/11/2010.
+ * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "catch.hpp"
+
+namespace
+{
+ class TestClass
+ {
+ std::string s;
+
+ public:
+ TestClass()
+ : s( "hello" )
+ {}
+
+ void succeedingCase()
+ {
+ REQUIRE( s == "hello" );
+ }
+ void failingCase()
+ {
+ REQUIRE( s == "world" );
+ }
+ };
+}
+
+
+METHOD_AS_TEST_CASE( TestClass::succeedingCase, "A METHOD_AS_TEST_CASE based test run that succeeds", "[class]" )
+METHOD_AS_TEST_CASE( TestClass::failingCase, "A METHOD_AS_TEST_CASE based test run that fails", "[.][class][failing]" )
+
+
+struct Fixture
+{
+ Fixture() : m_a( 1 ) {}
+
+ int m_a;
+};
+
+TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that succeeds", "[class]" )
+{
+ REQUIRE( m_a == 1 );
+}
+
+// We should be able to write our tests within a different namespace
+namespace Inner
+{
+ TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that fails", "[.][class][failing]" )
+ {
+ REQUIRE( m_a == 2 );
+ }
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/CmdLineTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/CmdLineTests.cpp
new file mode 100644
index 00000000000..719c89b8fb0
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/CmdLineTests.cpp
@@ -0,0 +1,264 @@
+/*
+ * Created by Phil on 13/5/2013.
+ * Copyright 2014 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "catch.hpp"
+#include "catch_test_spec_parser.hpp"
+
+#ifdef __clang__
+# pragma clang diagnostic ignored "-Wc++98-compat"
+#endif
+
+inline Catch::TestCase fakeTestCase( const char* name, const char* desc = "" ){ return Catch::makeTestCase( CATCH_NULL, "", name, desc, CATCH_INTERNAL_LINEINFO ); }
+
+TEST_CASE( "Parse test names and tags", "" ) {
+
+ using Catch::parseTestSpec;
+ using Catch::TestSpec;
+
+ Catch::TestCase tcA = fakeTestCase( "a", "" );
+ Catch::TestCase tcB = fakeTestCase( "b", "[one][x]" );
+ Catch::TestCase tcC = fakeTestCase( "longer name with spaces", "[two][three][.][x]" );
+ Catch::TestCase tcD = fakeTestCase( "zlonger name with spacesz", "" );
+
+ SECTION( "Empty test spec should have no filters", "" ) {
+ TestSpec spec;
+ CHECK( spec.hasFilters() == false );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ }
+
+ SECTION( "Test spec from empty string should have no filters", "" ) {
+ TestSpec spec = parseTestSpec( "" );
+ CHECK( spec.hasFilters() == false );
+ CHECK( spec.matches(tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ }
+
+ SECTION( "Test spec from just a comma should have no filters", "" ) {
+ TestSpec spec = parseTestSpec( "," );
+ CHECK( spec.hasFilters() == false );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ }
+
+ SECTION( "Test spec from name should have one filter", "" ) {
+ TestSpec spec = parseTestSpec( "b" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == true );
+ }
+
+ SECTION( "Test spec from quoted name should have one filter", "" ) {
+ TestSpec spec = parseTestSpec( "\"b\"" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == true );
+ }
+
+ SECTION( "Test spec from name should have one filter", "" ) {
+ TestSpec spec = parseTestSpec( "b" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == true );
+ CHECK( spec.matches( tcC ) == false );
+ }
+
+ SECTION( "Wildcard at the start", "" ) {
+ TestSpec spec = parseTestSpec( "*spaces" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == true );
+ CHECK( spec.matches( tcD ) == false );
+ CHECK( parseTestSpec( "*a" ).matches( tcA ) == true );
+ }
+ SECTION( "Wildcard at the end", "" ) {
+ TestSpec spec = parseTestSpec( "long*" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == true );
+ CHECK( spec.matches( tcD ) == false );
+ CHECK( parseTestSpec( "a*" ).matches( tcA ) == true );
+ }
+ SECTION( "Wildcard at both ends", "" ) {
+ TestSpec spec = parseTestSpec( "*name*" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == true );
+ CHECK( spec.matches( tcD ) == true );
+ CHECK( parseTestSpec( "*a*" ).matches( tcA ) == true );
+ }
+ SECTION( "Redundant wildcard at the start", "" ) {
+ TestSpec spec = parseTestSpec( "*a" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == true );
+ CHECK( spec.matches( tcB ) == false );
+ }
+ SECTION( "Redundant wildcard at the end", "" ) {
+ TestSpec spec = parseTestSpec( "a*" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == true );
+ CHECK( spec.matches( tcB ) == false );
+ }
+ SECTION( "Redundant wildcard at both ends", "" ) {
+ TestSpec spec = parseTestSpec( "*a*" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == true );
+ CHECK( spec.matches( tcB ) == false );
+ }
+ SECTION( "Wildcard at both ends, redundant at start", "" ) {
+ TestSpec spec = parseTestSpec( "*longer*" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == true );
+ CHECK( spec.matches( tcD ) == true );
+ }
+ SECTION( "Just wildcard", "" ) {
+ TestSpec spec = parseTestSpec( "*" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == true );
+ CHECK( spec.matches( tcB ) == true );
+ CHECK( spec.matches( tcC ) == true );
+ CHECK( spec.matches( tcD ) == true );
+ }
+
+ SECTION( "Single tag", "" ) {
+ TestSpec spec = parseTestSpec( "[one]" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == true );
+ CHECK( spec.matches( tcC ) == false );
+ }
+ SECTION( "Single tag, two matches", "" ) {
+ TestSpec spec = parseTestSpec( "[x]" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == true );
+ CHECK( spec.matches( tcC ) == true );
+ }
+ SECTION( "Two tags", "" ) {
+ TestSpec spec = parseTestSpec( "[two][x]" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == true );
+ }
+ SECTION( "Two tags, spare separated", "" ) {
+ TestSpec spec = parseTestSpec( "[two] [x]" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == true );
+ }
+ SECTION( "Wildcarded name and tag", "" ) {
+ TestSpec spec = parseTestSpec( "*name*[x]" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == true );
+ CHECK( spec.matches( tcD ) == false );
+ }
+ SECTION( "Single tag exclusion", "" ) {
+ TestSpec spec = parseTestSpec( "~[one]" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == true );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == true );
+ }
+ SECTION( "One tag exclusion and one tag inclusion", "" ) {
+ TestSpec spec = parseTestSpec( "~[two][x]" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == true );
+ CHECK( spec.matches( tcC ) == false );
+ }
+ SECTION( "One tag exclusion and one wldcarded name inclusion", "" ) {
+ TestSpec spec = parseTestSpec( "~[two]*name*" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == false );
+ CHECK( spec.matches( tcD ) == true );
+ }
+ SECTION( "One tag exclusion, using exclude:, and one wldcarded name inclusion", "" ) {
+ TestSpec spec = parseTestSpec( "exclude:[two]*name*" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == false );
+ CHECK( spec.matches( tcD ) == true );
+ }
+ SECTION( "name exclusion", "" ) {
+ TestSpec spec = parseTestSpec( "~b" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == true );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == true );
+ CHECK( spec.matches( tcD ) == true );
+ }
+ SECTION( "wildcarded name exclusion", "" ) {
+ TestSpec spec = parseTestSpec( "~*name*" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == true );
+ CHECK( spec.matches( tcB ) == true );
+ CHECK( spec.matches( tcC ) == false );
+ CHECK( spec.matches( tcD ) == false );
+ }
+ SECTION( "wildcarded name exclusion with tag inclusion", "" ) {
+ TestSpec spec = parseTestSpec( "~*name*,[three]" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == true );
+ CHECK( spec.matches( tcB ) == true );
+ CHECK( spec.matches( tcC ) == true );
+ CHECK( spec.matches( tcD ) == false );
+ }
+ SECTION( "wildcarded name exclusion, using exclude:, with tag inclusion", "" ) {
+ TestSpec spec = parseTestSpec( "exclude:*name*,[three]" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == true );
+ CHECK( spec.matches( tcB ) == true );
+ CHECK( spec.matches( tcC ) == true );
+ CHECK( spec.matches( tcD ) == false );
+ }
+ SECTION( "two wildcarded names", "" ) {
+ TestSpec spec = parseTestSpec( "\"longer*\"\"*spaces\"" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == true );
+ CHECK( spec.matches( tcD ) == false );
+ }
+ SECTION( "empty tag", "" ) {
+ TestSpec spec = parseTestSpec( "[]" );
+ CHECK( spec.hasFilters() == false );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == false );
+ CHECK( spec.matches( tcD ) == false );
+ }
+ SECTION( "empty quoted name", "" ) {
+ TestSpec spec = parseTestSpec( "\"\"" );
+ CHECK( spec.hasFilters() == false );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == false );
+ CHECK( spec.matches( tcD ) == false );
+ }
+ SECTION( "quoted string followed by tag exclusion", "" ) {
+ TestSpec spec = parseTestSpec( "\"*name*\"~[.]" );
+ CHECK( spec.hasFilters() == true );
+ CHECK( spec.matches( tcA ) == false );
+ CHECK( spec.matches( tcB ) == false );
+ CHECK( spec.matches( tcC ) == false );
+ CHECK( spec.matches( tcD ) == true );
+ }
+
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/ConditionTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/ConditionTests.cpp
new file mode 100644
index 00000000000..d1b7ed24ce3
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/ConditionTests.cpp
@@ -0,0 +1,335 @@
+/*
+ * Created by Phil on 08/11/2010.
+ * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifdef __clang__
+# pragma clang diagnostic ignored "-Wpadded"
+# pragma clang diagnostic ignored "-Wc++98-compat"
+#endif
+
+#include "catch.hpp"
+
+#include <string>
+#include <limits>
+
+struct TestData {
+ TestData()
+ : int_seven( 7 ),
+ str_hello( "hello" ),
+ float_nine_point_one( 9.1f ),
+ double_pi( 3.1415926535 )
+ {}
+
+ int int_seven;
+ std::string str_hello;
+ float float_nine_point_one;
+ double double_pi;
+};
+
+
+struct TestDef {
+ TestDef& operator + ( const std::string& ) {
+ return *this;
+ }
+ TestDef& operator[]( const std::string& ) {
+ return *this;
+ }
+
+};
+
+// The "failing" tests all use the CHECK macro, which continues if the specific test fails.
+// This allows us to see all results, even if an earlier check fails
+
+// Equality tests
+TEST_CASE( "Equality checks that should succeed", "" )
+{
+
+ TestDef td;
+ td + "hello" + "hello";
+
+ TestData data;
+
+ REQUIRE( data.int_seven == 7 );
+ REQUIRE( data.float_nine_point_one == Approx( 9.1f ) );
+ REQUIRE( data.double_pi == Approx( 3.1415926535 ) );
+ REQUIRE( data.str_hello == "hello" );
+ REQUIRE( "hello" == data.str_hello );
+ REQUIRE( data.str_hello.size() == 5 );
+
+ double x = 1.1 + 0.1 + 0.1;
+ REQUIRE( x == Approx( 1.3 ) );
+}
+
+TEST_CASE( "Equality checks that should fail", "[.][failing][!mayfail]" )
+{
+ TestData data;
+
+ CHECK( data.int_seven == 6 );
+ CHECK( data.int_seven == 8 );
+ CHECK( data.int_seven == 0 );
+ CHECK( data.float_nine_point_one == Approx( 9.11f ) );
+ CHECK( data.float_nine_point_one == Approx( 9.0f ) );
+ CHECK( data.float_nine_point_one == Approx( 1 ) );
+ CHECK( data.float_nine_point_one == Approx( 0 ) );
+ CHECK( data.double_pi == Approx( 3.1415 ) );
+ CHECK( data.str_hello == "goodbye" );
+ CHECK( data.str_hello == "hell" );
+ CHECK( data.str_hello == "hello1" );
+ CHECK( data.str_hello.size() == 6 );
+
+ double x = 1.1 + 0.1 + 0.1;
+ CHECK( x == Approx( 1.301 ) );
+}
+
+TEST_CASE( "Inequality checks that should succeed", "" )
+{
+ TestData data;
+
+ REQUIRE( data.int_seven != 6 );
+ REQUIRE( data.int_seven != 8 );
+ REQUIRE( data.float_nine_point_one != Approx( 9.11f ) );
+ REQUIRE( data.float_nine_point_one != Approx( 9.0f ) );
+ REQUIRE( data.float_nine_point_one != Approx( 1 ) );
+ REQUIRE( data.float_nine_point_one != Approx( 0 ) );
+ REQUIRE( data.double_pi != Approx( 3.1415 ) );
+ REQUIRE( data.str_hello != "goodbye" );
+ REQUIRE( data.str_hello != "hell" );
+ REQUIRE( data.str_hello != "hello1" );
+ REQUIRE( data.str_hello.size() != 6 );
+}
+
+TEST_CASE( "Inequality checks that should fail", "[.][failing]" )
+{
+ TestData data;
+
+ CHECK( data.int_seven != 7 );
+ CHECK( data.float_nine_point_one != Approx( 9.1f ) );
+ CHECK( data.double_pi != Approx( 3.1415926535 ) );
+ CHECK( data.str_hello != "hello" );
+ CHECK( data.str_hello.size() != 5 );
+}
+
+// Ordering comparison tests
+TEST_CASE( "Ordering comparison checks that should succeed", "" )
+{
+ TestData data;
+
+ REQUIRE( data.int_seven < 8 );
+ REQUIRE( data.int_seven > 6 );
+ REQUIRE( data.int_seven > 0 );
+ REQUIRE( data.int_seven > -1 );
+
+ REQUIRE( data.int_seven >= 7 );
+ REQUIRE( data.int_seven >= 6 );
+ REQUIRE( data.int_seven <= 7 );
+ REQUIRE( data.int_seven <= 8 );
+
+ REQUIRE( data.float_nine_point_one > 9 );
+ REQUIRE( data.float_nine_point_one < 10 );
+ REQUIRE( data.float_nine_point_one < 9.2 );
+
+ REQUIRE( data.str_hello <= "hello" );
+ REQUIRE( data.str_hello >= "hello" );
+
+ REQUIRE( data.str_hello < "hellp" );
+ REQUIRE( data.str_hello < "zebra" );
+ REQUIRE( data.str_hello > "hellm" );
+ REQUIRE( data.str_hello > "a" );
+}
+
+TEST_CASE( "Ordering comparison checks that should fail", "[.][failing]" )
+{
+ TestData data;
+
+ CHECK( data.int_seven > 7 );
+ CHECK( data.int_seven < 7 );
+ CHECK( data.int_seven > 8 );
+ CHECK( data.int_seven < 6 );
+ CHECK( data.int_seven < 0 );
+ CHECK( data.int_seven < -1 );
+
+ CHECK( data.int_seven >= 8 );
+ CHECK( data.int_seven <= 6 );
+
+ CHECK( data.float_nine_point_one < 9 );
+ CHECK( data.float_nine_point_one > 10 );
+ CHECK( data.float_nine_point_one > 9.2 );
+
+ CHECK( data.str_hello > "hello" );
+ CHECK( data.str_hello < "hello" );
+ CHECK( data.str_hello > "hellp" );
+ CHECK( data.str_hello > "z" );
+ CHECK( data.str_hello < "hellm" );
+ CHECK( data.str_hello < "a" );
+
+ CHECK( data.str_hello >= "z" );
+ CHECK( data.str_hello <= "a" );
+}
+
+// Comparisons with int literals
+TEST_CASE( "Comparisons with int literals don't warn when mixing signed/ unsigned", "" )
+{
+ int i = 1;
+ unsigned int ui = 2;
+ long l = 3;
+ unsigned long ul = 4;
+ char c = 5;
+ unsigned char uc = 6;
+
+ REQUIRE( i == 1 );
+ REQUIRE( ui == 2 );
+ REQUIRE( l == 3 );
+ REQUIRE( ul == 4 );
+ REQUIRE( c == 5 );
+ REQUIRE( uc == 6 );
+
+ REQUIRE( 1 == i );
+ REQUIRE( 2 == ui );
+ REQUIRE( 3 == l );
+ REQUIRE( 4 == ul );
+ REQUIRE( 5 == c );
+ REQUIRE( 6 == uc );
+
+ REQUIRE( (std::numeric_limits<unsigned long>::max)() > ul );
+}
+
+// Disable warnings about sign conversions for the next two tests
+// (as we are deliberately invoking them)
+// - Currently only disabled for GCC/ LLVM. Should add VC++ too
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#endif
+#ifdef _MSC_VER
+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
+#endif
+
+TEST_CASE( "comparisons between int variables", "" )
+{
+ long long_var = 1L;
+ unsigned char unsigned_char_var = 1;
+ unsigned short unsigned_short_var = 1;
+ unsigned int unsigned_int_var = 1;
+ unsigned long unsigned_long_var = 1L;
+
+ REQUIRE( long_var == unsigned_char_var );
+ REQUIRE( long_var == unsigned_short_var );
+ REQUIRE( long_var == unsigned_int_var );
+ REQUIRE( long_var == unsigned_long_var );
+}
+
+TEST_CASE( "comparisons between const int variables", "" )
+{
+ const unsigned char unsigned_char_var = 1;
+ const unsigned short unsigned_short_var = 1;
+ const unsigned int unsigned_int_var = 1;
+ const unsigned long unsigned_long_var = 1L;
+
+ REQUIRE( unsigned_char_var == 1 );
+ REQUIRE( unsigned_short_var == 1 );
+ REQUIRE( unsigned_int_var == 1 );
+ REQUIRE( unsigned_long_var == 1 );
+}
+
+TEST_CASE( "Comparisons between unsigned ints and negative signed ints match c++ standard behaviour", "" )
+{
+ CHECK( ( -1 > 2u ) );
+ CHECK( -1 > 2u );
+
+ CHECK( ( 2u < -1 ) );
+ CHECK( 2u < -1 );
+
+ const int minInt = (std::numeric_limits<int>::min)();
+ CHECK( ( minInt > 2u ) );
+ CHECK( minInt > 2u );
+}
+
+template<typename T>
+struct Ex
+{
+ Ex( T ){}
+
+ bool operator == ( const T& ) const { return true; }
+ T operator * ( const T& ) const { return T(); }
+};
+
+TEST_CASE( "Comparisons between ints where one side is computed", "" )
+{
+ CHECK( 54 == 6*9 );
+}
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+inline const char* returnsConstNull(){ return CATCH_NULL; }
+inline char* returnsNull(){ return CATCH_NULL; }
+
+TEST_CASE( "Pointers can be compared to null", "" )
+{
+ TestData* p = CATCH_NULL;
+ TestData* pNULL = CATCH_NULL;
+
+ REQUIRE( p == CATCH_NULL );
+ REQUIRE( p == pNULL );
+
+ TestData data;
+ p = &data;
+
+ REQUIRE( p != CATCH_NULL );
+
+ const TestData* cp = p;
+ REQUIRE( cp != CATCH_NULL );
+
+ const TestData* const cpc = p;
+ REQUIRE( cpc != CATCH_NULL );
+
+ REQUIRE( returnsNull() == CATCH_NULL );
+ REQUIRE( returnsConstNull() == CATCH_NULL );
+
+ REQUIRE( CATCH_NULL != p );
+}
+
+// Not (!) tests
+// The problem with the ! operator is that it has right-to-left associativity.
+// This means we can't isolate it when we decompose. The simple REQUIRE( !false ) form, therefore,
+// cannot have the operand value extracted. The test will work correctly, and the situation
+// is detected and a warning issued.
+// An alternative form of the macros (CHECK_FALSE and REQUIRE_FALSE) can be used instead to capture
+// the operand value.
+TEST_CASE( "'Not' checks that should succeed", "" )
+{
+ bool falseValue = false;
+
+ REQUIRE( false == false );
+ REQUIRE( true == true );
+ REQUIRE( !false );
+ REQUIRE_FALSE( false );
+
+ REQUIRE( !falseValue );
+ REQUIRE_FALSE( falseValue );
+
+ REQUIRE( !(1 == 2) );
+ REQUIRE_FALSE( 1 == 2 );
+}
+
+TEST_CASE( "'Not' checks that should fail", "[.][failing]" )
+{
+ bool trueValue = true;
+
+ CHECK( false != false );
+ CHECK( true != true );
+ CHECK( !true );
+ CHECK_FALSE( true );
+
+ CHECK( !trueValue );
+ CHECK_FALSE( trueValue );
+
+ CHECK( !(1 == 1) );
+ CHECK_FALSE( 1 == 1 );
+}
+
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/EnumToString.cpp b/3rdparty/sol2/Catch/projects/SelfTest/EnumToString.cpp
new file mode 100644
index 00000000000..6917d8ae8a0
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/EnumToString.cpp
@@ -0,0 +1,76 @@
+#include "catch.hpp"
+
+/*
+ TODO: maybe ought to check that user-provided specialisations of
+ Catch::toString also do the right thing
+*/
+
+// Enum without user-provided stream operator
+enum Enum1 { Enum1Value0, Enum1Value1 };
+
+TEST_CASE( "toString(enum)", "[toString][enum]" ) {
+ Enum1 e0 = Enum1Value0;
+ CHECK( Catch::toString(e0) == "0" );
+ Enum1 e1 = Enum1Value1;
+ CHECK( Catch::toString(e1) == "1" );
+}
+
+// Enum with user-provided stream operator
+enum Enum2 { Enum2Value0, Enum2Value1 };
+
+inline std::ostream& operator<<( std::ostream& os, Enum2 v ) {
+ return os << "E2{" << static_cast<int>(v) << "}";
+}
+
+TEST_CASE( "toString(enum w/operator<<)", "[toString][enum]" ) {
+ Enum2 e0 = Enum2Value0;
+ CHECK( Catch::toString(e0) == "E2{0}" );
+ Enum2 e1 = Enum2Value1;
+ CHECK( Catch::toString(e1) == "E2{1}" );
+}
+
+#if defined(CATCH_CPP11_OR_GREATER)
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++98-compat"
+#endif
+
+// Enum class without user-provided stream operator
+enum class EnumClass1 { EnumClass1Value0, EnumClass1Value1 };
+
+TEST_CASE( "toString(enum class)", "[toString][enum][enumClass]" ) {
+ EnumClass1 e0 = EnumClass1::EnumClass1Value0;
+ CHECK( Catch::toString(e0) == "0" );
+ EnumClass1 e1 = EnumClass1::EnumClass1Value1;
+ CHECK( Catch::toString(e1) == "1" );
+}
+
+// Enum class with user-provided stream operator
+enum class EnumClass2 : short { EnumClass2Value0, EnumClass2Value1 };
+
+inline std::ostream& operator<<( std::ostream& os, EnumClass2 e2 ) {
+ switch( static_cast<int>( e2 ) ) {
+ case static_cast<int>( EnumClass2::EnumClass2Value0 ):
+ return os << "E2/V0";
+ case static_cast<int>( EnumClass2::EnumClass2Value1 ):
+ return os << "E2/V1";
+ default:
+ return os << "Unknown enum value " << static_cast<int>( e2 );
+ }
+}
+
+TEST_CASE( "toString(enum class w/operator<<)", "[toString][enum][enumClass]" ) {
+ EnumClass2 e0 = EnumClass2::EnumClass2Value0;
+ CHECK( Catch::toString(e0) == "E2/V0" );
+ EnumClass2 e1 = EnumClass2::EnumClass2Value1;
+ CHECK( Catch::toString(e1) == "E2/V1" );
+
+ EnumClass2 e3 = static_cast<EnumClass2>(10);
+ CHECK( Catch::toString(e3) == "Unknown enum value 10" );
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+#endif // CATCH_CPP11_OR_GREATER
+
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/ExceptionTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/ExceptionTests.cpp
new file mode 100644
index 00000000000..5ef91a1239a
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/ExceptionTests.cpp
@@ -0,0 +1,203 @@
+/*
+ * Created by Phil on 09/11/2010.
+ * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "catch.hpp"
+
+#include <string>
+#include <stdexcept>
+
+namespace
+{
+ inline int thisThrows()
+ {
+ if( Catch::alwaysTrue() )
+ throw std::domain_error( "expected exception" );
+ return 1;
+ }
+
+ int thisDoesntThrow()
+ {
+ return 0;
+ }
+}
+
+TEST_CASE( "When checked exceptions are thrown they can be expected or unexpected", "" )
+{
+ REQUIRE_THROWS_AS( thisThrows(), std::domain_error );
+ REQUIRE_NOTHROW( thisDoesntThrow() );
+ REQUIRE_THROWS( thisThrows() );
+}
+
+TEST_CASE( "Expected exceptions that don't throw or unexpected exceptions fail the test", "[.][failing]" )
+{
+ CHECK_THROWS_AS( thisThrows(), std::string );
+ CHECK_THROWS_AS( thisDoesntThrow(), std::domain_error );
+ CHECK_NOTHROW( thisThrows() );
+}
+
+TEST_CASE( "When unchecked exceptions are thrown directly they are always failures", "[.][failing]" )
+{
+ if( Catch::alwaysTrue() )
+ throw std::domain_error( "unexpected exception" );
+}
+
+TEST_CASE( "An unchecked exception reports the line of the last assertion", "[.][failing]" )
+{
+ CHECK( 1 == 1 );
+ if( Catch::alwaysTrue() )
+ throw std::domain_error( "unexpected exception" );
+}
+
+TEST_CASE( "When unchecked exceptions are thrown from sections they are always failures", "[.][failing]" )
+{
+ SECTION( "section name", "" )
+ {
+ if( Catch::alwaysTrue() )
+ throw std::domain_error( "unexpected exception" );
+ }
+}
+
+TEST_CASE( "When unchecked exceptions are thrown from functions they are always failures", "[.][failing]" )
+{
+ CHECK( thisThrows() == 0 );
+}
+
+TEST_CASE( "When unchecked exceptions are thrown during a REQUIRE the test should abort fail", "[.][failing]" )
+{
+ REQUIRE( thisThrows() == 0 );
+ FAIL( "This should never happen" );
+}
+
+TEST_CASE( "When unchecked exceptions are thrown during a CHECK the test should abort and fail", "[.][failing]" )
+{
+ CHECK( thisThrows() == 0 );
+ FAIL( "This should never happen" );
+}
+
+TEST_CASE( "When unchecked exceptions are thrown, but caught, they do not affect the test", "" )
+{
+ try
+ {
+ throw std::domain_error( "unexpected exception" );
+ }
+ catch(...)
+ {
+ }
+}
+
+class CustomException
+{
+public:
+ CustomException( const std::string& msg )
+ : m_msg( msg )
+ {}
+
+ std::string getMessage() const
+ {
+ return m_msg;
+ }
+
+private:
+ std::string m_msg;
+};
+
+class CustomStdException : public std::exception
+{
+public:
+ CustomStdException( const std::string& msg )
+ : m_msg( msg )
+ {}
+ ~CustomStdException() CATCH_NOEXCEPT {}
+
+ std::string getMessage() const
+ {
+ return m_msg;
+ }
+
+private:
+ std::string m_msg;
+};
+
+
+CATCH_TRANSLATE_EXCEPTION( CustomException& ex )
+{
+ return ex.getMessage();
+}
+
+CATCH_TRANSLATE_EXCEPTION( CustomStdException& ex )
+{
+ return ex.getMessage();
+}
+
+CATCH_TRANSLATE_EXCEPTION( double& ex )
+{
+ return Catch::toString( ex );
+}
+
+TEST_CASE("Non-std exceptions can be translated", "[.][failing]" )
+{
+ if( Catch::alwaysTrue() )
+ throw CustomException( "custom exception" );
+}
+
+TEST_CASE("Custom std-exceptions can be custom translated", "[.][failing]" )
+{
+ if( Catch::alwaysTrue() )
+ throw CustomException( "custom std exception" );
+}
+
+inline void throwCustom() {
+ if( Catch::alwaysTrue() )
+ throw CustomException( "custom exception - not std" );
+}
+
+TEST_CASE( "Custom exceptions can be translated when testing for nothrow", "[.][failing]" )
+{
+ REQUIRE_NOTHROW( throwCustom() );
+}
+
+TEST_CASE( "Custom exceptions can be translated when testing for throwing as something else", "[.][failing]" )
+{
+ REQUIRE_THROWS_AS( throwCustom(), std::exception );
+}
+
+
+TEST_CASE( "Unexpected exceptions can be translated", "[.][failing]" )
+{
+ if( Catch::alwaysTrue() )
+ throw double( 3.14 );
+}
+
+inline int thisFunctionNotImplemented( int ) {
+ CATCH_NOT_IMPLEMENTED;
+}
+
+TEST_CASE( "NotImplemented exception", "" )
+{
+ REQUIRE_THROWS( thisFunctionNotImplemented( 7 ) );
+}
+
+TEST_CASE( "Exception messages can be tested for", "" ) {
+ using namespace Catch::Matchers;
+ SECTION( "exact match" )
+ REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
+ SECTION( "different case" )
+ REQUIRE_THROWS_WITH( thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No ) );
+ SECTION( "wildcarded" ) {
+ REQUIRE_THROWS_WITH( thisThrows(), StartsWith( "expected" ) );
+ REQUIRE_THROWS_WITH( thisThrows(), EndsWith( "exception" ) );
+ REQUIRE_THROWS_WITH( thisThrows(), Contains( "except" ) );
+ REQUIRE_THROWS_WITH( thisThrows(), Contains( "exCept", Catch::CaseSensitive::No ) );
+ }
+}
+
+TEST_CASE( "Mismatching exception messages failing the test", "[.][failing]" ) {
+ REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
+ REQUIRE_THROWS_WITH( thisThrows(), "should fail" );
+ REQUIRE_THROWS_WITH( thisThrows(), "expected exception" );
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/GeneratorTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/GeneratorTests.cpp
new file mode 100644
index 00000000000..af08b1d316a
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/GeneratorTests.cpp
@@ -0,0 +1,42 @@
+/*
+ * Created by Phil on 28/01/2011.
+ * Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+// This define means we have to prefix all the CATCH macros with CATCH_
+// We're using it here to test it out
+#define CATCH_CONFIG_PREFIX_ALL
+#include "catch.hpp"
+
+inline int multiply( int a, int b )
+{
+ return a*b;
+}
+
+CATCH_TEST_CASE( "Generators over two ranges", "[generators]" )
+{
+ using namespace Catch::Generators;
+
+ int i = CATCH_GENERATE( between( 1, 5 ).then( values( 15, 20, 21 ).then( 36 ) ) );
+ int j = CATCH_GENERATE( between( 100, 107 ) );
+
+ CATCH_REQUIRE( multiply( i, 2 ) == i*2 );
+ CATCH_REQUIRE( multiply( j, 2 ) == j*2 );
+}
+
+struct IntPair { int first, second; };
+
+CATCH_TEST_CASE( "Generator over a range of pairs", "[generators]" )
+{
+ using namespace Catch::Generators;
+
+ IntPair p[] = { { 0, 1 }, { 2, 3 } };
+
+ IntPair* i = CATCH_GENERATE( between( p, &p[1] ) );
+
+ CATCH_REQUIRE( i->first == i->second-1 );
+
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/MessageTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/MessageTests.cpp
new file mode 100644
index 00000000000..87a85a82d84
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/MessageTests.cpp
@@ -0,0 +1,133 @@
+/*
+ * Created by Phil on 09/11/2010.
+ * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "catch.hpp"
+#include <iostream>
+
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+#endif
+
+TEST_CASE( "INFO and WARN do not abort tests", "[messages][.]" )
+{
+ INFO( "this is a " << "message" ); // This should output the message if a failure occurs
+ WARN( "this is a " << "warning" ); // This should always output the message but then continue
+}
+TEST_CASE( "SUCCEED counts as a test pass", "[messages]" )
+{
+ SUCCEED( "this is a " << "success" );
+}
+
+TEST_CASE( "INFO gets logged on failure", "[failing][messages][.]" )
+{
+ INFO( "this message should be logged" );
+ INFO( "so should this" );
+ int a = 2;
+ REQUIRE( a == 1 );
+}
+
+TEST_CASE( "INFO gets logged on failure, even if captured before successful assertions", "[failing][messages][.]" )
+{
+ INFO( "this message may be logged later" );
+ int a = 2;
+ CHECK( a == 2 );
+
+ INFO( "this message should be logged" );
+
+ CHECK( a == 1 );
+
+ INFO( "and this, but later" );
+
+ CHECK( a == 0 );
+
+ INFO( "but not this" );
+
+ CHECK( a == 2 );
+}
+
+TEST_CASE( "FAIL aborts the test", "[failing][messages][.]" )
+{
+ FAIL( "This is a " << "failure" ); // This should output the message and abort
+}
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+TEST_CASE( "FAIL does not require an argument", "[failing][messages][.]" )
+{
+ FAIL();
+}
+TEST_CASE( "SUCCESS does not require an argument", "[messages][.]" )
+{
+ SUCCEED();
+}
+#endif
+
+TEST_CASE( "Output from all sections is reported", "[failing][messages][.]" )
+{
+ SECTION( "one", "" )
+ {
+ FAIL( "Message from section one" );
+ }
+
+ SECTION( "two", "" )
+ {
+ FAIL( "Message from section two" );
+ }
+}
+
+TEST_CASE( "Standard output from all sections is reported", "[messages][.]" )
+{
+ SECTION( "one", "" )
+ {
+ std::cout << "Message from section one" << std::endl;
+ }
+
+ SECTION( "two", "" )
+ {
+ std::cout << "Message from section two" << std::endl;
+ }
+}
+
+TEST_CASE( "SCOPED_INFO is reset for each loop", "[messages][failing][.]" )
+{
+ for( int i=0; i<100; i++ )
+ {
+ SCOPED_INFO( "current counter " << i );
+ SCOPED_CAPTURE( i );
+ REQUIRE( i < 10 );
+ }
+}
+
+TEST_CASE( "The NO_FAIL macro reports a failure but does not fail the test", "[messages]" )
+{
+ CHECK_NOFAIL( 1 == 2 );
+}
+
+TEST_CASE( "just info", "[info][isolated info][messages]" )
+{
+ INFO( "this should never be seen" );
+}
+TEST_CASE( "just failure", "[fail][isolated info][.][messages]" )
+{
+ FAIL( "Previous info should not be seen" );
+}
+
+
+TEST_CASE( "sends information to INFO", "[.][failing]" )
+{
+ INFO( "hi" );
+ int i = 7;
+ CAPTURE( i );
+ REQUIRE( false );
+}
+
+TEST_CASE( "Pointers can be converted to strings", "[messages][.]" )
+{
+ int p;
+ WARN( "actual address of p: " << &p );
+ WARN( "toString(p): " << Catch::toString( &p ) );
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/MiscTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/MiscTests.cpp
new file mode 100644
index 00000000000..cf7f48cf313
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/MiscTests.cpp
@@ -0,0 +1,480 @@
+/*
+ * Created by Phil on 29/11/2010.
+ * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "catch.hpp"
+
+#ifdef __clang__
+# pragma clang diagnostic ignored "-Wc++98-compat"
+# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+#endif
+
+#include "../include/internal/catch_xmlwriter.hpp"
+
+#include <iostream>
+
+TEST_CASE( "random SECTION tests", "[.][sections][failing]" )
+{
+ int a = 1;
+ int b = 2;
+
+ SECTION( "s1", "doesn't equal" )
+ {
+ REQUIRE( a != b );
+ REQUIRE( b != a );
+ }
+
+ SECTION( "s2", "not equal" )
+ {
+ REQUIRE( a != b);
+ }
+}
+
+TEST_CASE( "nested SECTION tests", "[.][sections][failing]" )
+{
+ int a = 1;
+ int b = 2;
+
+ SECTION( "s1", "doesn't equal" )
+ {
+ REQUIRE( a != b );
+ REQUIRE( b != a );
+
+ SECTION( "s2", "not equal" )
+ {
+ REQUIRE( a != b);
+ }
+ }
+}
+
+TEST_CASE( "more nested SECTION tests", "[sections][failing][.]" )
+{
+ int a = 1;
+ int b = 2;
+
+ SECTION( "s1", "doesn't equal" )
+ {
+ SECTION( "s2", "equal" )
+ {
+ REQUIRE( a == b );
+ }
+
+ SECTION( "s3", "not equal" )
+ {
+ REQUIRE( a != b );
+ }
+ SECTION( "s4", "less than" )
+ {
+ REQUIRE( a < b );
+ }
+ }
+}
+
+TEST_CASE( "even more nested SECTION tests", "[sections]" )
+{
+ SECTION( "c", "" )
+ {
+ SECTION( "d (leaf)", "" )
+ {
+ SUCCEED(""); // avoid failing due to no tests
+ }
+
+ SECTION( "e (leaf)", "" )
+ {
+ SUCCEED(""); // avoid failing due to no tests
+ }
+ }
+
+ SECTION( "f (leaf)", "" )
+ {
+ SUCCEED(""); // avoid failing due to no tests
+ }
+}
+
+TEST_CASE( "looped SECTION tests", "[.][failing][sections]" )
+{
+ int a = 1;
+
+ for( int b = 0; b < 10; ++b )
+ {
+ std::ostringstream oss;
+ oss << "b is currently: " << b;
+ SECTION( "s1", oss.str() )
+ {
+ CHECK( b > a );
+ }
+ }
+}
+
+TEST_CASE( "looped tests", "[.][failing]" )
+{
+ static const int fib[] = { 1, 1, 2, 3, 5, 8, 13, 21 };
+
+ for( size_t i=0; i < sizeof(fib)/sizeof(int); ++i )
+ {
+ INFO( "Testing if fib[" << i << "] (" << fib[i] << ") is even" );
+ CHECK( ( fib[i] % 2 ) == 0 );
+ }
+}
+
+TEST_CASE( "Sends stuff to stdout and stderr", "[.]" )
+{
+ std::cout << "A string sent directly to stdout" << std::endl;
+
+ std::cerr << "A string sent directly to stderr" << std::endl;
+}
+
+inline const char* makeString( bool makeNull )
+{
+ return makeNull ? CATCH_NULL : "valid string";
+}
+
+TEST_CASE( "null strings", "" )
+{
+ REQUIRE( makeString( false ) != static_cast<char*>(CATCH_NULL));
+ REQUIRE( makeString( true ) == static_cast<char*>(CATCH_NULL));
+}
+
+
+inline bool testCheckedIf( bool flag )
+{
+ CHECKED_IF( flag )
+ return true;
+ else
+ return false;
+}
+
+TEST_CASE( "checkedIf", "" )
+{
+ REQUIRE( testCheckedIf( true ) );
+}
+
+TEST_CASE( "checkedIf, failing", "[failing][.]" )
+{
+ REQUIRE( testCheckedIf( false ) );
+}
+
+inline bool testCheckedElse( bool flag )
+{
+ CHECKED_ELSE( flag )
+ return false;
+
+ return true;
+}
+
+TEST_CASE( "checkedElse", "" )
+{
+ REQUIRE( testCheckedElse( true ) );
+}
+
+TEST_CASE( "checkedElse, failing", "[failing][.]" )
+{
+ REQUIRE( testCheckedElse( false ) );
+}
+
+TEST_CASE( "xmlentitycheck", "" )
+{
+ SECTION( "embedded xml", "<test>it should be possible to embed xml characters, such as <, \" or &, or even whole <xml>documents</xml> within an attribute</test>" )
+ {
+ SUCCEED(""); // We need this here to stop it failing due to no tests
+ }
+ SECTION( "encoded chars", "these should all be encoded: &&&\"\"\"<<<&\"<<&\"" )
+ {
+ SUCCEED(""); // We need this here to stop it failing due to no tests
+ }
+}
+
+TEST_CASE( "send a single char to INFO", "[failing][.]" )
+{
+ INFO(3);
+ REQUIRE(false);
+}
+
+TEST_CASE( "atomic if", "[failing][0]")
+{
+ size_t x = 0;
+
+ if( x )
+ REQUIRE(x > 0);
+ else
+ REQUIRE(x == 0);
+}
+
+inline const char* testStringForMatching()
+{
+ return "this string contains 'abc' as a substring";
+}
+inline const char* testStringForMatching2()
+{
+ return "some completely different text that contains one common word";
+}
+
+using namespace Catch::Matchers;
+
+TEST_CASE("String matchers", "[matchers]" )
+{
+ REQUIRE_THAT( testStringForMatching(), Contains( "string" ) );
+ CHECK_THAT( testStringForMatching(), Contains( "abc" ) );
+
+ CHECK_THAT( testStringForMatching(), StartsWith( "this" ) );
+ CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) );
+}
+
+TEST_CASE("Contains string matcher", "[.][failing][matchers]")
+{
+ CHECK_THAT( testStringForMatching(), Contains( "not there" ) );
+}
+
+TEST_CASE("StartsWith string matcher", "[.][failing][matchers]")
+{
+ CHECK_THAT( testStringForMatching(), StartsWith( "string" ) );
+}
+
+TEST_CASE("EndsWith string matcher", "[.][failing][matchers]")
+{
+ CHECK_THAT( testStringForMatching(), EndsWith( "this" ) );
+}
+
+TEST_CASE("Equals string matcher", "[.][failing][matchers]")
+{
+ CHECK_THAT( testStringForMatching(), Equals( "something else" ) );
+}
+TEST_CASE("Equals string matcher, with NULL", "[matchers]")
+{
+ REQUIRE_THAT("", Equals(CATCH_NULL));
+}
+TEST_CASE("AllOf matcher", "[matchers]")
+{
+ CHECK_THAT( testStringForMatching(), AllOf( Catch::Contains( "string" ), Catch::Contains( "abc" ) ) );
+}
+TEST_CASE("AnyOf matcher", "[matchers]")
+{
+ CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "string" ), Catch::Contains( "not there" ) ) );
+ CHECK_THAT( testStringForMatching(), AnyOf( Catch::Contains( "not there" ), Catch::Contains( "string" ) ) );
+}
+
+TEST_CASE("Equals", "[matchers]")
+{
+ CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) );
+}
+
+TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]")
+{
+ CHECK_THAT( testStringForMatching(),
+ Contains( "string" ) &&
+ Contains( "abc" ) &&
+ Contains( "substring" ) &&
+ Contains( "contains" ) );
+}
+
+TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]")
+{
+ CHECK_THAT( testStringForMatching(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
+ CHECK_THAT( testStringForMatching2(), Contains( "string" ) || Contains( "different" ) || Contains( "random" ) );
+}
+
+TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]")
+{
+ CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "substring" ) );
+}
+
+TEST_CASE("Matchers can be composed with both && and || - failing", "[matchers][operators][operator||][operator&&][.failing]")
+{
+ CHECK_THAT( testStringForMatching(), ( Contains( "string" ) || Contains( "different" ) ) && Contains( "random" ) );
+}
+
+TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]")
+{
+ CHECK_THAT( testStringForMatching(), !Contains( "different" ) );
+}
+
+TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", "[matchers][operators][not][.failing]")
+{
+ CHECK_THAT( testStringForMatching(), !Contains( "substring" ) );
+}
+
+
+inline unsigned int Factorial( unsigned int number )
+{
+// return number <= 1 ? number : Factorial(number-1)*number;
+ return number > 1 ? Factorial(number-1)*number : 1;
+}
+
+TEST_CASE( "Factorials are computed", "[factorial]" ) {
+ REQUIRE( Factorial(0) == 1 );
+ REQUIRE( Factorial(1) == 1 );
+ REQUIRE( Factorial(2) == 2 );
+ REQUIRE( Factorial(3) == 6 );
+ REQUIRE( Factorial(10) == 3628800 );
+}
+
+TEST_CASE( "An empty test with no assertions", "[empty]" )
+{
+}
+
+TEST_CASE( "Nice descriptive name", "[tag1][tag2][tag3][.]" )
+{
+ WARN( "This one ran" );
+}
+TEST_CASE( "first tag", "[tag1]" )
+{
+}
+TEST_CASE( "second tag", "[tag2]" )
+{
+}
+//
+//TEST_CASE( "spawn a new process", "[.]" )
+//{
+// // !TBD Work in progress
+// char line[200];
+// FILE* output = popen("./CatchSelfTest ./failing/matchers/StartsWith", "r");
+// while ( fgets(line, 199, output) )
+// std::cout << line;
+//}
+
+TEST_CASE( "vectors can be sized and resized", "[vector]" ) {
+
+ std::vector<int> v( 5 );
+
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 5 );
+
+ SECTION( "resizing bigger changes size and capacity", "" ) {
+ v.resize( 10 );
+
+ REQUIRE( v.size() == 10 );
+ REQUIRE( v.capacity() >= 10 );
+ }
+ SECTION( "resizing smaller changes size but not capacity", "" ) {
+ v.resize( 0 );
+
+ REQUIRE( v.size() == 0 );
+ REQUIRE( v.capacity() >= 5 );
+
+ SECTION( "We can use the 'swap trick' to reset the capacity", "" ) {
+ std::vector<int> empty;
+ empty.swap( v );
+
+ REQUIRE( v.capacity() == 0 );
+ }
+ }
+ SECTION( "reserving bigger changes capacity but not size", "" ) {
+ v.reserve( 10 );
+
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 10 );
+ }
+ SECTION( "reserving smaller does not change size or capacity", "" ) {
+ v.reserve( 0 );
+
+ REQUIRE( v.size() == 5 );
+ REQUIRE( v.capacity() >= 5 );
+ }
+}
+
+// https://github.com/philsquared/Catch/issues/166
+TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]")
+{
+ SECTION("Outer", "")
+ SECTION("Inner", "")
+ SUCCEED("that's not flying - that's failing in style");
+
+ FAIL("to infinity and beyond");
+}
+
+TEST_CASE("not allowed", "[!throws]")
+{
+ // This test case should not be included if you run with -e on the command line
+ SUCCEED( "" );
+}
+
+//TEST_CASE( "Is big endian" ) {
+// CHECK( Catch::Detail::Endianness::which() == Catch::Detail::Endianness::Little );
+//}
+
+TEST_CASE( "Tabs and newlines show in output", "[.][whitespace][failing]" ) {
+
+ // Based on issue #242
+ std::string s1 = "if ($b == 10) {\n\t\t$a\t= 20;\n}";
+ std::string s2 = "if ($b == 10) {\n\t$a = 20;\n}\n";
+ CHECK( s1 == s2 );
+}
+
+
+TEST_CASE( "toString on const wchar_t const pointer returns the string contents", "[toString]" ) {
+ const wchar_t * const s = L"wide load";
+ std::string result = Catch::toString( s );
+ CHECK( result == "\"wide load\"" );
+}
+
+TEST_CASE( "toString on const wchar_t pointer returns the string contents", "[toString]" ) {
+ const wchar_t * s = L"wide load";
+ std::string result = Catch::toString( s );
+ CHECK( result == "\"wide load\"" );
+}
+
+TEST_CASE( "toString on wchar_t const pointer returns the string contents", "[toString]" ) {
+ wchar_t * const s = const_cast<wchar_t* const>( L"wide load" );
+ std::string result = Catch::toString( s );
+ CHECK( result == "\"wide load\"" );
+}
+
+TEST_CASE( "toString on wchar_t returns the string contents", "[toString]" ) {
+ wchar_t * s = const_cast<wchar_t*>( L"wide load" );
+ std::string result = Catch::toString( s );
+ CHECK( result == "\"wide load\"" );
+}
+
+inline std::string encode( std::string const& str, Catch::XmlEncode::ForWhat forWhat = Catch::XmlEncode::ForTextNodes ) {
+ std::ostringstream oss;
+ oss << Catch::XmlEncode( str, forWhat );
+ return oss.str();
+}
+
+TEST_CASE( "XmlEncode" ) {
+ SECTION( "normal string" ) {
+ REQUIRE( encode( "normal string" ) == "normal string" );
+ }
+ SECTION( "empty string" ) {
+ REQUIRE( encode( "" ) == "" );
+ }
+ SECTION( "string with ampersand" ) {
+ REQUIRE( encode( "smith & jones" ) == "smith &amp; jones" );
+ }
+ SECTION( "string with less-than" ) {
+ REQUIRE( encode( "smith < jones" ) == "smith &lt; jones" );
+ }
+ SECTION( "string with greater-than" ) {
+ REQUIRE( encode( "smith > jones" ) == "smith > jones" );
+ REQUIRE( encode( "smith ]]> jones" ) == "smith ]]&gt; jones" );
+ }
+ SECTION( "string with quotes" ) {
+ std::string stringWithQuotes = "don't \"quote\" me on that";
+ REQUIRE( encode( stringWithQuotes ) == stringWithQuotes );
+ REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't &quot;quote&quot; me on that" );
+ }
+ SECTION( "string with control char (1)" ) {
+ REQUIRE( encode( "[\x01]" ) == "[&#x1]" );
+ }
+ SECTION( "string with control char (x7F)" ) {
+ REQUIRE( encode( "[\x7F]" ) == "[&#x7F]" );
+ }
+}
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+TEST_CASE( "long long" ) {
+ long long l = std::numeric_limits<long long>::max();
+
+ REQUIRE( l == std::numeric_limits<long long>::max() );
+}
+#endif
+
+//TEST_CASE( "Divide by Zero signal handler", "[.][sig]" ) {
+// int i = 0;
+// int x = 10/i; // This should cause the signal to fire
+// CHECK( x == 0 );
+//}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/PartTrackerTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/PartTrackerTests.cpp
new file mode 100644
index 00000000000..29256351197
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/PartTrackerTests.cpp
@@ -0,0 +1,328 @@
+/*
+ * Created by Phil on 1/10/2015.
+ * Copyright 2015 Two Blue Cubes Ltd
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#include "internal/catch_suppress_warnings.h"
+#include "internal/catch_test_case_tracker.hpp"
+
+
+namespace Catch
+{
+ class LocalContext {
+
+ public:
+ TrackerContext& operator()() const {
+ return TrackerContext::instance();
+ }
+ };
+
+} // namespace Catch
+
+inline Catch::TrackerContext& C_A_T_C_H_Context() {
+ return Catch::TrackerContext::instance();
+}
+
+// -------------------
+
+#include "catch.hpp"
+
+using namespace Catch;
+
+//inline void testCase( Catch::LocalContext const& C_A_T_C_H_Context ) {
+//
+// REQUIRE( C_A_T_C_H_Context().i() == 42 );
+//}
+
+TEST_CASE( "Tracker", "" ) {
+
+ TrackerContext ctx;
+ ctx.startRun();
+ ctx.startCycle();
+
+ ITracker& testCase = SectionTracker::acquire( ctx, "Testcase" );
+ REQUIRE( testCase.isOpen() );
+
+ ITracker& s1 = SectionTracker::acquire( ctx, "S1" );
+ REQUIRE( s1.isOpen() );
+
+ SECTION( "successfully close one section", "" ) {
+ s1.close();
+ REQUIRE( s1.isSuccessfullyCompleted() );
+ REQUIRE( testCase.isComplete() == false );
+
+ testCase.close();
+ REQUIRE( ctx.completedCycle() );
+ REQUIRE( testCase.isSuccessfullyCompleted() );
+ }
+
+ SECTION( "fail one section", "" ) {
+ s1.fail();
+ REQUIRE( s1.isComplete() );
+ REQUIRE( s1.isSuccessfullyCompleted() == false );
+ REQUIRE( testCase.isComplete() == false );
+
+ testCase.close();
+ REQUIRE( ctx.completedCycle() );
+ REQUIRE( testCase.isSuccessfullyCompleted() == false );
+
+ SECTION( "re-enter after failed section", "" ) {
+ ctx.startCycle();
+ ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+ REQUIRE( testCase2.isOpen() );
+
+ ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+ REQUIRE( s1b.isOpen() == false );
+
+ testCase2.close();
+ REQUIRE( ctx.completedCycle() );
+ REQUIRE( testCase.isComplete() );
+ REQUIRE( testCase.isSuccessfullyCompleted() );
+ }
+ SECTION( "re-enter after failed section and find next section", "" ) {
+ ctx.startCycle();
+ ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+ REQUIRE( testCase2.isOpen() );
+
+ ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+ REQUIRE( s1b.isOpen() == false );
+
+ ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
+ REQUIRE( s2.isOpen() );
+
+ s2.close();
+ REQUIRE( ctx.completedCycle() );
+
+ testCase2.close();
+ REQUIRE( testCase.isComplete() );
+ REQUIRE( testCase.isSuccessfullyCompleted() );
+ }
+ }
+
+ SECTION( "successfully close one section, then find another", "" ) {
+ s1.close();
+
+ ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
+ REQUIRE( s2.isOpen() == false );
+
+ testCase.close();
+ REQUIRE( testCase.isComplete() == false );
+
+ SECTION( "Re-enter - skips S1 and enters S2", "" ) {
+ ctx.startCycle();
+ ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+ REQUIRE( testCase2.isOpen() );
+
+ ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+ REQUIRE( s1b.isOpen() == false );
+
+ ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
+ REQUIRE( s2b.isOpen() );
+
+ REQUIRE( ctx.completedCycle() == false );
+
+ SECTION ("Successfully close S2") {
+ s2b.close();
+ REQUIRE( ctx.completedCycle() );
+
+ REQUIRE( s2b.isSuccessfullyCompleted() );
+ REQUIRE( testCase2.isComplete() == false );
+
+ testCase2.close();
+ REQUIRE( testCase2.isSuccessfullyCompleted() );
+ }
+ SECTION ("fail S2") {
+ s2b.fail();
+ REQUIRE( ctx.completedCycle() );
+
+ REQUIRE( s2b.isComplete() );
+ REQUIRE( s2b.isSuccessfullyCompleted() == false );
+
+ testCase2.close();
+ REQUIRE( testCase2.isSuccessfullyCompleted() == false );
+
+ // Need a final cycle
+ ctx.startCycle();
+ ITracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" );
+ REQUIRE( testCase3.isOpen() );
+
+ ITracker& s1c = SectionTracker::acquire( ctx, "S1" );
+ REQUIRE( s1c.isOpen() == false );
+
+ ITracker& s2c = SectionTracker::acquire( ctx, "S2" );
+ REQUIRE( s2c.isOpen() == false );
+
+ testCase3.close();
+ REQUIRE( testCase3.isSuccessfullyCompleted() );
+ }
+ }
+ }
+
+ SECTION( "open a nested section", "" ) {
+ ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
+ REQUIRE( s2.isOpen() );
+
+ s2.close();
+ REQUIRE( s2.isComplete() );
+ REQUIRE( s1.isComplete() == false );
+
+ s1.close();
+ REQUIRE( s1.isComplete() );
+ REQUIRE( testCase.isComplete() == false );
+
+ testCase.close();
+ REQUIRE( testCase.isComplete() );
+ }
+
+ SECTION( "start a generator", "" ) {
+ IndexTracker& g1 = IndexTracker::acquire( ctx, "G1", 2 );
+ REQUIRE( g1.isOpen() );
+ REQUIRE( g1.index() == 0 );
+
+ REQUIRE( g1.isComplete() == false );
+ REQUIRE( s1.isComplete() == false );
+
+ SECTION( "close outer section" )
+ {
+ s1.close();
+ REQUIRE( s1.isComplete() == false );
+ testCase.close();
+ REQUIRE( testCase.isSuccessfullyCompleted() == false );
+
+ SECTION( "Re-enter for second generation", "" ) {
+ ctx.startCycle();
+ ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+ REQUIRE( testCase2.isOpen() );
+
+ ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+ REQUIRE( s1b.isOpen() );
+
+
+ IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
+ REQUIRE( g1b.isOpen() );
+ REQUIRE( g1b.index() == 1 );
+
+ REQUIRE( s1.isComplete() == false );
+
+ s1b.close();
+ REQUIRE( s1b.isComplete() );
+ REQUIRE( g1b.isComplete() );
+ testCase2.close();
+ REQUIRE( testCase2.isComplete() );
+ }
+ }
+ SECTION( "Start a new inner section", "" ) {
+ ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
+ REQUIRE( s2.isOpen() );
+
+ s2.close();
+ REQUIRE( s2.isComplete() );
+
+ s1.close();
+ REQUIRE( s1.isComplete() == false );
+
+ testCase.close();
+ REQUIRE( testCase.isComplete() == false );
+
+ SECTION( "Re-enter for second generation", "" ) {
+ ctx.startCycle();
+ ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+ REQUIRE( testCase2.isOpen() );
+
+ ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+ REQUIRE( s1b.isOpen() );
+
+ // generator - next value
+ IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
+ REQUIRE( g1b.isOpen() );
+ REQUIRE( g1b.index() == 1 );
+
+ // inner section again
+ ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
+ REQUIRE( s2b.isOpen() );
+
+ s2b.close();
+ REQUIRE( s2b.isComplete() );
+
+ s1b.close();
+ REQUIRE( g1b.isComplete() );
+ REQUIRE( s1b.isComplete() );
+
+ testCase2.close();
+ REQUIRE( testCase2.isComplete() );
+ }
+ }
+
+ SECTION( "Fail an inner section", "" ) {
+ ITracker& s2 = SectionTracker::acquire( ctx, "S2" );
+ REQUIRE( s2.isOpen() );
+
+ s2.fail();
+ REQUIRE( s2.isComplete() );
+ REQUIRE( s2.isSuccessfullyCompleted() == false );
+
+ s1.close();
+ REQUIRE( s1.isComplete() == false );
+
+ testCase.close();
+ REQUIRE( testCase.isComplete() == false );
+
+ SECTION( "Re-enter for second generation", "" ) {
+ ctx.startCycle();
+ ITracker& testCase2 = SectionTracker::acquire( ctx, "Testcase" );
+ REQUIRE( testCase2.isOpen() );
+
+ ITracker& s1b = SectionTracker::acquire( ctx, "S1" );
+ REQUIRE( s1b.isOpen() );
+
+ // generator - still same value
+ IndexTracker& g1b = IndexTracker::acquire( ctx, "G1", 2 );
+ REQUIRE( g1b.isOpen() );
+ REQUIRE( g1b.index() == 0 );
+
+ // inner section again - this time won't open
+ ITracker& s2b = SectionTracker::acquire( ctx, "S2" );
+ REQUIRE( s2b.isOpen() == false );
+
+ s1b.close();
+ REQUIRE( g1b.isComplete() == false );
+ REQUIRE( s1b.isComplete() == false );
+
+ testCase2.close();
+ REQUIRE( testCase2.isComplete() == false );
+
+ // Another cycle - now should complete
+ ctx.startCycle();
+ ITracker& testCase3 = SectionTracker::acquire( ctx, "Testcase" );
+ REQUIRE( testCase3.isOpen() );
+
+ ITracker& s1c = SectionTracker::acquire( ctx, "S1" );
+ REQUIRE( s1c.isOpen() );
+
+ // generator - now next value
+ IndexTracker& g1c = IndexTracker::acquire( ctx, "G1", 2 );
+ REQUIRE( g1c.isOpen() );
+ REQUIRE( g1c.index() == 1 );
+
+ // inner section - now should open again
+ ITracker& s2c = SectionTracker::acquire( ctx, "S2" );
+ REQUIRE( s2c.isOpen() );
+
+ s2c.close();
+ REQUIRE( s2c.isComplete() );
+
+ s1c.close();
+ REQUIRE( g1c.isComplete() );
+ REQUIRE( s1c.isComplete() );
+
+ testCase3.close();
+ REQUIRE( testCase3.isComplete() );
+ }
+ }
+ // !TBD"
+ // nested generator
+ // two sections within a generator
+ }
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_common.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_common.cpp
new file mode 100644
index 00000000000..72f90bd6aa5
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_common.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_common.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_console_colour.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_console_colour.cpp
new file mode 100644
index 00000000000..e7378c04ad7
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_console_colour.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_console_colour.hpp"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_debugger.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_debugger.cpp
new file mode 100644
index 00000000000..33f76ae6f9e
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_debugger.cpp
@@ -0,0 +1,2 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_debugger.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_capture.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_capture.cpp
new file mode 100644
index 00000000000..2d1c8f35462
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_capture.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_interfaces_capture.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_config.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_config.cpp
new file mode 100644
index 00000000000..de0f18d3793
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_config.cpp
@@ -0,0 +1,2 @@
+#include "catch_suppress_warnings.h"
+#include "catch_interfaces_config.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_exception.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_exception.cpp
new file mode 100644
index 00000000000..183d87d9aa4
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_exception.cpp
@@ -0,0 +1,2 @@
+#include "catch_suppress_warnings.h"
+#include "catch_interfaces_exception.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_generators.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_generators.cpp
new file mode 100644
index 00000000000..271b1bcc3a4
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_generators.cpp
@@ -0,0 +1 @@
+#include "catch_interfaces_generators.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_registry_hub.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_registry_hub.cpp
new file mode 100644
index 00000000000..ffece3b4317
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_registry_hub.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_interfaces_registry_hub.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_reporter.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_reporter.cpp
new file mode 100644
index 00000000000..544f9d0f081
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_reporter.cpp
@@ -0,0 +1,2 @@
+#include "catch_suppress_warnings.h"
+#include "catch_interfaces_reporter.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_runner.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_runner.cpp
new file mode 100644
index 00000000000..401de26251a
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_runner.cpp
@@ -0,0 +1 @@
+#include "catch_interfaces_runner.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_testcase.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_testcase.cpp
new file mode 100644
index 00000000000..733dcb4e547
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_interfaces_testcase.cpp
@@ -0,0 +1,2 @@
+#include "catch_suppress_warnings.h"
+#include "catch_interfaces_testcase.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_message.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_message.cpp
new file mode 100644
index 00000000000..ad2f5e77a1e
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_message.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_message.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_option.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_option.cpp
new file mode 100644
index 00000000000..35e3282901c
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_option.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_option.hpp"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_ptr.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_ptr.cpp
new file mode 100644
index 00000000000..a25ad66dfc2
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_ptr.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_ptr.hpp"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_stream.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_stream.cpp
new file mode 100644
index 00000000000..7aaffa1e709
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_stream.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_stream.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_streambuf.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_streambuf.cpp
new file mode 100644
index 00000000000..5c0043c2d8a
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_streambuf.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_streambuf.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp
new file mode 100644
index 00000000000..46bf89f681c
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_test_spec.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_test_spec.hpp"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_xmlwriter.cpp b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_xmlwriter.cpp
new file mode 100644
index 00000000000..15328efe74a
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/SurrogateCpps/catch_xmlwriter.cpp
@@ -0,0 +1,4 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_xmlwriter.hpp"
+#include "catch_reenable_warnings.h"
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/TagAliasTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/TagAliasTests.cpp
new file mode 100644
index 00000000000..002a93c04e9
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/TagAliasTests.cpp
@@ -0,0 +1,41 @@
+/*
+ * Created by Phil on 27/06/2014.
+ * Copyright 2014 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "catch.hpp"
+#include "internal/catch_tag_alias_registry.h"
+
+TEST_CASE( "Tag alias can be registered against tag patterns", "" ) {
+
+ using namespace Catch::Matchers;
+
+ Catch::TagAliasRegistry registry;
+
+ registry.add( "[@zzz]", "[one][two]", Catch::SourceLineInfo( "file", 2 ) );
+
+ SECTION( "The same tag alias can only be registered once", "" ) {
+
+ try {
+ registry.add( "[@zzz]", "[one][two]", Catch::SourceLineInfo( "file", 10 ) );
+ FAIL( "expected exception" );
+ }
+ catch( std::exception& ex ) {
+ std::string what = ex.what();
+ CHECK_THAT( what, Contains( "[@zzz]" ) );
+ CHECK_THAT( what, Contains( "file" ) );
+ CHECK_THAT( what, Contains( "2" ) );
+ CHECK_THAT( what, Contains( "10" ) );
+ }
+ }
+
+ SECTION( "Tag aliases must be of the form [@name]", "" ) {
+ CHECK_THROWS( registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) ) );
+ CHECK_THROWS( registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) );
+ CHECK_THROWS( registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) );
+ CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) );
+ }
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/TestMain.cpp b/3rdparty/sol2/Catch/projects/SelfTest/TestMain.cpp
new file mode 100644
index 00000000000..1713b51aad1
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/TestMain.cpp
@@ -0,0 +1,461 @@
+/*
+ * Created by Phil on 22/10/2010.
+ * Copyright 2010 Two Blue Cubes Ltd
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#define CATCH_CONFIG_MAIN
+#include "catch.hpp"
+#include "../include/reporters/catch_reporter_teamcity.hpp"
+
+// Some example tag aliases
+CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
+CATCH_REGISTER_TAG_ALIAS( "[@tricky]", "[tricky]~[.]" )
+
+
+#ifdef __clang__
+# pragma clang diagnostic ignored "-Wpadded"
+# pragma clang diagnostic ignored "-Wweak-vtables"
+# pragma clang diagnostic ignored "-Wc++98-compat"
+#endif
+
+
+template<size_t size>
+void parseIntoConfig( const char * (&argv)[size], Catch::ConfigData& config ) {
+ Catch::Clara::CommandLine<Catch::ConfigData> parser = Catch::makeCommandLineParser();
+ parser.parseInto( size, argv, config );
+}
+
+template<size_t size>
+std::string parseIntoConfigAndReturnError( const char * (&argv)[size], Catch::ConfigData& config ) {
+ try {
+ parseIntoConfig( argv, config );
+ FAIL( "expected exception" );
+ }
+ catch( std::exception& ex ) {
+ return ex.what();
+ }
+ return "";
+}
+
+inline Catch::TestCase fakeTestCase( const char* name, const char* desc = "" ){ return Catch::makeTestCase( CATCH_NULL, "", name, desc, CATCH_INTERNAL_LINEINFO ); }
+
+TEST_CASE( "Process can be configured on command line", "[config][command-line]" ) {
+
+ using namespace Catch::Matchers;
+
+ Catch::ConfigData config;
+
+ SECTION( "default - no arguments", "" ) {
+ const char* argv[] = { "test" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ CHECK( config.shouldDebugBreak == false );
+ CHECK( config.abortAfter == -1 );
+ CHECK( config.noThrow == false );
+ CHECK( config.reporterNames.empty() );
+ }
+
+ SECTION( "test lists", "" ) {
+ SECTION( "1 test", "Specify one test case using" ) {
+ const char* argv[] = { "test", "test1" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ Catch::Config cfg( config );
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false );
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) );
+ }
+ SECTION( "Specify one test case exclusion using exclude:", "" ) {
+ const char* argv[] = { "test", "exclude:test1" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ Catch::Config cfg( config );
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false );
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) );
+ }
+
+ SECTION( "Specify one test case exclusion using ~", "" ) {
+ const char* argv[] = { "test", "~test1" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ Catch::Config cfg( config );
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false );
+ REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) );
+ }
+
+ }
+
+ SECTION( "reporter", "" ) {
+ SECTION( "-r/console", "" ) {
+ const char* argv[] = { "test", "-r", "console" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.reporterNames[0] == "console" );
+ }
+ SECTION( "-r/xml", "" ) {
+ const char* argv[] = { "test", "-r", "xml" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.reporterNames[0] == "xml" );
+ }
+ SECTION( "-r xml and junit", "" ) {
+ const char* argv[] = { "test", "-r", "xml", "-r", "junit" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.reporterNames.size() == 2 );
+ REQUIRE( config.reporterNames[0] == "xml" );
+ REQUIRE( config.reporterNames[1] == "junit" );
+ }
+ SECTION( "--reporter/junit", "" ) {
+ const char* argv[] = { "test", "--reporter", "junit" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.reporterNames[0] == "junit" );
+ }
+ }
+
+ SECTION( "debugger", "" ) {
+ SECTION( "-b", "" ) {
+ const char* argv[] = { "test", "-b" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.shouldDebugBreak == true );
+ }
+ SECTION( "--break", "" ) {
+ const char* argv[] = { "test", "--break" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.shouldDebugBreak );
+ }
+ }
+
+ SECTION( "abort", "" ) {
+ SECTION( "-a aborts after first failure", "" ) {
+ const char* argv[] = { "test", "-a" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.abortAfter == 1 );
+ }
+ SECTION( "-x 2 aborts after two failures", "" ) {
+ const char* argv[] = { "test", "-x", "2" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.abortAfter == 2 );
+ }
+ SECTION( "-x must be greater than zero", "" ) {
+ const char* argv[] = { "test", "-x", "0" };
+ REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "greater than zero" ) );
+ }
+ SECTION( "-x must be numeric", "" ) {
+ const char* argv[] = { "test", "-x", "oops" };
+ REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) );
+ }
+ }
+
+ SECTION( "nothrow", "" ) {
+ SECTION( "-e", "" ) {
+ const char* argv[] = { "test", "-e" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.noThrow == true );
+ }
+ SECTION( "--nothrow", "" ) {
+ const char* argv[] = { "test", "--nothrow" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.noThrow == true );
+ }
+ }
+
+ SECTION( "output filename", "" ) {
+ SECTION( "-o filename", "" ) {
+ const char* argv[] = { "test", "-o", "filename.ext" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.outputFilename == "filename.ext" );
+ }
+ SECTION( "--out", "" ) {
+ const char* argv[] = { "test", "--out", "filename.ext" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.outputFilename == "filename.ext" );
+ }
+ }
+
+ SECTION( "combinations", "" ) {
+ SECTION( "Single character flags can be combined", "" ) {
+ const char* argv[] = { "test", "-abe" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ CHECK( config.abortAfter == 1 );
+ CHECK( config.shouldDebugBreak );
+ CHECK( config.noThrow == true );
+ }
+ }
+
+ SECTION( "force-colour", "") {
+ SECTION( "--force-colour", "" ) {
+ const char* argv[] = { "test", "--force-colour" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( config.forceColour );
+ }
+
+ SECTION( "without --force-colour", "" ) {
+ const char* argv[] = { "test" };
+ CHECK_NOTHROW( parseIntoConfig( argv, config ) );
+
+ REQUIRE( !config.forceColour );
+ }
+ }
+}
+
+
+TEST_CASE( "Long strings can be wrapped", "[wrap]" ) {
+
+ using namespace Catch;
+ SECTION( "plain string", "" ) {
+ // guide: 123456789012345678
+ std::string testString = "one two three four";
+
+ SECTION( "No wrapping", "" ) {
+ CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
+ CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString );
+ }
+ SECTION( "Wrapped once", "" ) {
+ CHECK( Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" );
+ CHECK( Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" );
+ CHECK( Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" );
+ CHECK( Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" );
+ CHECK( Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" );
+ }
+ SECTION( "Wrapped twice", "" ) {
+ CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" );
+ CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" );
+ CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" );
+ }
+ SECTION( "Wrapped three times", "" ) {
+ CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" );
+ CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" );
+ }
+ SECTION( "Short wrap", "" ) {
+ CHECK( Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" );
+ CHECK( Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" );
+ CHECK( Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" );
+
+ CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" );
+ CHECK( Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" );
+ }
+ SECTION( "As container", "" ) {
+ Text text( testString, TextAttributes().setWidth( 6 ) );
+ REQUIRE( text.size() == 4 );
+ CHECK( text[0] == "one" );
+ CHECK( text[1] == "two" );
+ CHECK( text[2] == "three" );
+ CHECK( text[3] == "four" );
+ }
+ SECTION( "Indent first line differently", "" ) {
+ Text text( testString, TextAttributes()
+ .setWidth( 10 )
+ .setIndent( 4 )
+ .setInitialIndent( 1 ) );
+ CHECK( text.toString() == " one two\n three\n four" );
+ }
+
+ }
+
+ SECTION( "With newlines", "" ) {
+
+ // guide: 1234567890123456789
+ std::string testString = "one two\nthree four";
+
+ SECTION( "No wrapping" , "" ) {
+ CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString );
+ CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString );
+ CHECK( Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString );
+ }
+ SECTION( "Trailing newline" , "" ) {
+ CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef\n" );
+ CHECK( Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" );
+ CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef\n" );
+ }
+ SECTION( "Wrapped once", "" ) {
+ CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" );
+ CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" );
+ CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" );
+ }
+ SECTION( "Wrapped twice", "" ) {
+ CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" );
+ }
+ }
+
+ SECTION( "With tabs", "" ) {
+
+ // guide: 1234567890123456789
+ std::string testString = "one two \tthree four five six";
+
+ CHECK( Text( testString, TextAttributes().setWidth( 15 ) ).toString()
+ == "one two three\n four\n five\n six" );
+ }
+
+
+}
+
+using namespace Catch;
+
+class ColourString {
+public:
+
+ struct ColourIndex {
+ ColourIndex( Colour::Code _colour, std::size_t _fromIndex, std::size_t _toIndex )
+ : colour( _colour ),
+ fromIndex( _fromIndex ),
+ toIndex( _toIndex )
+ {}
+
+ Colour::Code colour;
+ std::size_t fromIndex;
+ std::size_t toIndex;
+ };
+
+ ColourString( std::string const& _string )
+ : string( _string )
+ {}
+ ColourString( std::string const& _string, std::vector<ColourIndex> const& _colours )
+ : string( _string ), colours( _colours )
+ {}
+
+ ColourString& addColour( Colour::Code colour, int _index ) {
+ colours.push_back( ColourIndex( colour,
+ resolveRelativeIndex( _index ),
+ resolveRelativeIndex( _index )+1 ) );
+ return *this;
+ }
+ ColourString& addColour( Colour::Code colour, int _fromIndex, int _toIndex ) {
+ colours.push_back( ColourIndex( colour,
+ resolveRelativeIndex(_fromIndex),
+ resolveLastRelativeIndex( _toIndex ) ) );
+ return *this;
+ }
+
+ void writeToStream( std::ostream& _stream ) const {
+ std::size_t last = 0;
+ for( std::size_t i = 0; i < colours.size(); ++i ) {
+ ColourIndex const& index = colours[i];
+ if( index.fromIndex > last )
+ _stream << string.substr( last, index.fromIndex-last );
+ {
+ Colour colourGuard( index.colour );
+ _stream << string.substr( index.fromIndex, index.toIndex-index.fromIndex );
+ }
+ last = index.toIndex;
+ }
+ if( last < string.size() )
+ _stream << string.substr( last );
+ }
+ friend std::ostream& operator << ( std::ostream& _stream, ColourString const& _colourString ) {
+ _colourString.writeToStream( _stream );
+ return _stream;
+ }
+
+private:
+
+ std::size_t resolveLastRelativeIndex( int _index ) {
+ std::size_t index = resolveRelativeIndex( _index );
+ return index == 0 ? string.size() : index;
+ }
+ std::size_t resolveRelativeIndex( int _index ) {
+ return static_cast<std::size_t>( _index >= 0
+ ? _index
+ : static_cast<int>( string.size() )+_index );
+ }
+ std::string string;
+ std::vector<ColourIndex> colours;
+};
+
+TEST_CASE( "replaceInPlace", "" ) {
+ std::string letters = "abcdefcg";
+ SECTION( "replace single char" ) {
+ CHECK( replaceInPlace( letters, "b", "z" ) );
+ CHECK( letters == "azcdefcg" );
+ }
+ SECTION( "replace two chars" ) {
+ CHECK( replaceInPlace( letters, "c", "z" ) );
+ CHECK( letters == "abzdefzg" );
+ }
+ SECTION( "replace first char" ) {
+ CHECK( replaceInPlace( letters, "a", "z" ) );
+ CHECK( letters == "zbcdefcg" );
+ }
+ SECTION( "replace last char" ) {
+ CHECK( replaceInPlace( letters, "g", "z" ) );
+ CHECK( letters == "abcdefcz" );
+ }
+ SECTION( "replace all chars" ) {
+ CHECK( replaceInPlace( letters, letters, "replaced" ) );
+ CHECK( letters == "replaced" );
+ }
+ SECTION( "replace no chars" ) {
+ CHECK_FALSE( replaceInPlace( letters, "x", "z" ) );
+ CHECK( letters == letters );
+ }
+ SECTION( "escape '" ) {
+ std::string s = "didn't";
+ CHECK( replaceInPlace( s, "'", "|'" ) );
+ CHECK( s == "didn|'t" );
+ }
+}
+
+// !TBD: This will be folded into Text class
+TEST_CASE( "Strings can be rendered with colour", "[.colour]" ) {
+
+ {
+ ColourString cs( "hello" );
+ cs .addColour( Colour::Red, 0 )
+ .addColour( Colour::Green, -1 );
+
+ Catch::cout() << cs << std::endl;
+ }
+
+ {
+ ColourString cs( "hello" );
+ cs .addColour( Colour::Blue, 1, -2 );
+
+ Catch::cout() << cs << std::endl;
+ }
+
+}
+
+TEST_CASE( "Text can be formatted using the Text class", "" ) {
+
+ CHECK( Text( "hi there" ).toString() == "hi there" );
+
+ TextAttributes narrow;
+ narrow.setWidth( 6 );
+
+ CHECK( Text( "hi there", narrow ).toString() == "hi\nthere" );
+}
+
+TEST_CASE( "Long text is truncted", "[Text][Truncated]" ) {
+
+ std::string longLine( 90, '*' );
+
+ std::ostringstream oss;
+ for(int i = 0; i < 600; ++i )
+ oss << longLine << longLine << "\n";
+ Text t( oss.str() );
+ CHECK_THAT( t.toString(), EndsWith( "... message truncated due to excessive size" ) );
+
+}
+
+inline void manuallyRegisteredTestFunction() {
+ SUCCEED( "was called" );
+}
+struct AutoTestReg {
+ AutoTestReg() {
+ REGISTER_TEST_CASE( manuallyRegisteredTestFunction, "ManuallyRegistered", "" );
+ }
+};
+AutoTestReg autoTestReg;
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/ToStringPair.cpp b/3rdparty/sol2/Catch/projects/SelfTest/ToStringPair.cpp
new file mode 100644
index 00000000000..8f51070069b
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/ToStringPair.cpp
@@ -0,0 +1,47 @@
+#include "catch.hpp"
+
+// === Pair ===
+namespace Catch {
+ // Note: If we put this in the right place in catch_tostring, then
+ // we can make it an overload of Catch::toString
+ template<typename T1, typename T2>
+ struct StringMaker<std::pair<T1,T2> > {
+ static std::string convert( const std::pair<T1,T2>& pair ) {
+ std::ostringstream oss;
+ oss << "{ "
+ << toString( pair.first )
+ << ", "
+ << toString( pair.second )
+ << " }";
+ return oss.str();
+ }
+ };
+}
+
+TEST_CASE( "std::pair<int,std::string> -> toString", "[toString][pair]" ) {
+ std::pair<int,std::string> value( 34, "xyzzy" );
+ REQUIRE( Catch::toString( value ) == "{ 34, \"xyzzy\" }" );
+}
+
+TEST_CASE( "std::pair<int,const std::string> -> toString", "[toString][pair]" ) {
+ std::pair<int,const std::string> value( 34, "xyzzy" );
+ REQUIRE( Catch::toString(value) == "{ 34, \"xyzzy\" }" );
+}
+
+TEST_CASE( "std::vector<std::pair<std::string,int> > -> toString", "[toString][pair]" ) {
+ std::vector<std::pair<std::string,int> > pr;
+ pr.push_back( std::make_pair("green", 55 ) );
+ REQUIRE( Catch::toString( pr ) == "{ { \"green\", 55 } }" );
+}
+
+// This is pretty contrived - I figure if this works, anything will...
+TEST_CASE( "pair<pair<int,const char *,pair<std::string,int> > -> toString", "[toString][pair]" ) {
+ typedef std::pair<int,const char *> left_t;
+ typedef std::pair<std::string,int> right_t;
+
+ left_t left( 42, "Arthur" );
+ right_t right( "Ford", 24 );
+
+ std::pair<left_t,right_t> pair( left, right );
+ REQUIRE( Catch::toString( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }" );
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/ToStringTuple.cpp b/3rdparty/sol2/Catch/projects/SelfTest/ToStringTuple.cpp
new file mode 100644
index 00000000000..80e5453097a
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/ToStringTuple.cpp
@@ -0,0 +1,59 @@
+#include "catch.hpp"
+
+#ifdef CATCH_CPP11_OR_GREATER
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++98-compat"
+#endif
+
+TEST_CASE( "tuple<>", "[toString][tuple]" )
+{
+ typedef std::tuple<> type;
+ CHECK( "{ }" == Catch::toString(type{}) );
+ type value {};
+ CHECK( "{ }" == Catch::toString(value) );
+}
+
+TEST_CASE( "tuple<int>", "[toString][tuple]" )
+{
+ typedef std::tuple<int> type;
+ CHECK( "{ 0 }" == Catch::toString(type{0}) );
+}
+
+
+TEST_CASE( "tuple<float,int>", "[toString][tuple]" )
+{
+ typedef std::tuple<float,int> type;
+ CHECK( "1.2f" == Catch::toString(float(1.2)) );
+ CHECK( "{ 1.2f, 0 }" == Catch::toString(type{1.2,0}) );
+}
+
+TEST_CASE( "tuple<string,string>", "[toString][tuple]" )
+{
+ typedef std::tuple<std::string,std::string> type;
+ CHECK( "{ \"hello\", \"world\" }" == Catch::toString(type{"hello","world"}) );
+}
+
+TEST_CASE( "tuple<tuple<int>,tuple<>,float>", "[toString][tuple]" )
+{
+ typedef std::tuple<std::tuple<int>,std::tuple<>,float> type;
+ type value { std::tuple<int>{42}, {}, 1.2f };
+ CHECK( "{ { 42 }, { }, 1.2f }" == Catch::toString(value) );
+}
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+TEST_CASE( "tuple<nullptr,int,const char *>", "[toString][tuple]" )
+{
+ typedef std::tuple<std::nullptr_t,int,const char *> type;
+ type value { nullptr, 42, "Catch me" };
+ CHECK( "{ nullptr, 42, \"Catch me\" }" == Catch::toString(value) );
+}
+#endif
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif /* #ifdef CATCH_CPP11_OR_GREATER */
+
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/ToStringVector.cpp b/3rdparty/sol2/Catch/projects/SelfTest/ToStringVector.cpp
new file mode 100644
index 00000000000..c3a8d4ed647
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/ToStringVector.cpp
@@ -0,0 +1,77 @@
+#include "catch.hpp"
+#include <vector>
+
+
+// vedctor
+TEST_CASE( "vector<int> -> toString", "[toString][vector]" )
+{
+ std::vector<int> vv;
+ REQUIRE( Catch::toString(vv) == "{ }" );
+ vv.push_back( 42 );
+ REQUIRE( Catch::toString(vv) == "{ 42 }" );
+ vv.push_back( 250 );
+ REQUIRE( Catch::toString(vv) == "{ 42, 250 }" );
+}
+
+TEST_CASE( "vector<string> -> toString", "[toString][vector]" )
+{
+ std::vector<std::string> vv;
+ REQUIRE( Catch::toString(vv) == "{ }" );
+ vv.push_back( "hello" );
+ REQUIRE( Catch::toString(vv) == "{ \"hello\" }" );
+ vv.push_back( "world" );
+ REQUIRE( Catch::toString(vv) == "{ \"hello\", \"world\" }" );
+}
+
+#if defined(CATCH_CPP11_OR_GREATER)
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++98-compat"
+#endif
+
+/*
+ Note: These tests *can* be made to work with C++ < 11, but the
+ allocator is a lot more work...
+*/
+namespace {
+ /* Minimal Allocator */
+ template<typename T>
+ struct minimal_allocator {
+ typedef T value_type;
+ typedef std::size_t size_type;
+ T *allocate( size_type n ) {
+ return static_cast<T *>( ::operator new( n * sizeof(T) ) );
+ }
+ void deallocate( T *p, size_type /*n*/ ) {
+ ::operator delete( static_cast<void *>(p) );
+ }
+ template<typename U>
+ bool operator==( const minimal_allocator<U>& ) const { return true; }
+ template<typename U>
+ bool operator!=( const minimal_allocator<U>& ) const { return false; }
+ };
+}
+
+TEST_CASE( "vector<int,allocator> -> toString", "[toString][vector,allocator]" ) {
+ std::vector<int,minimal_allocator<int> > vv;
+ REQUIRE( Catch::toString(vv) == "{ }" );
+ vv.push_back( 42 );
+ REQUIRE( Catch::toString(vv) == "{ 42 }" );
+ vv.push_back( 250 );
+ REQUIRE( Catch::toString(vv) == "{ 42, 250 }" );
+}
+
+TEST_CASE( "vec<vec<string,alloc>> -> toString", "[toString][vector,allocator]" ) {
+ typedef std::vector<std::string,minimal_allocator<std::string> > inner;
+ typedef std::vector<inner> vector;
+ vector v;
+ REQUIRE( Catch::toString(v) == "{ }" );
+ v.push_back( inner { "hello" } );
+ v.push_back( inner { "world" } );
+ REQUIRE( Catch::toString(v) == "{ { \"hello\" }, { \"world\" } }" );
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+#endif // CATCH_CPP11_OR_GREATER
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/ToStringWhich.cpp b/3rdparty/sol2/Catch/projects/SelfTest/ToStringWhich.cpp
new file mode 100644
index 00000000000..1d4aa892581
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/ToStringWhich.cpp
@@ -0,0 +1,68 @@
+#include "catch.hpp"
+/*
+ Demonstrate which version of toString/StringMaker is being used
+ for various types
+*/
+
+
+struct has_toString { };
+struct has_maker {};
+struct has_maker_and_toString {};
+
+namespace Catch {
+ inline std::string toString( const has_toString& ) {
+ return "toString( has_toString )";
+ }
+ inline std::string toString( const has_maker_and_toString& ) {
+ return "toString( has_maker_and_toString )";
+ }
+ template<>
+ struct StringMaker<has_maker> {
+ static std::string convert( const has_maker& ) {
+ return "StringMaker<has_maker>";
+ }
+ };
+ template<>
+ struct StringMaker<has_maker_and_toString> {
+ static std::string convert( const has_maker_and_toString& ) {
+ return "StringMaker<has_maker_and_toString>";
+ }
+ };
+}
+
+// Call the overload
+TEST_CASE( "toString( has_toString )", "[toString]" ) {
+ has_toString item;
+ REQUIRE( Catch::toString( item ) == "toString( has_toString )" );
+}
+
+// Call the overload
+TEST_CASE( "toString( has_maker )", "[toString]" ) {
+ has_maker item;
+ REQUIRE( Catch::toString( item ) == "StringMaker<has_maker>" );
+}
+
+// Call the overload
+TEST_CASE( "toString( has_maker_and_toString )", "[toString]" ) {
+ has_maker_and_toString item;
+ REQUIRE( Catch::toString( item ) == "toString( has_maker_and_toString )" );
+}
+
+// Vectors...
+TEST_CASE( "toString( vectors<has_toString )", "[toString]" ) {
+ std::vector<has_toString> v(1);
+ // This invokes template<T> toString which actually gives us '{ ? }'
+ REQUIRE( Catch::toString( v ) == "{ {?} }" );
+}
+
+TEST_CASE( "toString( vectors<has_maker )", "[toString]" ) {
+ std::vector<has_maker> v(1);
+ REQUIRE( Catch::toString( v ) == "{ StringMaker<has_maker> }" );
+}
+
+
+TEST_CASE( "toString( vectors<has_maker_and_toString )", "[toString]" ) {
+ std::vector<has_maker_and_toString> v(1);
+ // Note: This invokes the template<T> toString -> StringMaker
+ REQUIRE( Catch::toString( v ) == "{ StringMaker<has_maker_and_toString> }" );
+}
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/TrickyTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/TrickyTests.cpp
new file mode 100644
index 00000000000..eb53e420156
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/TrickyTests.cpp
@@ -0,0 +1,401 @@
+/*
+ * Created by Phil on 09/11/2010.
+ * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+#include "catch.hpp"
+
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wc++98-compat"
+#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+#endif
+
+namespace Catch
+{
+ template<>
+ std::string toString<std::pair<int, int> >( const std::pair<int, int>& value )
+ {
+ std::ostringstream oss;
+ oss << "std::pair( " << value.first << ", " << value.second << " )";
+ return oss.str();
+
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "Parsing a std::pair",
+ "[Tricky][std::pair]"
+)
+{
+ std::pair<int, int> aNicePair( 1, 2 );
+
+ REQUIRE( (std::pair<int, int>( 1, 2 )) == aNicePair );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "Where there is more to the expression after the RHS",
+ "[Tricky][failing][.]"
+)
+{
+// int a = 1, b = 2;
+// REQUIRE( a == 2 || b == 2 );
+ WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" );
+}
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "Where the LHS is not a simple value",
+ "[Tricky][failing][.]"
+)
+{
+ /*
+ int a = 1;
+ int b = 2;
+
+ // This only captures part of the expression, but issues a warning about the rest
+ REQUIRE( a+1 == b-1 );
+ */
+ WARN( "Uncomment the code in this test to check that it gives a sensible compiler error" );
+}
+
+struct Opaque
+{
+ int val;
+ bool operator ==( const Opaque& o ) const
+ {
+ return val == o.val;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "A failing expression with a non streamable type is still captured",
+ "[Tricky][failing][.]"
+)
+{
+
+ Opaque o1, o2;
+ o1.val = 7;
+ o2.val = 8;
+
+ CHECK( &o1 == &o2 );
+ CHECK( o1 == o2 );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "string literals of different sizes can be compared",
+ "[Tricky][failing][.]"
+)
+{
+ REQUIRE( std::string( "first" ) == "second" );
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+TEST_CASE
+(
+ "An expression with side-effects should only be evaluated once",
+ "[Tricky]"
+)
+{
+ int i = 7;
+
+ REQUIRE( i++ == 7 );
+ REQUIRE( i++ == 8 );
+
+}
+
+namespace A {
+ struct X
+ {
+ X() : a(4), b(2), c(7) {}
+ X(int v) : a(v), b(2), c(7) {}
+ int a;
+ int b;
+ int c;
+ };
+}
+
+namespace B {
+ struct Y
+ {
+ Y() : a(4), b(2), c(7) {}
+ Y(int v) : a(v), b(2), c(7) {}
+ int a;
+ int b;
+ int c;
+ };
+}
+
+inline bool operator==(const A::X& lhs, const B::Y& rhs)
+{
+ return (lhs.a == rhs.a);
+}
+
+inline bool operator==(const B::Y& lhs, const A::X& rhs)
+{
+ return (lhs.a == rhs.a);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+/* This, currently, does not compile with LLVM
+TEST_CASE
+(
+ "Operators at different namespace levels not hijacked by Koenig lookup"
+ "[Tricky]"
+)
+{
+ A::X x;
+ B::Y y;
+ REQUIRE( x == y );
+}
+*/
+
+namespace ObjectWithConversions
+{
+ struct Object
+ {
+ operator unsigned int() {return 0xc0000000;}
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////
+ TEST_CASE
+ (
+ "Operators at different namespace levels not hijacked by Koenig lookup",
+ "[Tricky]"
+ )
+ {
+ Object o;
+ REQUIRE(0xc0000000 == o );
+ }
+}
+
+namespace ObjectWithNonConstEqualityOperator
+{
+ struct Test
+ {
+ Test( unsigned int v )
+ : m_value(v)
+ {}
+
+ bool operator==( const Test&rhs )
+ {
+ return (m_value == rhs.m_value);
+ }
+ bool operator==( const Test&rhs ) const
+ {
+ return (m_value != rhs.m_value);
+ }
+ unsigned int m_value;
+ };
+
+ TEST_CASE("Demonstrate that a non-const == is not used", "[Tricky]" )
+ {
+ Test t( 1 );
+ REQUIRE( t == 1u );
+ }
+}
+
+namespace EnumBitFieldTests
+{
+ enum Bits {bit0 = 0x0001, bit1 = 0x0002, bit2 = 0x0004, bit3 = 0x0008, bit1and2 = 0x0006,
+ bit30 = 0x40000000, bit31 = 0x80000000,
+ bit30and31 = 0xc0000000};
+
+ TEST_CASE( "Test enum bit values", "[Tricky]" )
+ {
+ REQUIRE( 0xc0000000 == bit30and31 );
+ }
+}
+
+struct Obj
+{
+ Obj():prop(&p){}
+
+ int p;
+ int* prop;
+};
+
+TEST_CASE("boolean member", "[Tricky]")
+{
+ Obj obj;
+ REQUIRE( obj.prop != CATCH_NULL );
+}
+
+// Tests for a problem submitted by Ralph McArdell
+//
+// The static bool value should not need to be defined outside the
+// struct it is declared in - but when evaluating it in a deduced
+// context it appears to require the extra definition.
+// The issue was fixed by adding bool overloads to bypass the
+// templates that were there to deduce it.
+template <bool B>
+struct is_true
+{
+ static const bool value = B;
+};
+
+TEST_CASE( "(unimplemented) static bools can be evaluated", "[Tricky]" )
+{
+ SECTION("compare to true","")
+ {
+ REQUIRE( is_true<true>::value == true );
+ REQUIRE( true == is_true<true>::value );
+ }
+ SECTION("compare to false","")
+ {
+ REQUIRE( is_true<false>::value == false );
+ REQUIRE( false == is_true<false>::value );
+ }
+
+ SECTION("negation", "")
+ {
+ REQUIRE( !is_true<false>::value );
+ }
+
+ SECTION("double negation","")
+ {
+ REQUIRE( !!is_true<true>::value );
+ }
+
+ SECTION("direct","")
+ {
+ REQUIRE( is_true<true>::value );
+ REQUIRE_FALSE( is_true<false>::value );
+ }
+}
+
+// Uncomment these tests to produce an error at test registration time
+/*
+TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
+{
+
+}
+TEST_CASE( "Tests with the same name are not allowed", "[Tricky]" )
+{
+
+}
+*/
+
+struct Boolable
+{
+ explicit Boolable( bool value ) : m_value( value ) {}
+
+ operator Catch::SafeBool::type() const {
+ return Catch::SafeBool::makeSafe( m_value );
+ }
+
+ bool m_value;
+};
+
+TEST_CASE( "Objects that evaluated in boolean contexts can be checked", "[Tricky][SafeBool]" )
+{
+ Boolable True( true );
+ Boolable False( false );
+
+ CHECK( True );
+ CHECK( !False );
+ CHECK_FALSE( False );
+}
+
+TEST_CASE( "Assertions then sections", "[Tricky]" )
+{
+ // This was causing a failure due to the way the console reporter was handling
+ // the current section
+
+ REQUIRE( Catch::alwaysTrue() );
+
+ SECTION( "A section", "" )
+ {
+ REQUIRE( Catch::alwaysTrue() );
+
+ SECTION( "Another section", "" )
+ {
+ REQUIRE( Catch::alwaysTrue() );
+ }
+ SECTION( "Another other section", "" )
+ {
+ REQUIRE( Catch::alwaysTrue() );
+ }
+ }
+}
+
+struct Awkward
+{
+ operator int() const { return 7; }
+};
+
+TEST_CASE( "non streamable - with conv. op", "[Tricky]" )
+{
+ Awkward awkward;
+ std::string s = Catch::toString( awkward );
+ REQUIRE( s == "7" );
+}
+
+inline void foo() {}
+
+typedef void (*fooptr_t)();
+
+TEST_CASE( "Comparing function pointers", "[Tricky][function pointer]" )
+{
+ // This was giving a warning in VS2010
+ // #179
+ fooptr_t a = foo;
+
+ REQUIRE( a );
+ REQUIRE( a == &foo );
+}
+
+struct S
+{
+ void f() {}
+};
+
+
+TEST_CASE( "Comparing member function pointers", "[Tricky][member function pointer]" )
+{
+ typedef void (S::*MF)();
+ MF m = &S::f;
+
+ CHECK( m == &S::f );
+}
+
+class ClassName {};
+
+TEST_CASE( "pointer to class", "[Tricky]" )
+{
+ ClassName *p = 0;
+ REQUIRE( p == 0 );
+}
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+
+#include <memory>
+
+TEST_CASE( "null_ptr", "[Tricky][c++11]" )
+{
+ std::unique_ptr<int> ptr;
+ REQUIRE(ptr.get() == nullptr);
+}
+
+#endif
+
+TEST_CASE( "X/level/0/a", "[Tricky]" ) { SUCCEED(""); }
+TEST_CASE( "X/level/0/b", "[Tricky][fizz]" ){ SUCCEED(""); }
+TEST_CASE( "X/level/1/a", "[Tricky]" ) { SUCCEED(""); }
+TEST_CASE( "X/level/1/b", "[Tricky]" ) { SUCCEED(""); }
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/VariadicMacrosTests.cpp b/3rdparty/sol2/Catch/projects/SelfTest/VariadicMacrosTests.cpp
new file mode 100644
index 00000000000..b784076d89f
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/VariadicMacrosTests.cpp
@@ -0,0 +1,31 @@
+/*
+ * Created by Phil on 15/03/2013.
+ * Copyright 2013 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "catch.hpp"
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+
+TEST_CASE()
+{
+ SUCCEED( "anonymous test case" );
+}
+
+TEST_CASE( "Test case with one argument" )
+{
+ SUCCEED( "no assertions" );
+}
+
+TEST_CASE( "Variadic macros", "[variadic][sections]" )
+{
+ SECTION( "Section with one argument" )
+ {
+ SUCCEED( "no assertions" );
+ }
+}
+
+#endif
diff --git a/3rdparty/sol2/Catch/projects/SelfTest/makefile b/3rdparty/sol2/Catch/projects/SelfTest/makefile
new file mode 100644
index 00000000000..0a29372c875
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/SelfTest/makefile
@@ -0,0 +1,30 @@
+SOURCES = ApproxTests.cpp \
+ ClassTests.cpp \
+ ConditionTests.cpp \
+ ExceptionTests.cpp \
+ GeneratorTests.cpp \
+ MessageTests.cpp \
+ MiscTests.cpp \
+ TestMain.cpp \
+ TrickyTests.cpp \
+ BDDTests.cpp \
+ VariadicMacrosTests.cpp \
+ EnumToString.cpp \
+ ToStringPair.cpp \
+ ToStringVector.cpp \
+ ToStringWhich.cpp
+
+
+OBJECTS = $(patsubst %.cpp, %.o, $(SOURCES))
+CXX = g++
+CXXFLAGS = -I../../include -std=c++11
+
+CatchSelfTest: $(OBJECTS)
+ $(CXX) -o $@ $^
+
+test: CatchSelfTest
+ ./CatchSelfTest
+
+clean:
+ rm -f $(OBJECTS) CatchSelfTest
+
diff --git a/3rdparty/sol2/Catch/projects/VS2008/TestCatch/TestCatch/TestCatch.cpp b/3rdparty/sol2/Catch/projects/VS2008/TestCatch/TestCatch/TestCatch.cpp
new file mode 100644
index 00000000000..8dd2067d480
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/VS2008/TestCatch/TestCatch/TestCatch.cpp
@@ -0,0 +1,8 @@
+// TestCatch.cpp : Defines the entry point for the console application.
+//
+
+int main(int argc, char* argv[])
+{
+ return 0;
+}
+
diff --git a/3rdparty/sol2/Catch/projects/VS2008/TestCatch/TestCatch/TestCatch.vcproj b/3rdparty/sol2/Catch/projects/VS2008/TestCatch/TestCatch/TestCatch.vcproj
new file mode 100644
index 00000000000..d4cb0c97532
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/VS2008/TestCatch/TestCatch/TestCatch.vcproj
@@ -0,0 +1,390 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="TestCatch"
+ ProjectGUID="{A2F23B19-9CF7-4246-AE58-BC65E39C6F7E}"
+ RootNamespace="TestCatch"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\..\include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\..\SelfTest\TestMain.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Include"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\..\..\include\catch.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\catch_objc.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\catch_objc_main.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\catch_runner.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\catch_with_main.hpp"
+ >
+ </File>
+ <Filter
+ Name="Internal"
+ >
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_capture.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_commandline.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_common.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_config.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_debugger.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_evaluate.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_exception_translator_registry.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_generators.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_generators_impl.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_hub.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_hub_impl.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_interfaces_capture.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_interfaces_exception.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_interfaces_reporter.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_interfaces_runner.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_interfaces_testcase.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_list.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_reporter_registrars.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_reporter_registry.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_result_type.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_resultinfo.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_runner_impl.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_section.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_stream.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_test_case_info.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_test_case_registry_impl.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_test_registry.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\internal\catch_xmlwriter.hpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Reporters"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath="..\..\..\..\include\reporters\catch_reporter_basic.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\reporters\catch_reporter_junit.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\..\include\reporters\catch_reporter_xml.hpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="TestCases"
+ >
+ <File
+ RelativePath="..\..\..\SelfTest\ApproxTests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\SelfTest\BDDTests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\SelfTest\ClassTests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\SelfTest\ConditionTests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\SelfTest\ExceptionTests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\SelfTest\GeneratorTests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\SelfTest\MessageTests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\SelfTest\MiscTests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\SelfTest\SectionTrackerTests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\SelfTest\TrickyTests.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\SelfTest\VariadicMacrosTests.cpp"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj
new file mode 100644
index 00000000000..a26df5361bd
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj
@@ -0,0 +1,742 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 26059AF21BD4B94C003D575C /* PartTrackerTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */; };
+ 263F7A4719B6FCBF009474C2 /* EnumToString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4619B6FCBF009474C2 /* EnumToString.cpp */; };
+ 263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4819B6FE1E009474C2 /* ToStringPair.cpp */; };
+ 263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4919B6FE1E009474C2 /* ToStringVector.cpp */; };
+ 263F7A4D19B6FE1E009474C2 /* ToStringWhich.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263F7A4A19B6FE1E009474C2 /* ToStringWhich.cpp */; };
+ 2656C2211925E7330040DB02 /* catch_test_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2656C2201925E7330040DB02 /* catch_test_spec.cpp */; };
+ 266B06B816F3A60A004ED264 /* VariadicMacrosTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266B06B616F3A60A004ED264 /* VariadicMacrosTests.cpp */; };
+ 266ECD74170F3C620030D735 /* BDDTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266ECD73170F3C620030D735 /* BDDTests.cpp */; };
+ 26711C8F195D465C0033EDA2 /* TagAliasTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26711C8D195D465C0033EDA2 /* TagAliasTests.cpp */; };
+ 26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26847E5D16BBADB40043B9C1 /* catch_message.cpp */; };
+ 2691574C1A532A280054F1ED /* ToStringTuple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2691574B1A532A280054F1ED /* ToStringTuple.cpp */; };
+ 2694A1FD16A0000E004816E3 /* catch_text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2694A1FB16A0000E004816E3 /* catch_text.cpp */; };
+ 26E1B7D319213BC900812682 /* CmdLineTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E1B7D119213BC900812682 /* CmdLineTests.cpp */; };
+ 4A45DA2416161EF9004F8D6B /* catch_console_colour.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA2316161EF9004F8D6B /* catch_console_colour.cpp */; };
+ 4A45DA2716161F1F004F8D6B /* catch_ptr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA2616161F1F004F8D6B /* catch_ptr.cpp */; };
+ 4A45DA2916161F3D004F8D6B /* catch_streambuf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA2816161F3D004F8D6B /* catch_streambuf.cpp */; };
+ 4A45DA2B16161F79004F8D6B /* catch_interfaces_registry_hub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA2A16161F79004F8D6B /* catch_interfaces_registry_hub.cpp */; };
+ 4A45DA2D16161FA2004F8D6B /* catch_interfaces_capture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA2C16161FA2004F8D6B /* catch_interfaces_capture.cpp */; };
+ 4A45DA3116161FFC004F8D6B /* catch_interfaces_reporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA3016161FFB004F8D6B /* catch_interfaces_reporter.cpp */; };
+ 4A45DA3316162047004F8D6B /* catch_interfaces_exception.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA3216162047004F8D6B /* catch_interfaces_exception.cpp */; };
+ 4A45DA3516162071004F8D6B /* catch_interfaces_runner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A45DA3416162071004F8D6B /* catch_interfaces_runner.cpp */; };
+ 4A6D0C27149B3D3B00DB3EAA /* CatchSelfTest.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4A6D0C26149B3D3B00DB3EAA /* CatchSelfTest.1 */; };
+ 4A6D0C37149B3D9E00DB3EAA /* ApproxTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C2D149B3D9E00DB3EAA /* ApproxTests.cpp */; };
+ 4A6D0C38149B3D9E00DB3EAA /* ClassTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C2F149B3D9E00DB3EAA /* ClassTests.cpp */; };
+ 4A6D0C39149B3D9E00DB3EAA /* ConditionTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C30149B3D9E00DB3EAA /* ConditionTests.cpp */; };
+ 4A6D0C3A149B3D9E00DB3EAA /* ExceptionTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C31149B3D9E00DB3EAA /* ExceptionTests.cpp */; };
+ 4A6D0C3B149B3D9E00DB3EAA /* GeneratorTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C32149B3D9E00DB3EAA /* GeneratorTests.cpp */; };
+ 4A6D0C3C149B3D9E00DB3EAA /* MessageTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C33149B3D9E00DB3EAA /* MessageTests.cpp */; };
+ 4A6D0C3D149B3D9E00DB3EAA /* MiscTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C34149B3D9E00DB3EAA /* MiscTests.cpp */; };
+ 4A6D0C3E149B3D9E00DB3EAA /* TestMain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C35149B3D9E00DB3EAA /* TestMain.cpp */; };
+ 4A6D0C3F149B3D9E00DB3EAA /* TrickyTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A6D0C36149B3D9E00DB3EAA /* TrickyTests.cpp */; };
+ 4AB3D99D1616216500C9A0F8 /* catch_interfaces_testcase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AB3D99C1616216500C9A0F8 /* catch_interfaces_testcase.cpp */; };
+ 4AB3D9A01616219100C9A0F8 /* catch_interfaces_config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AB3D99F1616219100C9A0F8 /* catch_interfaces_config.cpp */; };
+ 4AB3D9A2161621B500C9A0F8 /* catch_interfaces_generators.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AB3D9A1161621B500C9A0F8 /* catch_interfaces_generators.cpp */; };
+ 4ACE21CC166CA1B300FB5509 /* catch_option.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4ACE21CA166CA1B300FB5509 /* catch_option.cpp */; };
+ 4AEE032016142F910071E950 /* catch_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AEE031F16142F910071E950 /* catch_common.cpp */; };
+ 4AEE032316142FC70071E950 /* catch_debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AEE032216142FC70071E950 /* catch_debugger.cpp */; };
+ 4AEE032516142FF10071E950 /* catch_stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AEE032416142FF10071E950 /* catch_stream.cpp */; };
+ 4AEE0328161434FD0071E950 /* catch_xmlwriter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AEE0327161434FD0071E950 /* catch_xmlwriter.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 4A6D0C1E149B3D3B00DB3EAA /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = /usr/share/man/man1/;
+ dstSubfolderSpec = 0;
+ files = (
+ 4A6D0C27149B3D3B00DB3EAA /* CatchSelfTest.1 in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PartTrackerTests.cpp; path = ../../../SelfTest/PartTrackerTests.cpp; sourceTree = "<group>"; };
+ 261488FA184C81130041FBEB /* catch_test_spec.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_spec.hpp; sourceTree = "<group>"; };
+ 261488FC184D1DC10041FBEB /* catch_stream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_stream.h; sourceTree = "<group>"; };
+ 261488FD184D21290041FBEB /* catch_section_info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_section_info.h; sourceTree = "<group>"; };
+ 261488FE184DC32F0041FBEB /* catch_section.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_section.h; sourceTree = "<group>"; };
+ 261488FF184DC4A20041FBEB /* catch_debugger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_debugger.h; sourceTree = "<group>"; };
+ 2627F7051935B16F009BCE2D /* catch_result_builder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_result_builder.h; sourceTree = "<group>"; };
+ 2627F7061935B55F009BCE2D /* catch_result_builder.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_result_builder.hpp; sourceTree = "<group>"; };
+ 262E7399184673A800CAC268 /* catch_reporter_bases.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_bases.hpp; sourceTree = "<group>"; };
+ 262E739A1846759000CAC268 /* catch_common.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_common.hpp; sourceTree = "<group>"; };
+ 263F7A4519A66608009474C2 /* catch_fatal_condition.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_fatal_condition.hpp; sourceTree = "<group>"; };
+ 263F7A4619B6FCBF009474C2 /* EnumToString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = EnumToString.cpp; path = ../../../SelfTest/EnumToString.cpp; sourceTree = "<group>"; };
+ 263F7A4819B6FE1E009474C2 /* ToStringPair.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToStringPair.cpp; path = ../../../SelfTest/ToStringPair.cpp; sourceTree = "<group>"; };
+ 263F7A4919B6FE1E009474C2 /* ToStringVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToStringVector.cpp; path = ../../../SelfTest/ToStringVector.cpp; sourceTree = "<group>"; };
+ 263F7A4A19B6FE1E009474C2 /* ToStringWhich.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToStringWhich.cpp; path = ../../../SelfTest/ToStringWhich.cpp; sourceTree = "<group>"; };
+ 263FD06017AF8DF200988A20 /* catch_timer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_timer.hpp; sourceTree = "<group>"; };
+ 263FD06117AF8DF200988A20 /* catch_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_timer.h; sourceTree = "<group>"; };
+ 2656C21F1925E5100040DB02 /* catch_test_spec_parser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_test_spec_parser.hpp; sourceTree = "<group>"; };
+ 2656C2201925E7330040DB02 /* catch_test_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_test_spec.cpp; path = ../../../SelfTest/SurrogateCpps/catch_test_spec.cpp; sourceTree = "<group>"; };
+ 2656C226192A77EF0040DB02 /* catch_suppress_warnings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_suppress_warnings.h; sourceTree = "<group>"; };
+ 2656C227192A78410040DB02 /* catch_reenable_warnings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_reenable_warnings.h; sourceTree = "<group>"; };
+ 266B06B616F3A60A004ED264 /* VariadicMacrosTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VariadicMacrosTests.cpp; path = ../../../SelfTest/VariadicMacrosTests.cpp; sourceTree = "<group>"; };
+ 266ECD73170F3C620030D735 /* BDDTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BDDTests.cpp; path = ../../../SelfTest/BDDTests.cpp; sourceTree = "<group>"; };
+ 266ECD8C1713614B0030D735 /* catch_legacy_reporter_adapter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_legacy_reporter_adapter.hpp; sourceTree = "<group>"; };
+ 266ECD8D1713614B0030D735 /* catch_legacy_reporter_adapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_legacy_reporter_adapter.h; sourceTree = "<group>"; };
+ 26711C8D195D465C0033EDA2 /* TagAliasTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TagAliasTests.cpp; path = ../../../SelfTest/TagAliasTests.cpp; sourceTree = "<group>"; };
+ 26711C90195D46CD0033EDA2 /* catch_interfaces_tag_alias_registry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_interfaces_tag_alias_registry.h; sourceTree = "<group>"; };
+ 26711C91195D47820033EDA2 /* catch_tag_alias.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_tag_alias.h; sourceTree = "<group>"; };
+ 26711C92195D48F60033EDA2 /* catch_tag_alias_registry.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_tag_alias_registry.hpp; sourceTree = "<group>"; };
+ 26711C94195D4B120033EDA2 /* catch_tag_alias_registry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_tag_alias_registry.h; sourceTree = "<group>"; };
+ 26759473171C74C200A84BD1 /* catch_compiler_capabilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = catch_compiler_capabilities.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 26847E5B16BBAB790043B9C1 /* catch_message.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_message.h; sourceTree = "<group>"; };
+ 26847E5C16BBACB60043B9C1 /* catch_message.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_message.hpp; sourceTree = "<group>"; };
+ 26847E5D16BBADB40043B9C1 /* catch_message.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_message.cpp; path = ../../../SelfTest/SurrogateCpps/catch_message.cpp; sourceTree = "<group>"; };
+ 268F47B018A93F7800D8C14F /* catch_clara.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_clara.h; sourceTree = "<group>"; };
+ 2691574A1A4480C50054F1ED /* catch_reporter_teamcity.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_teamcity.hpp; sourceTree = "<group>"; };
+ 2691574B1A532A280054F1ED /* ToStringTuple.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ToStringTuple.cpp; path = ../../../SelfTest/ToStringTuple.cpp; sourceTree = "<group>"; };
+ 26926E8318D7777D004E10F2 /* clara.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = clara.h; path = ../../../../include/external/clara.h; sourceTree = "<group>"; };
+ 26926E8418D77809004E10F2 /* tbc_text_format.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tbc_text_format.h; path = ../../../../include/external/tbc_text_format.h; sourceTree = "<group>"; };
+ 26948287179EF7F900ED166E /* catch_test_case_tracker.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_case_tracker.hpp; sourceTree = "<group>"; };
+ 2694A1FB16A0000E004816E3 /* catch_text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = catch_text.cpp; sourceTree = "<group>"; };
+ 269831E519078C1600BB0CE0 /* catch_tostring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_tostring.h; sourceTree = "<group>"; };
+ 269831E619078CA200BB0CE0 /* catch_tostring.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_tostring.hpp; sourceTree = "<group>"; };
+ 269831E719121CA500BB0CE0 /* catch_reporter_compact.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_compact.hpp; sourceTree = "<group>"; };
+ 26AEAF1617BEA18E009E32C9 /* catch_platform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_platform.h; sourceTree = "<group>"; };
+ 26DACF2F17206D3400A21326 /* catch_text.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_text.h; sourceTree = "<group>"; };
+ 26DFD3B11B53F84700FD6F16 /* catch_wildcard_pattern.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_wildcard_pattern.hpp; sourceTree = "<group>"; };
+ 26E1B7D119213BC900812682 /* CmdLineTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CmdLineTests.cpp; path = ../../../SelfTest/CmdLineTests.cpp; sourceTree = "<group>"; };
+ 26EDFBD91B72011F00B1873C /* catch_reporter_multi.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_multi.hpp; sourceTree = "<group>"; };
+ 4A084F1C15DACEEA0027E631 /* catch_test_case_info.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_case_info.hpp; sourceTree = "<group>"; };
+ 4A3D7DD01503869D005F9203 /* catch_matchers.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_matchers.hpp; sourceTree = "<group>"; };
+ 4A45DA2316161EF9004F8D6B /* catch_console_colour.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_console_colour.cpp; path = ../../../SelfTest/SurrogateCpps/catch_console_colour.cpp; sourceTree = "<group>"; };
+ 4A45DA2616161F1F004F8D6B /* catch_ptr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_ptr.cpp; path = ../../../SelfTest/SurrogateCpps/catch_ptr.cpp; sourceTree = "<group>"; };
+ 4A45DA2816161F3D004F8D6B /* catch_streambuf.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_streambuf.cpp; path = ../../../SelfTest/SurrogateCpps/catch_streambuf.cpp; sourceTree = "<group>"; };
+ 4A45DA2A16161F79004F8D6B /* catch_interfaces_registry_hub.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_interfaces_registry_hub.cpp; path = ../../../SelfTest/SurrogateCpps/catch_interfaces_registry_hub.cpp; sourceTree = "<group>"; };
+ 4A45DA2C16161FA2004F8D6B /* catch_interfaces_capture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_interfaces_capture.cpp; path = ../../../SelfTest/SurrogateCpps/catch_interfaces_capture.cpp; sourceTree = "<group>"; };
+ 4A45DA3016161FFB004F8D6B /* catch_interfaces_reporter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_interfaces_reporter.cpp; path = ../../../SelfTest/SurrogateCpps/catch_interfaces_reporter.cpp; sourceTree = "<group>"; };
+ 4A45DA3216162047004F8D6B /* catch_interfaces_exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_interfaces_exception.cpp; path = ../../../SelfTest/SurrogateCpps/catch_interfaces_exception.cpp; sourceTree = "<group>"; };
+ 4A45DA3416162071004F8D6B /* catch_interfaces_runner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_interfaces_runner.cpp; path = ../../../SelfTest/SurrogateCpps/catch_interfaces_runner.cpp; sourceTree = "<group>"; };
+ 4A4B0F9715CE6CFB00AE2392 /* catch_registry_hub.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_registry_hub.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4A4B0F9915CE6EC100AE2392 /* catch_interfaces_registry_hub.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = catch_interfaces_registry_hub.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 4A4B0F9A15CEF84800AE2392 /* catch_notimplemented_exception.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_notimplemented_exception.h; sourceTree = "<group>"; };
+ 4A4B0F9B15CEF8C400AE2392 /* catch_notimplemented_exception.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_notimplemented_exception.hpp; sourceTree = "<group>"; };
+ 4A4B0F9C15CEFA8300AE2392 /* catch_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_impl.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4A6D0C20149B3D3B00DB3EAA /* CatchSelfTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = CatchSelfTest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4A6D0C26149B3D3B00DB3EAA /* CatchSelfTest.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = CatchSelfTest.1; sourceTree = "<group>"; };
+ 4A6D0C2D149B3D9E00DB3EAA /* ApproxTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ApproxTests.cpp; path = ../../../SelfTest/ApproxTests.cpp; sourceTree = "<group>"; };
+ 4A6D0C2F149B3D9E00DB3EAA /* ClassTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClassTests.cpp; path = ../../../SelfTest/ClassTests.cpp; sourceTree = "<group>"; };
+ 4A6D0C30149B3D9E00DB3EAA /* ConditionTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConditionTests.cpp; path = ../../../SelfTest/ConditionTests.cpp; sourceTree = "<group>"; };
+ 4A6D0C31149B3D9E00DB3EAA /* ExceptionTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExceptionTests.cpp; path = ../../../SelfTest/ExceptionTests.cpp; sourceTree = "<group>"; };
+ 4A6D0C32149B3D9E00DB3EAA /* GeneratorTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GeneratorTests.cpp; path = ../../../SelfTest/GeneratorTests.cpp; sourceTree = "<group>"; };
+ 4A6D0C33149B3D9E00DB3EAA /* MessageTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MessageTests.cpp; path = ../../../SelfTest/MessageTests.cpp; sourceTree = "<group>"; };
+ 4A6D0C34149B3D9E00DB3EAA /* MiscTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MiscTests.cpp; path = ../../../SelfTest/MiscTests.cpp; sourceTree = "<group>"; };
+ 4A6D0C35149B3D9E00DB3EAA /* TestMain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TestMain.cpp; path = ../../../SelfTest/TestMain.cpp; sourceTree = "<group>"; };
+ 4A6D0C36149B3D9E00DB3EAA /* TrickyTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TrickyTests.cpp; path = ../../../SelfTest/TrickyTests.cpp; sourceTree = "<group>"; };
+ 4A6D0C42149B3E1500DB3EAA /* catch_session.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = catch_session.hpp; path = ../../../../include/catch_session.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4A6D0C43149B3E1500DB3EAA /* catch_with_main.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_with_main.hpp; path = ../../../../include/catch_with_main.hpp; sourceTree = "<group>"; };
+ 4A6D0C44149B3E1500DB3EAA /* catch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch.hpp; path = ../../../../include/catch.hpp; sourceTree = "<group>"; };
+ 4A6D0C46149B3E3D00DB3EAA /* catch_approx.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_approx.hpp; sourceTree = "<group>"; };
+ 4A6D0C47149B3E3D00DB3EAA /* catch_capture.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_capture.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4A6D0C48149B3E3D00DB3EAA /* catch_commandline.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_commandline.hpp; sourceTree = "<group>"; };
+ 4A6D0C49149B3E3D00DB3EAA /* catch_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_common.h; sourceTree = "<group>"; };
+ 4A6D0C4A149B3E3D00DB3EAA /* catch_config.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_config.hpp; sourceTree = "<group>"; };
+ 4A6D0C4B149B3E3D00DB3EAA /* catch_debugger.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_debugger.hpp; sourceTree = "<group>"; };
+ 4A6D0C4C149B3E3D00DB3EAA /* catch_default_main.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_default_main.hpp; sourceTree = "<group>"; };
+ 4A6D0C4D149B3E3D00DB3EAA /* catch_evaluate.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_evaluate.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4A6D0C4E149B3E3D00DB3EAA /* catch_exception_translator_registry.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_exception_translator_registry.hpp; sourceTree = "<group>"; };
+ 4A6D0C4F149B3E3D00DB3EAA /* catch_generators.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_generators.hpp; sourceTree = "<group>"; };
+ 4A6D0C50149B3E3D00DB3EAA /* catch_generators_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_generators_impl.hpp; sourceTree = "<group>"; };
+ 4A6D0C51149B3E3D00DB3EAA /* catch_context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_context.h; sourceTree = "<group>"; };
+ 4A6D0C52149B3E3D00DB3EAA /* catch_context_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_context_impl.hpp; sourceTree = "<group>"; };
+ 4A6D0C53149B3E3D00DB3EAA /* catch_interfaces_capture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_interfaces_capture.h; sourceTree = "<group>"; };
+ 4A6D0C54149B3E3D00DB3EAA /* catch_interfaces_exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = catch_interfaces_exception.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 4A6D0C55149B3E3D00DB3EAA /* catch_interfaces_reporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_interfaces_reporter.h; sourceTree = "<group>"; };
+ 4A6D0C56149B3E3D00DB3EAA /* catch_interfaces_runner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_interfaces_runner.h; sourceTree = "<group>"; };
+ 4A6D0C57149B3E3D00DB3EAA /* catch_interfaces_testcase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_interfaces_testcase.h; sourceTree = "<group>"; };
+ 4A6D0C58149B3E3D00DB3EAA /* catch_list.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_list.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4A6D0C59149B3E3D00DB3EAA /* catch_objc.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_objc.hpp; sourceTree = "<group>"; };
+ 4A6D0C5A149B3E3D00DB3EAA /* catch_reporter_registrars.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_reporter_registrars.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4A6D0C5B149B3E3D00DB3EAA /* catch_reporter_registry.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_registry.hpp; sourceTree = "<group>"; };
+ 4A6D0C5C149B3E3D00DB3EAA /* catch_result_type.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_result_type.h; sourceTree = "<group>"; };
+ 4A6D0C5D149B3E3D00DB3EAA /* catch_assertionresult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = catch_assertionresult.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
+ 4A6D0C5E149B3E3D00DB3EAA /* catch_run_context.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_run_context.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4A6D0C5F149B3E3D00DB3EAA /* catch_section.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_section.hpp; sourceTree = "<group>"; };
+ 4A6D0C60149B3E3D00DB3EAA /* catch_stream.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_stream.hpp; sourceTree = "<group>"; };
+ 4A6D0C61149B3E3D00DB3EAA /* catch_test_case_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_test_case_info.h; sourceTree = "<group>"; };
+ 4A6D0C62149B3E3D00DB3EAA /* catch_test_case_registry_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_test_case_registry_impl.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4A6D0C63149B3E3D00DB3EAA /* catch_test_registry.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_test_registry.hpp; sourceTree = "<group>"; };
+ 4A6D0C64149B3E3D00DB3EAA /* catch_xmlwriter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_xmlwriter.hpp; sourceTree = "<group>"; };
+ 4A6D0C67149B3E3D00DB3EAA /* catch_reporter_junit.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_junit.hpp; sourceTree = "<group>"; };
+ 4A6D0C68149B3E3D00DB3EAA /* catch_reporter_xml.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_xml.hpp; sourceTree = "<group>"; };
+ 4A7ADB4314F631E10094FE10 /* catch_totals.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_totals.hpp; sourceTree = "<group>"; };
+ 4A7DB2CD1652FE4B00FA6523 /* catch_version.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = catch_version.h; path = ../../../../include/internal/catch_version.h; sourceTree = "<group>"; };
+ 4A90B59B15D0F61A00EF71BC /* catch_interfaces_generators.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_interfaces_generators.h; sourceTree = "<group>"; };
+ 4A90B59D15D24FE900EF71BC /* catch_assertionresult.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_assertionresult.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4AA7B8B4165428BA003155F6 /* catch_version.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = catch_version.hpp; path = ../../../../include/internal/catch_version.hpp; sourceTree = "<group>"; };
+ 4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_console_colour_impl.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_console_colour.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4AB3D99C1616216500C9A0F8 /* catch_interfaces_testcase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_interfaces_testcase.cpp; path = ../../../SelfTest/SurrogateCpps/catch_interfaces_testcase.cpp; sourceTree = "<group>"; };
+ 4AB3D99F1616219100C9A0F8 /* catch_interfaces_config.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_interfaces_config.cpp; path = ../../../SelfTest/SurrogateCpps/catch_interfaces_config.cpp; sourceTree = "<group>"; };
+ 4AB3D9A1161621B500C9A0F8 /* catch_interfaces_generators.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_interfaces_generators.cpp; path = ../../../SelfTest/SurrogateCpps/catch_interfaces_generators.cpp; sourceTree = "<group>"; };
+ 4AB42F84166F3E1A0099F2C8 /* catch_reporter_console.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_console.hpp; sourceTree = "<group>"; };
+ 4AB77CB51551AEA200857BF0 /* catch_ptr.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_ptr.hpp; sourceTree = "<group>"; };
+ 4AB77CB71553B72B00857BF0 /* catch_section_info.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_section_info.hpp; sourceTree = "<group>"; };
+ 4ABEA80415C90D2B009F0424 /* catch_objc_arc.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_objc_arc.hpp; sourceTree = "<group>"; };
+ 4AC91CCE155CF02800DC5117 /* catch_expression_lhs.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_expression_lhs.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
+ 4ACE21C8166CA19700FB5509 /* catch_option.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_option.hpp; sourceTree = "<group>"; };
+ 4ACE21CA166CA1B300FB5509 /* catch_option.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_option.cpp; path = ../../../SelfTest/SurrogateCpps/catch_option.cpp; sourceTree = "<group>"; };
+ 4AEE031F16142F910071E950 /* catch_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_common.cpp; path = ../../../SelfTest/SurrogateCpps/catch_common.cpp; sourceTree = "<group>"; };
+ 4AEE032216142FC70071E950 /* catch_debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_debugger.cpp; path = ../../../SelfTest/SurrogateCpps/catch_debugger.cpp; sourceTree = "<group>"; };
+ 4AEE032416142FF10071E950 /* catch_stream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_stream.cpp; path = ../../../SelfTest/SurrogateCpps/catch_stream.cpp; sourceTree = "<group>"; };
+ 4AEE0326161431070071E950 /* catch_streambuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_streambuf.h; sourceTree = "<group>"; };
+ 4AEE0327161434FD0071E950 /* catch_xmlwriter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_xmlwriter.cpp; path = ../../../SelfTest/SurrogateCpps/catch_xmlwriter.cpp; sourceTree = "<group>"; };
+ 4AFC661D157E96A7009D58CF /* catch_interfaces_config.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_interfaces_config.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 4A6D0C1D149B3D3B00DB3EAA /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 266E9AD317290E710061DAB2 /* Introspective Tests */ = {
+ isa = PBXGroup;
+ children = (
+ 26059AF11BD4B94C003D575C /* PartTrackerTests.cpp */,
+ 26E1B7D119213BC900812682 /* CmdLineTests.cpp */,
+ 26711C8D195D465C0033EDA2 /* TagAliasTests.cpp */,
+ );
+ name = "Introspective Tests";
+ sourceTree = "<group>";
+ };
+ 26C5F3EB17514B670056FB3C /* External */ = {
+ isa = PBXGroup;
+ children = (
+ 26926E8418D77809004E10F2 /* tbc_text_format.h */,
+ 26926E8318D7777D004E10F2 /* clara.h */,
+ );
+ name = External;
+ sourceTree = "<group>";
+ };
+ 4A6D0C15149B3D3B00DB3EAA = {
+ isa = PBXGroup;
+ children = (
+ 4A6D0C23149B3D3B00DB3EAA /* CatchSelfTest */,
+ 4A6D0C21149B3D3B00DB3EAA /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ 4A6D0C21149B3D3B00DB3EAA /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 4A6D0C20149B3D3B00DB3EAA /* CatchSelfTest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 4A6D0C23149B3D3B00DB3EAA /* CatchSelfTest */ = {
+ isa = PBXGroup;
+ children = (
+ 4A6D0C35149B3D9E00DB3EAA /* TestMain.cpp */,
+ 266E9AD317290E710061DAB2 /* Introspective Tests */,
+ 4A6D0C40149B3DAB00DB3EAA /* Tests */,
+ 4A6D0C41149B3DE900DB3EAA /* Catch */,
+ 4A6D0C26149B3D3B00DB3EAA /* CatchSelfTest.1 */,
+ );
+ path = CatchSelfTest;
+ sourceTree = "<group>";
+ };
+ 4A6D0C40149B3DAB00DB3EAA /* Tests */ = {
+ isa = PBXGroup;
+ children = (
+ 2691574B1A532A280054F1ED /* ToStringTuple.cpp */,
+ 263F7A4819B6FE1E009474C2 /* ToStringPair.cpp */,
+ 263F7A4919B6FE1E009474C2 /* ToStringVector.cpp */,
+ 263F7A4A19B6FE1E009474C2 /* ToStringWhich.cpp */,
+ 263F7A4619B6FCBF009474C2 /* EnumToString.cpp */,
+ 266ECD73170F3C620030D735 /* BDDTests.cpp */,
+ 4A6D0C36149B3D9E00DB3EAA /* TrickyTests.cpp */,
+ 4A6D0C2D149B3D9E00DB3EAA /* ApproxTests.cpp */,
+ 4A6D0C2F149B3D9E00DB3EAA /* ClassTests.cpp */,
+ 4A6D0C30149B3D9E00DB3EAA /* ConditionTests.cpp */,
+ 4A6D0C31149B3D9E00DB3EAA /* ExceptionTests.cpp */,
+ 4A6D0C32149B3D9E00DB3EAA /* GeneratorTests.cpp */,
+ 4A6D0C33149B3D9E00DB3EAA /* MessageTests.cpp */,
+ 4A6D0C34149B3D9E00DB3EAA /* MiscTests.cpp */,
+ 266B06B616F3A60A004ED264 /* VariadicMacrosTests.cpp */,
+ );
+ name = Tests;
+ sourceTree = "<group>";
+ };
+ 4A6D0C41149B3DE900DB3EAA /* Catch */ = {
+ isa = PBXGroup;
+ children = (
+ 26C5F3EB17514B670056FB3C /* External */,
+ 4A7DB2CD1652FE4B00FA6523 /* catch_version.h */,
+ 4AA7B8B4165428BA003155F6 /* catch_version.hpp */,
+ 4A8E4DCF160A34E200194CBD /* SurrogateCpps */,
+ 4A6D0C44149B3E1500DB3EAA /* catch.hpp */,
+ 4A6D0C42149B3E1500DB3EAA /* catch_session.hpp */,
+ 4A6D0C43149B3E1500DB3EAA /* catch_with_main.hpp */,
+ 4A6D0C45149B3E3D00DB3EAA /* internal */,
+ 4A6D0C65149B3E3D00DB3EAA /* reporters */,
+ );
+ name = Catch;
+ sourceTree = "<group>";
+ };
+ 4A6D0C45149B3E3D00DB3EAA /* internal */ = {
+ isa = PBXGroup;
+ children = (
+ 4AC91CC3155C38D300DC5117 /* Objective-C */,
+ 4AC91CC2155C388300DC5117 /* Infrastructure */,
+ 4AC91CC1155C387400DC5117 /* Interfaces */,
+ 4AC91CC0155C384400DC5117 /* Process */,
+ 4AC91CBF155C381600DC5117 /* Test execution */,
+ 4AC91CBE155C37F800DC5117 /* Registries */,
+ 4AC91CBD155C37B500DC5117 /* Assertions */,
+ 4AC91CB4155B9EBF00DC5117 /* impl */,
+ );
+ name = internal;
+ path = ../../../../include/internal;
+ sourceTree = "<group>";
+ };
+ 4A6D0C65149B3E3D00DB3EAA /* reporters */ = {
+ isa = PBXGroup;
+ children = (
+ 269831E719121CA500BB0CE0 /* catch_reporter_compact.hpp */,
+ 262E7399184673A800CAC268 /* catch_reporter_bases.hpp */,
+ 4A6D0C67149B3E3D00DB3EAA /* catch_reporter_junit.hpp */,
+ 4A6D0C68149B3E3D00DB3EAA /* catch_reporter_xml.hpp */,
+ 4AB42F84166F3E1A0099F2C8 /* catch_reporter_console.hpp */,
+ 2691574A1A4480C50054F1ED /* catch_reporter_teamcity.hpp */,
+ 26EDFBD91B72011F00B1873C /* catch_reporter_multi.hpp */,
+ );
+ name = reporters;
+ path = ../../../../include/reporters;
+ sourceTree = "<group>";
+ };
+ 4A8E4DCF160A34E200194CBD /* SurrogateCpps */ = {
+ isa = PBXGroup;
+ children = (
+ 2656C2201925E7330040DB02 /* catch_test_spec.cpp */,
+ 4AEE031F16142F910071E950 /* catch_common.cpp */,
+ 4AEE032216142FC70071E950 /* catch_debugger.cpp */,
+ 4AEE032416142FF10071E950 /* catch_stream.cpp */,
+ 4AEE0327161434FD0071E950 /* catch_xmlwriter.cpp */,
+ 4A45DA2316161EF9004F8D6B /* catch_console_colour.cpp */,
+ 4A45DA2616161F1F004F8D6B /* catch_ptr.cpp */,
+ 4A45DA2816161F3D004F8D6B /* catch_streambuf.cpp */,
+ 4A45DA2A16161F79004F8D6B /* catch_interfaces_registry_hub.cpp */,
+ 4A45DA2C16161FA2004F8D6B /* catch_interfaces_capture.cpp */,
+ 4A45DA3216162047004F8D6B /* catch_interfaces_exception.cpp */,
+ 4A45DA3016161FFB004F8D6B /* catch_interfaces_reporter.cpp */,
+ 4A45DA3416162071004F8D6B /* catch_interfaces_runner.cpp */,
+ 4AB3D99C1616216500C9A0F8 /* catch_interfaces_testcase.cpp */,
+ 4AB3D99F1616219100C9A0F8 /* catch_interfaces_config.cpp */,
+ 4AB3D9A1161621B500C9A0F8 /* catch_interfaces_generators.cpp */,
+ 4ACE21CA166CA1B300FB5509 /* catch_option.cpp */,
+ 2694A1FB16A0000E004816E3 /* catch_text.cpp */,
+ 26847E5D16BBADB40043B9C1 /* catch_message.cpp */,
+ );
+ name = SurrogateCpps;
+ sourceTree = "<group>";
+ };
+ 4AC91CB4155B9EBF00DC5117 /* impl */ = {
+ isa = PBXGroup;
+ children = (
+ 4A6D0C5F149B3E3D00DB3EAA /* catch_section.hpp */,
+ 263FD06017AF8DF200988A20 /* catch_timer.hpp */,
+ 4A4B0F9C15CEFA8300AE2392 /* catch_impl.hpp */,
+ 4A4B0F9715CE6CFB00AE2392 /* catch_registry_hub.hpp */,
+ 4A6D0C50149B3E3D00DB3EAA /* catch_generators_impl.hpp */,
+ 4A6D0C52149B3E3D00DB3EAA /* catch_context_impl.hpp */,
+ 4A6D0C5E149B3E3D00DB3EAA /* catch_run_context.hpp */,
+ 4A6D0C62149B3E3D00DB3EAA /* catch_test_case_registry_impl.hpp */,
+ 4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */,
+ 4A4B0F9B15CEF8C400AE2392 /* catch_notimplemented_exception.hpp */,
+ 4A90B59D15D24FE900EF71BC /* catch_assertionresult.hpp */,
+ 4A084F1C15DACEEA0027E631 /* catch_test_case_info.hpp */,
+ 26847E5C16BBACB60043B9C1 /* catch_message.hpp */,
+ 2627F7061935B55F009BCE2D /* catch_result_builder.hpp */,
+ 26711C92195D48F60033EDA2 /* catch_tag_alias_registry.hpp */,
+ );
+ name = impl;
+ sourceTree = "<group>";
+ };
+ 4AC91CBD155C37B500DC5117 /* Assertions */ = {
+ isa = PBXGroup;
+ children = (
+ 269831E519078C1600BB0CE0 /* catch_tostring.h */,
+ 269831E619078CA200BB0CE0 /* catch_tostring.hpp */,
+ 4A6D0C4D149B3E3D00DB3EAA /* catch_evaluate.hpp */,
+ 4A6D0C4F149B3E3D00DB3EAA /* catch_generators.hpp */,
+ 4A6D0C5C149B3E3D00DB3EAA /* catch_result_type.h */,
+ 4A6D0C5D149B3E3D00DB3EAA /* catch_assertionresult.h */,
+ 261488FE184DC32F0041FBEB /* catch_section.h */,
+ 4A3D7DD01503869D005F9203 /* catch_matchers.hpp */,
+ 4A6D0C46149B3E3D00DB3EAA /* catch_approx.hpp */,
+ 4A6D0C47149B3E3D00DB3EAA /* catch_capture.hpp */,
+ 4AC91CCE155CF02800DC5117 /* catch_expression_lhs.hpp */,
+ 4A4B0F9A15CEF84800AE2392 /* catch_notimplemented_exception.h */,
+ 26847E5B16BBAB790043B9C1 /* catch_message.h */,
+ 261488FD184D21290041FBEB /* catch_section_info.h */,
+ 2627F7051935B16F009BCE2D /* catch_result_builder.h */,
+ );
+ name = Assertions;
+ sourceTree = "<group>";
+ };
+ 4AC91CBE155C37F800DC5117 /* Registries */ = {
+ isa = PBXGroup;
+ children = (
+ 4A6D0C4E149B3E3D00DB3EAA /* catch_exception_translator_registry.hpp */,
+ 4A6D0C5A149B3E3D00DB3EAA /* catch_reporter_registrars.hpp */,
+ 4A6D0C5B149B3E3D00DB3EAA /* catch_reporter_registry.hpp */,
+ 4A6D0C63149B3E3D00DB3EAA /* catch_test_registry.hpp */,
+ );
+ name = Registries;
+ sourceTree = "<group>";
+ };
+ 4AC91CBF155C381600DC5117 /* Test execution */ = {
+ isa = PBXGroup;
+ children = (
+ 261488FA184C81130041FBEB /* catch_test_spec.hpp */,
+ 2656C21F1925E5100040DB02 /* catch_test_spec_parser.hpp */,
+ 4A6D0C4A149B3E3D00DB3EAA /* catch_config.hpp */,
+ 4A6D0C51149B3E3D00DB3EAA /* catch_context.h */,
+ 4A6D0C61149B3E3D00DB3EAA /* catch_test_case_info.h */,
+ 4A7ADB4314F631E10094FE10 /* catch_totals.hpp */,
+ 4AB77CB71553B72B00857BF0 /* catch_section_info.hpp */,
+ 26948287179EF7F900ED166E /* catch_test_case_tracker.hpp */,
+ 26711C91195D47820033EDA2 /* catch_tag_alias.h */,
+ 26711C94195D4B120033EDA2 /* catch_tag_alias_registry.h */,
+ );
+ name = "Test execution";
+ sourceTree = "<group>";
+ };
+ 4AC91CC0155C384400DC5117 /* Process */ = {
+ isa = PBXGroup;
+ children = (
+ 4A6D0C58149B3E3D00DB3EAA /* catch_list.hpp */,
+ 4A6D0C48149B3E3D00DB3EAA /* catch_commandline.hpp */,
+ 4A6D0C4C149B3E3D00DB3EAA /* catch_default_main.hpp */,
+ );
+ name = Process;
+ sourceTree = "<group>";
+ };
+ 4AC91CC1155C387400DC5117 /* Interfaces */ = {
+ isa = PBXGroup;
+ children = (
+ 4A4B0F9915CE6EC100AE2392 /* catch_interfaces_registry_hub.h */,
+ 4A6D0C53149B3E3D00DB3EAA /* catch_interfaces_capture.h */,
+ 4A6D0C54149B3E3D00DB3EAA /* catch_interfaces_exception.h */,
+ 4A6D0C55149B3E3D00DB3EAA /* catch_interfaces_reporter.h */,
+ 4A6D0C56149B3E3D00DB3EAA /* catch_interfaces_runner.h */,
+ 4A6D0C57149B3E3D00DB3EAA /* catch_interfaces_testcase.h */,
+ 4AFC661D157E96A7009D58CF /* catch_interfaces_config.h */,
+ 4A90B59B15D0F61A00EF71BC /* catch_interfaces_generators.h */,
+ 26711C90195D46CD0033EDA2 /* catch_interfaces_tag_alias_registry.h */,
+ );
+ name = Interfaces;
+ sourceTree = "<group>";
+ };
+ 4AC91CC2155C388300DC5117 /* Infrastructure */ = {
+ isa = PBXGroup;
+ children = (
+ 266ECD8C1713614B0030D735 /* catch_legacy_reporter_adapter.hpp */,
+ 266ECD8D1713614B0030D735 /* catch_legacy_reporter_adapter.h */,
+ 4A6D0C49149B3E3D00DB3EAA /* catch_common.h */,
+ 262E739A1846759000CAC268 /* catch_common.hpp */,
+ 4A6D0C4B149B3E3D00DB3EAA /* catch_debugger.hpp */,
+ 261488FF184DC4A20041FBEB /* catch_debugger.h */,
+ 4A6D0C60149B3E3D00DB3EAA /* catch_stream.hpp */,
+ 4A6D0C64149B3E3D00DB3EAA /* catch_xmlwriter.hpp */,
+ 4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */,
+ 4AB77CB51551AEA200857BF0 /* catch_ptr.hpp */,
+ 4AEE0326161431070071E950 /* catch_streambuf.h */,
+ 4ACE21C8166CA19700FB5509 /* catch_option.hpp */,
+ 26759473171C74C200A84BD1 /* catch_compiler_capabilities.h */,
+ 26DACF2F17206D3400A21326 /* catch_text.h */,
+ 263FD06117AF8DF200988A20 /* catch_timer.h */,
+ 26AEAF1617BEA18E009E32C9 /* catch_platform.h */,
+ 261488FC184D1DC10041FBEB /* catch_stream.h */,
+ 268F47B018A93F7800D8C14F /* catch_clara.h */,
+ 2656C226192A77EF0040DB02 /* catch_suppress_warnings.h */,
+ 2656C227192A78410040DB02 /* catch_reenable_warnings.h */,
+ 263F7A4519A66608009474C2 /* catch_fatal_condition.hpp */,
+ 26DFD3B11B53F84700FD6F16 /* catch_wildcard_pattern.hpp */,
+ );
+ name = Infrastructure;
+ sourceTree = "<group>";
+ };
+ 4AC91CC3155C38D300DC5117 /* Objective-C */ = {
+ isa = PBXGroup;
+ children = (
+ 4A6D0C59149B3E3D00DB3EAA /* catch_objc.hpp */,
+ 4ABEA80415C90D2B009F0424 /* catch_objc_arc.hpp */,
+ );
+ name = "Objective-C";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 4A6D0C1F149B3D3B00DB3EAA /* CatchSelfTest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 4A6D0C2A149B3D3B00DB3EAA /* Build configuration list for PBXNativeTarget "CatchSelfTest" */;
+ buildPhases = (
+ 4A6D0C1C149B3D3B00DB3EAA /* Sources */,
+ 4A6D0C1D149B3D3B00DB3EAA /* Frameworks */,
+ 4A6D0C1E149B3D3B00DB3EAA /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = CatchSelfTest;
+ productName = CatchSelfTest;
+ productReference = 4A6D0C20149B3D3B00DB3EAA /* CatchSelfTest */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 4A6D0C17149B3D3B00DB3EAA /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0710;
+ };
+ buildConfigurationList = 4A6D0C1A149B3D3B00DB3EAA /* Build configuration list for PBXProject "CatchSelfTest" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 4A6D0C15149B3D3B00DB3EAA;
+ productRefGroup = 4A6D0C21149B3D3B00DB3EAA /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 4A6D0C1F149B3D3B00DB3EAA /* CatchSelfTest */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 4A6D0C1C149B3D3B00DB3EAA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 263F7A4719B6FCBF009474C2 /* EnumToString.cpp in Sources */,
+ 4A6D0C37149B3D9E00DB3EAA /* ApproxTests.cpp in Sources */,
+ 4A6D0C38149B3D9E00DB3EAA /* ClassTests.cpp in Sources */,
+ 4A6D0C39149B3D9E00DB3EAA /* ConditionTests.cpp in Sources */,
+ 4A6D0C3A149B3D9E00DB3EAA /* ExceptionTests.cpp in Sources */,
+ 4A6D0C3B149B3D9E00DB3EAA /* GeneratorTests.cpp in Sources */,
+ 4A6D0C3C149B3D9E00DB3EAA /* MessageTests.cpp in Sources */,
+ 4A6D0C3D149B3D9E00DB3EAA /* MiscTests.cpp in Sources */,
+ 4A6D0C3E149B3D9E00DB3EAA /* TestMain.cpp in Sources */,
+ 4A6D0C3F149B3D9E00DB3EAA /* TrickyTests.cpp in Sources */,
+ 263F7A4D19B6FE1E009474C2 /* ToStringWhich.cpp in Sources */,
+ 26059AF21BD4B94C003D575C /* PartTrackerTests.cpp in Sources */,
+ 263F7A4B19B6FE1E009474C2 /* ToStringPair.cpp in Sources */,
+ 4AEE032016142F910071E950 /* catch_common.cpp in Sources */,
+ 263F7A4C19B6FE1E009474C2 /* ToStringVector.cpp in Sources */,
+ 4AEE032316142FC70071E950 /* catch_debugger.cpp in Sources */,
+ 4AEE032516142FF10071E950 /* catch_stream.cpp in Sources */,
+ 4AEE0328161434FD0071E950 /* catch_xmlwriter.cpp in Sources */,
+ 4A45DA2416161EF9004F8D6B /* catch_console_colour.cpp in Sources */,
+ 4A45DA2716161F1F004F8D6B /* catch_ptr.cpp in Sources */,
+ 26E1B7D319213BC900812682 /* CmdLineTests.cpp in Sources */,
+ 2656C2211925E7330040DB02 /* catch_test_spec.cpp in Sources */,
+ 4A45DA2916161F3D004F8D6B /* catch_streambuf.cpp in Sources */,
+ 4A45DA2B16161F79004F8D6B /* catch_interfaces_registry_hub.cpp in Sources */,
+ 4A45DA2D16161FA2004F8D6B /* catch_interfaces_capture.cpp in Sources */,
+ 4A45DA3116161FFC004F8D6B /* catch_interfaces_reporter.cpp in Sources */,
+ 4A45DA3316162047004F8D6B /* catch_interfaces_exception.cpp in Sources */,
+ 2691574C1A532A280054F1ED /* ToStringTuple.cpp in Sources */,
+ 26711C8F195D465C0033EDA2 /* TagAliasTests.cpp in Sources */,
+ 4A45DA3516162071004F8D6B /* catch_interfaces_runner.cpp in Sources */,
+ 4AB3D99D1616216500C9A0F8 /* catch_interfaces_testcase.cpp in Sources */,
+ 4AB3D9A01616219100C9A0F8 /* catch_interfaces_config.cpp in Sources */,
+ 4AB3D9A2161621B500C9A0F8 /* catch_interfaces_generators.cpp in Sources */,
+ 4ACE21CC166CA1B300FB5509 /* catch_option.cpp in Sources */,
+ 2694A1FD16A0000E004816E3 /* catch_text.cpp in Sources */,
+ 26847E5F16BBADB40043B9C1 /* catch_message.cpp in Sources */,
+ 266B06B816F3A60A004ED264 /* VariadicMacrosTests.cpp in Sources */,
+ 266ECD74170F3C620030D735 /* BDDTests.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 4A6D0C28149B3D3B00DB3EAA /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_WARN_CXX0X_EXTENSIONS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
+ CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CLANG_WARN__EXIT_TIME_DESTRUCTORS = NO;
+ COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
+ GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+ GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
+ GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+ GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+ GCC_WARN_PEDANTIC = YES;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_SIGN_COMPARE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_PARAMETER = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = "";
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ USER_HEADER_SEARCH_PATHS = "\"$(PROJECT_DIR)/../../../include\"";
+ };
+ name = Debug;
+ };
+ 4A6D0C29149B3D3B00DB3EAA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_WARN_CXX0X_EXTENSIONS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
+ CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CLANG_WARN__EXIT_TIME_DESTRUCTORS = NO;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
+ GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+ GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
+ GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+ GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
+ GCC_WARN_PEDANTIC = YES;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_SIGN_COMPARE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_PARAMETER = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = "";
+ SDKROOT = macosx;
+ USER_HEADER_SEARCH_PATHS = "\"$(PROJECT_DIR)/../../../include\"";
+ };
+ name = Release;
+ };
+ 4A6D0C2B149B3D3B00DB3EAA /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+ CLANG_CXX_LIBRARY = "compiler-default";
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WARNING_CFLAGS = (
+ "-Weverything",
+ "-Wparentheses",
+ "-Wno-disabled-macro-expansion",
+ );
+ };
+ name = Debug;
+ };
+ 4A6D0C2C149B3D3B00DB3EAA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+ CLANG_CXX_LIBRARY = "compiler-default";
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WARNING_CFLAGS = (
+ "-Weverything",
+ "-Wparentheses",
+ "-Wno-disabled-macro-expansion",
+ );
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 4A6D0C1A149B3D3B00DB3EAA /* Build configuration list for PBXProject "CatchSelfTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4A6D0C28149B3D3B00DB3EAA /* Debug */,
+ 4A6D0C29149B3D3B00DB3EAA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 4A6D0C2A149B3D3B00DB3EAA /* Build configuration list for PBXNativeTarget "CatchSelfTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4A6D0C2B149B3D3B00DB3EAA /* Debug */,
+ 4A6D0C2C149B3D3B00DB3EAA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 4A6D0C17149B3D3B00DB3EAA /* Project object */;
+}
diff --git a/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000000..804437d0651
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:CatchSelfTest.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest/CatchSelfTest.1 b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest/CatchSelfTest.1
new file mode 100644
index 00000000000..28b36e20289
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest/CatchSelfTest.1
@@ -0,0 +1,79 @@
+.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
+.\"See Also:
+.\"man mdoc.samples for a complete listing of options
+.\"man mdoc for the short list of editing options
+.\"/usr/share/misc/mdoc.template
+.Dd 16/12/2011 \" DATE
+.Dt CatchSelfTest 1 \" Program name and manual section number
+.Os Darwin
+.Sh NAME \" Section Header - required - don't modify
+.Nm CatchSelfTest,
+.\" The following lines are read in generating the apropos(man -k) database. Use only key
+.\" words here as the database is built based on the words here and in the .ND line.
+.Nm Other_name_for_same_program(),
+.Nm Yet another name for the same program.
+.\" Use .Nm macro to designate other names for the documented program.
+.Nd This line parsed for whatis database.
+.Sh SYNOPSIS \" Section Header - required - don't modify
+.Nm
+.Op Fl abcd \" [-abcd]
+.Op Fl a Ar path \" [-a path]
+.Op Ar file \" [file]
+.Op Ar \" [file ...]
+.Ar arg0 \" Underlined argument - use .Ar anywhere to underline
+arg2 ... \" Arguments
+.Sh DESCRIPTION \" Section Header - required - don't modify
+Use the .Nm macro to refer to your program throughout the man page like such:
+.Nm
+Underlining is accomplished with the .Ar macro like this:
+.Ar underlined text .
+.Pp \" Inserts a space
+A list of items with descriptions:
+.Bl -tag -width -indent \" Begins a tagged list
+.It item a \" Each item preceded by .It macro
+Description of item a
+.It item b
+Description of item b
+.El \" Ends the list
+.Pp
+A list of flags and their descriptions:
+.Bl -tag -width -indent \" Differs from above in tag removed
+.It Fl a \"-a flag as a list item
+Description of -a flag
+.It Fl b
+Description of -b flag
+.El \" Ends the list
+.Pp
+.\" .Sh ENVIRONMENT \" May not be needed
+.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
+.\" .It Ev ENV_VAR_1
+.\" Description of ENV_VAR_1
+.\" .It Ev ENV_VAR_2
+.\" Description of ENV_VAR_2
+.\" .El
+.Sh FILES \" File used or created by the topic of the man page
+.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
+.It Pa /usr/share/file_name
+FILE_1 description
+.It Pa /Users/joeuser/Library/really_long_file_name
+FILE_2 description
+.El \" Ends the list
+.\" .Sh DIAGNOSTICS \" May not be needed
+.\" .Bl -diag
+.\" .It Diagnostic Tag
+.\" Diagnostic informtion here.
+.\" .It Diagnostic Tag
+.\" Diagnostic informtion here.
+.\" .El
+.Sh SEE ALSO
+.\" List links in ascending order by section, alphabetically within a section.
+.\" Please do not reference files that do not exist without filing a bug report
+.Xr a 1 ,
+.Xr b 1 ,
+.Xr c 1 ,
+.Xr a 2 ,
+.Xr b 2 ,
+.Xr a 3 ,
+.Xr b 3
+.\" .Sh BUGS \" Document known, unremedied bugs
+.\" .Sh HISTORY \" Document history if command behaves in a unique manner \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest/catch_text.cpp b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest/catch_text.cpp
new file mode 100644
index 00000000000..a08e67b3670
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTest/catch_text.cpp
@@ -0,0 +1,3 @@
+// This file is only here to verify (to the extent possible) the self sufficiency of the header
+#include "catch_suppress_warnings.h"
+#include "catch_text.h"
diff --git a/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle.xcodeproj/project.pbxproj b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle.xcodeproj/project.pbxproj
new file mode 100644
index 00000000000..1eee6eb6b64
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle.xcodeproj/project.pbxproj
@@ -0,0 +1,258 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 4A2894D615D3956000E20735 /* ApproxTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A2894D515D3956000E20735 /* ApproxTests.cpp */; };
+ 4AB735FA15D396F400F9F7C3 /* TestMain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A2894E015D3957500E20735 /* TestMain.cpp */; };
+ 4AB735FB15D3970C00F9F7C3 /* ClassTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A2894DA15D3957500E20735 /* ClassTests.cpp */; };
+ 4AB735FC15D3971100F9F7C3 /* ConditionTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A2894DB15D3957500E20735 /* ConditionTests.cpp */; };
+ 4AB735FD15D3971600F9F7C3 /* ExceptionTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A2894DC15D3957500E20735 /* ExceptionTests.cpp */; };
+ 4AB735FE15D3971600F9F7C3 /* GeneratorTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A2894DD15D3957500E20735 /* GeneratorTests.cpp */; };
+ 4AB735FF15D3971600F9F7C3 /* MessageTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A2894DE15D3957500E20735 /* MessageTests.cpp */; };
+ 4AB7360015D3971600F9F7C3 /* MiscTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A2894DF15D3957500E20735 /* MiscTests.cpp */; };
+ 4AB7360115D3971600F9F7C3 /* TrickyTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4A2894E115D3957500E20735 /* TrickyTests.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 4A90B5D415D2E3E900EF71BC /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = /usr/share/man/man1/;
+ dstSubfolderSpec = 0;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 4A2894D515D3956000E20735 /* ApproxTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ApproxTests.cpp; path = ../../../SelfTest/ApproxTests.cpp; sourceTree = "<group>"; };
+ 4A2894DA15D3957500E20735 /* ClassTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ClassTests.cpp; path = ../../../SelfTest/ClassTests.cpp; sourceTree = "<group>"; };
+ 4A2894DB15D3957500E20735 /* ConditionTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ConditionTests.cpp; path = ../../../SelfTest/ConditionTests.cpp; sourceTree = "<group>"; };
+ 4A2894DC15D3957500E20735 /* ExceptionTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ExceptionTests.cpp; path = ../../../SelfTest/ExceptionTests.cpp; sourceTree = "<group>"; };
+ 4A2894DD15D3957500E20735 /* GeneratorTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = GeneratorTests.cpp; path = ../../../SelfTest/GeneratorTests.cpp; sourceTree = "<group>"; };
+ 4A2894DE15D3957500E20735 /* MessageTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MessageTests.cpp; path = ../../../SelfTest/MessageTests.cpp; sourceTree = "<group>"; };
+ 4A2894DF15D3957500E20735 /* MiscTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = MiscTests.cpp; path = ../../../SelfTest/MiscTests.cpp; sourceTree = "<group>"; };
+ 4A2894E015D3957500E20735 /* TestMain.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = TestMain.cpp; path = ../../../SelfTest/TestMain.cpp; sourceTree = "<group>"; };
+ 4A2894E115D3957500E20735 /* TrickyTests.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = TrickyTests.cpp; path = ../../../SelfTest/TrickyTests.cpp; sourceTree = "<group>"; };
+ 4A90B5D615D2E3E900EF71BC /* CatchSelfTestSingle */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = CatchSelfTestSingle; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 4A90B5D315D2E3E900EF71BC /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 4A2894E215D3957D00E20735 /* Self Test */ = {
+ isa = PBXGroup;
+ children = (
+ 4A2894E015D3957500E20735 /* TestMain.cpp */,
+ );
+ name = "Self Test";
+ sourceTree = "<group>";
+ };
+ 4A2894E315D3959800E20735 /* Test Cases */ = {
+ isa = PBXGroup;
+ children = (
+ 4A2894DA15D3957500E20735 /* ClassTests.cpp */,
+ 4A2894DB15D3957500E20735 /* ConditionTests.cpp */,
+ 4A2894DC15D3957500E20735 /* ExceptionTests.cpp */,
+ 4A2894DD15D3957500E20735 /* GeneratorTests.cpp */,
+ 4A2894DE15D3957500E20735 /* MessageTests.cpp */,
+ 4A2894DF15D3957500E20735 /* MiscTests.cpp */,
+ 4A2894E115D3957500E20735 /* TrickyTests.cpp */,
+ 4A2894D515D3956000E20735 /* ApproxTests.cpp */,
+ );
+ name = "Test Cases";
+ sourceTree = "<group>";
+ };
+ 4A90B5CB15D2E3E900EF71BC = {
+ isa = PBXGroup;
+ children = (
+ 4A90B5D915D2E3E900EF71BC /* CatchSelfTestSingle */,
+ 4A90B5D715D2E3E900EF71BC /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ 4A90B5D715D2E3E900EF71BC /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 4A90B5D615D2E3E900EF71BC /* CatchSelfTestSingle */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 4A90B5D915D2E3E900EF71BC /* CatchSelfTestSingle */ = {
+ isa = PBXGroup;
+ children = (
+ 4A2894E315D3959800E20735 /* Test Cases */,
+ 4A2894E215D3957D00E20735 /* Self Test */,
+ );
+ path = CatchSelfTestSingle;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 4A90B5D515D2E3E900EF71BC /* CatchSelfTestSingle */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 4A90B5E015D2E3E900EF71BC /* Build configuration list for PBXNativeTarget "CatchSelfTestSingle" */;
+ buildPhases = (
+ 4A90B5D215D2E3E900EF71BC /* Sources */,
+ 4A90B5D315D2E3E900EF71BC /* Frameworks */,
+ 4A90B5D415D2E3E900EF71BC /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = CatchSelfTestSingle;
+ productName = CatchSelfTestSingle;
+ productReference = 4A90B5D615D2E3E900EF71BC /* CatchSelfTestSingle */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 4A90B5CD15D2E3E900EF71BC /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0500;
+ ORGANIZATIONNAME = "Phil Nash";
+ };
+ buildConfigurationList = 4A90B5D015D2E3E900EF71BC /* Build configuration list for PBXProject "CatchSelfTestSingle" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 4A90B5CB15D2E3E900EF71BC;
+ productRefGroup = 4A90B5D715D2E3E900EF71BC /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 4A90B5D515D2E3E900EF71BC /* CatchSelfTestSingle */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 4A90B5D215D2E3E900EF71BC /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4A2894D615D3956000E20735 /* ApproxTests.cpp in Sources */,
+ 4AB735FA15D396F400F9F7C3 /* TestMain.cpp in Sources */,
+ 4AB735FB15D3970C00F9F7C3 /* ClassTests.cpp in Sources */,
+ 4AB735FC15D3971100F9F7C3 /* ConditionTests.cpp in Sources */,
+ 4AB735FD15D3971600F9F7C3 /* ExceptionTests.cpp in Sources */,
+ 4AB735FE15D3971600F9F7C3 /* GeneratorTests.cpp in Sources */,
+ 4AB735FF15D3971600F9F7C3 /* MessageTests.cpp in Sources */,
+ 4AB7360015D3971600F9F7C3 /* MiscTests.cpp in Sources */,
+ 4AB7360115D3971600F9F7C3 /* TrickyTests.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 4A90B5DE15D2E3E900EF71BC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.8;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 4A90B5DF15D2E3E900EF71BC /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.8;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+ 4A90B5E115D2E3E900EF71BC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LIBRARY = "libc++";
+ HEADER_SEARCH_PATHS = "../../../single_include/**";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 4A90B5E215D2E3E900EF71BC /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LIBRARY = "libc++";
+ HEADER_SEARCH_PATHS = "../../../single_include/**";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 4A90B5D015D2E3E900EF71BC /* Build configuration list for PBXProject "CatchSelfTestSingle" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4A90B5DE15D2E3E900EF71BC /* Debug */,
+ 4A90B5DF15D2E3E900EF71BC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 4A90B5E015D2E3E900EF71BC /* Build configuration list for PBXNativeTarget "CatchSelfTestSingle" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4A90B5E115D2E3E900EF71BC /* Debug */,
+ 4A90B5E215D2E3E900EF71BC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 4A90B5CD15D2E3E900EF71BC /* Project object */;
+}
diff --git a/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000000..4fcfc0e62ac
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:CatchSelfTestSingle.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle/dummy.txt b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle/dummy.txt
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/CatchSelfTest/CatchSelfTestSingle/dummy.txt
diff --git a/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest.xcodeproj/project.pbxproj b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest.xcodeproj/project.pbxproj
new file mode 100644
index 00000000000..6777e8e72c9
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest.xcodeproj/project.pbxproj
@@ -0,0 +1,265 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 4A63D2AC14E3C1A900F615CB /* OCTest.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4A63D2AB14E3C1A900F615CB /* OCTest.1 */; };
+ 4A63D2B314E3C1E600F615CB /* Main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4A63D2B214E3C1E600F615CB /* Main.mm */; };
+ 4A63D2C014E4544700F615CB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A63D2BF14E4544700F615CB /* Foundation.framework */; };
+ 4A63D2C614E454CC00F615CB /* CatchOCTestCase.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4A63D2C214E454CC00F615CB /* CatchOCTestCase.mm */; };
+ 4A63D2C714E454CC00F615CB /* OCTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4A63D2C314E454CC00F615CB /* OCTest.mm */; };
+ 4A63D2C814E454CC00F615CB /* TestObj.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A63D2C514E454CC00F615CB /* TestObj.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 4A63D2A314E3C1A900F615CB /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = /usr/share/man/man1/;
+ dstSubfolderSpec = 0;
+ files = (
+ 4A63D2AC14E3C1A900F615CB /* OCTest.1 in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 4A63D2A514E3C1A900F615CB /* OCTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = OCTest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4A63D2AB14E3C1A900F615CB /* OCTest.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = OCTest.1; sourceTree = "<group>"; };
+ 4A63D2B214E3C1E600F615CB /* Main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Main.mm; sourceTree = "<group>"; };
+ 4A63D2BF14E4544700F615CB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 4A63D2C114E454CC00F615CB /* CatchOCTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CatchOCTestCase.h; sourceTree = "<group>"; };
+ 4A63D2C214E454CC00F615CB /* CatchOCTestCase.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CatchOCTestCase.mm; sourceTree = "<group>"; };
+ 4A63D2C314E454CC00F615CB /* OCTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OCTest.mm; sourceTree = "<group>"; };
+ 4A63D2C414E454CC00F615CB /* TestObj.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestObj.h; sourceTree = "<group>"; };
+ 4A63D2C514E454CC00F615CB /* TestObj.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestObj.m; sourceTree = "<group>"; };
+ 4AA0D951154C0A7A004B4193 /* catch_objc.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_objc.hpp; path = ../../../include/internal/catch_objc.hpp; sourceTree = "<group>"; };
+ 4ABEA80615C90E10009F0424 /* catch_objc_arc.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_objc_arc.hpp; path = ../../../include/internal/catch_objc_arc.hpp; sourceTree = "<group>"; };
+ 4ABEA80815C90E38009F0424 /* catch_tostring.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_tostring.hpp; path = ../../../include/internal/catch_tostring.hpp; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 4A63D2A214E3C1A900F615CB /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4A63D2C014E4544700F615CB /* Foundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 4A63D29A14E3C1A900F615CB = {
+ isa = PBXGroup;
+ children = (
+ 4AA0D94F154C0A63004B4193 /* Catch */,
+ 4A63D2BF14E4544700F615CB /* Foundation.framework */,
+ 4A63D2A814E3C1A900F615CB /* OCTest */,
+ 4A63D2A614E3C1A900F615CB /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ 4A63D2A614E3C1A900F615CB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 4A63D2A514E3C1A900F615CB /* OCTest */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 4A63D2A814E3C1A900F615CB /* OCTest */ = {
+ isa = PBXGroup;
+ children = (
+ 4A63D2C114E454CC00F615CB /* CatchOCTestCase.h */,
+ 4A63D2C214E454CC00F615CB /* CatchOCTestCase.mm */,
+ 4A63D2C314E454CC00F615CB /* OCTest.mm */,
+ 4A63D2C414E454CC00F615CB /* TestObj.h */,
+ 4A63D2C514E454CC00F615CB /* TestObj.m */,
+ 4A63D2B214E3C1E600F615CB /* Main.mm */,
+ 4A63D2AB14E3C1A900F615CB /* OCTest.1 */,
+ );
+ path = OCTest;
+ sourceTree = "<group>";
+ };
+ 4AA0D94F154C0A63004B4193 /* Catch */ = {
+ isa = PBXGroup;
+ children = (
+ 4ABEA80815C90E38009F0424 /* catch_tostring.hpp */,
+ 4ABEA80615C90E10009F0424 /* catch_objc_arc.hpp */,
+ 4AA0D951154C0A7A004B4193 /* catch_objc.hpp */,
+ );
+ name = Catch;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 4A63D2A414E3C1A900F615CB /* OCTest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 4A63D2AF14E3C1A900F615CB /* Build configuration list for PBXNativeTarget "OCTest" */;
+ buildPhases = (
+ 4A63D2A114E3C1A900F615CB /* Sources */,
+ 4A63D2A214E3C1A900F615CB /* Frameworks */,
+ 4A63D2A314E3C1A900F615CB /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = OCTest;
+ productName = OCTest;
+ productReference = 4A63D2A514E3C1A900F615CB /* OCTest */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 4A63D29C14E3C1A900F615CB /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0500;
+ };
+ buildConfigurationList = 4A63D29F14E3C1A900F615CB /* Build configuration list for PBXProject "OCTest" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 4A63D29A14E3C1A900F615CB;
+ productRefGroup = 4A63D2A614E3C1A900F615CB /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 4A63D2A414E3C1A900F615CB /* OCTest */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 4A63D2A114E3C1A900F615CB /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4A63D2B314E3C1E600F615CB /* Main.mm in Sources */,
+ 4A63D2C614E454CC00F615CB /* CatchOCTestCase.mm in Sources */,
+ 4A63D2C714E454CC00F615CB /* OCTest.mm in Sources */,
+ 4A63D2C814E454CC00F615CB /* TestObj.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 4A63D2AD14E3C1A900F615CB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = ../../../include;
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 4A63D2AE14E3C1A900F615CB /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = ../../../include;
+ MACOSX_DEPLOYMENT_TARGET = 10.7;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+ 4A63D2B014E3C1A900F615CB /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ HEADER_SEARCH_PATHS = ../../../include;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 4A63D2B114E3C1A900F615CB /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_ARC = YES;
+ HEADER_SEARCH_PATHS = ../../../include;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 4A63D29F14E3C1A900F615CB /* Build configuration list for PBXProject "OCTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4A63D2AD14E3C1A900F615CB /* Debug */,
+ 4A63D2AE14E3C1A900F615CB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 4A63D2AF14E3C1A900F615CB /* Build configuration list for PBXNativeTarget "OCTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4A63D2B014E3C1A900F615CB /* Debug */,
+ 4A63D2B114E3C1A900F615CB /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 4A63D29C14E3C1A900F615CB /* Project object */;
+}
diff --git a/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000000..119e61c58c7
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:OCTest.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/CatchOCTestCase.h b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/CatchOCTestCase.h
new file mode 100644
index 00000000000..bd26239ae16
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/CatchOCTestCase.h
@@ -0,0 +1,25 @@
+//
+// CatchOCTestCase.h
+// OCTest
+//
+// Created by Phil on 13/11/2010.
+// Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef TWOBLUECUBES_CATCHOCTESTCASE_H_INCLUDED
+#define TWOBLUECUBES_CATCHOCTESTCASE_H_INCLUDED
+
+#include "catch.hpp"
+
+#import <Cocoa/Cocoa.h>
+#import "TestObj.h"
+
+@interface TestFixture : NSObject <OcFixture>
+{
+ TestObj* obj;
+}
+
+@end
+
+#endif // TWOBLUECUBES_CATCHOCTESTCASE_H_INCLUDED
diff --git a/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/CatchOCTestCase.mm b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/CatchOCTestCase.mm
new file mode 100644
index 00000000000..fb20287b8f0
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/CatchOCTestCase.mm
@@ -0,0 +1,83 @@
+//
+// CatchOCTestCase.mm
+// OCTest
+//
+// Created by Phil Nash on 13/11/2010.
+// Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#import "CatchOCTestCase.h"
+
+
+@implementation TestFixture
+
+
+-(void) setUp
+{
+ obj = [[TestObj alloc] init];
+}
+
+-(void) tearDown
+{
+ arcSafeRelease( obj );
+}
+
+OC_TEST_CASE( "OCTest/test1", "This is a test case" )
+{
+ REQUIRE( obj.int_val == 0 );
+
+ obj.int_val = 1;
+
+ REQUIRE( obj.int_val == 1 );
+}
+
+OC_TEST_CASE( "OCTest/test2", "This is another test case" )
+{
+ REQUIRE( obj.int_val == 0 );
+
+ obj.int_val = 2;
+
+ REQUIRE( obj.int_val == 2 );
+}
+
+OC_TEST_CASE( "OCTest/BOOL", "tests a boolean value" )
+{
+ CHECK( [obj isTrue] == NO );
+ CHECK( [obj isFalse] == YES );
+}
+
+OC_TEST_CASE( "OCTest/throws/objc", "throws an Objective-C exception" )
+{
+ @throw [[NSException alloc] initWithName: NSGenericException
+ reason: @"Objective-C exception"
+ userInfo: nil];
+}
+OC_TEST_CASE( "OCTest/throws/stdc++", "throws a std c++ exception" )
+{
+ throw std::domain_error( "std C++ exception" );
+}
+
+///////////////////////////////////////////////////////////////////////////
+template<typename T>
+void useObject( const T& object ){}
+
+template<typename T>
+void useObject( const T* object ){}
+
+OC_TEST_CASE( "OCTest/matchers", "Matches work with OC types (NSString so far)" )
+{
+ REQUIRE_THAT( @"This is a string", Equals( @"This isnt a string" ) );
+ REQUIRE_THAT( @"This is a string", Contains( @"is a" ) );
+ REQUIRE_THAT( @"This is a string", StartsWith( @"This" ) );
+ REQUIRE_THAT( @"This is a string", EndsWith( @"string" ) );
+}
+
+OC_TEST_CASE( "OCTest/matchers/nil", "nil NSString should not crash the test" )
+{
+ CHECK_THAT( (NSString*)nil, Equals( @"This should fail, but not crash" ) );
+ CHECK_THAT( (NSString*)nil, StartsWith( @"anything" ) );
+}
+
+@end
diff --git a/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/Main.mm b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/Main.mm
new file mode 100644
index 00000000000..569dc4d9cab
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/Main.mm
@@ -0,0 +1,2 @@
+#define CATCH_CONFIG_MAIN
+#import "catch.hpp"
diff --git a/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/OCTest.1 b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/OCTest.1
new file mode 100644
index 00000000000..7915d02a059
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/OCTest.1
@@ -0,0 +1,79 @@
+.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
+.\"See Also:
+.\"man mdoc.samples for a complete listing of options
+.\"man mdoc for the short list of editing options
+.\"/usr/share/misc/mdoc.template
+.Dd 09/02/2012 \" DATE
+.Dt OCTest 1 \" Program name and manual section number
+.Os Darwin
+.Sh NAME \" Section Header - required - don't modify
+.Nm OCTest,
+.\" The following lines are read in generating the apropos(man -k) database. Use only key
+.\" words here as the database is built based on the words here and in the .ND line.
+.Nm Other_name_for_same_program(),
+.Nm Yet another name for the same program.
+.\" Use .Nm macro to designate other names for the documented program.
+.Nd This line parsed for whatis database.
+.Sh SYNOPSIS \" Section Header - required - don't modify
+.Nm
+.Op Fl abcd \" [-abcd]
+.Op Fl a Ar path \" [-a path]
+.Op Ar file \" [file]
+.Op Ar \" [file ...]
+.Ar arg0 \" Underlined argument - use .Ar anywhere to underline
+arg2 ... \" Arguments
+.Sh DESCRIPTION \" Section Header - required - don't modify
+Use the .Nm macro to refer to your program throughout the man page like such:
+.Nm
+Underlining is accomplished with the .Ar macro like this:
+.Ar underlined text .
+.Pp \" Inserts a space
+A list of items with descriptions:
+.Bl -tag -width -indent \" Begins a tagged list
+.It item a \" Each item preceded by .It macro
+Description of item a
+.It item b
+Description of item b
+.El \" Ends the list
+.Pp
+A list of flags and their descriptions:
+.Bl -tag -width -indent \" Differs from above in tag removed
+.It Fl a \"-a flag as a list item
+Description of -a flag
+.It Fl b
+Description of -b flag
+.El \" Ends the list
+.Pp
+.\" .Sh ENVIRONMENT \" May not be needed
+.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
+.\" .It Ev ENV_VAR_1
+.\" Description of ENV_VAR_1
+.\" .It Ev ENV_VAR_2
+.\" Description of ENV_VAR_2
+.\" .El
+.Sh FILES \" File used or created by the topic of the man page
+.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
+.It Pa /usr/share/file_name
+FILE_1 description
+.It Pa /Users/joeuser/Library/really_long_file_name
+FILE_2 description
+.El \" Ends the list
+.\" .Sh DIAGNOSTICS \" May not be needed
+.\" .Bl -diag
+.\" .It Diagnostic Tag
+.\" Diagnostic informtion here.
+.\" .It Diagnostic Tag
+.\" Diagnostic informtion here.
+.\" .El
+.Sh SEE ALSO
+.\" List links in ascending order by section, alphabetically within a section.
+.\" Please do not reference files that do not exist without filing a bug report
+.Xr a 1 ,
+.Xr b 1 ,
+.Xr c 1 ,
+.Xr a 2 ,
+.Xr b 2 ,
+.Xr a 3 ,
+.Xr b 3
+.\" .Sh BUGS \" Document known, unremedied bugs
+.\" .Sh HISTORY \" Document history if command behaves in a unique manner \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/OCTest.mm b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/OCTest.mm
new file mode 100644
index 00000000000..bfb2ca26d00
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/OCTest.mm
@@ -0,0 +1,28 @@
+/*
+ * OCTest.mm
+ * OCTest
+ *
+ * Created by Phil on 13/11/2010.
+ * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+
+#import "catch.hpp"
+
+#import "TestObj.h"
+
+TEST_CASE( "OCTest/TestObj", "tests TestObj" )
+{
+ TestObj* obj = [[TestObj alloc] init];
+
+ REQUIRE( obj.int_val == 0 );
+
+ obj.int_val = 1;
+
+ REQUIRE( obj.int_val == 1 );
+
+ arcSafeRelease( obj );
+}
diff --git a/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/TestObj.h b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/TestObj.h
new file mode 100644
index 00000000000..8443921ffe4
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/TestObj.h
@@ -0,0 +1,28 @@
+//
+// TestObj.h
+// OCTest
+//
+// Created by Phil on 13/11/2010.
+// Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef TWOBLUECUBES_TESTOBJ_H_INCLUDED
+#define TWOBLUECUBES_TESTOBJ_H_INCLUDED
+
+#import <Foundation/Foundation.h>
+
+
+@interface TestObj : NSObject {
+
+ int int_val;
+}
+
+-(BOOL) isTrue;
+-(BOOL) isFalse;
+
+@property (nonatomic, assign ) int int_val;
+
+@end
+
+#endif // TWOBLUECUBES_TESTOBJ_H_INCLUDED
diff --git a/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/TestObj.m b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/TestObj.m
new file mode 100644
index 00000000000..2c7dc99b8f7
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/OCTest/OCTest/TestObj.m
@@ -0,0 +1,25 @@
+//
+// TestObj.m
+// OCTest
+//
+// Created by Phil on 13/11/2010.
+// Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#import "TestObj.h"
+
+
+@implementation TestObj
+
+@synthesize int_val;
+
+-(BOOL) isTrue {
+ return YES;
+}
+-(BOOL) isFalse {
+ return NO;
+}
+
+@end
diff --git a/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest.xcodeproj/project.pbxproj b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest.xcodeproj/project.pbxproj
new file mode 100644
index 00000000000..e968cf620fc
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest.xcodeproj/project.pbxproj
@@ -0,0 +1,299 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 4A73280A14E66CFC0044823F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A73280914E66CFC0044823F /* UIKit.framework */; };
+ 4A73280C14E66CFC0044823F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A73280B14E66CFC0044823F /* Foundation.framework */; };
+ 4A73280E14E66CFC0044823F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A73280D14E66CFC0044823F /* CoreGraphics.framework */; };
+ 4A73281414E66CFC0044823F /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4A73281214E66CFC0044823F /* InfoPlist.strings */; };
+ 4A73282614E66D8B0044823F /* itChRunnerMain.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4A73282514E66D8B0044823F /* itChRunnerMain.mm */; };
+ 4AB1C74F14FCC74900F31DF7 /* OCTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4AB1C74C14FCC74900F31DF7 /* OCTest.mm */; };
+ 4AB1C75014FCC74900F31DF7 /* TestObj.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AB1C74E14FCC74900F31DF7 /* TestObj.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 4A73280514E66CFC0044823F /* iOSTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOSTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4A73280914E66CFC0044823F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
+ 4A73280B14E66CFC0044823F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ 4A73280D14E66CFC0044823F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 4A73281114E66CFC0044823F /* iOSTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "iOSTest-Info.plist"; sourceTree = "<group>"; };
+ 4A73281314E66CFC0044823F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 4A73281714E66CFC0044823F /* iOSTest-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "iOSTest-Prefix.pch"; sourceTree = "<group>"; };
+ 4A73282214E66D8B0044823F /* iTchRunnerAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTchRunnerAppDelegate.h; sourceTree = "<group>"; };
+ 4A73282314E66D8B0044823F /* iTchRunnerMainView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTchRunnerMainView.h; sourceTree = "<group>"; };
+ 4A73282414E66D8B0044823F /* iTchRunnerReporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTchRunnerReporter.h; sourceTree = "<group>"; };
+ 4A73282514E66D8B0044823F /* itChRunnerMain.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = itChRunnerMain.mm; path = ../../../runners/iTchRunner/itChRunnerMain.mm; sourceTree = "<group>"; };
+ 4AB1C74C14FCC74900F31DF7 /* OCTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OCTest.mm; sourceTree = "<group>"; };
+ 4AB1C74D14FCC74900F31DF7 /* TestObj.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestObj.h; sourceTree = "<group>"; };
+ 4AB1C74E14FCC74900F31DF7 /* TestObj.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestObj.m; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 4A73280214E66CFC0044823F /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4A73280A14E66CFC0044823F /* UIKit.framework in Frameworks */,
+ 4A73280C14E66CFC0044823F /* Foundation.framework in Frameworks */,
+ 4A73280E14E66CFC0044823F /* CoreGraphics.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 4A7327FA14E66CFC0044823F = {
+ isa = PBXGroup;
+ children = (
+ 4A73280F14E66CFC0044823F /* iOSTest */,
+ 4A73280814E66CFC0044823F /* Frameworks */,
+ 4A73280614E66CFC0044823F /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ 4A73280614E66CFC0044823F /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 4A73280514E66CFC0044823F /* iOSTest.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 4A73280814E66CFC0044823F /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 4A73280914E66CFC0044823F /* UIKit.framework */,
+ 4A73280B14E66CFC0044823F /* Foundation.framework */,
+ 4A73280D14E66CFC0044823F /* CoreGraphics.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 4A73280F14E66CFC0044823F /* iOSTest */ = {
+ isa = PBXGroup;
+ children = (
+ 4A73282014E66D6C0044823F /* iTch */,
+ 4A73281014E66CFC0044823F /* Supporting Files */,
+ );
+ path = iOSTest;
+ sourceTree = "<group>";
+ };
+ 4A73281014E66CFC0044823F /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 4A73281114E66CFC0044823F /* iOSTest-Info.plist */,
+ 4A73281214E66CFC0044823F /* InfoPlist.strings */,
+ 4A73281714E66CFC0044823F /* iOSTest-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ 4A73282014E66D6C0044823F /* iTch */ = {
+ isa = PBXGroup;
+ children = (
+ 4AB1C74C14FCC74900F31DF7 /* OCTest.mm */,
+ 4AB1C74D14FCC74900F31DF7 /* TestObj.h */,
+ 4AB1C74E14FCC74900F31DF7 /* TestObj.m */,
+ 4A73282114E66D8B0044823F /* internal */,
+ 4A73282514E66D8B0044823F /* itChRunnerMain.mm */,
+ );
+ name = iTch;
+ sourceTree = "<group>";
+ };
+ 4A73282114E66D8B0044823F /* internal */ = {
+ isa = PBXGroup;
+ children = (
+ 4A73282214E66D8B0044823F /* iTchRunnerAppDelegate.h */,
+ 4A73282314E66D8B0044823F /* iTchRunnerMainView.h */,
+ 4A73282414E66D8B0044823F /* iTchRunnerReporter.h */,
+ );
+ name = internal;
+ path = ../../../runners/iTchRunner/internal;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 4A73280414E66CFC0044823F /* iOSTest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 4A73281D14E66CFC0044823F /* Build configuration list for PBXNativeTarget "iOSTest" */;
+ buildPhases = (
+ 4A73280114E66CFC0044823F /* Sources */,
+ 4A73280214E66CFC0044823F /* Frameworks */,
+ 4A73280314E66CFC0044823F /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = iOSTest;
+ productName = iOSTest;
+ productReference = 4A73280514E66CFC0044823F /* iOSTest.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 4A7327FC14E66CFC0044823F /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0420;
+ };
+ buildConfigurationList = 4A7327FF14E66CFC0044823F /* Build configuration list for PBXProject "iOSTest" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 4A7327FA14E66CFC0044823F;
+ productRefGroup = 4A73280614E66CFC0044823F /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 4A73280414E66CFC0044823F /* iOSTest */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 4A73280314E66CFC0044823F /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4A73281414E66CFC0044823F /* InfoPlist.strings in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 4A73280114E66CFC0044823F /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4A73282614E66D8B0044823F /* itChRunnerMain.mm in Sources */,
+ 4AB1C74F14FCC74900F31DF7 /* OCTest.mm in Sources */,
+ 4AB1C75014FCC74900F31DF7 /* TestObj.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 4A73281214E66CFC0044823F /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 4A73281314E66CFC0044823F /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 4A73281B14E66CFC0044823F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer: Phil Nash (4KJCM5XSVL)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ PROVISIONING_PROFILE = "95C4758A-E0B8-4714-9DA3-C7E1284444A4";
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ USER_HEADER_SEARCH_PATHS = ../../../include;
+ };
+ name = Debug;
+ };
+ 4A73281C14E66CFC0044823F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer: Phil Nash (4KJCM5XSVL)";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.0;
+ OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
+ PROVISIONING_PROFILE = "95C4758A-E0B8-4714-9DA3-C7E1284444A4";
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ USER_HEADER_SEARCH_PATHS = ../../../include;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 4A73281E14E66CFC0044823F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "iOSTest/iOSTest-Prefix.pch";
+ INFOPLIST_FILE = "iOSTest/iOSTest-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ 4A73281F14E66CFC0044823F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "iOSTest/iOSTest-Prefix.pch";
+ INFOPLIST_FILE = "iOSTest/iOSTest-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 4A7327FF14E66CFC0044823F /* Build configuration list for PBXProject "iOSTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4A73281B14E66CFC0044823F /* Debug */,
+ 4A73281C14E66CFC0044823F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 4A73281D14E66CFC0044823F /* Build configuration list for PBXNativeTarget "iOSTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4A73281E14E66CFC0044823F /* Debug */,
+ 4A73281F14E66CFC0044823F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 4A7327FC14E66CFC0044823F /* Project object */;
+}
diff --git a/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000000..aaadc7d492c
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+ version = "1.0">
+ <FileRef
+ location = "self:iOSTest.xcodeproj">
+ </FileRef>
+</Workspace>
diff --git a/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/OCTest.mm b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/OCTest.mm
new file mode 100644
index 00000000000..d476cb42bf0
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/OCTest.mm
@@ -0,0 +1,27 @@
+/*
+ * OCTest.mm
+ * OCTest
+ *
+ * Created by Phil on 13/11/2010.
+ * Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+#include "catch.hpp"
+
+#import "TestObj.h"
+
+TEST_CASE( "OCTest/TestObj", "tests TestObj" )
+{
+ TestObj* obj = [[TestObj alloc] init];
+
+ REQUIRE( obj.int_val == 0 );
+
+ obj.int_val = 1;
+
+ REQUIRE( obj.int_val == 1 );
+
+ arcSafeRelease( obj );
+}
diff --git a/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/TestObj.h b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/TestObj.h
new file mode 100644
index 00000000000..de6725027a2
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/TestObj.h
@@ -0,0 +1,25 @@
+//
+// TestObj.h
+// OCTest
+//
+// Created by Phil on 13/11/2010.
+// Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef TWOBLUECUBES_TESTOBJ_H_INCLUDED
+#define TWOBLUECUBES_TESTOBJ_H_INCLUDED
+
+#import <Foundation/Foundation.h>
+
+
+@interface TestObj : NSObject {
+
+ int int_val;
+}
+
+@property (nonatomic, assign ) int int_val;
+
+@end
+
+#endif // TWOBLUECUBES_TESTOBJ_H_INCLUDED
diff --git a/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/TestObj.m b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/TestObj.m
new file mode 100644
index 00000000000..943f4450837
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/TestObj.m
@@ -0,0 +1,18 @@
+//
+// TestObj.m
+// OCTest
+//
+// Created by Phil on 13/11/2010.
+// Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#import "TestObj.h"
+
+
+@implementation TestObj
+
+@synthesize int_val;
+
+@end
diff --git a/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/en.lproj/InfoPlist.strings b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/en.lproj/InfoPlist.strings
new file mode 100644
index 00000000000..477b28ff8f8
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/iOSTest-Info.plist b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/iOSTest-Info.plist
new file mode 100644
index 00000000000..f74b6db0993
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/iOSTest-Info.plist
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFiles</key>
+ <array/>
+ <key>CFBundleIdentifier</key>
+ <string>twobluecubes.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/iOSTest-Prefix.pch b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/iOSTest-Prefix.pch
new file mode 100644
index 00000000000..403e8e45e5e
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/XCode/iOSTest/iOSTest/iOSTest-Prefix.pch
@@ -0,0 +1,14 @@
+//
+// Prefix header for all source files of the 'iOSTest' target in the 'iOSTest' project
+//
+
+#import <Availability.h>
+
+#ifndef __IPHONE_3_0
+#warning "This project uses features only available in iOS SDK 3.0 and later."
+#endif
+
+#ifdef __OBJC__
+ #import <UIKit/UIKit.h>
+ #import <Foundation/Foundation.h>
+#endif
diff --git a/3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerAppDelegate.h b/3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerAppDelegate.h
new file mode 100644
index 00000000000..522291a905a
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerAppDelegate.h
@@ -0,0 +1,114 @@
+/*
+ * iTchRunnerAppDelegate.h
+ * iTchRunner
+ *
+ * Created by Phil on 07/02/2011.
+ * Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
+ *
+ */
+#ifndef TWOBLUECUBES_ITCHRUNNERAPPDELEGATE_H_INCLUDED
+#define TWOBLUECUBES_ITCHRUNNERAPPDELEGATE_H_INCLUDED
+
+#import "iTchRunnerMainView.h"
+
+
+
+@interface iTchRunnerAppDelegate : NSObject <UIApplicationDelegate>
+{
+ UIWindow *window;
+}
+
+@end
+
+
+@implementation iTchRunnerAppDelegate
+
+
+///////////////////////////////////////////////////////////////////////////////
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ [window setUserInteractionEnabled:YES];
+ [window setMultipleTouchEnabled:YES];
+
+ CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
+ iTchRunnerMainView* view = [[iTchRunnerMainView alloc] initWithFrame:screenRect];
+
+ [window addSubview:view];
+ [window makeKeyAndVisible];
+ arcSafeRelease( view );
+
+ return YES;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+- (void)dealloc
+{
+#if !CATCH_ARC_ENABLED
+ [window release];
+ [super dealloc];
+#endif
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+- (void)applicationWillResignActive:(UIApplication *)application
+{
+ /*
+ Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+ */
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+ /*
+ Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
+ */
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+- (void)applicationWillEnterForeground:(UIApplication *)application
+{
+ /*
+ Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
+ */
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+- (void)applicationDidBecomeActive:(UIApplication *)application
+{
+ /*
+ Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+ */
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+ /*
+ Called when the application is about to terminate.
+ See also applicationDidEnterBackground:.
+ */
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
+{
+ /*
+ Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
+ */
+}
+
+
+
+@end
+
+#endif // TWOBLUECUBES_ITCHRUNNERAPPDELEGATE_H_INCLUDED
diff --git a/3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerMainView.h b/3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerMainView.h
new file mode 100644
index 00000000000..c6a6394ea57
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerMainView.h
@@ -0,0 +1,189 @@
+/*
+ * iTchRunnerMainView.h
+ * iTchRunner
+ *
+ * Created by Phil on 07/02/2011.
+ * Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
+ *
+ */
+#ifndef TWOBLUECUBES_ITCHRUNNERMAINVIEW_H_INCLUDED
+#define TWOBLUECUBES_ITCHRUNNERMAINVIEW_H_INCLUDED
+
+#include "internal/catch_config.hpp"
+#include "internal/catch_runner_impl.hpp"
+#include "internal/catch_context_impl.hpp"
+#include "catch.hpp"
+
+#include "iTchRunnerReporter.h"
+
+#import <UIKit/UIKit.h>
+
+@interface iTchRunnerMainView : UIView<iTchRunnerDelegate, UIActionSheetDelegate>
+{
+ UITextField* appName;
+}
+
+-(void) showAlert;
+
+@end
+
+@implementation iTchRunnerMainView
+
+
+///////////////////////////////////////////////////////////////////////////////
+-(id) initWithFrame:(CGRect)frame
+{
+ if ((self = [super initWithFrame:frame]))
+ {
+ // Initialization code
+ self.backgroundColor = [UIColor blackColor];
+
+ appName = [[UITextField alloc] initWithFrame: CGRectMake( 0, 50, 320, 50 )];
+ [self addSubview: appName];
+ arcSafeRelease( appName );
+ appName.textColor = [[UIColor alloc] initWithRed:0.35 green:0.35 blue:1 alpha:1];
+ arcSafeRelease( appName.textColor );
+ appName.textAlignment = NSTextAlignmentCenter;
+
+ appName.text = [NSString stringWithFormat:@"CATCH tests"];
+// [self performSelector: @selector(showAlert) withObject:nil afterDelay:0.1];
+ [self performSelectorOnMainThread:@selector(showAlert) withObject:nil waitUntilDone:NO];
+
+ }
+ return self;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+-(void) dealloc
+{
+ [appName removeFromSuperview];
+#if !CATCH_ARC_ENABLED
+ [super dealloc];
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+-(void) showAlert
+{
+ UIActionSheet* menu = [[UIActionSheet alloc] initWithTitle:@"Options"
+ delegate:self
+ cancelButtonTitle:nil
+ destructiveButtonTitle:nil
+ otherButtonTitles:@"Run all tests", nil];
+ [menu showInView: self];
+ arcSafeRelease( menu );
+
+}
+
+// This is a copy & paste from Catch::Runner2 to get us bootstrapped (this is due to all be
+// replaced anyway)
+inline Catch::Totals runTestsForGroup( Catch::RunContext& context, const Catch::TestCaseFilters& filterGroup ) {
+ using namespace Catch;
+ Totals totals;
+ std::vector<TestCase>::const_iterator it = getRegistryHub().getTestCaseRegistry().getAllTests().begin();
+ std::vector<TestCase>::const_iterator itEnd = getRegistryHub().getTestCaseRegistry().getAllTests().end();
+ int testsRunForGroup = 0;
+ for(; it != itEnd; ++it ) {
+ if( filterGroup.shouldInclude( *it ) ) {
+ testsRunForGroup++;
+
+ if( context.aborting() )
+ break;
+
+ totals += context.runTest( *it );
+ }
+ }
+ if( testsRunForGroup == 0 )
+ std::cerr << "\n[No test cases matched with: " << filterGroup.getName() << "]" << std::endl;
+ return totals;
+
+}
+
+///////////////////////////////////////////////////////////////////////////////
+-(void) actionSheet: (UIActionSheet*) sheet clickedButtonAtIndex: (NSInteger) index
+{
+ Catch::Ptr<Catch::Config> config = new Catch::Config();
+ Catch::IReporter* reporter = new Catch::iTchRunnerReporter( self );
+ Catch::LegacyReporterAdapter* reporterAdapter = new Catch::LegacyReporterAdapter( reporter );
+ Catch::RunContext runner( config.get(), reporterAdapter );
+
+
+ std::vector<Catch::TestCaseFilters> filterGroups;
+ Catch::TestCaseFilters filterGroup( "" );
+ filterGroups.push_back( filterGroup );
+
+ Catch::Totals totals;
+
+ std::vector<Catch::TestCaseFilters>::const_iterator it = filterGroups.begin();
+ std::vector<Catch::TestCaseFilters>::const_iterator itEnd = filterGroups.end();
+
+ std::size_t groupCount = filterGroups.size();
+ std::size_t groupIndex = 0;
+ for(; it != itEnd && !runner.aborting(); ++it, ++index ) {
+ runner.testGroupStarting( it->getName(), groupIndex, groupCount );
+ totals += runTestsForGroup( runner, *it );
+ runner.testGroupEnded( it->getName(), totals, groupIndex, groupCount );
+ }
+
+
+ if( totals.assertions.failed == 0 )
+ {
+ NSLog( @"no failures" );
+ if( totals.assertions.passed > 0 )
+ appName.textColor = [[UIColor alloc] initWithRed:0.35 green:1 blue:0.35 alpha:1];
+ }
+ else
+ {
+ NSLog( @"%lu failures", totals.assertions.failed );
+ appName.textColor = [[UIColor alloc] initWithRed:1 green:0.35 blue:0.35 alpha:1];
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+-(void) testWasRun: (const Catch::AssertionResult*) pResultInfo
+{
+ const Catch::AssertionResult& resultInfo = *pResultInfo;
+ std::ostringstream oss;
+
+ if( resultInfo.hasExpression() )
+ {
+ oss << resultInfo.getExpression();
+ if( resultInfo.isOk() )
+ oss << " succeeded";
+ else
+ oss << " failed";
+ }
+ switch( resultInfo.getResultType() )
+ {
+ case Catch::ResultWas::ThrewException:
+ if( resultInfo.hasExpression() )
+ oss << " with unexpected";
+ else
+ oss << "Unexpected";
+ oss << " exception with message: '" << resultInfo.getMessage() << "'";
+ break;
+ case Catch::ResultWas::Info:
+ oss << "info: '" << resultInfo.getMessage() << "'";
+ break;
+ case Catch::ResultWas::Warning:
+ oss << "warning: '" << resultInfo.getMessage() << "'";
+ break;
+ case Catch::ResultWas::ExplicitFailure:
+ oss << "failed with message: '" << resultInfo.getMessage() << "'";
+ break;
+ default:
+ break;
+ }
+
+ if( resultInfo.hasExpression() )
+ {
+ oss << " for: " << resultInfo.getExpandedExpression();
+ }
+ oss << std::endl;
+ NSLog( @"%s", oss.str().c_str() );
+}
+
+
+@end
+
+#endif // TWOBLUECUBES_ITCHRUNNERMAINVIEW_H_INCLUDED
diff --git a/3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerReporter.h b/3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerReporter.h
new file mode 100644
index 00000000000..d2628861562
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/runners/iTchRunner/internal/iTchRunnerReporter.h
@@ -0,0 +1,115 @@
+/*
+ * iTchRunnerReporter.h
+ * iTchRunner
+ *
+ * Created by Phil on 07/02/2011.
+ * Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
+ *
+ */
+#ifndef TWOBLUECUBES_ITCHRUNNERREPORTER_H_INCLUDED
+#define TWOBLUECUBES_ITCHRUNNERREPORTER_H_INCLUDED
+
+#include "catch.hpp"
+
+@protocol iTchRunnerDelegate
+
+-(void) testWasRun: (const Catch::AssertionResult*) result;
+
+@end
+
+namespace Catch
+{
+ class iTchRunnerReporter : public SharedImpl<IReporter>
+ {
+ public:
+ ///////////////////////////////////////////////////////////////////////////
+ iTchRunnerReporter
+ (
+ id<iTchRunnerDelegate> delegate
+ )
+ : m_delegate( delegate )
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ virtual bool shouldRedirectStdout
+ ()
+ const
+ {
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ static std::string getDescription
+ ()
+ {
+ return "Captures results for iOS runner";
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ size_t getSucceeded
+ ()
+ const
+ {
+ return m_totals.assertions.passed;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ size_t getFailed
+ ()
+ const
+ {
+ return m_totals.assertions.failed;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ void reset()
+ {
+ m_totals = Totals();
+ }
+
+ private: // IReporter
+
+ ///////////////////////////////////////////////////////////////////////////
+ virtual void StartTesting
+ ()
+ {}
+
+ ///////////////////////////////////////////////////////////////////////////
+ virtual void EndTesting
+ (
+ const Totals& totals
+ )
+ {
+ m_totals = totals;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ virtual void Result
+ (
+ const AssertionResult& result
+ )
+ {
+ [m_delegate testWasRun: &result];
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Deliberately unimplemented:
+ virtual void StartGroup( const std::string& ){}
+ virtual void EndGroup( const std::string&, const Totals& ){}
+ virtual void StartTestCase( const TestCaseInfo& ){}
+ virtual void StartSection( const std::string& sectionName, const std::string& description ) {}
+ virtual void EndSection( const std::string&, const Counts& ){}
+ virtual void EndTestCase( const TestCaseInfo&, const Totals&, const std::string&, const std::string& ){}
+ virtual void Aborted() {}
+ virtual void NoAssertionsInSection( std::string const& sectionName ) {}
+ virtual void NoAssertionsInTestCase( std::string const& testName ) {}
+
+ private:
+ Totals m_totals;
+
+ id<iTchRunnerDelegate> m_delegate;
+ };
+}
+
+#endif // TWOBLUECUBES_ITCHRUNNERREPORTER_H_INCLUDED
diff --git a/3rdparty/sol2/Catch/projects/runners/iTchRunner/itChRunnerMain.mm b/3rdparty/sol2/Catch/projects/runners/iTchRunner/itChRunnerMain.mm
new file mode 100644
index 00000000000..cac5faecca4
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/runners/iTchRunner/itChRunnerMain.mm
@@ -0,0 +1,27 @@
+//
+// iTchRunnerMain.mm
+// iTchRunner
+//
+// Created by Phil on 04/02/2011.
+// Copyright Two Blue Cubes Ltd 2011. All rights reserved.
+//
+
+#define CATCH_CONFIG_RUNNER
+#include "catch.hpp"
+#import "internal/iTchRunnerAppDelegate.h"
+
+int main(int argc, char *argv[])
+{
+#if !CATCH_ARC_ENABLED
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+#endif
+
+ Catch::registerTestMethods();
+ int retVal = UIApplicationMain(argc, argv, nil, @"iTchRunnerAppDelegate");
+
+#if !CATCH_ARC_ENABLED
+ [pool release];
+#endif
+
+ return retVal;
+}
diff --git a/3rdparty/sol2/Catch/projects/runners/iTchRunner/readme b/3rdparty/sol2/Catch/projects/runners/iTchRunner/readme
new file mode 100644
index 00000000000..2b2549176ce
--- /dev/null
+++ b/3rdparty/sol2/Catch/projects/runners/iTchRunner/readme
@@ -0,0 +1,6 @@
+* Select Project -> New Target. Select Cocoa Touch -> Application. Click next and name it something like "Unit Tests"
+* While the target info is displayed, find: 'User Header Search Paths' and add a path to the Catch folder
+* Open the plist file for the target (Unit Test-Info.plist, if you used that name). Delete the entry for "Main nib file base name: MainWindow"
+* From the overview drop-down select the new target.
+* Add the file Catch/Runner/iTchRunnerMain.mm into your project - but only in the new target
+* Write tests (adding files under test into the target as necessary) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/scripts/approvalTests.py b/3rdparty/sol2/Catch/scripts/approvalTests.py
new file mode 100644
index 00000000000..618812f888d
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/approvalTests.py
@@ -0,0 +1,115 @@
+from __future__ import print_function
+
+import os
+import sys
+import subprocess
+import re
+
+from scriptCommon import catchPath
+
+rootPath = os.path.join( catchPath, 'projects/SelfTest/Baselines' )
+
+filenameParser = re.compile( r'(.*)/(.*\..pp:)(.*)' )
+filelineParser = re.compile( r'(.*\..pp:)([0-9]*)(.*)' )
+pathParser = re.compile( r'(.*?)/(.*\..pp)(.*)' )
+lineNumberParser = re.compile( r'(.*)line="[0-9]*"(.*)' )
+hexParser = re.compile( r'(.*)\b(0[xX][0-9a-fA-F]+)\b(.*)' )
+durationsParser = re.compile( r'(.*)time="[0-9]*\.[0-9]*"(.*)' )
+versionParser = re.compile( r'(.*?)Catch v[0-9]*\.[0-9]*\.[0-9]*(.*)' )
+devVersionParser = re.compile( r'(.*?)Catch v[0-9]*\.[0-9]*\.[0-9]*-develop\.[0-9]*(.*)' )
+
+if len(sys.argv) == 2:
+ cmdPath = sys.argv[1]
+else:
+ cmdPath = os.path.join( catchPath, 'projects/XCode/CatchSelfTest/DerivedData/CatchSelfTest/Build/Products/Debug/CatchSelfTest' )
+
+overallResult = 0
+
+def filterLine( line ):
+ m = filenameParser.match( line )
+ if m:
+ line = m.group(2) + m.group(3)
+ m2 = filelineParser.match( line )
+ if m2:
+ line = m2.group(1) + "<line number>" + m2.group(3)
+ else:
+ m2 = lineNumberParser.match( line )
+ if m2:
+ line = m2.group(1) + m2.group(2)
+ m = pathParser.match( line )
+ if m:
+ path = "/" + m.group(2)
+ if path.startswith( catchPath ):
+ path = path[1+len(catchPath):]
+ line = m.group(1) + path + m.group(3)
+ m = devVersionParser.match( line )
+ if m:
+ line = m.group(1) + "<version>" + m.group(2)
+ else:
+ m = versionParser.match( line )
+ if m:
+ line = m.group(1) + "<version>" + m.group(2)
+
+ while True:
+ m = hexParser.match( line )
+ if m:
+ line = m.group(1) + "0x<hex digits>" + m.group(3)
+ else:
+ break
+ m = durationsParser.match( line )
+ if m:
+ line = m.group(1) + 'time="{duration}"' + m.group(2)
+ return line
+
+def approve( baseName, args ):
+ global overallResult
+ args[0:0] = [cmdPath]
+ if not os.path.exists( cmdPath ):
+ raise Exception( "Executable doesn't exist at " + cmdPath )
+ baselinesPath = os.path.join( rootPath, '{0}.approved.txt'.format( baseName ) )
+ rawResultsPath = os.path.join( rootPath, '_{0}.tmp'.format( baseName ) )
+ filteredResultsPath = os.path.join( rootPath, '{0}.unapproved.txt'.format( baseName ) )
+
+ f = open( rawResultsPath, 'w' )
+ subprocess.call( args, stdout=f, stderr=f )
+ f.close()
+
+ rawFile = open( rawResultsPath, 'r' )
+ filteredFile = open( filteredResultsPath, 'w' )
+ for line in rawFile:
+ filteredFile.write( filterLine( line ).rstrip() + "\n" )
+ filteredFile.close()
+ rawFile.close()
+
+ os.remove( rawResultsPath )
+ print()
+ print( baseName + ":" )
+ if os.path.exists( baselinesPath ):
+ diffResult = subprocess.call([ "diff", baselinesPath, filteredResultsPath ] )
+ if diffResult == 0:
+ os.remove( filteredResultsPath )
+ print( " \033[92mResults matched" )
+ else:
+ print( " \n****************************\n \033[91mResults differed" )
+ if diffResult > overallResult:
+ overallResult = diffResult
+ print( "\033[0m" )
+ else:
+ print( " first approval" )
+ if overallResult == 0:
+ overallResult = 1
+
+# Standard console reporter
+approve( "console.std", ["~_"] )
+# console reporter, include passes, warn about No Assertions
+approve( "console.sw", ["~_", "-s", "-w", "NoAssertions"] )
+# console reporter, include passes, warn about No Assertions, limit failures to first 4
+approve( "console.swa4", ["~_", "-s", "-w", "NoAssertions", "-x", "4"] )
+# junit reporter, include passes, warn about No Assertions
+approve( "junit.sw", ["~_", "-s", "-w", "NoAssertions", "-r", "junit"] )
+# xml reporter, include passes, warn about No Assertions
+approve( "xml.sw", ["~_", "-s", "-w", "NoAssertions", "-r", "xml"] )
+
+if overallResult != 0:
+ print( "run approve.py to approve new baselines" )
+exit( overallResult)
diff --git a/3rdparty/sol2/Catch/scripts/approve.py b/3rdparty/sol2/Catch/scripts/approve.py
new file mode 100644
index 00000000000..f4b66aa4a90
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/approve.py
@@ -0,0 +1,31 @@
+from __future__ import print_function
+
+import os
+import sys
+import shutil
+import glob
+from scriptCommon import catchPath
+
+rootPath = os.path.join( catchPath, 'projects/SelfTest/Baselines' )
+
+if len(sys.argv) > 1:
+ files = [os.path.join( rootPath, f ) for f in sys.argv[1:]]
+else:
+ files = glob.glob( os.path.join( rootPath, "*.unapproved.txt" ) )
+
+
+def approveFile( approvedFile, unapprovedFile ):
+ justFilename = unapprovedFile[len(rootPath)+1:]
+ if os.path.exists( unapprovedFile ):
+ if os.path.exists( approvedFile ):
+ os.remove( approvedFile )
+ os.rename( unapprovedFile, approvedFile )
+ print( "approved " + justFilename )
+ else:
+ print( "approval file " + justFilename + " does not exist" )
+
+if len(files) > 0:
+ for unapprovedFile in files:
+ approveFile( unapprovedFile.replace( "unapproved.txt", "approved.txt" ), unapprovedFile )
+else:
+ print( "no files to approve" )
diff --git a/3rdparty/sol2/Catch/scripts/developBuild.py b/3rdparty/sol2/Catch/scripts/developBuild.py
new file mode 100644
index 00000000000..c244871ab79
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/developBuild.py
@@ -0,0 +1,9 @@
+from __future__ import print_function
+from releaseCommon import Version
+
+v = Version()
+v.incrementBuildNumber()
+v.updateVersionFile()
+v.updateReadmeFile()
+
+print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) ) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/scripts/fixTrailingWhitespace.py b/3rdparty/sol2/Catch/scripts/fixTrailingWhitespace.py
new file mode 100644
index 00000000000..a1b6bbe871b
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/fixTrailingWhitespace.py
@@ -0,0 +1,46 @@
+from __future__ import print_function
+import os
+from scriptCommon import catchPath
+
+changedFiles = 0
+
+def isSourceFile( path ):
+ return path.endswith( ".cpp" ) or path.endswith( ".h" ) or path.endswith( ".hpp" )
+
+def fixAllFilesInDir( dir ):
+ for f in os.listdir( dir ):
+ path = os.path.join( dir,f )
+ if os.path.isfile( path ):
+ if isSourceFile( path ):
+ fixFile( path )
+ else:
+ fixAllFilesInDir( path )
+
+def fixFile( path ):
+ f = open( path, 'r' )
+ lines = []
+ changed = 0
+ for line in f:
+ trimmed = line.rstrip() + "\n"
+ if trimmed != line:
+ changed = changed +1
+ lines.append( trimmed )
+ f.close()
+ if changed > 0:
+ global changedFiles
+ changedFiles = changedFiles + 1
+ print( path + ":" )
+ print( " - fixed " + str(changed) + " line(s)" )
+ altPath = path + ".backup"
+ os.rename( path, altPath )
+ f2 = open( path, 'w' )
+ for line in lines:
+ f2.write( line )
+ f2.close()
+ os.remove( altPath )
+
+fixAllFilesInDir(catchPath)
+if changedFiles > 0:
+ print( "Fixed " + str(changedFiles) + " file(s)" )
+else:
+ print( "No trailing whitespace found" )
diff --git a/3rdparty/sol2/Catch/scripts/generateSingleHeader.py b/3rdparty/sol2/Catch/scripts/generateSingleHeader.py
new file mode 100644
index 00000000000..419633f8328
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/generateSingleHeader.py
@@ -0,0 +1,103 @@
+from __future__ import print_function
+
+import os
+import sys
+import re
+import datetime
+import string
+
+from scriptCommon import catchPath
+from releaseCommon import Version
+
+
+includesParser = re.compile( r'\s*#include\s*"(.*)"' )
+guardParser = re.compile( r'\s*#.*TWOBLUECUBES_CATCH_.*_INCLUDED')
+defineParser = re.compile( r'\s*#define')
+ifParser = re.compile( r'\s*#ifndef TWOBLUECUBES_CATCH_.*_INCLUDED')
+endIfParser = re.compile( r'\s*#endif // TWOBLUECUBES_CATCH_.*_INCLUDED')
+ifImplParser = re.compile( r'\s*#ifdef CATCH_CONFIG_RUNNER' )
+commentParser1 = re.compile( r'^\s*/\*')
+commentParser2 = re.compile( r'^ \*')
+blankParser = re.compile( r'^\s*$')
+seenHeaders = set([])
+rootPath = os.path.join( catchPath, 'include/' )
+outputPath = os.path.join( catchPath, 'single_include/catch.hpp' )
+
+includeImpl = True
+
+for arg in sys.argv[1:]:
+ arg = string.lower(arg)
+ if arg == "noimpl":
+ includeImpl = False
+ print( "Not including impl code" )
+ else:
+ print( "\n** Unrecognised argument: " + arg + " **\n" )
+ exit(1)
+
+out = open( outputPath, 'w' )
+ifdefs = 0
+implIfDefs = -1
+
+def write( line ):
+ if includeImpl or implIfDefs == -1:
+ out.write( line )
+
+def parseFile( path, filename ):
+ global ifdefs
+ global implIfDefs
+
+ f = open( path + filename, 'r' )
+ blanks = 0
+ for line in f:
+ if ifParser.match( line ):
+ ifdefs = ifdefs + 1
+ elif endIfParser.match( line ):
+ ifdefs = ifdefs - 1
+ if ifdefs == implIfDefs:
+ implIfDefs = -1
+ m = includesParser.match( line )
+ if m:
+ header = m.group(1)
+ headerPath, sep, headerFile = header.rpartition( "/" )
+ if not headerFile in seenHeaders:
+ if headerFile != "tbc_text_format.h" and headerFile != "clara.h":
+ seenHeaders.add( headerFile )
+ write( "// #included from: {0}\n".format( header ) )
+ if( headerPath == "internal" and path.endswith( "internal/" ) ):
+ headerPath = ""
+ sep = ""
+ if os.path.exists( path + headerPath + sep + headerFile ):
+ parseFile( path + headerPath + sep, headerFile )
+ else:
+ parseFile( rootPath + headerPath + sep, headerFile )
+ else:
+ if ifImplParser.match(line):
+ implIfDefs = ifdefs
+ if (not guardParser.match( line ) or defineParser.match( line ) ) and not commentParser1.match( line )and not commentParser2.match( line ):
+ if blankParser.match( line ):
+ blanks = blanks + 1
+ else:
+ blanks = 0
+ if blanks < 2:
+ write( line.rstrip() + "\n" )
+
+
+v = Version()
+out.write( "/*\n" )
+out.write( " * Catch v{0}\n".format( v.getVersionString() ) )
+out.write( " * Generated: {0}\n".format( datetime.datetime.now() ) )
+out.write( " * ----------------------------------------------------------\n" )
+out.write( " * This file has been merged from multiple headers. Please don't edit it directly\n" )
+out.write( " * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.\n" )
+out.write( " *\n" )
+out.write( " * Distributed under the Boost Software License, Version 1.0. (See accompanying\n" )
+out.write( " * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n" )
+out.write( " */\n" )
+out.write( "#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" )
+out.write( "#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" )
+
+parseFile( rootPath, 'catch.hpp' )
+
+out.write( "#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n" )
+
+print ("Generated single include for Catch v{0}\n".format( v.getVersionString() ) )
diff --git a/3rdparty/sol2/Catch/scripts/majorRelease.py b/3rdparty/sol2/Catch/scripts/majorRelease.py
new file mode 100644
index 00000000000..03b7e78ec66
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/majorRelease.py
@@ -0,0 +1,9 @@
+from __future__ import print_function
+from releaseCommon import Version
+
+v = Version()
+v.incrementMajorVersion()
+v.updateVersionFile()
+v.updateReadmeFile()
+
+print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) ) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/scripts/minorRelease.py b/3rdparty/sol2/Catch/scripts/minorRelease.py
new file mode 100644
index 00000000000..bbd97ed042e
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/minorRelease.py
@@ -0,0 +1,9 @@
+from __future__ import print_function
+from releaseCommon import Version
+
+v = Version()
+v.incrementMinorVersion()
+v.updateVersionFile()
+v.updateReadmeFile()
+
+print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) ) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/scripts/patchRelease.py b/3rdparty/sol2/Catch/scripts/patchRelease.py
new file mode 100644
index 00000000000..6abf87af152
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/patchRelease.py
@@ -0,0 +1,9 @@
+from __future__ import print_function
+from releaseCommon import Version
+
+v = Version()
+v.incrementPatchNumber()
+v.updateVersionFile()
+v.updateReadmeFile()
+
+print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) ) \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/scripts/releaseCommon.py b/3rdparty/sol2/Catch/scripts/releaseCommon.py
new file mode 100644
index 00000000000..14eb235e5bf
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/releaseCommon.py
@@ -0,0 +1,89 @@
+from __future__ import print_function
+
+import os
+import sys
+import re
+import string
+
+from scriptCommon import catchPath
+
+versionParser = re.compile( r'(\s*Version\slibraryVersion)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*,\s*(.*)\s*\).*' )
+rootPath = os.path.join( catchPath, 'include/' )
+versionPath = os.path.join( rootPath, "internal/catch_version.hpp" )
+readmePath = os.path.join( catchPath, "README.md" )
+
+class Version:
+ def __init__(self):
+ f = open( versionPath, 'r' )
+ for line in f:
+ m = versionParser.match( line )
+ if m:
+ self.variableDecl = m.group(1)
+ self.majorVersion = int(m.group(2))
+ self.minorVersion = int(m.group(3))
+ self.patchNumber = int(m.group(4))
+ self.branchName = m.group(5)
+ self.buildNumber = int(m.group(6))
+ f.close()
+
+ def nonDevelopRelease(self):
+ if self.branchName != "":
+ self.branchName = ""
+ self.buildNumber = 0
+ def developBuild(self):
+ if self.branchName == "":
+ self.branchName = "develop"
+ self.buildNumber = 0
+
+ def incrementBuildNumber(self):
+ self.developBuild()
+ self.buildNumber = self.buildNumber+1
+
+ def incrementPatchNumber(self):
+ self.nonDevelopRelease()
+ self.patchNumber = self.patchNumber+1
+
+ def incrementMinorVersion(self):
+ self.nonDevelopRelease()
+ self.patchNumber = 0
+ self.minorVersion = self.minorVersion+1
+
+ def incrementMajorVersion(self):
+ self.nonDevelopRelease()
+ self.patchNumber = 0
+ self.minorVersion = 0
+ self.majorVersion = self.majorVersion+1
+
+ def getVersionString(self):
+ versionString = '{0}.{1}.{2}'.format( self.majorVersion, self.minorVersion, self.patchNumber )
+ if self.branchName != "":
+ versionString = versionString + '-{0}.{1}'.format( self.branchName, self.buildNumber )
+ return versionString
+
+ def updateVersionFile(self):
+ f = open( versionPath, 'r' )
+ lines = []
+ for line in f:
+ m = versionParser.match( line )
+ if m:
+ lines.append( '{0}( {1}, {2}, {3}, "{4}", {5} );'.format( self.variableDecl, self.majorVersion, self.minorVersion, self.patchNumber, self.branchName, self.buildNumber ) )
+ else:
+ lines.append( line.rstrip() )
+ f.close()
+ f = open( versionPath, 'w' )
+ for line in lines:
+ f.write( line + "\n" )
+
+ def updateReadmeFile(self):
+ f = open( readmePath, 'r' )
+ lines = []
+ for line in f:
+ lines.append( line.rstrip() )
+ f.close()
+ f = open( readmePath, 'w' )
+ for line in lines:
+ if line.startswith( "*v" ):
+ f.write( '*v{0}*\n'.format( self.getVersionString() ) )
+ else:
+ f.write( line + "\n" )
+
diff --git a/3rdparty/sol2/Catch/scripts/releaseNotes.py b/3rdparty/sol2/Catch/scripts/releaseNotes.py
new file mode 100644
index 00000000000..e083ec94534
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/releaseNotes.py
@@ -0,0 +1,62 @@
+import os
+import re
+import urllib2
+import json
+
+from scriptCommon import catchPath
+from scriptCommon import runAndCapture
+
+issueNumberRe = re.compile( r'(.*?)#([0-9]*)([^0-9]?.*)' )
+
+rootPath = os.path.join( catchPath, 'include/' )
+versionPath = os.path.join( rootPath, "internal/catch_version.hpp" )
+
+
+hashes = runAndCapture( ['git', 'log', '-2', '--format="%H"', versionPath] )
+lines = runAndCapture( ['git', 'log', hashes[1] + ".." + hashes[0], catchPath] )
+
+prevLine = ""
+messages = []
+dates = []
+issues = {}
+
+def getIssueTitle( issueNumber ):
+ try:
+ s = urllib2.urlopen("https://api.github.com/repos/philsquared/catch/issues/" + issueNumber ).read()
+ except e:
+ return "#HTTP Error#"
+
+ try:
+ j = json.loads( s )
+ return j["title"]
+ except e:
+ return "#JSON Error#"
+
+for line in lines:
+ if line.startswith( "commit"):
+ pass
+ elif line.startswith( "Author:"):
+ pass
+ elif line.startswith( "Date:"):
+ dates.append( line[5:].lstrip() )
+ pass
+ elif line == "" and prevLine == "":
+ pass
+ else:
+ prevLine = line
+ match = issueNumberRe.match( line )
+ line2 = ""
+ while match:
+ issueNumber = match.group(2)
+ issue = '#{0} ("{1}")'.format( issueNumber, getIssueTitle( issueNumber ) )
+ line2 = line2 + match.group(1) + issue
+ match = issueNumberRe.match( match.group(3) )
+ if line2 == "":
+ messages.append( line )
+ else:
+ messages.append( line2 )
+
+print "All changes between {0} and {1}:\n".format( dates[-1], dates[0] )
+
+for line in messages:
+ print line
diff --git a/3rdparty/sol2/Catch/scripts/scriptCommon.py b/3rdparty/sol2/Catch/scripts/scriptCommon.py
new file mode 100644
index 00000000000..6ac381adcb6
--- /dev/null
+++ b/3rdparty/sol2/Catch/scripts/scriptCommon.py
@@ -0,0 +1,21 @@
+import os
+import sys
+import subprocess
+
+catchPath = os.path.dirname(os.path.realpath( os.path.dirname(sys.argv[0])))
+
+def runAndCapture( args ):
+ child = subprocess.Popen(" ".join( args ), shell=True, stdout=subprocess.PIPE)
+ lines = []
+ line = ""
+ while True:
+ out = child.stdout.read(1)
+ if out == '' and child.poll() != None:
+ break
+ if out != '':
+ if out == '\n':
+ lines.append( line )
+ line = ""
+ else:
+ line = line + out
+ return lines \ No newline at end of file
diff --git a/3rdparty/sol2/Catch/single_include/catch.hpp b/3rdparty/sol2/Catch/single_include/catch.hpp
new file mode 100644
index 00000000000..5cc33a8388e
--- /dev/null
+++ b/3rdparty/sol2/Catch/single_include/catch.hpp
@@ -0,0 +1,10359 @@
+/*
+ * Catch v1.3.4
+ * Generated: 2016-02-10 19:24:03.089683
+ * ----------------------------------------------------------
+ * This file has been merged from multiple headers. Please don't edit it directly
+ * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
+#define TWOBLUECUBES_CATCH_HPP_INCLUDED
+
+#ifdef __clang__
+# pragma clang system_header
+#elif defined __GNUC__
+# pragma GCC system_header
+#endif
+
+// #included from: internal/catch_suppress_warnings.h
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(push)
+# pragma warning(disable: 161 1682)
+# else // __ICC
+# pragma clang diagnostic ignored "-Wglobal-constructors"
+# pragma clang diagnostic ignored "-Wvariadic-macros"
+# pragma clang diagnostic ignored "-Wc99-extensions"
+# pragma clang diagnostic ignored "-Wunused-variable"
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wpadded"
+# pragma clang diagnostic ignored "-Wc++98-compat"
+# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+# pragma clang diagnostic ignored "-Wswitch-enum"
+# pragma clang diagnostic ignored "-Wcovered-switch-default"
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic ignored "-Wvariadic-macros"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpadded"
+#endif
+#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)
+# define CATCH_IMPL
+#endif
+
+#ifdef CATCH_IMPL
+# ifndef CLARA_CONFIG_MAIN
+# define CLARA_CONFIG_MAIN_NOT_DEFINED
+# define CLARA_CONFIG_MAIN
+# endif
+#endif
+
+// #included from: internal/catch_notimplemented_exception.h
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED
+
+// #included from: catch_common.h
+#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
+
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
+#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )
+#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )
+
+#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr
+#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr )
+
+#include <sstream>
+#include <stdexcept>
+#include <algorithm>
+
+// #included from: catch_compiler_capabilities.h
+#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
+
+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
+// The following features are defined:
+//
+// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported?
+// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
+// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
+// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
+// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
+// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
+// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
+// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
+
+// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
+
+// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported?
+
+// ****************
+// Note to maintainers: if new toggles are added please document them
+// in configuration.md, too
+// ****************
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11
+
+#ifdef __clang__
+
+# if __has_feature(cxx_nullptr)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# if __has_feature(cxx_noexcept)
+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// Borland
+#ifdef __BORLANDC__
+
+#endif // __BORLANDC__
+
+////////////////////////////////////////////////////////////////////////////////
+// EDG
+#ifdef __EDG_VERSION__
+
+#endif // __EDG_VERSION__
+
+////////////////////////////////////////////////////////////////////////////////
+// Digital Mars
+#ifdef __DMC__
+
+#endif // __DMC__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+// - otherwise more recent versions define __cplusplus >= 201103L
+// and will get picked up below
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#if (_MSC_VER >= 1600)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
+#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Use variadic macros if the compiler supports them
+#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \
+ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \
+ ( defined __GNUC__ && __GNUC__ >= 3 ) || \
+ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L )
+
+#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// catch all support for C++11
+#if defined(__cplusplus) && __cplusplus >= 201103L
+
+# define CATCH_CPP11_OR_GREATER
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR)
+# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE
+# endif
+
+# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
+# endif
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
+# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
+# endif
+
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
+# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
+# endif
+# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
+# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+# endif
+
+#endif // __cplusplus >= 201103L
+
+// Now set the actual defines based on the above + anything the user has configured
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_NULLPTR
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_NOEXCEPT
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_GENERATED_METHODS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_IS_ENUM
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_TUPLE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
+# define CATCH_CONFIG_VARIADIC_MACROS
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_LONG_LONG
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_OVERRIDE
+#endif
+#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
+# define CATCH_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+// noexcept support:
+#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT)
+# define CATCH_NOEXCEPT noexcept
+# define CATCH_NOEXCEPT_IS(x) noexcept(x)
+#else
+# define CATCH_NOEXCEPT throw()
+# define CATCH_NOEXCEPT_IS(x)
+#endif
+
+// nullptr support
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+# define CATCH_NULL nullptr
+#else
+# define CATCH_NULL NULL
+#endif
+
+// override support
+#ifdef CATCH_CONFIG_CPP11_OVERRIDE
+# define CATCH_OVERRIDE override
+#else
+# define CATCH_OVERRIDE
+#endif
+
+// unique_ptr support
+#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR
+# define CATCH_AUTO_PTR( T ) std::unique_ptr<T>
+#else
+# define CATCH_AUTO_PTR( T ) std::auto_ptr<T>
+#endif
+
+namespace Catch {
+
+ struct IConfig;
+
+ struct CaseSensitive { enum Choice {
+ Yes,
+ No
+ }; };
+
+ class NonCopyable {
+#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ NonCopyable( NonCopyable const& ) = delete;
+ NonCopyable( NonCopyable && ) = delete;
+ NonCopyable& operator = ( NonCopyable const& ) = delete;
+ NonCopyable& operator = ( NonCopyable && ) = delete;
+#else
+ NonCopyable( NonCopyable const& info );
+ NonCopyable& operator = ( NonCopyable const& );
+#endif
+
+ protected:
+ NonCopyable() {}
+ virtual ~NonCopyable();
+ };
+
+ class SafeBool {
+ public:
+ typedef void (SafeBool::*type)() const;
+
+ static type makeSafe( bool value ) {
+ return value ? &SafeBool::trueValue : 0;
+ }
+ private:
+ void trueValue() const {}
+ };
+
+ template<typename ContainerT>
+ inline void deleteAll( ContainerT& container ) {
+ typename ContainerT::const_iterator it = container.begin();
+ typename ContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete *it;
+ }
+ template<typename AssociativeContainerT>
+ inline void deleteAllValues( AssociativeContainerT& container ) {
+ typename AssociativeContainerT::const_iterator it = container.begin();
+ typename AssociativeContainerT::const_iterator itEnd = container.end();
+ for(; it != itEnd; ++it )
+ delete it->second;
+ }
+
+ bool startsWith( std::string const& s, std::string const& prefix );
+ bool endsWith( std::string const& s, std::string const& suffix );
+ bool contains( std::string const& s, std::string const& infix );
+ void toLowerInPlace( std::string& s );
+ std::string toLower( std::string const& s );
+ std::string trim( std::string const& str );
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );
+
+ struct pluralise {
+ pluralise( std::size_t count, std::string const& label );
+
+ friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
+
+ std::size_t m_count;
+ std::string m_label;
+ };
+
+ struct SourceLineInfo {
+
+ SourceLineInfo();
+ SourceLineInfo( char const* _file, std::size_t _line );
+ SourceLineInfo( SourceLineInfo const& other );
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ SourceLineInfo( SourceLineInfo && ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo const& ) = default;
+ SourceLineInfo& operator = ( SourceLineInfo && ) = default;
+# endif
+ bool empty() const;
+ bool operator == ( SourceLineInfo const& other ) const;
+ bool operator < ( SourceLineInfo const& other ) const;
+
+ std::string file;
+ std::size_t line;
+ };
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
+
+ // This is just here to avoid compiler warnings with macro constants and boolean literals
+ inline bool isTrue( bool value ){ return value; }
+ inline bool alwaysTrue() { return true; }
+ inline bool alwaysFalse() { return false; }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
+
+ void seedRng( IConfig const& config );
+ unsigned int rngSeed();
+
+ // Use this in variadic streaming macros to allow
+ // >> +StreamEndStop
+ // as well as
+ // >> stuff +StreamEndStop
+ struct StreamEndStop {
+ std::string operator+() {
+ return std::string();
+ }
+ };
+ template<typename T>
+ T const& operator + ( T const& value, StreamEndStop ) {
+ return value;
+ }
+}
+
+#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
+#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO );
+
+#include <ostream>
+
+namespace Catch {
+
+ class NotImplementedException : public std::exception
+ {
+ public:
+ NotImplementedException( SourceLineInfo const& lineInfo );
+ NotImplementedException( NotImplementedException const& ) {}
+
+ virtual ~NotImplementedException() CATCH_NOEXCEPT {}
+
+ virtual const char* what() const CATCH_NOEXCEPT;
+
+ private:
+ std::string m_what;
+ SourceLineInfo m_lineInfo;
+ };
+
+} // end namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO )
+
+// #included from: internal/catch_context.h
+#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED
+
+// #included from: catch_interfaces_generators.h
+#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct IGeneratorInfo {
+ virtual ~IGeneratorInfo();
+ virtual bool moveNext() = 0;
+ virtual std::size_t getCurrentIndex() const = 0;
+ };
+
+ struct IGeneratorsForTest {
+ virtual ~IGeneratorsForTest();
+
+ virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0;
+ virtual bool moveNext() = 0;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest();
+
+} // end namespace Catch
+
+// #included from: catch_ptr.hpp
+#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ // An intrusive reference counting smart pointer.
+ // T must implement addRef() and release() methods
+ // typically implementing the IShared interface
+ template<typename T>
+ class Ptr {
+ public:
+ Ptr() : m_p( CATCH_NULL ){}
+ Ptr( T* p ) : m_p( p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ Ptr( Ptr const& other ) : m_p( other.m_p ){
+ if( m_p )
+ m_p->addRef();
+ }
+ ~Ptr(){
+ if( m_p )
+ m_p->release();
+ }
+ void reset() {
+ if( m_p )
+ m_p->release();
+ m_p = CATCH_NULL;
+ }
+ Ptr& operator = ( T* p ){
+ Ptr temp( p );
+ swap( temp );
+ return *this;
+ }
+ Ptr& operator = ( Ptr const& other ){
+ Ptr temp( other );
+ swap( temp );
+ return *this;
+ }
+ void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
+ T* get() const{ return m_p; }
+ T& operator*() const { return *m_p; }
+ T* operator->() const { return m_p; }
+ bool operator !() const { return m_p == CATCH_NULL; }
+ operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); }
+
+ private:
+ T* m_p;
+ };
+
+ struct IShared : NonCopyable {
+ virtual ~IShared();
+ virtual void addRef() const = 0;
+ virtual void release() const = 0;
+ };
+
+ template<typename T = IShared>
+ struct SharedImpl : T {
+
+ SharedImpl() : m_rc( 0 ){}
+
+ virtual void addRef() const {
+ ++m_rc;
+ }
+ virtual void release() const {
+ if( --m_rc == 0 )
+ delete this;
+ }
+
+ mutable unsigned int m_rc;
+ };
+
+} // end namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#include <memory>
+#include <vector>
+#include <stdlib.h>
+
+namespace Catch {
+
+ class TestCase;
+ class Stream;
+ struct IResultCapture;
+ struct IRunner;
+ struct IGeneratorsForTest;
+ struct IConfig;
+
+ struct IContext
+ {
+ virtual ~IContext();
+
+ virtual IResultCapture* getResultCapture() = 0;
+ virtual IRunner* getRunner() = 0;
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0;
+ virtual bool advanceGeneratorsForCurrentTest() = 0;
+ virtual Ptr<IConfig const> getConfig() const = 0;
+ };
+
+ struct IMutableContext : IContext
+ {
+ virtual ~IMutableContext();
+ virtual void setResultCapture( IResultCapture* resultCapture ) = 0;
+ virtual void setRunner( IRunner* runner ) = 0;
+ virtual void setConfig( Ptr<IConfig const> const& config ) = 0;
+ };
+
+ IContext& getCurrentContext();
+ IMutableContext& getCurrentMutableContext();
+ void cleanUpContext();
+ Stream createStream( std::string const& streamName );
+
+}
+
+// #included from: internal/catch_test_registry.hpp
+#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_interfaces_testcase.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
+
+#include <vector>
+
+namespace Catch {
+
+ class TestSpec;
+
+ struct ITestCase : IShared {
+ virtual void invoke () const = 0;
+ protected:
+ virtual ~ITestCase();
+ };
+
+ class TestCase;
+ struct IConfig;
+
+ struct ITestCaseRegistry {
+ virtual ~ITestCaseRegistry();
+ virtual std::vector<TestCase> const& getAllTests() const = 0;
+ virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
+ };
+
+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
+
+}
+
+namespace Catch {
+
+template<typename C>
+class MethodTestCase : public SharedImpl<ITestCase> {
+
+public:
+ MethodTestCase( void (C::*method)() ) : m_method( method ) {}
+
+ virtual void invoke() const {
+ C obj;
+ (obj.*m_method)();
+ }
+
+private:
+ virtual ~MethodTestCase() {}
+
+ void (C::*m_method)();
+};
+
+typedef void(*TestFunction)();
+
+struct NameAndDesc {
+ NameAndDesc( const char* _name = "", const char* _description= "" )
+ : name( _name ), description( _description )
+ {}
+
+ const char* name;
+ const char* description;
+};
+
+void registerTestCase
+ ( ITestCase* testCase,
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo );
+
+struct AutoReg {
+
+ AutoReg
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc );
+
+ template<typename C>
+ AutoReg
+ ( void (C::*method)(),
+ char const* className,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+
+ registerTestCase
+ ( new MethodTestCase<C>( method ),
+ className,
+ nameAndDesc,
+ lineInfo );
+ }
+
+ ~AutoReg();
+
+private:
+ AutoReg( AutoReg const& );
+ void operator= ( AutoReg const& );
+};
+
+void registerTestCaseFunction
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc );
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE( ... ) \
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\
+ namespace{ \
+ struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \
+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) );
+
+#else
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\
+ static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )()
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \
+ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\
+ namespace{ \
+ struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \
+ void test(); \
+ }; \
+ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \
+ } \
+ void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test()
+
+ ///////////////////////////////////////////////////////////////////////////////
+ #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \
+ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) );
+#endif
+
+// #included from: internal/catch_capture.hpp
+#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED
+
+// #included from: catch_result_builder.h
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED
+
+// #included from: catch_result_type.h
+#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED
+
+namespace Catch {
+
+ // ResultWas::OfType enum
+ struct ResultWas { enum OfType {
+ Unknown = -1,
+ Ok = 0,
+ Info = 1,
+ Warning = 2,
+
+ FailureBit = 0x10,
+
+ ExpressionFailed = FailureBit | 1,
+ ExplicitFailure = FailureBit | 2,
+
+ Exception = 0x100 | FailureBit,
+
+ ThrewException = Exception | 1,
+ DidntThrowException = Exception | 2,
+
+ FatalErrorCondition = 0x200 | FailureBit
+
+ }; };
+
+ inline bool isOk( ResultWas::OfType resultType ) {
+ return ( resultType & ResultWas::FailureBit ) == 0;
+ }
+ inline bool isJustInfo( int flags ) {
+ return flags == ResultWas::Info;
+ }
+
+ // ResultDisposition::Flags enum
+ struct ResultDisposition { enum Flags {
+ Normal = 0x01,
+
+ ContinueOnFailure = 0x02, // Failures fail test, but execution continues
+ FalseTest = 0x04, // Prefix expression with !
+ SuppressFail = 0x08 // Failures are reported but do not fail the test
+ }; };
+
+ inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {
+ return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );
+ }
+
+ inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }
+ inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }
+ inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.h
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct AssertionInfo
+ {
+ AssertionInfo() {}
+ AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ std::string capturedExpression;
+ ResultDisposition::Flags resultDisposition;
+ };
+
+ struct AssertionResultData
+ {
+ AssertionResultData() : resultType( ResultWas::Unknown ) {}
+
+ std::string reconstructedExpression;
+ std::string message;
+ ResultWas::OfType resultType;
+ };
+
+ class AssertionResult {
+ public:
+ AssertionResult();
+ AssertionResult( AssertionInfo const& info, AssertionResultData const& data );
+ ~AssertionResult();
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ AssertionResult( AssertionResult const& ) = default;
+ AssertionResult( AssertionResult && ) = default;
+ AssertionResult& operator = ( AssertionResult const& ) = default;
+ AssertionResult& operator = ( AssertionResult && ) = default;
+# endif
+
+ bool isOk() const;
+ bool succeeded() const;
+ ResultWas::OfType getResultType() const;
+ bool hasExpression() const;
+ bool hasMessage() const;
+ std::string getExpression() const;
+ std::string getExpressionInMacro() const;
+ bool hasExpandedExpression() const;
+ std::string getExpandedExpression() const;
+ std::string getMessage() const;
+ SourceLineInfo getSourceInfo() const;
+ std::string getTestMacroName() const;
+
+ protected:
+ AssertionInfo m_info;
+ AssertionResultData m_resultData;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_matchers.hpp
+#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED
+
+namespace Catch {
+namespace Matchers {
+ namespace Impl {
+
+ namespace Generic {
+ template<typename ExpressionT> class AllOf;
+ template<typename ExpressionT> class AnyOf;
+ template<typename ExpressionT> class Not;
+ }
+
+ template<typename ExpressionT>
+ struct Matcher : SharedImpl<IShared>
+ {
+ typedef ExpressionT ExpressionType;
+
+ virtual ~Matcher() {}
+ virtual Ptr<Matcher> clone() const = 0;
+ virtual bool match( ExpressionT const& expr ) const = 0;
+ virtual std::string toString() const = 0;
+
+ Generic::AllOf<ExpressionT> operator && ( Matcher<ExpressionT> const& other ) const;
+ Generic::AnyOf<ExpressionT> operator || ( Matcher<ExpressionT> const& other ) const;
+ Generic::Not<ExpressionT> operator ! () const;
+ };
+
+ template<typename DerivedT, typename ExpressionT>
+ struct MatcherImpl : Matcher<ExpressionT> {
+
+ virtual Ptr<Matcher<ExpressionT> > clone() const {
+ return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) );
+ }
+ };
+
+ namespace Generic {
+ template<typename ExpressionT>
+ class Not : public MatcherImpl<Not<ExpressionT>, ExpressionT> {
+ public:
+ explicit Not( Matcher<ExpressionT> const& matcher ) : m_matcher(matcher.clone()) {}
+ Not( Not const& other ) : m_matcher( other.m_matcher ) {}
+
+ virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE {
+ return !m_matcher->match( expr );
+ }
+
+ virtual std::string toString() const CATCH_OVERRIDE {
+ return "not " + m_matcher->toString();
+ }
+ private:
+ Ptr< Matcher<ExpressionT> > m_matcher;
+ };
+
+ template<typename ExpressionT>
+ class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> {
+ public:
+
+ AllOf() {}
+ AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {}
+
+ AllOf& add( Matcher<ExpressionT> const& matcher ) {
+ m_matchers.push_back( matcher.clone() );
+ return *this;
+ }
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
+ if( !m_matchers[i]->match( expr ) )
+ return false;
+ return true;
+ }
+ virtual std::string toString() const {
+ std::ostringstream oss;
+ oss << "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ oss << " and ";
+ oss << m_matchers[i]->toString();
+ }
+ oss << " )";
+ return oss.str();
+ }
+
+ AllOf operator && ( Matcher<ExpressionT> const& other ) const {
+ AllOf allOfExpr( *this );
+ allOfExpr.add( other );
+ return allOfExpr;
+ }
+
+ private:
+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
+ };
+
+ template<typename ExpressionT>
+ class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> {
+ public:
+
+ AnyOf() {}
+ AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {}
+
+ AnyOf& add( Matcher<ExpressionT> const& matcher ) {
+ m_matchers.push_back( matcher.clone() );
+ return *this;
+ }
+ virtual bool match( ExpressionT const& expr ) const
+ {
+ for( std::size_t i = 0; i < m_matchers.size(); ++i )
+ if( m_matchers[i]->match( expr ) )
+ return true;
+ return false;
+ }
+ virtual std::string toString() const {
+ std::ostringstream oss;
+ oss << "( ";
+ for( std::size_t i = 0; i < m_matchers.size(); ++i ) {
+ if( i != 0 )
+ oss << " or ";
+ oss << m_matchers[i]->toString();
+ }
+ oss << " )";
+ return oss.str();
+ }
+
+ AnyOf operator || ( Matcher<ExpressionT> const& other ) const {
+ AnyOf anyOfExpr( *this );
+ anyOfExpr.add( other );
+ return anyOfExpr;
+ }
+
+ private:
+ std::vector<Ptr<Matcher<ExpressionT> > > m_matchers;
+ };
+
+ } // namespace Generic
+
+ template<typename ExpressionT>
+ Generic::AllOf<ExpressionT> Matcher<ExpressionT>::operator && ( Matcher<ExpressionT> const& other ) const {
+ Generic::AllOf<ExpressionT> allOfExpr;
+ allOfExpr.add( *this );
+ allOfExpr.add( other );
+ return allOfExpr;
+ }
+
+ template<typename ExpressionT>
+ Generic::AnyOf<ExpressionT> Matcher<ExpressionT>::operator || ( Matcher<ExpressionT> const& other ) const {
+ Generic::AnyOf<ExpressionT> anyOfExpr;
+ anyOfExpr.add( *this );
+ anyOfExpr.add( other );
+ return anyOfExpr;
+ }
+
+ template<typename ExpressionT>
+ Generic::Not<ExpressionT> Matcher<ExpressionT>::operator ! () const {
+ return Generic::Not<ExpressionT>( *this );
+ }
+
+ namespace StdString {
+
+ inline std::string makeString( std::string const& str ) { return str; }
+ inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); }
+
+ struct CasedString
+ {
+ CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )
+ : m_caseSensitivity( caseSensitivity ),
+ m_str( adjustString( str ) )
+ {}
+ std::string adjustString( std::string const& str ) const {
+ return m_caseSensitivity == CaseSensitive::No
+ ? toLower( str )
+ : str;
+
+ }
+ std::string toStringSuffix() const
+ {
+ return m_caseSensitivity == CaseSensitive::No
+ ? " (case insensitive)"
+ : "";
+ }
+ CaseSensitive::Choice m_caseSensitivity;
+ std::string m_str;
+ };
+
+ struct Equals : MatcherImpl<Equals, std::string> {
+ Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( str, caseSensitivity )
+ {}
+ Equals( Equals const& other ) : m_data( other.m_data ){}
+
+ virtual ~Equals();
+
+ virtual bool match( std::string const& expr ) const {
+ return m_data.m_str == m_data.adjustString( expr );;
+ }
+ virtual std::string toString() const {
+ return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+
+ struct Contains : MatcherImpl<Contains, std::string> {
+ Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( substr, caseSensitivity ){}
+ Contains( Contains const& other ) : m_data( other.m_data ){}
+
+ virtual ~Contains();
+
+ virtual bool match( std::string const& expr ) const {
+ return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos;
+ }
+ virtual std::string toString() const {
+ return "contains: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+
+ struct StartsWith : MatcherImpl<StartsWith, std::string> {
+ StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( substr, caseSensitivity ){}
+
+ StartsWith( StartsWith const& other ) : m_data( other.m_data ){}
+
+ virtual ~StartsWith();
+
+ virtual bool match( std::string const& expr ) const {
+ return startsWith( m_data.adjustString( expr ), m_data.m_str );
+ }
+ virtual std::string toString() const {
+ return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+
+ struct EndsWith : MatcherImpl<EndsWith, std::string> {
+ EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes )
+ : m_data( substr, caseSensitivity ){}
+ EndsWith( EndsWith const& other ) : m_data( other.m_data ){}
+
+ virtual ~EndsWith();
+
+ virtual bool match( std::string const& expr ) const {
+ return endsWith( m_data.adjustString( expr ), m_data.m_str );
+ }
+ virtual std::string toString() const {
+ return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix();
+ }
+
+ CasedString m_data;
+ };
+ } // namespace StdString
+ } // namespace Impl
+
+ // The following functions create the actual matcher objects.
+ // This allows the types to be inferred
+ template<typename ExpressionT>
+ inline Impl::Generic::Not<ExpressionT> Not( Impl::Matcher<ExpressionT> const& m ) {
+ return Impl::Generic::Not<ExpressionT>( m );
+ }
+
+ template<typename ExpressionT>
+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2 ) {
+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2,
+ Impl::Matcher<ExpressionT> const& m3 ) {
+ return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2 ) {
+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 );
+ }
+ template<typename ExpressionT>
+ inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1,
+ Impl::Matcher<ExpressionT> const& m2,
+ Impl::Matcher<ExpressionT> const& m3 ) {
+ return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 );
+ }
+
+ inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Equals( str, caseSensitivity );
+ }
+ inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity );
+ }
+ inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Contains( substr, caseSensitivity );
+ }
+ inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) {
+ return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity );
+ }
+ inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) {
+ return Impl::StdString::StartsWith( substr );
+ }
+ inline Impl::StdString::StartsWith StartsWith( const char* substr ) {
+ return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) );
+ }
+ inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) {
+ return Impl::StdString::EndsWith( substr );
+ }
+ inline Impl::StdString::EndsWith EndsWith( const char* substr ) {
+ return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) );
+ }
+
+} // namespace Matchers
+
+using namespace Matchers;
+
+} // namespace Catch
+
+namespace Catch {
+
+ struct TestFailureException{};
+
+ template<typename T> class ExpressionLhs;
+
+ struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison;
+
+ struct CopyableStream {
+ CopyableStream() {}
+ CopyableStream( CopyableStream const& other ) {
+ oss << other.oss.str();
+ }
+ CopyableStream& operator=( CopyableStream const& other ) {
+ oss.str("");
+ oss << other.oss.str();
+ return *this;
+ }
+ std::ostringstream oss;
+ };
+
+ class ResultBuilder {
+ public:
+ ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition,
+ char const* secondArg = "" );
+
+ template<typename T>
+ ExpressionLhs<T const&> operator <= ( T const& operand );
+ ExpressionLhs<bool> operator <= ( bool value );
+
+ template<typename T>
+ ResultBuilder& operator << ( T const& value ) {
+ m_stream.oss << value;
+ return *this;
+ }
+
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+
+ ResultBuilder& setResultType( ResultWas::OfType result );
+ ResultBuilder& setResultType( bool result );
+ ResultBuilder& setLhs( std::string const& lhs );
+ ResultBuilder& setRhs( std::string const& rhs );
+ ResultBuilder& setOp( std::string const& op );
+
+ void endExpression();
+
+ std::string reconstructExpression() const;
+ AssertionResult build() const;
+
+ void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal );
+ void captureResult( ResultWas::OfType resultType );
+ void captureExpression();
+ void captureExpectedException( std::string const& expectedMessage );
+ void captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher );
+ void handleResult( AssertionResult const& result );
+ void react();
+ bool shouldDebugBreak() const;
+ bool allowThrows() const;
+
+ private:
+ AssertionInfo m_assertionInfo;
+ AssertionResultData m_data;
+ struct ExprComponents {
+ ExprComponents() : testFalse( false ) {}
+ bool testFalse;
+ std::string lhs, rhs, op;
+ } m_exprComponents;
+ CopyableStream m_stream;
+
+ bool m_shouldDebugBreak;
+ bool m_shouldThrow;
+ };
+
+} // namespace Catch
+
+// Include after due to circular dependency:
+// #included from: catch_expression_lhs.hpp
+#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED
+
+// #included from: catch_evaluate.hpp
+#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4389) // '==' : signed/unsigned mismatch
+#endif
+
+#include <cstddef>
+
+namespace Catch {
+namespace Internal {
+
+ enum Operator {
+ IsEqualTo,
+ IsNotEqualTo,
+ IsLessThan,
+ IsGreaterThan,
+ IsLessThanOrEqualTo,
+ IsGreaterThanOrEqualTo
+ };
+
+ template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } };
+ template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } };
+ template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } };
+ template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } };
+ template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } };
+ template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } };
+ template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
+
+ template<typename T>
+ inline T& opCast(T const& t) { return const_cast<T&>(t); }
+
+// nullptr_t support based on pull request #154 from Konstantin Baumann
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+ // So the compare overloads can be operator agnostic we convey the operator as a template
+ // enum, which is used to specialise an Evaluator for doing the comparison.
+ template<typename T1, typename T2, Operator Op>
+ class Evaluator{};
+
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs) {
+ return opCast( lhs ) == opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsNotEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) != opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsLessThan> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) < opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsGreaterThan> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) > opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) >= opCast( rhs );
+ }
+ };
+ template<typename T1, typename T2>
+ struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
+ static bool evaluate( T1 const& lhs, T2 const& rhs ) {
+ return opCast( lhs ) <= opCast( rhs );
+ }
+ };
+
+ template<Operator Op, typename T1, typename T2>
+ bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+ }
+
+ // This level of indirection allows us to specialise for integer types
+ // to avoid signed/ unsigned warnings
+
+ // "base" overload
+ template<Operator Op, typename T1, typename T2>
+ bool compare( T1 const& lhs, T2 const& rhs ) {
+ return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
+ }
+
+ // unsigned X to int
+ template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
+ }
+
+ // unsigned X to long
+ template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+ template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
+ return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
+ }
+
+ // int to unsigned X
+ template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
+ }
+
+ // long to unsigned X
+ template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+
+ // pointer to long (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+
+ // pointer to int (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+ // long long to unsigned X
+ template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
+ return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
+ }
+
+ // unsigned long long to X
+ template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+ template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
+ return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
+ }
+
+ // pointer to long long (when comparing against NULL)
+ template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
+ }
+#endif // CATCH_CONFIG_CPP11_LONG_LONG
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+ // pointer to nullptr_t (when comparing against nullptr)
+ template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
+ return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
+ }
+ template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
+ return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
+ }
+#endif // CATCH_CONFIG_CPP11_NULLPTR
+
+} // end of namespace Internal
+} // end of namespace Catch
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// #included from: catch_tostring.h
+#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED
+
+#include <sstream>
+#include <iomanip>
+#include <limits>
+#include <vector>
+#include <cstddef>
+
+#ifdef __OBJC__
+// #included from: catch_objc_arc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED
+
+#import <Foundation/Foundation.h>
+
+#ifdef __has_feature
+#define CATCH_ARC_ENABLED __has_feature(objc_arc)
+#else
+#define CATCH_ARC_ENABLED 0
+#endif
+
+void arcSafeRelease( NSObject* obj );
+id performOptionalSelector( id obj, SEL sel );
+
+#if !CATCH_ARC_ENABLED
+inline void arcSafeRelease( NSObject* obj ) {
+ [obj release];
+}
+inline id performOptionalSelector( id obj, SEL sel ) {
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED
+#define CATCH_ARC_STRONG
+#else
+inline void arcSafeRelease( NSObject* ){}
+inline id performOptionalSelector( id obj, SEL sel ) {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
+#endif
+ if( [obj respondsToSelector: sel] )
+ return [obj performSelector: sel];
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ return nil;
+}
+#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained
+#define CATCH_ARC_STRONG __strong
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_TUPLE
+#include <tuple>
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_IS_ENUM
+#include <type_traits>
+#endif
+
+namespace Catch {
+
+// Why we're here.
+template<typename T>
+std::string toString( T const& value );
+
+// Built in overloads
+
+std::string toString( std::string const& value );
+std::string toString( std::wstring const& value );
+std::string toString( const char* const value );
+std::string toString( char* const value );
+std::string toString( const wchar_t* const value );
+std::string toString( wchar_t* const value );
+std::string toString( int value );
+std::string toString( unsigned long value );
+std::string toString( unsigned int value );
+std::string toString( const double value );
+std::string toString( const float value );
+std::string toString( bool value );
+std::string toString( char value );
+std::string toString( signed char value );
+std::string toString( unsigned char value );
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+std::string toString( long long value );
+std::string toString( unsigned long long value );
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t );
+#endif
+
+#ifdef __OBJC__
+ std::string toString( NSString const * const& nsstring );
+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring );
+ std::string toString( NSObject* const& nsObject );
+#endif
+
+namespace Detail {
+
+ extern const std::string unprintableString;
+
+ struct BorgType {
+ template<typename T> BorgType( T const& );
+ };
+
+ struct TrueType { char sizer[1]; };
+ struct FalseType { char sizer[2]; };
+
+ TrueType& testStreamable( std::ostream& );
+ FalseType testStreamable( FalseType );
+
+ FalseType operator<<( std::ostream const&, BorgType const& );
+
+ template<typename T>
+ struct IsStreamInsertable {
+ static std::ostream &s;
+ static T const&t;
+ enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
+ };
+
+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
+ template<typename T,
+ bool IsEnum = std::is_enum<T>::value
+ >
+ struct EnumStringMaker
+ {
+ static std::string convert( T const& ) { return unprintableString; }
+ };
+
+ template<typename T>
+ struct EnumStringMaker<T,true>
+ {
+ static std::string convert( T const& v )
+ {
+ return ::Catch::toString(
+ static_cast<typename std::underlying_type<T>::type>(v)
+ );
+ }
+ };
+#endif
+ template<bool C>
+ struct StringMakerBase {
+#if defined(CATCH_CONFIG_CPP11_IS_ENUM)
+ template<typename T>
+ static std::string convert( T const& v )
+ {
+ return EnumStringMaker<T>::convert( v );
+ }
+#else
+ template<typename T>
+ static std::string convert( T const& ) { return unprintableString; }
+#endif
+ };
+
+ template<>
+ struct StringMakerBase<true> {
+ template<typename T>
+ static std::string convert( T const& _value ) {
+ std::ostringstream oss;
+ oss << _value;
+ return oss.str();
+ }
+ };
+
+ std::string rawMemoryToString( const void *object, std::size_t size );
+
+ template<typename T>
+ inline std::string rawMemoryToString( const T& object ) {
+ return rawMemoryToString( &object, sizeof(object) );
+ }
+
+} // end namespace Detail
+
+template<typename T>
+struct StringMaker :
+ Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
+
+template<typename T>
+struct StringMaker<T*> {
+ template<typename U>
+ static std::string convert( U* p ) {
+ if( !p )
+ return "NULL";
+ else
+ return Detail::rawMemoryToString( p );
+ }
+};
+
+template<typename R, typename C>
+struct StringMaker<R C::*> {
+ static std::string convert( R C::* p ) {
+ if( !p )
+ return "NULL";
+ else
+ return Detail::rawMemoryToString( p );
+ }
+};
+
+namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString( InputIterator first, InputIterator last );
+}
+
+//template<typename T, typename Allocator>
+//struct StringMaker<std::vector<T, Allocator> > {
+// static std::string convert( std::vector<T,Allocator> const& v ) {
+// return Detail::rangeToString( v.begin(), v.end() );
+// }
+//};
+
+template<typename T, typename Allocator>
+std::string toString( std::vector<T,Allocator> const& v ) {
+ return Detail::rangeToString( v.begin(), v.end() );
+}
+
+#ifdef CATCH_CONFIG_CPP11_TUPLE
+
+// toString for tuples
+namespace TupleDetail {
+ template<
+ typename Tuple,
+ std::size_t N = 0,
+ bool = (N < std::tuple_size<Tuple>::value)
+ >
+ struct ElementPrinter {
+ static void print( const Tuple& tuple, std::ostream& os )
+ {
+ os << ( N ? ", " : " " )
+ << Catch::toString(std::get<N>(tuple));
+ ElementPrinter<Tuple,N+1>::print(tuple,os);
+ }
+ };
+
+ template<
+ typename Tuple,
+ std::size_t N
+ >
+ struct ElementPrinter<Tuple,N,false> {
+ static void print( const Tuple&, std::ostream& ) {}
+ };
+
+}
+
+template<typename ...Types>
+struct StringMaker<std::tuple<Types...>> {
+
+ static std::string convert( const std::tuple<Types...>& tuple )
+ {
+ std::ostringstream os;
+ os << '{';
+ TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os );
+ os << " }";
+ return os.str();
+ }
+};
+#endif // CATCH_CONFIG_CPP11_TUPLE
+
+namespace Detail {
+ template<typename T>
+ std::string makeString( T const& value ) {
+ return StringMaker<T>::convert( value );
+ }
+} // end namespace Detail
+
+/// \brief converts any type to a string
+///
+/// The default template forwards on to ostringstream - except when an
+/// ostringstream overload does not exist - in which case it attempts to detect
+/// that and writes {?}.
+/// Overload (not specialise) this template for custom typs that you don't want
+/// to provide an ostream overload for.
+template<typename T>
+std::string toString( T const& value ) {
+ return StringMaker<T>::convert( value );
+}
+
+ namespace Detail {
+ template<typename InputIterator>
+ std::string rangeToString( InputIterator first, InputIterator last ) {
+ std::ostringstream oss;
+ oss << "{ ";
+ if( first != last ) {
+ oss << Catch::toString( *first );
+ for( ++first ; first != last ; ++first )
+ oss << ", " << Catch::toString( *first );
+ }
+ oss << " }";
+ return oss.str();
+ }
+}
+
+} // end namespace Catch
+
+namespace Catch {
+
+// Wraps the LHS of an expression and captures the operator and RHS (if any) -
+// wrapping them all in a ResultBuilder object
+template<typename T>
+class ExpressionLhs {
+ ExpressionLhs& operator = ( ExpressionLhs const& );
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ ExpressionLhs& operator = ( ExpressionLhs && ) = delete;
+# endif
+
+public:
+ ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {}
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ ExpressionLhs( ExpressionLhs const& ) = default;
+ ExpressionLhs( ExpressionLhs && ) = default;
+# endif
+
+ template<typename RhsT>
+ ResultBuilder& operator == ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator != ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsNotEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator < ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsLessThan>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator > ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsGreaterThan>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator <= ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsLessThanOrEqualTo>( rhs );
+ }
+
+ template<typename RhsT>
+ ResultBuilder& operator >= ( RhsT const& rhs ) {
+ return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs );
+ }
+
+ ResultBuilder& operator == ( bool rhs ) {
+ return captureExpression<Internal::IsEqualTo>( rhs );
+ }
+
+ ResultBuilder& operator != ( bool rhs ) {
+ return captureExpression<Internal::IsNotEqualTo>( rhs );
+ }
+
+ void endExpression() {
+ bool value = m_lhs ? true : false;
+ m_rb
+ .setLhs( Catch::toString( value ) )
+ .setResultType( value )
+ .endExpression();
+ }
+
+ // Only simple binary expressions are allowed on the LHS.
+ // If more complex compositions are required then place the sub expression in parentheses
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& );
+ template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& );
+
+private:
+ template<Internal::Operator Op, typename RhsT>
+ ResultBuilder& captureExpression( RhsT const& rhs ) {
+ return m_rb
+ .setResultType( Internal::compare<Op>( m_lhs, rhs ) )
+ .setLhs( Catch::toString( m_lhs ) )
+ .setRhs( Catch::toString( rhs ) )
+ .setOp( Internal::OperatorTraits<Op>::getName() );
+ }
+
+private:
+ ResultBuilder& m_rb;
+ T m_lhs;
+};
+
+} // end namespace Catch
+
+
+namespace Catch {
+
+ template<typename T>
+ inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
+ return ExpressionLhs<T const&>( *this, operand );
+ }
+
+ inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
+ return ExpressionLhs<bool>( *this, value );
+ }
+
+} // namespace Catch
+
+// #included from: catch_message.h
+#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct MessageInfo {
+ MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type );
+
+ std::string macroName;
+ SourceLineInfo lineInfo;
+ ResultWas::OfType type;
+ std::string message;
+ unsigned int sequence;
+
+ bool operator == ( MessageInfo const& other ) const {
+ return sequence == other.sequence;
+ }
+ bool operator < ( MessageInfo const& other ) const {
+ return sequence < other.sequence;
+ }
+ private:
+ static unsigned int globalCount;
+ };
+
+ struct MessageBuilder {
+ MessageBuilder( std::string const& macroName,
+ SourceLineInfo const& lineInfo,
+ ResultWas::OfType type )
+ : m_info( macroName, lineInfo, type )
+ {}
+
+ template<typename T>
+ MessageBuilder& operator << ( T const& value ) {
+ m_stream << value;
+ return *this;
+ }
+
+ MessageInfo m_info;
+ std::ostringstream m_stream;
+ };
+
+ class ScopedMessage {
+ public:
+ ScopedMessage( MessageBuilder const& builder );
+ ScopedMessage( ScopedMessage const& other );
+ ~ScopedMessage();
+
+ MessageInfo m_info;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_capture.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ class TestCase;
+ class AssertionResult;
+ struct AssertionInfo;
+ struct SectionInfo;
+ struct SectionEndInfo;
+ struct MessageInfo;
+ class ScopedMessageBuilder;
+ struct Counts;
+
+ struct IResultCapture {
+
+ virtual ~IResultCapture();
+
+ virtual void assertionEnded( AssertionResult const& result ) = 0;
+ virtual bool sectionStarted( SectionInfo const& sectionInfo,
+ Counts& assertions ) = 0;
+ virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;
+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;
+ virtual void pushScopedMessage( MessageInfo const& message ) = 0;
+ virtual void popScopedMessage( MessageInfo const& message ) = 0;
+
+ virtual std::string getCurrentTestName() const = 0;
+ virtual const AssertionResult* getLastResult() const = 0;
+
+ virtual void handleFatalErrorCondition( std::string const& message ) = 0;
+ };
+
+ IResultCapture& getResultCapture();
+}
+
+// #included from: catch_debugger.h
+#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
+
+// #included from: catch_platform.h
+#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED
+
+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
+#define CATCH_PLATFORM_MAC
+#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
+#define CATCH_PLATFORM_IPHONE
+#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)
+#define CATCH_PLATFORM_WINDOWS
+#endif
+
+#include <string>
+
+namespace Catch{
+
+ bool isDebuggerActive();
+ void writeToDebugConsole( std::string const& text );
+}
+
+#ifdef CATCH_PLATFORM_MAC
+
+ // The following code snippet based on:
+ // http://cocoawithlove.com/2008/03/break-into-debugger.html
+ #ifdef DEBUG
+ #if defined(__ppc64__) || defined(__ppc__)
+ #define CATCH_BREAK_INTO_DEBUGGER() \
+ if( Catch::isDebuggerActive() ) { \
+ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
+ : : : "memory","r0","r3","r4" ); \
+ }
+ #else
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
+ #endif
+ #endif
+
+#elif defined(_MSC_VER)
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
+ #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
+#endif
+
+#ifndef CATCH_BREAK_INTO_DEBUGGER
+#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue();
+#endif
+
+// #included from: catch_interfaces_runner.h
+#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
+
+namespace Catch {
+ class TestCase;
+
+ struct IRunner {
+ virtual ~IRunner();
+ virtual bool aborting() const = 0;
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// In the event of a failure works out if the debugger needs to be invoked
+// and/or an exception thrown and takes appropriate action.
+// This needs to be done as a macro so the debugger will stop in the user
+// source code rather than in Catch library code
+#define INTERNAL_CATCH_REACT( resultBuilder ) \
+ if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \
+ resultBuilder.react();
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ try { \
+ ( __catchResult <= expr ).endExpression(); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::isTrue( false && static_cast<bool>(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \
+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
+ if( Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \
+ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \
+ if( !Catch::getResultCapture().getLastResult()->succeeded() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \
+ if( __catchResult.allowThrows() ) \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+ } \
+ catch( ... ) { \
+ __catchResult.captureExpectedException( matcher ); \
+ } \
+ else \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
+ if( __catchResult.allowThrows() ) \
+ try { \
+ expr; \
+ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \
+ } \
+ catch( exceptionType ) { \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ } \
+ catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition ); \
+ } \
+ else \
+ __catchResult.captureResult( Catch::ResultWas::Ok ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+///////////////////////////////////////////////////////////////////////////////
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \
+ __catchResult.captureResult( messageType ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+#else
+ #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \
+ __catchResult << log + ::Catch::StreamEndStop(); \
+ __catchResult.captureResult( messageType ); \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_INFO( log, macroName ) \
+ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log;
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \
+ do { \
+ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \
+ try { \
+ std::string matcherAsString = (matcher).toString(); \
+ __catchResult \
+ .setLhs( Catch::toString( arg ) ) \
+ .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \
+ .setOp( "matches" ) \
+ .setResultType( (matcher).match( arg ) ); \
+ __catchResult.captureExpression(); \
+ } catch( ... ) { \
+ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \
+ } \
+ INTERNAL_CATCH_REACT( __catchResult ) \
+ } while( Catch::alwaysFalse() )
+
+// #included from: internal/catch_section.h
+#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
+
+// #included from: catch_section_info.h
+#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
+
+// #included from: catch_totals.hpp
+#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED
+
+#include <cstddef>
+
+namespace Catch {
+
+ struct Counts {
+ Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {}
+
+ Counts operator - ( Counts const& other ) const {
+ Counts diff;
+ diff.passed = passed - other.passed;
+ diff.failed = failed - other.failed;
+ diff.failedButOk = failedButOk - other.failedButOk;
+ return diff;
+ }
+ Counts& operator += ( Counts const& other ) {
+ passed += other.passed;
+ failed += other.failed;
+ failedButOk += other.failedButOk;
+ return *this;
+ }
+
+ std::size_t total() const {
+ return passed + failed + failedButOk;
+ }
+ bool allPassed() const {
+ return failed == 0 && failedButOk == 0;
+ }
+ bool allOk() const {
+ return failed == 0;
+ }
+
+ std::size_t passed;
+ std::size_t failed;
+ std::size_t failedButOk;
+ };
+
+ struct Totals {
+
+ Totals operator - ( Totals const& other ) const {
+ Totals diff;
+ diff.assertions = assertions - other.assertions;
+ diff.testCases = testCases - other.testCases;
+ return diff;
+ }
+
+ Totals delta( Totals const& prevTotals ) const {
+ Totals diff = *this - prevTotals;
+ if( diff.assertions.failed > 0 )
+ ++diff.testCases.failed;
+ else if( diff.assertions.failedButOk > 0 )
+ ++diff.testCases.failedButOk;
+ else
+ ++diff.testCases.passed;
+ return diff;
+ }
+
+ Totals& operator += ( Totals const& other ) {
+ assertions += other.assertions;
+ testCases += other.testCases;
+ return *this;
+ }
+
+ Counts assertions;
+ Counts testCases;
+ };
+}
+
+namespace Catch {
+
+ struct SectionInfo {
+ SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description = std::string() );
+
+ std::string name;
+ std::string description;
+ SourceLineInfo lineInfo;
+ };
+
+ struct SectionEndInfo {
+ SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds )
+ : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds )
+ {}
+
+ SectionInfo sectionInfo;
+ Counts prevAssertions;
+ double durationInSeconds;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_timer.h
+#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED
+
+#ifdef CATCH_PLATFORM_WINDOWS
+typedef unsigned long long uint64_t;
+#else
+#include <stdint.h>
+#endif
+
+namespace Catch {
+
+ class Timer {
+ public:
+ Timer() : m_ticks( 0 ) {}
+ void start();
+ unsigned int getElapsedMicroseconds() const;
+ unsigned int getElapsedMilliseconds() const;
+ double getElapsedSeconds() const;
+
+ private:
+ uint64_t m_ticks;
+ };
+
+} // namespace Catch
+
+#include <string>
+
+namespace Catch {
+
+ class Section : NonCopyable {
+ public:
+ Section( SectionInfo const& info );
+ ~Section();
+
+ // This indicates whether the section should be executed or not
+ operator bool() const;
+
+ private:
+ SectionInfo m_info;
+
+ std::string m_name;
+ Counts m_assertions;
+ bool m_sectionIncluded;
+ Timer m_timer;
+ };
+
+} // end namespace Catch
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define INTERNAL_CATCH_SECTION( ... ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
+#else
+ #define INTERNAL_CATCH_SECTION( name, desc ) \
+ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) )
+#endif
+
+// #included from: internal/catch_generators.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
+
+#include <iterator>
+#include <vector>
+#include <string>
+#include <stdlib.h>
+
+namespace Catch {
+
+template<typename T>
+struct IGenerator {
+ virtual ~IGenerator() {}
+ virtual T getValue( std::size_t index ) const = 0;
+ virtual std::size_t size () const = 0;
+};
+
+template<typename T>
+class BetweenGenerator : public IGenerator<T> {
+public:
+ BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){}
+
+ virtual T getValue( std::size_t index ) const {
+ return m_from+static_cast<int>( index );
+ }
+
+ virtual std::size_t size() const {
+ return static_cast<std::size_t>( 1+m_to-m_from );
+ }
+
+private:
+
+ T m_from;
+ T m_to;
+};
+
+template<typename T>
+class ValuesGenerator : public IGenerator<T> {
+public:
+ ValuesGenerator(){}
+
+ void add( T value ) {
+ m_values.push_back( value );
+ }
+
+ virtual T getValue( std::size_t index ) const {
+ return m_values[index];
+ }
+
+ virtual std::size_t size() const {
+ return m_values.size();
+ }
+
+private:
+ std::vector<T> m_values;
+};
+
+template<typename T>
+class CompositeGenerator {
+public:
+ CompositeGenerator() : m_totalSize( 0 ) {}
+
+ // *** Move semantics, similar to auto_ptr ***
+ CompositeGenerator( CompositeGenerator& other )
+ : m_fileInfo( other.m_fileInfo ),
+ m_totalSize( 0 )
+ {
+ move( other );
+ }
+
+ CompositeGenerator& setFileInfo( const char* fileInfo ) {
+ m_fileInfo = fileInfo;
+ return *this;
+ }
+
+ ~CompositeGenerator() {
+ deleteAll( m_composed );
+ }
+
+ operator T () const {
+ size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize );
+
+ typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
+ typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
+ for( size_t index = 0; it != itEnd; ++it )
+ {
+ const IGenerator<T>* generator = *it;
+ if( overallIndex >= index && overallIndex < index + generator->size() )
+ {
+ return generator->getValue( overallIndex-index );
+ }
+ index += generator->size();
+ }
+ CATCH_INTERNAL_ERROR( "Indexed past end of generated range" );
+ return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
+ }
+
+ void add( const IGenerator<T>* generator ) {
+ m_totalSize += generator->size();
+ m_composed.push_back( generator );
+ }
+
+ CompositeGenerator& then( CompositeGenerator& other ) {
+ move( other );
+ return *this;
+ }
+
+ CompositeGenerator& then( T value ) {
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( value );
+ add( valuesGen );
+ return *this;
+ }
+
+private:
+
+ void move( CompositeGenerator& other ) {
+ std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
+ m_totalSize += other.m_totalSize;
+ other.m_composed.clear();
+ }
+
+ std::vector<const IGenerator<T>*> m_composed;
+ std::string m_fileInfo;
+ size_t m_totalSize;
+};
+
+namespace Generators
+{
+ template<typename T>
+ CompositeGenerator<T> between( T from, T to ) {
+ CompositeGenerator<T> generators;
+ generators.add( new BetweenGenerator<T>( from, to ) );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2 ) {
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2, T val3 ){
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ valuesGen->add( val3 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+ template<typename T>
+ CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) {
+ CompositeGenerator<T> generators;
+ ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
+ valuesGen->add( val1 );
+ valuesGen->add( val2 );
+ valuesGen->add( val3 );
+ valuesGen->add( val4 );
+ generators.add( valuesGen );
+ return generators;
+ }
+
+} // end namespace Generators
+
+using namespace Generators;
+
+} // end namespace Catch
+
+#define INTERNAL_CATCH_LINESTR2( line ) #line
+#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
+
+#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
+
+// #included from: internal/catch_interfaces_exception.h
+#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
+
+#include <string>
+#include <vector>
+
+// #included from: catch_interfaces_registry_hub.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ class TestCase;
+ struct ITestCaseRegistry;
+ struct IExceptionTranslatorRegistry;
+ struct IExceptionTranslator;
+ struct IReporterRegistry;
+ struct IReporterFactory;
+
+ struct IRegistryHub {
+ virtual ~IRegistryHub();
+
+ virtual IReporterRegistry const& getReporterRegistry() const = 0;
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0;
+ };
+
+ struct IMutableRegistryHub {
+ virtual ~IMutableRegistryHub();
+ virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
+ virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
+ virtual void registerTest( TestCase const& testInfo ) = 0;
+ virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
+ };
+
+ IRegistryHub& getRegistryHub();
+ IMutableRegistryHub& getMutableRegistryHub();
+ void cleanUp();
+ std::string translateActiveException();
+
+}
+
+namespace Catch {
+
+ typedef std::string(*exceptionTranslateFunction)();
+
+ struct IExceptionTranslator;
+ typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
+
+ struct IExceptionTranslator {
+ virtual ~IExceptionTranslator();
+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
+ };
+
+ struct IExceptionTranslatorRegistry {
+ virtual ~IExceptionTranslatorRegistry();
+
+ virtual std::string translateActiveException() const = 0;
+ };
+
+ class ExceptionTranslatorRegistrar {
+ template<typename T>
+ class ExceptionTranslator : public IExceptionTranslator {
+ public:
+
+ ExceptionTranslator( std::string(*translateFunction)( T& ) )
+ : m_translateFunction( translateFunction )
+ {}
+
+ virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
+ try {
+ if( it == itEnd )
+ throw;
+ else
+ return (*it)->translate( it+1, itEnd );
+ }
+ catch( T& ex ) {
+ return m_translateFunction( ex );
+ }
+ }
+
+ protected:
+ std::string(*m_translateFunction)( T& );
+ };
+
+ public:
+ template<typename T>
+ ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
+ getMutableRegistryHub().registerTranslator
+ ( new ExceptionTranslator<T>( translateFunction ) );
+ }
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \
+ static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \
+ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\
+ static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature )
+
+// #included from: internal/catch_approx.hpp
+#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED
+
+#include <cmath>
+#include <limits>
+
+namespace Catch {
+namespace Detail {
+
+ class Approx {
+ public:
+ explicit Approx ( double value )
+ : m_epsilon( std::numeric_limits<float>::epsilon()*100 ),
+ m_scale( 1.0 ),
+ m_value( value )
+ {}
+
+ Approx( Approx const& other )
+ : m_epsilon( other.m_epsilon ),
+ m_scale( other.m_scale ),
+ m_value( other.m_value )
+ {}
+
+ static Approx custom() {
+ return Approx( 0 );
+ }
+
+ Approx operator()( double value ) {
+ Approx approx( value );
+ approx.epsilon( m_epsilon );
+ approx.scale( m_scale );
+ return approx;
+ }
+
+ friend bool operator == ( double lhs, Approx const& rhs ) {
+ // Thanks to Richard Harris for his help refining this formula
+ return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) );
+ }
+
+ friend bool operator == ( Approx const& lhs, double rhs ) {
+ return operator==( rhs, lhs );
+ }
+
+ friend bool operator != ( double lhs, Approx const& rhs ) {
+ return !operator==( lhs, rhs );
+ }
+
+ friend bool operator != ( Approx const& lhs, double rhs ) {
+ return !operator==( rhs, lhs );
+ }
+
+ Approx& epsilon( double newEpsilon ) {
+ m_epsilon = newEpsilon;
+ return *this;
+ }
+
+ Approx& scale( double newScale ) {
+ m_scale = newScale;
+ return *this;
+ }
+
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << "Approx( " << Catch::toString( m_value ) << " )";
+ return oss.str();
+ }
+
+ private:
+ double m_epsilon;
+ double m_scale;
+ double m_value;
+ };
+}
+
+template<>
+inline std::string toString<Detail::Approx>( Detail::Approx const& value ) {
+ return value.toString();
+}
+
+} // end namespace Catch
+
+// #included from: internal/catch_interfaces_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+// #included from: catch_tag_alias.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED
+
+#include <string>
+
+namespace Catch {
+
+ struct TagAlias {
+ TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {}
+
+ std::string tag;
+ SourceLineInfo lineInfo;
+ };
+
+ struct RegistrarForTagAliases {
+ RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ };
+
+} // end namespace Catch
+
+#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); }
+// #included from: catch_option.hpp
+#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED
+
+namespace Catch {
+
+ // An optional type
+ template<typename T>
+ class Option {
+ public:
+ Option() : nullableValue( CATCH_NULL ) {}
+ Option( T const& _value )
+ : nullableValue( new( storage ) T( _value ) )
+ {}
+ Option( Option const& _other )
+ : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL )
+ {}
+
+ ~Option() {
+ reset();
+ }
+
+ Option& operator= ( Option const& _other ) {
+ if( &_other != this ) {
+ reset();
+ if( _other )
+ nullableValue = new( storage ) T( *_other );
+ }
+ return *this;
+ }
+ Option& operator = ( T const& _value ) {
+ reset();
+ nullableValue = new( storage ) T( _value );
+ return *this;
+ }
+
+ void reset() {
+ if( nullableValue )
+ nullableValue->~T();
+ nullableValue = CATCH_NULL;
+ }
+
+ T& operator*() { return *nullableValue; }
+ T const& operator*() const { return *nullableValue; }
+ T* operator->() { return nullableValue; }
+ const T* operator->() const { return nullableValue; }
+
+ T valueOr( T const& defaultValue ) const {
+ return nullableValue ? *nullableValue : defaultValue;
+ }
+
+ bool some() const { return nullableValue != CATCH_NULL; }
+ bool none() const { return nullableValue == CATCH_NULL; }
+
+ bool operator !() const { return nullableValue == CATCH_NULL; }
+ operator SafeBool::type() const {
+ return SafeBool::makeSafe( some() );
+ }
+
+ private:
+ T* nullableValue;
+ char storage[sizeof(T)];
+ };
+
+} // end namespace Catch
+
+namespace Catch {
+
+ struct ITagAliasRegistry {
+ virtual ~ITagAliasRegistry();
+ virtual Option<TagAlias> find( std::string const& alias ) const = 0;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;
+
+ static ITagAliasRegistry const& get();
+ };
+
+} // end namespace Catch
+
+// These files are included here so the single_include script doesn't put them
+// in the conditionally compiled sections
+// #included from: internal/catch_test_case_info.h
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED
+
+#include <string>
+#include <set>
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+namespace Catch {
+
+ struct ITestCase;
+
+ struct TestCaseInfo {
+ enum SpecialProperties{
+ None = 0,
+ IsHidden = 1 << 1,
+ ShouldFail = 1 << 2,
+ MayFail = 1 << 3,
+ Throws = 1 << 4
+ };
+
+ TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::set<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo );
+
+ TestCaseInfo( TestCaseInfo const& other );
+
+ friend void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags );
+
+ bool isHidden() const;
+ bool throws() const;
+ bool okToFail() const;
+ bool expectedToFail() const;
+
+ std::string name;
+ std::string className;
+ std::string description;
+ std::set<std::string> tags;
+ std::set<std::string> lcaseTags;
+ std::string tagsAsString;
+ SourceLineInfo lineInfo;
+ SpecialProperties properties;
+ };
+
+ class TestCase : public TestCaseInfo {
+ public:
+
+ TestCase( ITestCase* testCase, TestCaseInfo const& info );
+ TestCase( TestCase const& other );
+
+ TestCase withName( std::string const& _newName ) const;
+
+ void invoke() const;
+
+ TestCaseInfo const& getTestCaseInfo() const;
+
+ void swap( TestCase& other );
+ bool operator == ( TestCase const& other ) const;
+ bool operator < ( TestCase const& other ) const;
+ TestCase& operator = ( TestCase const& other );
+
+ private:
+ Ptr<ITestCase> test;
+ };
+
+ TestCase makeTestCase( ITestCase* testCase,
+ std::string const& className,
+ std::string const& name,
+ std::string const& description,
+ SourceLineInfo const& lineInfo );
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+
+#ifdef __OBJC__
+// #included from: internal/catch_objc.hpp
+#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED
+
+#import <objc/runtime.h>
+
+#include <string>
+
+// NB. Any general catch headers included here must be included
+// in catch.hpp first to make sure they are included by the single
+// header for non obj-usage
+
+///////////////////////////////////////////////////////////////////////////////
+// This protocol is really only here for (self) documenting purposes, since
+// all its methods are optional.
+@protocol OcFixture
+
+@optional
+
+-(void) setUp;
+-(void) tearDown;
+
+@end
+
+namespace Catch {
+
+ class OcMethod : public SharedImpl<ITestCase> {
+
+ public:
+ OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}
+
+ virtual void invoke() const {
+ id obj = [[m_cls alloc] init];
+
+ performOptionalSelector( obj, @selector(setUp) );
+ performOptionalSelector( obj, m_sel );
+ performOptionalSelector( obj, @selector(tearDown) );
+
+ arcSafeRelease( obj );
+ }
+ private:
+ virtual ~OcMethod() {}
+
+ Class m_cls;
+ SEL m_sel;
+ };
+
+ namespace Detail{
+
+ inline std::string getAnnotation( Class cls,
+ std::string const& annotationName,
+ std::string const& testCaseName ) {
+ NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()];
+ SEL sel = NSSelectorFromString( selStr );
+ arcSafeRelease( selStr );
+ id value = performOptionalSelector( cls, sel );
+ if( value )
+ return [(NSString*)value UTF8String];
+ return "";
+ }
+ }
+
+ inline size_t registerTestMethods() {
+ size_t noTestMethods = 0;
+ int noClasses = objc_getClassList( CATCH_NULL, 0 );
+
+ Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);
+ objc_getClassList( classes, noClasses );
+
+ for( int c = 0; c < noClasses; c++ ) {
+ Class cls = classes[c];
+ {
+ u_int count;
+ Method* methods = class_copyMethodList( cls, &count );
+ for( u_int m = 0; m < count ; m++ ) {
+ SEL selector = method_getName(methods[m]);
+ std::string methodName = sel_getName(selector);
+ if( startsWith( methodName, "Catch_TestCase_" ) ) {
+ std::string testCaseName = methodName.substr( 15 );
+ std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
+ std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
+ const char* className = class_getName( cls );
+
+ getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) );
+ noTestMethods++;
+ }
+ }
+ free(methods);
+ }
+ }
+ return noTestMethods;
+ }
+
+ namespace Matchers {
+ namespace Impl {
+ namespace NSStringMatchers {
+
+ template<typename MatcherT>
+ struct StringHolder : MatcherImpl<MatcherT, NSString*>{
+ StringHolder( NSString* substr ) : m_substr( [substr copy] ){}
+ StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}
+ StringHolder() {
+ arcSafeRelease( m_substr );
+ }
+
+ NSString* m_substr;
+ };
+
+ struct Equals : StringHolder<Equals> {
+ Equals( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str isEqualToString:m_substr];
+ }
+
+ virtual std::string toString() const {
+ return "equals string: " + Catch::toString( m_substr );
+ }
+ };
+
+ struct Contains : StringHolder<Contains> {
+ Contains( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location != NSNotFound;
+ }
+
+ virtual std::string toString() const {
+ return "contains string: " + Catch::toString( m_substr );
+ }
+ };
+
+ struct StartsWith : StringHolder<StartsWith> {
+ StartsWith( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == 0;
+ }
+
+ virtual std::string toString() const {
+ return "starts with: " + Catch::toString( m_substr );
+ }
+ };
+ struct EndsWith : StringHolder<EndsWith> {
+ EndsWith( NSString* substr ) : StringHolder( substr ){}
+
+ virtual bool match( ExpressionType const& str ) const {
+ return (str != nil || m_substr == nil ) &&
+ [str rangeOfString:m_substr].location == [str length] - [m_substr length];
+ }
+
+ virtual std::string toString() const {
+ return "ends with: " + Catch::toString( m_substr );
+ }
+ };
+
+ } // namespace NSStringMatchers
+ } // namespace Impl
+
+ inline Impl::NSStringMatchers::Equals
+ Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }
+
+ inline Impl::NSStringMatchers::Contains
+ Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }
+
+ inline Impl::NSStringMatchers::StartsWith
+ StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }
+
+ inline Impl::NSStringMatchers::EndsWith
+ EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }
+
+ } // namespace Matchers
+
+ using namespace Matchers;
+
+} // namespace Catch
+
+///////////////////////////////////////////////////////////////////////////////
+#define OC_TEST_CASE( name, desc )\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \
+{\
+return @ name; \
+}\
++(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \
+{ \
+return @ desc; \
+} \
+-(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test )
+
+#endif
+
+#ifdef CATCH_IMPL
+// #included from: internal/catch_impl.hpp
+#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED
+
+// Collect all the implementation files together here
+// These are the equivalent of what would usually be cpp files
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wweak-vtables"
+#endif
+
+// #included from: ../catch_session.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED
+
+// #included from: internal/catch_commandline.hpp
+#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
+
+// #included from: catch_config.hpp
+#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED
+
+// #included from: catch_test_spec_parser.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// #included from: catch_test_spec.hpp
+#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+// #included from: catch_wildcard_pattern.hpp
+#define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED
+
+namespace Catch
+{
+ class WildcardPattern {
+ enum WildcardPosition {
+ NoWildcard = 0,
+ WildcardAtStart = 1,
+ WildcardAtEnd = 2,
+ WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd
+ };
+
+ public:
+
+ WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity )
+ : m_caseSensitivity( caseSensitivity ),
+ m_wildcard( NoWildcard ),
+ m_pattern( adjustCase( pattern ) )
+ {
+ if( startsWith( m_pattern, "*" ) ) {
+ m_pattern = m_pattern.substr( 1 );
+ m_wildcard = WildcardAtStart;
+ }
+ if( endsWith( m_pattern, "*" ) ) {
+ m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );
+ m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );
+ }
+ }
+ virtual ~WildcardPattern();
+ virtual bool matches( std::string const& str ) const {
+ switch( m_wildcard ) {
+ case NoWildcard:
+ return m_pattern == adjustCase( str );
+ case WildcardAtStart:
+ return endsWith( adjustCase( str ), m_pattern );
+ case WildcardAtEnd:
+ return startsWith( adjustCase( str ), m_pattern );
+ case WildcardAtBothEnds:
+ return contains( adjustCase( str ), m_pattern );
+ }
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+ throw std::logic_error( "Unknown enum" );
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+ }
+ private:
+ std::string adjustCase( std::string const& str ) const {
+ return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str;
+ }
+ CaseSensitive::Choice m_caseSensitivity;
+ WildcardPosition m_wildcard;
+ std::string m_pattern;
+ };
+}
+
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ class TestSpec {
+ struct Pattern : SharedImpl<> {
+ virtual ~Pattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const = 0;
+ };
+ class NamePattern : public Pattern {
+ public:
+ NamePattern( std::string const& name )
+ : m_wildcardPattern( toLower( name ), CaseSensitive::No )
+ {}
+ virtual ~NamePattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const {
+ return m_wildcardPattern.matches( toLower( testCase.name ) );
+ }
+ private:
+ WildcardPattern m_wildcardPattern;
+ };
+
+ class TagPattern : public Pattern {
+ public:
+ TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {}
+ virtual ~TagPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const {
+ return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end();
+ }
+ private:
+ std::string m_tag;
+ };
+
+ class ExcludedPattern : public Pattern {
+ public:
+ ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {}
+ virtual ~ExcludedPattern();
+ virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); }
+ private:
+ Ptr<Pattern> m_underlyingPattern;
+ };
+
+ struct Filter {
+ std::vector<Ptr<Pattern> > m_patterns;
+
+ bool matches( TestCaseInfo const& testCase ) const {
+ // All patterns in a filter must match for the filter to be a match
+ for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it )
+ if( !(*it)->matches( testCase ) )
+ return false;
+ return true;
+ }
+ };
+
+ public:
+ bool hasFilters() const {
+ return !m_filters.empty();
+ }
+ bool matches( TestCaseInfo const& testCase ) const {
+ // A TestSpec matches if any filter matches
+ for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it )
+ if( it->matches( testCase ) )
+ return true;
+ return false;
+ }
+
+ private:
+ std::vector<Filter> m_filters;
+
+ friend class TestSpecParser;
+ };
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+namespace Catch {
+
+ class TestSpecParser {
+ enum Mode{ None, Name, QuotedName, Tag };
+ Mode m_mode;
+ bool m_exclusion;
+ std::size_t m_start, m_pos;
+ std::string m_arg;
+ TestSpec::Filter m_currentFilter;
+ TestSpec m_testSpec;
+ ITagAliasRegistry const* m_tagAliases;
+
+ public:
+ TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}
+
+ TestSpecParser& parse( std::string const& arg ) {
+ m_mode = None;
+ m_exclusion = false;
+ m_start = std::string::npos;
+ m_arg = m_tagAliases->expandAliases( arg );
+ for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )
+ visitChar( m_arg[m_pos] );
+ if( m_mode == Name )
+ addPattern<TestSpec::NamePattern>();
+ return *this;
+ }
+ TestSpec testSpec() {
+ addFilter();
+ return m_testSpec;
+ }
+ private:
+ void visitChar( char c ) {
+ if( m_mode == None ) {
+ switch( c ) {
+ case ' ': return;
+ case '~': m_exclusion = true; return;
+ case '[': return startNewMode( Tag, ++m_pos );
+ case '"': return startNewMode( QuotedName, ++m_pos );
+ default: startNewMode( Name, m_pos ); break;
+ }
+ }
+ if( m_mode == Name ) {
+ if( c == ',' ) {
+ addPattern<TestSpec::NamePattern>();
+ addFilter();
+ }
+ else if( c == '[' ) {
+ if( subString() == "exclude:" )
+ m_exclusion = true;
+ else
+ addPattern<TestSpec::NamePattern>();
+ startNewMode( Tag, ++m_pos );
+ }
+ }
+ else if( m_mode == QuotedName && c == '"' )
+ addPattern<TestSpec::NamePattern>();
+ else if( m_mode == Tag && c == ']' )
+ addPattern<TestSpec::TagPattern>();
+ }
+ void startNewMode( Mode mode, std::size_t start ) {
+ m_mode = mode;
+ m_start = start;
+ }
+ std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); }
+ template<typename T>
+ void addPattern() {
+ std::string token = subString();
+ if( startsWith( token, "exclude:" ) ) {
+ m_exclusion = true;
+ token = token.substr( 8 );
+ }
+ if( !token.empty() ) {
+ Ptr<TestSpec::Pattern> pattern = new T( token );
+ if( m_exclusion )
+ pattern = new TestSpec::ExcludedPattern( pattern );
+ m_currentFilter.m_patterns.push_back( pattern );
+ }
+ m_exclusion = false;
+ m_mode = None;
+ }
+ void addFilter() {
+ if( !m_currentFilter.m_patterns.empty() ) {
+ m_testSpec.m_filters.push_back( m_currentFilter );
+ m_currentFilter = TestSpec::Filter();
+ }
+ }
+ };
+ inline TestSpec parseTestSpec( std::string const& arg ) {
+ return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();
+ }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+// #included from: catch_interfaces_config.h
+#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace Catch {
+
+ struct Verbosity { enum Level {
+ NoOutput = 0,
+ Quiet,
+ Normal
+ }; };
+
+ struct WarnAbout { enum What {
+ Nothing = 0x00,
+ NoAssertions = 0x01
+ }; };
+
+ struct ShowDurations { enum OrNot {
+ DefaultForReporter,
+ Always,
+ Never
+ }; };
+ struct RunTests { enum InWhatOrder {
+ InDeclarationOrder,
+ InLexicographicalOrder,
+ InRandomOrder
+ }; };
+
+ class TestSpec;
+
+ struct IConfig : IShared {
+
+ virtual ~IConfig();
+
+ virtual bool allowThrows() const = 0;
+ virtual std::ostream& stream() const = 0;
+ virtual std::string name() const = 0;
+ virtual bool includeSuccessfulResults() const = 0;
+ virtual bool shouldDebugBreak() const = 0;
+ virtual bool warnAboutMissingAssertions() const = 0;
+ virtual int abortAfter() const = 0;
+ virtual bool showInvisibles() const = 0;
+ virtual ShowDurations::OrNot showDurations() const = 0;
+ virtual TestSpec const& testSpec() const = 0;
+ virtual RunTests::InWhatOrder runOrder() const = 0;
+ virtual unsigned int rngSeed() const = 0;
+ virtual bool forceColour() const = 0;
+ };
+}
+
+// #included from: catch_stream.h
+#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
+
+// #included from: catch_streambuf.h
+#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED
+
+#include <streambuf>
+
+namespace Catch {
+
+ class StreamBufBase : public std::streambuf {
+ public:
+ virtual ~StreamBufBase() CATCH_NOEXCEPT;
+ };
+}
+
+#include <streambuf>
+#include <ostream>
+#include <fstream>
+
+namespace Catch {
+
+ std::ostream& cout();
+ std::ostream& cerr();
+
+ struct IStream {
+ virtual ~IStream() CATCH_NOEXCEPT;
+ virtual std::ostream& stream() const = 0;
+ };
+
+ class FileStream : public IStream {
+ mutable std::ofstream m_ofs;
+ public:
+ FileStream( std::string const& filename );
+ virtual ~FileStream() CATCH_NOEXCEPT;
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
+
+ class CoutStream : public IStream {
+ mutable std::ostream m_os;
+ public:
+ CoutStream();
+ virtual ~CoutStream() CATCH_NOEXCEPT;
+
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
+
+ class DebugOutStream : public IStream {
+ std::auto_ptr<StreamBufBase> m_streamBuf;
+ mutable std::ostream m_os;
+ public:
+ DebugOutStream();
+ virtual ~DebugOutStream() CATCH_NOEXCEPT;
+
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
+}
+
+#include <memory>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <ctime>
+
+#ifndef CATCH_CONFIG_CONSOLE_WIDTH
+#define CATCH_CONFIG_CONSOLE_WIDTH 80
+#endif
+
+namespace Catch {
+
+ struct ConfigData {
+
+ ConfigData()
+ : listTests( false ),
+ listTags( false ),
+ listReporters( false ),
+ listTestNamesOnly( false ),
+ showSuccessfulTests( false ),
+ shouldDebugBreak( false ),
+ noThrow( false ),
+ showHelp( false ),
+ showInvisibles( false ),
+ forceColour( false ),
+ filenamesAsTags( false ),
+ abortAfter( -1 ),
+ rngSeed( 0 ),
+ verbosity( Verbosity::Normal ),
+ warnings( WarnAbout::Nothing ),
+ showDurations( ShowDurations::DefaultForReporter ),
+ runOrder( RunTests::InDeclarationOrder )
+ {}
+
+ bool listTests;
+ bool listTags;
+ bool listReporters;
+ bool listTestNamesOnly;
+
+ bool showSuccessfulTests;
+ bool shouldDebugBreak;
+ bool noThrow;
+ bool showHelp;
+ bool showInvisibles;
+ bool forceColour;
+ bool filenamesAsTags;
+
+ int abortAfter;
+ unsigned int rngSeed;
+
+ Verbosity::Level verbosity;
+ WarnAbout::What warnings;
+ ShowDurations::OrNot showDurations;
+ RunTests::InWhatOrder runOrder;
+
+ std::string outputFilename;
+ std::string name;
+ std::string processName;
+
+ std::vector<std::string> reporterNames;
+ std::vector<std::string> testsOrTags;
+ };
+
+ class Config : public SharedImpl<IConfig> {
+ private:
+ Config( Config const& other );
+ Config& operator = ( Config const& other );
+ virtual void dummy();
+ public:
+
+ Config()
+ {}
+
+ Config( ConfigData const& data )
+ : m_data( data ),
+ m_stream( openStream() )
+ {
+ if( !data.testsOrTags.empty() ) {
+ TestSpecParser parser( ITagAliasRegistry::get() );
+ for( std::size_t i = 0; i < data.testsOrTags.size(); ++i )
+ parser.parse( data.testsOrTags[i] );
+ m_testSpec = parser.testSpec();
+ }
+ }
+
+ virtual ~Config() {
+ }
+
+ std::string const& getFilename() const {
+ return m_data.outputFilename ;
+ }
+
+ bool listTests() const { return m_data.listTests; }
+ bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
+ bool listTags() const { return m_data.listTags; }
+ bool listReporters() const { return m_data.listReporters; }
+
+ std::string getProcessName() const { return m_data.processName; }
+
+ bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
+
+ std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
+
+ int abortAfter() const { return m_data.abortAfter; }
+
+ TestSpec const& testSpec() const { return m_testSpec; }
+
+ bool showHelp() const { return m_data.showHelp; }
+ bool showInvisibles() const { return m_data.showInvisibles; }
+
+ // IConfig interface
+ virtual bool allowThrows() const { return !m_data.noThrow; }
+ virtual std::ostream& stream() const { return m_stream->stream(); }
+ virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
+ virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
+ virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
+ virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; }
+ virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; }
+ virtual unsigned int rngSeed() const { return m_data.rngSeed; }
+ virtual bool forceColour() const { return m_data.forceColour; }
+
+ private:
+
+ IStream const* openStream() {
+ if( m_data.outputFilename.empty() )
+ return new CoutStream();
+ else if( m_data.outputFilename[0] == '%' ) {
+ if( m_data.outputFilename == "%debug" )
+ return new DebugOutStream();
+ else
+ throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
+ }
+ else
+ return new FileStream( m_data.outputFilename );
+ }
+ ConfigData m_data;
+
+ std::auto_ptr<IStream const> m_stream;
+ TestSpec m_testSpec;
+ };
+
+} // end namespace Catch
+
+// #included from: catch_clara.h
+#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED
+
+// Use Catch's value for console width (store Clara's off to the side, if present)
+#ifdef CLARA_CONFIG_CONSOLE_WIDTH
+#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH
+#undef CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+// Declare Clara inside the Catch namespace
+#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch {
+// #included from: ../external/clara.h
+
+// Version 0.0.1.1
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE)
+
+#ifndef STITCH_CLARA_OPEN_NAMESPACE
+#define TWOBLUECUBES_CLARA_H_INCLUDED
+#define STITCH_CLARA_OPEN_NAMESPACE
+#define STITCH_CLARA_CLOSE_NAMESPACE
+#else
+#define STITCH_CLARA_CLOSE_NAMESPACE }
+#endif
+
+#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE
+
+// ----------- #included from tbc_text_format.h -----------
+
+// Only use header guard if we are not using an outer namespace
+#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE)
+#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+#define TBC_TEXT_FORMAT_H_INCLUDED
+#endif
+
+#include <string>
+#include <vector>
+#include <sstream>
+#include <algorithm>
+
+// Use optional outer namespace
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ struct TextAttributes {
+ TextAttributes()
+ : initialIndent( std::string::npos ),
+ indent( 0 ),
+ width( consoleWidth-1 ),
+ tabChar( '\t' )
+ {}
+
+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
+
+ std::size_t initialIndent; // indent of first line, or npos
+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
+ char tabChar; // If this char is seen the indent is changed to current pos
+ };
+
+ class Text {
+ public:
+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+ : attr( _attr )
+ {
+ std::string wrappableChars = " [({.,/|\\-";
+ std::size_t indent = _attr.initialIndent != std::string::npos
+ ? _attr.initialIndent
+ : _attr.indent;
+ std::string remainder = _str;
+
+ while( !remainder.empty() ) {
+ if( lines.size() >= 1000 ) {
+ lines.push_back( "... message truncated due to excessive size" );
+ return;
+ }
+ std::size_t tabPos = std::string::npos;
+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+ std::size_t pos = remainder.find_first_of( '\n' );
+ if( pos <= width ) {
+ width = pos;
+ }
+ pos = remainder.find_last_of( _attr.tabChar, width );
+ if( pos != std::string::npos ) {
+ tabPos = pos;
+ if( remainder[width] == '\n' )
+ width--;
+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+ }
+
+ if( width == remainder.size() ) {
+ spliceLine( indent, remainder, width );
+ }
+ else if( remainder[width] == '\n' ) {
+ spliceLine( indent, remainder, width );
+ if( width <= 1 || remainder.size() != 1 )
+ remainder = remainder.substr( 1 );
+ indent = _attr.indent;
+ }
+ else {
+ pos = remainder.find_last_of( wrappableChars, width );
+ if( pos != std::string::npos && pos > 0 ) {
+ spliceLine( indent, remainder, pos );
+ if( remainder[0] == ' ' )
+ remainder = remainder.substr( 1 );
+ }
+ else {
+ spliceLine( indent, remainder, width-1 );
+ lines.back() += "-";
+ }
+ if( lines.size() == 1 )
+ indent = _attr.indent;
+ if( tabPos != std::string::npos )
+ indent += tabPos;
+ }
+ }
+ }
+
+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+ _remainder = _remainder.substr( _pos );
+ }
+
+ typedef std::vector<std::string>::const_iterator const_iterator;
+
+ const_iterator begin() const { return lines.begin(); }
+ const_iterator end() const { return lines.end(); }
+ std::string const& last() const { return lines.back(); }
+ std::size_t size() const { return lines.size(); }
+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+ it != itEnd; ++it ) {
+ if( it != _text.begin() )
+ _stream << "\n";
+ _stream << *it;
+ }
+ return _stream;
+ }
+
+ private:
+ std::string str;
+ TextAttributes attr;
+ std::vector<std::string> lines;
+ };
+
+} // end namespace Tbc
+
+#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TBC_TEXT_FORMAT_H_INCLUDED
+
+// ----------- end of #include from tbc_text_format.h -----------
+// ........... back in clara.h
+
+#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE
+
+// ----------- #included from clara_compilers.h -----------
+
+#ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+#define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+
+// Detect a number of compiler features - mostly C++11/14 conformance - by compiler
+// The following features are defined:
+//
+// CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported?
+// CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported?
+// CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
+// CLARA_CONFIG_CPP11_OVERRIDE : is override supported?
+// CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr)
+
+// CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
+
+// CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported?
+
+// In general each macro has a _NO_<feature name> form
+// (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature.
+// Many features, at point of detection, define an _INTERNAL_ macro, so they
+// can be combined, en-mass, with the _NO_ forms later.
+
+// All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11
+
+#ifdef __clang__
+
+#if __has_feature(cxx_nullptr)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+#if __has_feature(cxx_noexcept)
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#endif
+
+#endif // __clang__
+
+////////////////////////////////////////////////////////////////////////////////
+// GCC
+#ifdef __GNUC__
+
+#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+// - otherwise more recent versions define __cplusplus >= 201103L
+// and will get picked up below
+
+#endif // __GNUC__
+
+////////////////////////////////////////////////////////////////////////////////
+// Visual C++
+#ifdef _MSC_VER
+
+#if (_MSC_VER >= 1600)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015))
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+// C++ language feature support
+
+// catch all support for C++11
+#if defined(__cplusplus) && __cplusplus >= 201103L
+
+#define CLARA_CPP11_OR_GREATER
+
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR)
+#define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR
+#endif
+
+#ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT
+#endif
+
+#ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS
+#endif
+
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE)
+#define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE
+#endif
+#if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR)
+#define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+#endif // __cplusplus >= 201103L
+
+// Now set the actual defines based on the above + anything the user has configured
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_NULLPTR
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_NOEXCEPT
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_GENERATED_METHODS
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_OVERRIDE
+#endif
+#if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11)
+#define CLARA_CONFIG_CPP11_UNIQUE_PTR
+#endif
+
+// noexcept support:
+#if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT)
+#define CLARA_NOEXCEPT noexcept
+# define CLARA_NOEXCEPT_IS(x) noexcept(x)
+#else
+#define CLARA_NOEXCEPT throw()
+# define CLARA_NOEXCEPT_IS(x)
+#endif
+
+// nullptr support
+#ifdef CLARA_CONFIG_CPP11_NULLPTR
+#define CLARA_NULL nullptr
+#else
+#define CLARA_NULL NULL
+#endif
+
+// override support
+#ifdef CLARA_CONFIG_CPP11_OVERRIDE
+#define CLARA_OVERRIDE override
+#else
+#define CLARA_OVERRIDE
+#endif
+
+// unique_ptr support
+#ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR
+# define CLARA_AUTO_PTR( T ) std::unique_ptr<T>
+#else
+# define CLARA_AUTO_PTR( T ) std::auto_ptr<T>
+#endif
+
+#endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED
+
+// ----------- end of #include from clara_compilers.h -----------
+// ........... back in clara.h
+
+#include <map>
+#include <stdexcept>
+#include <memory>
+
+// Use optional outer namespace
+#ifdef STITCH_CLARA_OPEN_NAMESPACE
+STITCH_CLARA_OPEN_NAMESPACE
+#endif
+
+namespace Clara {
+
+ struct UnpositionalTag {};
+
+ extern UnpositionalTag _;
+
+#ifdef CLARA_CONFIG_MAIN
+ UnpositionalTag _;
+#endif
+
+ namespace Detail {
+
+#ifdef CLARA_CONSOLE_WIDTH
+ const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ // Use this to try and stop compiler from warning about unreachable code
+ inline bool isTrue( bool value ) { return value; }
+
+ using namespace Tbc;
+
+ inline bool startsWith( std::string const& str, std::string const& prefix ) {
+ return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix;
+ }
+
+ template<typename T> struct RemoveConstRef{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T&>{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T const&>{ typedef T type; };
+ template<typename T> struct RemoveConstRef<T const>{ typedef T type; };
+
+ template<typename T> struct IsBool { static const bool value = false; };
+ template<> struct IsBool<bool> { static const bool value = true; };
+
+ template<typename T>
+ void convertInto( std::string const& _source, T& _dest ) {
+ std::stringstream ss;
+ ss << _source;
+ ss >> _dest;
+ if( ss.fail() )
+ throw std::runtime_error( "Unable to convert " + _source + " to destination type" );
+ }
+ inline void convertInto( std::string const& _source, std::string& _dest ) {
+ _dest = _source;
+ }
+ inline void convertInto( std::string const& _source, bool& _dest ) {
+ std::string sourceLC = _source;
+ std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower );
+ if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" )
+ _dest = true;
+ else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" )
+ _dest = false;
+ else
+ throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" );
+ }
+ inline void convertInto( bool _source, bool& _dest ) {
+ _dest = _source;
+ }
+ template<typename T>
+ inline void convertInto( bool, T& ) {
+ if( isTrue( true ) )
+ throw std::runtime_error( "Invalid conversion" );
+ }
+
+ template<typename ConfigT>
+ struct IArgFunction {
+ virtual ~IArgFunction() {}
+#ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS
+ IArgFunction() = default;
+ IArgFunction( IArgFunction const& ) = default;
+#endif
+ virtual void set( ConfigT& config, std::string const& value ) const = 0;
+ virtual void setFlag( ConfigT& config ) const = 0;
+ virtual bool takesArg() const = 0;
+ virtual IArgFunction* clone() const = 0;
+ };
+
+ template<typename ConfigT>
+ class BoundArgFunction {
+ public:
+ BoundArgFunction() : functionObj( CLARA_NULL ) {}
+ BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {}
+ BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {}
+ BoundArgFunction& operator = ( BoundArgFunction const& other ) {
+ IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL;
+ delete functionObj;
+ functionObj = newFunctionObj;
+ return *this;
+ }
+ ~BoundArgFunction() { delete functionObj; }
+
+ void set( ConfigT& config, std::string const& value ) const {
+ functionObj->set( config, value );
+ }
+ void setFlag( ConfigT& config ) const {
+ functionObj->setFlag( config );
+ }
+ bool takesArg() const { return functionObj->takesArg(); }
+
+ bool isSet() const {
+ return functionObj != CLARA_NULL;
+ }
+ private:
+ IArgFunction<ConfigT>* functionObj;
+ };
+
+ template<typename C>
+ struct NullBinder : IArgFunction<C>{
+ virtual void set( C&, std::string const& ) const {}
+ virtual void setFlag( C& ) const {}
+ virtual bool takesArg() const { return true; }
+ virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); }
+ };
+
+ template<typename C, typename M>
+ struct BoundDataMember : IArgFunction<C>{
+ BoundDataMember( M C::* _member ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ convertInto( stringValue, p.*member );
+ }
+ virtual void setFlag( C& p ) const {
+ convertInto( true, p.*member );
+ }
+ virtual bool takesArg() const { return !IsBool<M>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); }
+ M C::* member;
+ };
+ template<typename C, typename M>
+ struct BoundUnaryMethod : IArgFunction<C>{
+ BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ typename RemoveConstRef<M>::type value;
+ convertInto( stringValue, value );
+ (p.*member)( value );
+ }
+ virtual void setFlag( C& p ) const {
+ typename RemoveConstRef<M>::type value;
+ convertInto( true, value );
+ (p.*member)( value );
+ }
+ virtual bool takesArg() const { return !IsBool<M>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); }
+ void (C::*member)( M );
+ };
+ template<typename C>
+ struct BoundNullaryMethod : IArgFunction<C>{
+ BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {}
+ virtual void set( C& p, std::string const& stringValue ) const {
+ bool value;
+ convertInto( stringValue, value );
+ if( value )
+ (p.*member)();
+ }
+ virtual void setFlag( C& p ) const {
+ (p.*member)();
+ }
+ virtual bool takesArg() const { return false; }
+ virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); }
+ void (C::*member)();
+ };
+
+ template<typename C>
+ struct BoundUnaryFunction : IArgFunction<C>{
+ BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {}
+ virtual void set( C& obj, std::string const& stringValue ) const {
+ bool value;
+ convertInto( stringValue, value );
+ if( value )
+ function( obj );
+ }
+ virtual void setFlag( C& p ) const {
+ function( p );
+ }
+ virtual bool takesArg() const { return false; }
+ virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); }
+ void (*function)( C& );
+ };
+
+ template<typename C, typename T>
+ struct BoundBinaryFunction : IArgFunction<C>{
+ BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {}
+ virtual void set( C& obj, std::string const& stringValue ) const {
+ typename RemoveConstRef<T>::type value;
+ convertInto( stringValue, value );
+ function( obj, value );
+ }
+ virtual void setFlag( C& obj ) const {
+ typename RemoveConstRef<T>::type value;
+ convertInto( true, value );
+ function( obj, value );
+ }
+ virtual bool takesArg() const { return !IsBool<T>::value; }
+ virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); }
+ void (*function)( C&, T );
+ };
+
+ } // namespace Detail
+
+ struct Parser {
+ Parser() : separators( " \t=:" ) {}
+
+ struct Token {
+ enum Type { Positional, ShortOpt, LongOpt };
+ Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {}
+ Type type;
+ std::string data;
+ };
+
+ void parseIntoTokens( int argc, char const* const argv[], std::vector<Parser::Token>& tokens ) const {
+ const std::string doubleDash = "--";
+ for( int i = 1; i < argc && argv[i] != doubleDash; ++i )
+ parseIntoTokens( argv[i] , tokens);
+ }
+ void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const {
+ while( !arg.empty() ) {
+ Parser::Token token( Parser::Token::Positional, arg );
+ arg = "";
+ if( token.data[0] == '-' ) {
+ if( token.data.size() > 1 && token.data[1] == '-' ) {
+ token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) );
+ }
+ else {
+ token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) );
+ if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) {
+ arg = "-" + token.data.substr( 1 );
+ token.data = token.data.substr( 0, 1 );
+ }
+ }
+ }
+ if( token.type != Parser::Token::Positional ) {
+ std::size_t pos = token.data.find_first_of( separators );
+ if( pos != std::string::npos ) {
+ arg = token.data.substr( pos+1 );
+ token.data = token.data.substr( 0, pos );
+ }
+ }
+ tokens.push_back( token );
+ }
+ }
+ std::string separators;
+ };
+
+ template<typename ConfigT>
+ struct CommonArgProperties {
+ CommonArgProperties() {}
+ CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {}
+
+ Detail::BoundArgFunction<ConfigT> boundField;
+ std::string description;
+ std::string detail;
+ std::string placeholder; // Only value if boundField takes an arg
+
+ bool takesArg() const {
+ return !placeholder.empty();
+ }
+ void validate() const {
+ if( !boundField.isSet() )
+ throw std::logic_error( "option not bound" );
+ }
+ };
+ struct OptionArgProperties {
+ std::vector<std::string> shortNames;
+ std::string longName;
+
+ bool hasShortName( std::string const& shortName ) const {
+ return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end();
+ }
+ bool hasLongName( std::string const& _longName ) const {
+ return _longName == longName;
+ }
+ };
+ struct PositionalArgProperties {
+ PositionalArgProperties() : position( -1 ) {}
+ int position; // -1 means non-positional (floating)
+
+ bool isFixedPositional() const {
+ return position != -1;
+ }
+ };
+
+ template<typename ConfigT>
+ class CommandLine {
+
+ struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties {
+ Arg() {}
+ Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {}
+
+ using CommonArgProperties<ConfigT>::placeholder; // !TBD
+
+ std::string dbgName() const {
+ if( !longName.empty() )
+ return "--" + longName;
+ if( !shortNames.empty() )
+ return "-" + shortNames[0];
+ return "positional args";
+ }
+ std::string commands() const {
+ std::ostringstream oss;
+ bool first = true;
+ std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end();
+ for(; it != itEnd; ++it ) {
+ if( first )
+ first = false;
+ else
+ oss << ", ";
+ oss << "-" << *it;
+ }
+ if( !longName.empty() ) {
+ if( !first )
+ oss << ", ";
+ oss << "--" << longName;
+ }
+ if( !placeholder.empty() )
+ oss << " <" << placeholder << ">";
+ return oss.str();
+ }
+ };
+
+ typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr;
+
+ friend void addOptName( Arg& arg, std::string const& optName )
+ {
+ if( optName.empty() )
+ return;
+ if( Detail::startsWith( optName, "--" ) ) {
+ if( !arg.longName.empty() )
+ throw std::logic_error( "Only one long opt may be specified. '"
+ + arg.longName
+ + "' already specified, now attempting to add '"
+ + optName + "'" );
+ arg.longName = optName.substr( 2 );
+ }
+ else if( Detail::startsWith( optName, "-" ) )
+ arg.shortNames.push_back( optName.substr( 1 ) );
+ else
+ throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" );
+ }
+ friend void setPositionalArg( Arg& arg, int position )
+ {
+ arg.position = position;
+ }
+
+ class ArgBuilder {
+ public:
+ ArgBuilder( Arg* arg ) : m_arg( arg ) {}
+
+ // Bind a non-boolean data member (requires placeholder string)
+ template<typename C, typename M>
+ void bind( M C::* field, std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundDataMember<C,M>( field );
+ m_arg->placeholder = placeholder;
+ }
+ // Bind a boolean data member (no placeholder required)
+ template<typename C>
+ void bind( bool C::* field ) {
+ m_arg->boundField = new Detail::BoundDataMember<C,bool>( field );
+ }
+
+ // Bind a method taking a single, non-boolean argument (requires a placeholder string)
+ template<typename C, typename M>
+ void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod );
+ m_arg->placeholder = placeholder;
+ }
+
+ // Bind a method taking a single, boolean argument (no placeholder string required)
+ template<typename C>
+ void bind( void (C::* unaryMethod)( bool ) ) {
+ m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod );
+ }
+
+ // Bind a method that takes no arguments (will be called if opt is present)
+ template<typename C>
+ void bind( void (C::* nullaryMethod)() ) {
+ m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod );
+ }
+
+ // Bind a free function taking a single argument - the object to operate on (no placeholder string required)
+ template<typename C>
+ void bind( void (* unaryFunction)( C& ) ) {
+ m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction );
+ }
+
+ // Bind a free function taking a single argument - the object to operate on (requires a placeholder string)
+ template<typename C, typename T>
+ void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) {
+ m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction );
+ m_arg->placeholder = placeholder;
+ }
+
+ ArgBuilder& describe( std::string const& description ) {
+ m_arg->description = description;
+ return *this;
+ }
+ ArgBuilder& detail( std::string const& detail ) {
+ m_arg->detail = detail;
+ return *this;
+ }
+
+ protected:
+ Arg* m_arg;
+ };
+
+ class OptBuilder : public ArgBuilder {
+ public:
+ OptBuilder( Arg* arg ) : ArgBuilder( arg ) {}
+ OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {}
+
+ OptBuilder& operator[]( std::string const& optName ) {
+ addOptName( *ArgBuilder::m_arg, optName );
+ return *this;
+ }
+ };
+
+ public:
+
+ CommandLine()
+ : m_boundProcessName( new Detail::NullBinder<ConfigT>() ),
+ m_highestSpecifiedArgPosition( 0 ),
+ m_throwOnUnrecognisedTokens( false )
+ {}
+ CommandLine( CommandLine const& other )
+ : m_boundProcessName( other.m_boundProcessName ),
+ m_options ( other.m_options ),
+ m_positionalArgs( other.m_positionalArgs ),
+ m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ),
+ m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens )
+ {
+ if( other.m_floatingArg.get() )
+ m_floatingArg.reset( new Arg( *other.m_floatingArg ) );
+ }
+
+ CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) {
+ m_throwOnUnrecognisedTokens = shouldThrow;
+ return *this;
+ }
+
+ OptBuilder operator[]( std::string const& optName ) {
+ m_options.push_back( Arg() );
+ addOptName( m_options.back(), optName );
+ OptBuilder builder( &m_options.back() );
+ return builder;
+ }
+
+ ArgBuilder operator[]( int position ) {
+ m_positionalArgs.insert( std::make_pair( position, Arg() ) );
+ if( position > m_highestSpecifiedArgPosition )
+ m_highestSpecifiedArgPosition = position;
+ setPositionalArg( m_positionalArgs[position], position );
+ ArgBuilder builder( &m_positionalArgs[position] );
+ return builder;
+ }
+
+ // Invoke this with the _ instance
+ ArgBuilder operator[]( UnpositionalTag ) {
+ if( m_floatingArg.get() )
+ throw std::logic_error( "Only one unpositional argument can be added" );
+ m_floatingArg.reset( new Arg() );
+ ArgBuilder builder( m_floatingArg.get() );
+ return builder;
+ }
+
+ template<typename C, typename M>
+ void bindProcessName( M C::* field ) {
+ m_boundProcessName = new Detail::BoundDataMember<C,M>( field );
+ }
+ template<typename C, typename M>
+ void bindProcessName( void (C::*_unaryMethod)( M ) ) {
+ m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod );
+ }
+
+ void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const {
+ typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it;
+ std::size_t maxWidth = 0;
+ for( it = itBegin; it != itEnd; ++it )
+ maxWidth = (std::max)( maxWidth, it->commands().size() );
+
+ for( it = itBegin; it != itEnd; ++it ) {
+ Detail::Text usage( it->commands(), Detail::TextAttributes()
+ .setWidth( maxWidth+indent )
+ .setIndent( indent ) );
+ Detail::Text desc( it->description, Detail::TextAttributes()
+ .setWidth( width - maxWidth - 3 ) );
+
+ for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) {
+ std::string usageCol = i < usage.size() ? usage[i] : "";
+ os << usageCol;
+
+ if( i < desc.size() && !desc[i].empty() )
+ os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' )
+ << desc[i];
+ os << "\n";
+ }
+ }
+ }
+ std::string optUsage() const {
+ std::ostringstream oss;
+ optUsage( oss );
+ return oss.str();
+ }
+
+ void argSynopsis( std::ostream& os ) const {
+ for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) {
+ if( i > 1 )
+ os << " ";
+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i );
+ if( it != m_positionalArgs.end() )
+ os << "<" << it->second.placeholder << ">";
+ else if( m_floatingArg.get() )
+ os << "<" << m_floatingArg->placeholder << ">";
+ else
+ throw std::logic_error( "non consecutive positional arguments with no floating args" );
+ }
+ // !TBD No indication of mandatory args
+ if( m_floatingArg.get() ) {
+ if( m_highestSpecifiedArgPosition > 1 )
+ os << " ";
+ os << "[<" << m_floatingArg->placeholder << "> ...]";
+ }
+ }
+ std::string argSynopsis() const {
+ std::ostringstream oss;
+ argSynopsis( oss );
+ return oss.str();
+ }
+
+ void usage( std::ostream& os, std::string const& procName ) const {
+ validate();
+ os << "usage:\n " << procName << " ";
+ argSynopsis( os );
+ if( !m_options.empty() ) {
+ os << " [options]\n\nwhere options are: \n";
+ optUsage( os, 2 );
+ }
+ os << "\n";
+ }
+ std::string usage( std::string const& procName ) const {
+ std::ostringstream oss;
+ usage( oss, procName );
+ return oss.str();
+ }
+
+ ConfigT parse( int argc, char const* const argv[] ) const {
+ ConfigT config;
+ parseInto( argc, argv, config );
+ return config;
+ }
+
+ std::vector<Parser::Token> parseInto( int argc, char const* argv[], ConfigT& config ) const {
+ std::string processName = argv[0];
+ std::size_t lastSlash = processName.find_last_of( "/\\" );
+ if( lastSlash != std::string::npos )
+ processName = processName.substr( lastSlash+1 );
+ m_boundProcessName.set( config, processName );
+ std::vector<Parser::Token> tokens;
+ Parser parser;
+ parser.parseIntoTokens( argc, argv, tokens );
+ return populate( tokens, config );
+ }
+
+ std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ validate();
+ std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config );
+ unusedTokens = populateFixedArgs( unusedTokens, config );
+ unusedTokens = populateFloatingArgs( unusedTokens, config );
+ return unusedTokens;
+ }
+
+ std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ std::vector<Parser::Token> unusedTokens;
+ std::vector<std::string> errors;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end();
+ for(; it != itEnd; ++it ) {
+ Arg const& arg = *it;
+
+ try {
+ if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) ||
+ ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) {
+ if( arg.takesArg() ) {
+ if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional )
+ errors.push_back( "Expected argument to option: " + token.data );
+ else
+ arg.boundField.set( config, tokens[++i].data );
+ }
+ else {
+ arg.boundField.setFlag( config );
+ }
+ break;
+ }
+ }
+ catch( std::exception& ex ) {
+ errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" );
+ }
+ }
+ if( it == itEnd ) {
+ if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens )
+ unusedTokens.push_back( token );
+ else if( errors.empty() && m_throwOnUnrecognisedTokens )
+ errors.push_back( "unrecognised option: " + token.data );
+ }
+ }
+ if( !errors.empty() ) {
+ std::ostringstream oss;
+ for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end();
+ it != itEnd;
+ ++it ) {
+ if( it != errors.begin() )
+ oss << "\n";
+ oss << *it;
+ }
+ throw std::runtime_error( oss.str() );
+ }
+ return unusedTokens;
+ }
+ std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ std::vector<Parser::Token> unusedTokens;
+ int position = 1;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position );
+ if( it != m_positionalArgs.end() )
+ it->second.boundField.set( config, token.data );
+ else
+ unusedTokens.push_back( token );
+ if( token.type == Parser::Token::Positional )
+ position++;
+ }
+ return unusedTokens;
+ }
+ std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const {
+ if( !m_floatingArg.get() )
+ return tokens;
+ std::vector<Parser::Token> unusedTokens;
+ for( std::size_t i = 0; i < tokens.size(); ++i ) {
+ Parser::Token const& token = tokens[i];
+ if( token.type == Parser::Token::Positional )
+ m_floatingArg->boundField.set( config, token.data );
+ else
+ unusedTokens.push_back( token );
+ }
+ return unusedTokens;
+ }
+
+ void validate() const
+ {
+ if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() )
+ throw std::logic_error( "No options or arguments specified" );
+
+ for( typename std::vector<Arg>::const_iterator it = m_options.begin(),
+ itEnd = m_options.end();
+ it != itEnd; ++it )
+ it->validate();
+ }
+
+ private:
+ Detail::BoundArgFunction<ConfigT> m_boundProcessName;
+ std::vector<Arg> m_options;
+ std::map<int, Arg> m_positionalArgs;
+ ArgAutoPtr m_floatingArg;
+ int m_highestSpecifiedArgPosition;
+ bool m_throwOnUnrecognisedTokens;
+ };
+
+} // end namespace Clara
+
+STITCH_CLARA_CLOSE_NAMESPACE
+#undef STITCH_CLARA_OPEN_NAMESPACE
+#undef STITCH_CLARA_CLOSE_NAMESPACE
+
+#endif // TWOBLUECUBES_CLARA_H_INCLUDED
+#undef STITCH_CLARA_OPEN_NAMESPACE
+
+// Restore Clara's value for console width, if present
+#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH
+#endif
+
+#include <fstream>
+
+namespace Catch {
+
+ inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
+ inline void abortAfterX( ConfigData& config, int x ) {
+ if( x < 1 )
+ throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" );
+ config.abortAfter = x;
+ }
+ inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
+ inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
+
+ inline void addWarning( ConfigData& config, std::string const& _warning ) {
+ if( _warning == "NoAssertions" )
+ config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions );
+ else
+ throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" );
+ }
+ inline void setOrder( ConfigData& config, std::string const& order ) {
+ if( startsWith( "declared", order ) )
+ config.runOrder = RunTests::InDeclarationOrder;
+ else if( startsWith( "lexical", order ) )
+ config.runOrder = RunTests::InLexicographicalOrder;
+ else if( startsWith( "random", order ) )
+ config.runOrder = RunTests::InRandomOrder;
+ else
+ throw std::runtime_error( "Unrecognised ordering: '" + order + "'" );
+ }
+ inline void setRngSeed( ConfigData& config, std::string const& seed ) {
+ if( seed == "time" ) {
+ config.rngSeed = static_cast<unsigned int>( std::time(0) );
+ }
+ else {
+ std::stringstream ss;
+ ss << seed;
+ ss >> config.rngSeed;
+ if( ss.fail() )
+ throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" );
+ }
+ }
+ inline void setVerbosity( ConfigData& config, int level ) {
+ // !TBD: accept strings?
+ config.verbosity = static_cast<Verbosity::Level>( level );
+ }
+ inline void setShowDurations( ConfigData& config, bool _showDurations ) {
+ config.showDurations = _showDurations
+ ? ShowDurations::Always
+ : ShowDurations::Never;
+ }
+ inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
+ std::ifstream f( _filename.c_str() );
+ if( !f.is_open() )
+ throw std::domain_error( "Unable to load input file: " + _filename );
+
+ std::string line;
+ while( std::getline( f, line ) ) {
+ line = trim(line);
+ if( !line.empty() && !startsWith( line, "#" ) )
+ addTestOrTags( config, "\"" + line + "\"," );
+ }
+ }
+
+ inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
+
+ using namespace Clara;
+ CommandLine<ConfigData> cli;
+
+ cli.bindProcessName( &ConfigData::processName );
+
+ cli["-?"]["-h"]["--help"]
+ .describe( "display usage information" )
+ .bind( &ConfigData::showHelp );
+
+ cli["-l"]["--list-tests"]
+ .describe( "list all/matching test cases" )
+ .bind( &ConfigData::listTests );
+
+ cli["-t"]["--list-tags"]
+ .describe( "list all/matching tags" )
+ .bind( &ConfigData::listTags );
+
+ cli["-s"]["--success"]
+ .describe( "include successful tests in output" )
+ .bind( &ConfigData::showSuccessfulTests );
+
+ cli["-b"]["--break"]
+ .describe( "break into debugger on failure" )
+ .bind( &ConfigData::shouldDebugBreak );
+
+ cli["-e"]["--nothrow"]
+ .describe( "skip exception tests" )
+ .bind( &ConfigData::noThrow );
+
+ cli["-i"]["--invisibles"]
+ .describe( "show invisibles (tabs, newlines)" )
+ .bind( &ConfigData::showInvisibles );
+
+ cli["-o"]["--out"]
+ .describe( "output filename" )
+ .bind( &ConfigData::outputFilename, "filename" );
+
+ cli["-r"]["--reporter"]
+// .placeholder( "name[:filename]" )
+ .describe( "reporter to use (defaults to console)" )
+ .bind( &addReporterName, "name" );
+
+ cli["-n"]["--name"]
+ .describe( "suite name" )
+ .bind( &ConfigData::name, "name" );
+
+ cli["-a"]["--abort"]
+ .describe( "abort at first failure" )
+ .bind( &abortAfterFirst );
+
+ cli["-x"]["--abortx"]
+ .describe( "abort after x failures" )
+ .bind( &abortAfterX, "no. failures" );
+
+ cli["-w"]["--warn"]
+ .describe( "enable warnings" )
+ .bind( &addWarning, "warning name" );
+
+// - needs updating if reinstated
+// cli.into( &setVerbosity )
+// .describe( "level of verbosity (0=no output)" )
+// .shortOpt( "v")
+// .longOpt( "verbosity" )
+// .placeholder( "level" );
+
+ cli[_]
+ .describe( "which test or tests to use" )
+ .bind( &addTestOrTags, "test name, pattern or tags" );
+
+ cli["-d"]["--durations"]
+ .describe( "show test durations" )
+ .bind( &setShowDurations, "yes/no" );
+
+ cli["-f"]["--input-file"]
+ .describe( "load test names to run from a file" )
+ .bind( &loadTestNamesFromFile, "filename" );
+
+ cli["-#"]["--filenames-as-tags"]
+ .describe( "adds a tag for the filename" )
+ .bind( &ConfigData::filenamesAsTags );
+
+ // Less common commands which don't have a short form
+ cli["--list-test-names-only"]
+ .describe( "list all/matching test cases names only" )
+ .bind( &ConfigData::listTestNamesOnly );
+
+ cli["--list-reporters"]
+ .describe( "list all reporters" )
+ .bind( &ConfigData::listReporters );
+
+ cli["--order"]
+ .describe( "test case order (defaults to decl)" )
+ .bind( &setOrder, "decl|lex|rand" );
+
+ cli["--rng-seed"]
+ .describe( "set a specific seed for random numbers" )
+ .bind( &setRngSeed, "'time'|number" );
+
+ cli["--force-colour"]
+ .describe( "force colourised output" )
+ .bind( &ConfigData::forceColour );
+
+ return cli;
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_list.hpp
+#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED
+
+// #included from: catch_text.h
+#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED
+
+#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH
+
+#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch
+// #included from: ../external/tbc_text_format.h
+// Only use header guard if we are not using an outer namespace
+#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+# endif
+# else
+# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED
+# endif
+#endif
+#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#include <string>
+#include <vector>
+#include <sstream>
+
+// Use optional outer namespace
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE {
+#endif
+
+namespace Tbc {
+
+#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH
+ const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH;
+#else
+ const unsigned int consoleWidth = 80;
+#endif
+
+ struct TextAttributes {
+ TextAttributes()
+ : initialIndent( std::string::npos ),
+ indent( 0 ),
+ width( consoleWidth-1 ),
+ tabChar( '\t' )
+ {}
+
+ TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; }
+ TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; }
+ TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; }
+ TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; }
+
+ std::size_t initialIndent; // indent of first line, or npos
+ std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos
+ std::size_t width; // maximum width of text, including indent. Longer text will wrap
+ char tabChar; // If this char is seen the indent is changed to current pos
+ };
+
+ class Text {
+ public:
+ Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() )
+ : attr( _attr )
+ {
+ std::string wrappableChars = " [({.,/|\\-";
+ std::size_t indent = _attr.initialIndent != std::string::npos
+ ? _attr.initialIndent
+ : _attr.indent;
+ std::string remainder = _str;
+
+ while( !remainder.empty() ) {
+ if( lines.size() >= 1000 ) {
+ lines.push_back( "... message truncated due to excessive size" );
+ return;
+ }
+ std::size_t tabPos = std::string::npos;
+ std::size_t width = (std::min)( remainder.size(), _attr.width - indent );
+ std::size_t pos = remainder.find_first_of( '\n' );
+ if( pos <= width ) {
+ width = pos;
+ }
+ pos = remainder.find_last_of( _attr.tabChar, width );
+ if( pos != std::string::npos ) {
+ tabPos = pos;
+ if( remainder[width] == '\n' )
+ width--;
+ remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 );
+ }
+
+ if( width == remainder.size() ) {
+ spliceLine( indent, remainder, width );
+ }
+ else if( remainder[width] == '\n' ) {
+ spliceLine( indent, remainder, width );
+ if( width <= 1 || remainder.size() != 1 )
+ remainder = remainder.substr( 1 );
+ indent = _attr.indent;
+ }
+ else {
+ pos = remainder.find_last_of( wrappableChars, width );
+ if( pos != std::string::npos && pos > 0 ) {
+ spliceLine( indent, remainder, pos );
+ if( remainder[0] == ' ' )
+ remainder = remainder.substr( 1 );
+ }
+ else {
+ spliceLine( indent, remainder, width-1 );
+ lines.back() += "-";
+ }
+ if( lines.size() == 1 )
+ indent = _attr.indent;
+ if( tabPos != std::string::npos )
+ indent += tabPos;
+ }
+ }
+ }
+
+ void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) {
+ lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) );
+ _remainder = _remainder.substr( _pos );
+ }
+
+ typedef std::vector<std::string>::const_iterator const_iterator;
+
+ const_iterator begin() const { return lines.begin(); }
+ const_iterator end() const { return lines.end(); }
+ std::string const& last() const { return lines.back(); }
+ std::size_t size() const { return lines.size(); }
+ std::string const& operator[]( std::size_t _index ) const { return lines[_index]; }
+ std::string toString() const {
+ std::ostringstream oss;
+ oss << *this;
+ return oss.str();
+ }
+
+ inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) {
+ for( Text::const_iterator it = _text.begin(), itEnd = _text.end();
+ it != itEnd; ++it ) {
+ if( it != _text.begin() )
+ _stream << "\n";
+ _stream << *it;
+ }
+ return _stream;
+ }
+
+ private:
+ std::string str;
+ TextAttributes attr;
+ std::vector<std::string> lines;
+ };
+
+} // end namespace Tbc
+
+#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+} // end outer namespace
+#endif
+
+#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED
+#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE
+
+namespace Catch {
+ using Tbc::Text;
+ using Tbc::TextAttributes;
+}
+
+// #included from: catch_console_colour.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED
+
+namespace Catch {
+
+ struct Colour {
+ enum Code {
+ None = 0,
+
+ White,
+ Red,
+ Green,
+ Blue,
+ Cyan,
+ Yellow,
+ Grey,
+
+ Bright = 0x10,
+
+ BrightRed = Bright | Red,
+ BrightGreen = Bright | Green,
+ LightGrey = Bright | Grey,
+ BrightWhite = Bright | White,
+
+ // By intention
+ FileName = LightGrey,
+ Warning = Yellow,
+ ResultError = BrightRed,
+ ResultSuccess = BrightGreen,
+ ResultExpectedFailure = Warning,
+
+ Error = BrightRed,
+ Success = Green,
+
+ OriginalExpression = Cyan,
+ ReconstructedExpression = Yellow,
+
+ SecondaryText = LightGrey,
+ Headers = White
+ };
+
+ // Use constructed object for RAII guard
+ Colour( Code _colourCode );
+ Colour( Colour const& other );
+ ~Colour();
+
+ // Use static method for one-shot changes
+ static void use( Code _colourCode );
+
+ private:
+ bool m_moved;
+ };
+
+ inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; }
+
+} // end namespace Catch
+
+// #included from: catch_interfaces_reporter.h
+#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
+
+#include <string>
+#include <ostream>
+#include <map>
+#include <assert.h>
+
+namespace Catch
+{
+ struct ReporterConfig {
+ explicit ReporterConfig( Ptr<IConfig const> const& _fullConfig )
+ : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}
+
+ ReporterConfig( Ptr<IConfig const> const& _fullConfig, std::ostream& _stream )
+ : m_stream( &_stream ), m_fullConfig( _fullConfig ) {}
+
+ std::ostream& stream() const { return *m_stream; }
+ Ptr<IConfig const> fullConfig() const { return m_fullConfig; }
+
+ private:
+ std::ostream* m_stream;
+ Ptr<IConfig const> m_fullConfig;
+ };
+
+ struct ReporterPreferences {
+ ReporterPreferences()
+ : shouldRedirectStdOut( false )
+ {}
+
+ bool shouldRedirectStdOut;
+ };
+
+ template<typename T>
+ struct LazyStat : Option<T> {
+ LazyStat() : used( false ) {}
+ LazyStat& operator=( T const& _value ) {
+ Option<T>::operator=( _value );
+ used = false;
+ return *this;
+ }
+ void reset() {
+ Option<T>::reset();
+ used = false;
+ }
+ bool used;
+ };
+
+ struct TestRunInfo {
+ TestRunInfo( std::string const& _name ) : name( _name ) {}
+ std::string name;
+ };
+ struct GroupInfo {
+ GroupInfo( std::string const& _name,
+ std::size_t _groupIndex,
+ std::size_t _groupsCount )
+ : name( _name ),
+ groupIndex( _groupIndex ),
+ groupsCounts( _groupsCount )
+ {}
+
+ std::string name;
+ std::size_t groupIndex;
+ std::size_t groupsCounts;
+ };
+
+ struct AssertionStats {
+ AssertionStats( AssertionResult const& _assertionResult,
+ std::vector<MessageInfo> const& _infoMessages,
+ Totals const& _totals )
+ : assertionResult( _assertionResult ),
+ infoMessages( _infoMessages ),
+ totals( _totals )
+ {
+ if( assertionResult.hasMessage() ) {
+ // Copy message into messages list.
+ // !TBD This should have been done earlier, somewhere
+ MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );
+ builder << assertionResult.getMessage();
+ builder.m_info.message = builder.m_stream.str();
+
+ infoMessages.push_back( builder.m_info );
+ }
+ }
+ virtual ~AssertionStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ AssertionStats( AssertionStats const& ) = default;
+ AssertionStats( AssertionStats && ) = default;
+ AssertionStats& operator = ( AssertionStats const& ) = default;
+ AssertionStats& operator = ( AssertionStats && ) = default;
+# endif
+
+ AssertionResult assertionResult;
+ std::vector<MessageInfo> infoMessages;
+ Totals totals;
+ };
+
+ struct SectionStats {
+ SectionStats( SectionInfo const& _sectionInfo,
+ Counts const& _assertions,
+ double _durationInSeconds,
+ bool _missingAssertions )
+ : sectionInfo( _sectionInfo ),
+ assertions( _assertions ),
+ durationInSeconds( _durationInSeconds ),
+ missingAssertions( _missingAssertions )
+ {}
+ virtual ~SectionStats();
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ SectionStats( SectionStats const& ) = default;
+ SectionStats( SectionStats && ) = default;
+ SectionStats& operator = ( SectionStats const& ) = default;
+ SectionStats& operator = ( SectionStats && ) = default;
+# endif
+
+ SectionInfo sectionInfo;
+ Counts assertions;
+ double durationInSeconds;
+ bool missingAssertions;
+ };
+
+ struct TestCaseStats {
+ TestCaseStats( TestCaseInfo const& _testInfo,
+ Totals const& _totals,
+ std::string const& _stdOut,
+ std::string const& _stdErr,
+ bool _aborting )
+ : testInfo( _testInfo ),
+ totals( _totals ),
+ stdOut( _stdOut ),
+ stdErr( _stdErr ),
+ aborting( _aborting )
+ {}
+ virtual ~TestCaseStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestCaseStats( TestCaseStats const& ) = default;
+ TestCaseStats( TestCaseStats && ) = default;
+ TestCaseStats& operator = ( TestCaseStats const& ) = default;
+ TestCaseStats& operator = ( TestCaseStats && ) = default;
+# endif
+
+ TestCaseInfo testInfo;
+ Totals totals;
+ std::string stdOut;
+ std::string stdErr;
+ bool aborting;
+ };
+
+ struct TestGroupStats {
+ TestGroupStats( GroupInfo const& _groupInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : groupInfo( _groupInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+ TestGroupStats( GroupInfo const& _groupInfo )
+ : groupInfo( _groupInfo ),
+ aborting( false )
+ {}
+ virtual ~TestGroupStats();
+
+# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestGroupStats( TestGroupStats const& ) = default;
+ TestGroupStats( TestGroupStats && ) = default;
+ TestGroupStats& operator = ( TestGroupStats const& ) = default;
+ TestGroupStats& operator = ( TestGroupStats && ) = default;
+# endif
+
+ GroupInfo groupInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct TestRunStats {
+ TestRunStats( TestRunInfo const& _runInfo,
+ Totals const& _totals,
+ bool _aborting )
+ : runInfo( _runInfo ),
+ totals( _totals ),
+ aborting( _aborting )
+ {}
+ virtual ~TestRunStats();
+
+# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS
+ TestRunStats( TestRunStats const& _other )
+ : runInfo( _other.runInfo ),
+ totals( _other.totals ),
+ aborting( _other.aborting )
+ {}
+# else
+ TestRunStats( TestRunStats const& ) = default;
+ TestRunStats( TestRunStats && ) = default;
+ TestRunStats& operator = ( TestRunStats const& ) = default;
+ TestRunStats& operator = ( TestRunStats && ) = default;
+# endif
+
+ TestRunInfo runInfo;
+ Totals totals;
+ bool aborting;
+ };
+
+ struct IStreamingReporter : IShared {
+ virtual ~IStreamingReporter();
+
+ // Implementing class must also provide the following static method:
+ // static std::string getDescription();
+
+ virtual ReporterPreferences getPreferences() const = 0;
+
+ virtual void noMatchingTestCases( std::string const& spec ) = 0;
+
+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;
+
+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;
+
+ // The return value indicates if the messages buffer should be cleared:
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
+ virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
+
+ virtual void skipTest( TestCaseInfo const& testInfo ) = 0;
+ };
+
+ struct IReporterFactory : IShared {
+ virtual ~IReporterFactory();
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
+ virtual std::string getDescription() const = 0;
+ };
+
+ struct IReporterRegistry {
+ typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
+ typedef std::vector<Ptr<IReporterFactory> > Listeners;
+
+ virtual ~IReporterRegistry();
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const = 0;
+ virtual FactoryMap const& getFactories() const = 0;
+ virtual Listeners const& getListeners() const = 0;
+ };
+
+ Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
+
+}
+
+#include <limits>
+#include <algorithm>
+
+namespace Catch {
+
+ inline std::size_t listTests( Config const& config ) {
+
+ TestSpec testSpec = config.testSpec();
+ if( config.testSpec().hasFilters() )
+ Catch::cout() << "Matching test cases:\n";
+ else {
+ Catch::cout() << "All available test cases:\n";
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ }
+
+ std::size_t matchedTests = 0;
+ TextAttributes nameAttr, tagsAttr;
+ nameAttr.setInitialIndent( 2 ).setIndent( 4 );
+ tagsAttr.setIndent( 6 );
+
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ matchedTests++;
+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+ Colour::Code colour = testCaseInfo.isHidden()
+ ? Colour::SecondaryText
+ : Colour::None;
+ Colour colourGuard( colour );
+
+ Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl;
+ if( !testCaseInfo.tags.empty() )
+ Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl;
+ }
+
+ if( !config.testSpec().hasFilters() )
+ Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl;
+ else
+ Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl;
+ return matchedTests;
+ }
+
+ inline std::size_t listTestsNamesOnly( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( !config.testSpec().hasFilters() )
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ std::size_t matchedTests = 0;
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ matchedTests++;
+ TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
+ Catch::cout() << testCaseInfo.name << std::endl;
+ }
+ return matchedTests;
+ }
+
+ struct TagInfo {
+ TagInfo() : count ( 0 ) {}
+ void add( std::string const& spelling ) {
+ ++count;
+ spellings.insert( spelling );
+ }
+ std::string all() const {
+ std::string out;
+ for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end();
+ it != itEnd;
+ ++it )
+ out += "[" + *it + "]";
+ return out;
+ }
+ std::set<std::string> spellings;
+ std::size_t count;
+ };
+
+ inline std::size_t listTags( Config const& config ) {
+ TestSpec testSpec = config.testSpec();
+ if( config.testSpec().hasFilters() )
+ Catch::cout() << "Tags for matching test cases:\n";
+ else {
+ Catch::cout() << "All available tags:\n";
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
+ }
+
+ std::map<std::string, TagInfo> tagCounts;
+
+ std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
+ for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
+ it != itEnd;
+ ++it ) {
+ for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(),
+ tagItEnd = it->getTestCaseInfo().tags.end();
+ tagIt != tagItEnd;
+ ++tagIt ) {
+ std::string tagName = *tagIt;
+ std::string lcaseTagName = toLower( tagName );
+ std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName );
+ if( countIt == tagCounts.end() )
+ countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;
+ countIt->second.add( tagName );
+ }
+ }
+
+ for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(),
+ countItEnd = tagCounts.end();
+ countIt != countItEnd;
+ ++countIt ) {
+ std::ostringstream oss;
+ oss << " " << std::setw(2) << countIt->second.count << " ";
+ Text wrapper( countIt->second.all(), TextAttributes()
+ .setInitialIndent( 0 )
+ .setIndent( oss.str().size() )
+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) );
+ Catch::cout() << oss.str() << wrapper << "\n";
+ }
+ Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl;
+ return tagCounts.size();
+ }
+
+ inline std::size_t listReporters( Config const& /*config*/ ) {
+ Catch::cout() << "Available reporters:\n";
+ IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();
+ IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it;
+ std::size_t maxNameLen = 0;
+ for(it = itBegin; it != itEnd; ++it )
+ maxNameLen = (std::max)( maxNameLen, it->first.size() );
+
+ for(it = itBegin; it != itEnd; ++it ) {
+ Text wrapper( it->second->getDescription(), TextAttributes()
+ .setInitialIndent( 0 )
+ .setIndent( 7+maxNameLen )
+ .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) );
+ Catch::cout() << " "
+ << it->first
+ << ":"
+ << std::string( maxNameLen - it->first.size() + 2, ' ' )
+ << wrapper << "\n";
+ }
+ Catch::cout() << std::endl;
+ return factories.size();
+ }
+
+ inline Option<std::size_t> list( Config const& config ) {
+ Option<std::size_t> listedCount;
+ if( config.listTests() )
+ listedCount = listedCount.valueOr(0) + listTests( config );
+ if( config.listTestNamesOnly() )
+ listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
+ if( config.listTags() )
+ listedCount = listedCount.valueOr(0) + listTags( config );
+ if( config.listReporters() )
+ listedCount = listedCount.valueOr(0) + listReporters( config );
+ return listedCount;
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_run_context.hpp
+#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED
+
+// #included from: catch_test_case_tracker.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED
+
+#include <map>
+#include <string>
+#include <assert.h>
+#include <vector>
+
+namespace Catch {
+namespace TestCaseTracking {
+
+ struct ITracker : SharedImpl<> {
+ virtual ~ITracker();
+
+ // static queries
+ virtual std::string name() const = 0;
+
+ // dynamic queries
+ virtual bool isComplete() const = 0; // Successfully completed or failed
+ virtual bool isSuccessfullyCompleted() const = 0;
+ virtual bool isOpen() const = 0; // Started but not complete
+ virtual bool hasChildren() const = 0;
+
+ virtual ITracker& parent() = 0;
+
+ // actions
+ virtual void close() = 0; // Successfully complete
+ virtual void fail() = 0;
+ virtual void markAsNeedingAnotherRun() = 0;
+
+ virtual void addChild( Ptr<ITracker> const& child ) = 0;
+ virtual ITracker* findChild( std::string const& name ) = 0;
+ virtual void openChild() = 0;
+ };
+
+ class TrackerContext {
+
+ enum RunState {
+ NotStarted,
+ Executing,
+ CompletedCycle
+ };
+
+ Ptr<ITracker> m_rootTracker;
+ ITracker* m_currentTracker;
+ RunState m_runState;
+
+ public:
+
+ static TrackerContext& instance() {
+ static TrackerContext s_instance;
+ return s_instance;
+ }
+
+ TrackerContext()
+ : m_currentTracker( CATCH_NULL ),
+ m_runState( NotStarted )
+ {}
+
+ ITracker& startRun();
+
+ void endRun() {
+ m_rootTracker.reset();
+ m_currentTracker = CATCH_NULL;
+ m_runState = NotStarted;
+ }
+
+ void startCycle() {
+ m_currentTracker = m_rootTracker.get();
+ m_runState = Executing;
+ }
+ void completeCycle() {
+ m_runState = CompletedCycle;
+ }
+
+ bool completedCycle() const {
+ return m_runState == CompletedCycle;
+ }
+ ITracker& currentTracker() {
+ return *m_currentTracker;
+ }
+ void setCurrentTracker( ITracker* tracker ) {
+ m_currentTracker = tracker;
+ }
+ };
+
+ class TrackerBase : public ITracker {
+ protected:
+ enum CycleState {
+ NotStarted,
+ Executing,
+ ExecutingChildren,
+ NeedsAnotherRun,
+ CompletedSuccessfully,
+ Failed
+ };
+ class TrackerHasName {
+ std::string m_name;
+ public:
+ TrackerHasName( std::string const& name ) : m_name( name ) {}
+ bool operator ()( Ptr<ITracker> const& tracker ) {
+ return tracker->name() == m_name;
+ }
+ };
+ typedef std::vector<Ptr<ITracker> > Children;
+ std::string m_name;
+ TrackerContext& m_ctx;
+ ITracker* m_parent;
+ Children m_children;
+ CycleState m_runState;
+ public:
+ TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent )
+ : m_name( name ),
+ m_ctx( ctx ),
+ m_parent( parent ),
+ m_runState( NotStarted )
+ {}
+ virtual ~TrackerBase();
+
+ virtual std::string name() const CATCH_OVERRIDE {
+ return m_name;
+ }
+ virtual bool isComplete() const CATCH_OVERRIDE {
+ return m_runState == CompletedSuccessfully || m_runState == Failed;
+ }
+ virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE {
+ return m_runState == CompletedSuccessfully;
+ }
+ virtual bool isOpen() const CATCH_OVERRIDE {
+ return m_runState != NotStarted && !isComplete();
+ }
+ virtual bool hasChildren() const CATCH_OVERRIDE {
+ return !m_children.empty();
+ }
+
+ virtual void addChild( Ptr<ITracker> const& child ) CATCH_OVERRIDE {
+ m_children.push_back( child );
+ }
+
+ virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE {
+ Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) );
+ return( it != m_children.end() )
+ ? it->get()
+ : CATCH_NULL;
+ }
+ virtual ITracker& parent() CATCH_OVERRIDE {
+ assert( m_parent ); // Should always be non-null except for root
+ return *m_parent;
+ }
+
+ virtual void openChild() CATCH_OVERRIDE {
+ if( m_runState != ExecutingChildren ) {
+ m_runState = ExecutingChildren;
+ if( m_parent )
+ m_parent->openChild();
+ }
+ }
+ void open() {
+ m_runState = Executing;
+ moveToThis();
+ if( m_parent )
+ m_parent->openChild();
+ }
+
+ virtual void close() CATCH_OVERRIDE {
+
+ // Close any still open children (e.g. generators)
+ while( &m_ctx.currentTracker() != this )
+ m_ctx.currentTracker().close();
+
+ switch( m_runState ) {
+ case NotStarted:
+ case CompletedSuccessfully:
+ case Failed:
+ throw std::logic_error( "Illogical state" );
+
+ case NeedsAnotherRun:
+ break;;
+
+ case Executing:
+ m_runState = CompletedSuccessfully;
+ break;
+ case ExecutingChildren:
+ if( m_children.empty() || m_children.back()->isComplete() )
+ m_runState = CompletedSuccessfully;
+ break;
+
+ default:
+ throw std::logic_error( "Unexpected state" );
+ }
+ moveToParent();
+ m_ctx.completeCycle();
+ }
+ virtual void fail() CATCH_OVERRIDE {
+ m_runState = Failed;
+ if( m_parent )
+ m_parent->markAsNeedingAnotherRun();
+ moveToParent();
+ m_ctx.completeCycle();
+ }
+ virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE {
+ m_runState = NeedsAnotherRun;
+ }
+ private:
+ void moveToParent() {
+ assert( m_parent );
+ m_ctx.setCurrentTracker( m_parent );
+ }
+ void moveToThis() {
+ m_ctx.setCurrentTracker( this );
+ }
+ };
+
+ class SectionTracker : public TrackerBase {
+ public:
+ SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent )
+ : TrackerBase( name, ctx, parent )
+ {}
+ virtual ~SectionTracker();
+
+ static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) {
+ SectionTracker* section = CATCH_NULL;
+
+ ITracker& currentTracker = ctx.currentTracker();
+ if( ITracker* childTracker = currentTracker.findChild( name ) ) {
+ section = dynamic_cast<SectionTracker*>( childTracker );
+ assert( section );
+ }
+ else {
+ section = new SectionTracker( name, ctx, &currentTracker );
+ currentTracker.addChild( section );
+ }
+ if( !ctx.completedCycle() && !section->isComplete() ) {
+
+ section->open();
+ }
+ return *section;
+ }
+ };
+
+ class IndexTracker : public TrackerBase {
+ int m_size;
+ int m_index;
+ public:
+ IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size )
+ : TrackerBase( name, ctx, parent ),
+ m_size( size ),
+ m_index( -1 )
+ {}
+ virtual ~IndexTracker();
+
+ static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) {
+ IndexTracker* tracker = CATCH_NULL;
+
+ ITracker& currentTracker = ctx.currentTracker();
+ if( ITracker* childTracker = currentTracker.findChild( name ) ) {
+ tracker = dynamic_cast<IndexTracker*>( childTracker );
+ assert( tracker );
+ }
+ else {
+ tracker = new IndexTracker( name, ctx, &currentTracker, size );
+ currentTracker.addChild( tracker );
+ }
+
+ if( !ctx.completedCycle() && !tracker->isComplete() ) {
+ if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun )
+ tracker->moveNext();
+ tracker->open();
+ }
+
+ return *tracker;
+ }
+
+ int index() const { return m_index; }
+
+ void moveNext() {
+ m_index++;
+ m_children.clear();
+ }
+
+ virtual void close() CATCH_OVERRIDE {
+ TrackerBase::close();
+ if( m_runState == CompletedSuccessfully && m_index < m_size-1 )
+ m_runState = Executing;
+ }
+ };
+
+ inline ITracker& TrackerContext::startRun() {
+ m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL );
+ m_currentTracker = CATCH_NULL;
+ m_runState = Executing;
+ return *m_rootTracker;
+ }
+
+} // namespace TestCaseTracking
+
+using TestCaseTracking::ITracker;
+using TestCaseTracking::TrackerContext;
+using TestCaseTracking::SectionTracker;
+using TestCaseTracking::IndexTracker;
+
+} // namespace Catch
+
+// #included from: catch_fatal_condition.hpp
+#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
+
+namespace Catch {
+
+ // Report the error condition then exit the process
+ inline void fatal( std::string const& message, int exitCode ) {
+ IContext& context = Catch::getCurrentContext();
+ IResultCapture* resultCapture = context.getResultCapture();
+ resultCapture->handleFatalErrorCondition( message );
+
+ if( Catch::alwaysTrue() ) // avoids "no return" warnings
+ exit( exitCode );
+ }
+
+} // namespace Catch
+
+#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
+
+namespace Catch {
+
+ struct FatalConditionHandler {
+ void reset() {}
+ };
+
+} // namespace Catch
+
+#else // Not Windows - assumed to be POSIX compatible //////////////////////////
+
+#include <signal.h>
+
+namespace Catch {
+
+ struct SignalDefs { int id; const char* name; };
+ extern SignalDefs signalDefs[];
+ SignalDefs signalDefs[] = {
+ { SIGINT, "SIGINT - Terminal interrupt signal" },
+ { SIGILL, "SIGILL - Illegal instruction signal" },
+ { SIGFPE, "SIGFPE - Floating point error signal" },
+ { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
+ { SIGTERM, "SIGTERM - Termination request signal" },
+ { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+ };
+
+ struct FatalConditionHandler {
+
+ static void handleSignal( int sig ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ if( sig == signalDefs[i].id )
+ fatal( signalDefs[i].name, -sig );
+ fatal( "<unknown signal>", -sig );
+ }
+
+ FatalConditionHandler() : m_isSet( true ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ signal( signalDefs[i].id, handleSignal );
+ }
+ ~FatalConditionHandler() {
+ reset();
+ }
+ void reset() {
+ if( m_isSet ) {
+ for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+ signal( signalDefs[i].id, SIG_DFL );
+ m_isSet = false;
+ }
+ }
+
+ bool m_isSet;
+ };
+
+} // namespace Catch
+
+#endif // not Windows
+
+#include <set>
+#include <string>
+
+namespace Catch {
+
+ class StreamRedirect {
+
+ public:
+ StreamRedirect( std::ostream& stream, std::string& targetString )
+ : m_stream( stream ),
+ m_prevBuf( stream.rdbuf() ),
+ m_targetString( targetString )
+ {
+ stream.rdbuf( m_oss.rdbuf() );
+ }
+
+ ~StreamRedirect() {
+ m_targetString += m_oss.str();
+ m_stream.rdbuf( m_prevBuf );
+ }
+
+ private:
+ std::ostream& m_stream;
+ std::streambuf* m_prevBuf;
+ std::ostringstream m_oss;
+ std::string& m_targetString;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class RunContext : public IResultCapture, public IRunner {
+
+ RunContext( RunContext const& );
+ void operator =( RunContext const& );
+
+ public:
+
+ explicit RunContext( Ptr<IConfig const> const& _config, Ptr<IStreamingReporter> const& reporter )
+ : m_runInfo( _config->name() ),
+ m_context( getCurrentMutableContext() ),
+ m_activeTestCase( CATCH_NULL ),
+ m_config( _config ),
+ m_reporter( reporter )
+ {
+ m_context.setRunner( this );
+ m_context.setConfig( m_config );
+ m_context.setResultCapture( this );
+ m_reporter->testRunStarting( m_runInfo );
+ }
+
+ virtual ~RunContext() {
+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) );
+ }
+
+ void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) {
+ m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) );
+ }
+ void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) {
+ m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) );
+ }
+
+ Totals runTest( TestCase const& testCase ) {
+ Totals prevTotals = m_totals;
+
+ std::string redirectedCout;
+ std::string redirectedCerr;
+
+ TestCaseInfo testInfo = testCase.getTestCaseInfo();
+
+ m_reporter->testCaseStarting( testInfo );
+
+ m_activeTestCase = &testCase;
+
+ do {
+ m_trackerContext.startRun();
+ do {
+ m_trackerContext.startCycle();
+ m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name );
+ runCurrentTest( redirectedCout, redirectedCerr );
+ }
+ while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() );
+ }
+ // !TBD: deprecated - this will be replaced by indexed trackers
+ while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
+
+ Totals deltaTotals = m_totals.delta( prevTotals );
+ m_totals.testCases += deltaTotals.testCases;
+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
+ deltaTotals,
+ redirectedCout,
+ redirectedCerr,
+ aborting() ) );
+
+ m_activeTestCase = CATCH_NULL;
+ m_testCaseTracker = CATCH_NULL;
+
+ return deltaTotals;
+ }
+
+ Ptr<IConfig const> config() const {
+ return m_config;
+ }
+
+ private: // IResultCapture
+
+ virtual void assertionEnded( AssertionResult const& result ) {
+ if( result.getResultType() == ResultWas::Ok ) {
+ m_totals.assertions.passed++;
+ }
+ else if( !result.isOk() ) {
+ m_totals.assertions.failed++;
+ }
+
+ if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) )
+ m_messages.clear();
+
+ // Reset working state
+ m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition );
+ m_lastResult = result;
+ }
+
+ virtual bool sectionStarted (
+ SectionInfo const& sectionInfo,
+ Counts& assertions
+ )
+ {
+ std::ostringstream oss;
+ oss << sectionInfo.name << "@" << sectionInfo.lineInfo;
+
+ ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() );
+ if( !sectionTracker.isOpen() )
+ return false;
+ m_activeSections.push_back( &sectionTracker );
+
+ m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;
+
+ m_reporter->sectionStarting( sectionInfo );
+
+ assertions = m_totals.assertions;
+
+ return true;
+ }
+ bool testForMissingAssertions( Counts& assertions ) {
+ if( assertions.total() != 0 )
+ return false;
+ if( !m_config->warnAboutMissingAssertions() )
+ return false;
+ if( m_trackerContext.currentTracker().hasChildren() )
+ return false;
+ m_totals.assertions.failed++;
+ assertions.failed++;
+ return true;
+ }
+
+ virtual void sectionEnded( SectionEndInfo const& endInfo ) {
+ Counts assertions = m_totals.assertions - endInfo.prevAssertions;
+ bool missingAssertions = testForMissingAssertions( assertions );
+
+ if( !m_activeSections.empty() ) {
+ m_activeSections.back()->close();
+ m_activeSections.pop_back();
+ }
+
+ m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) );
+ m_messages.clear();
+ }
+
+ virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) {
+ if( m_unfinishedSections.empty() )
+ m_activeSections.back()->fail();
+ else
+ m_activeSections.back()->close();
+ m_activeSections.pop_back();
+
+ m_unfinishedSections.push_back( endInfo );
+ }
+
+ virtual void pushScopedMessage( MessageInfo const& message ) {
+ m_messages.push_back( message );
+ }
+
+ virtual void popScopedMessage( MessageInfo const& message ) {
+ m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() );
+ }
+
+ virtual std::string getCurrentTestName() const {
+ return m_activeTestCase
+ ? m_activeTestCase->getTestCaseInfo().name
+ : "";
+ }
+
+ virtual const AssertionResult* getLastResult() const {
+ return &m_lastResult;
+ }
+
+ virtual void handleFatalErrorCondition( std::string const& message ) {
+ ResultBuilder resultBuilder = makeUnexpectedResultBuilder();
+ resultBuilder.setResultType( ResultWas::FatalErrorCondition );
+ resultBuilder << message;
+ resultBuilder.captureExpression();
+
+ handleUnfinishedSections();
+
+ // Recreate section for test case (as we will lose the one that was in scope)
+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+
+ Counts assertions;
+ assertions.failed = 1;
+ SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false );
+ m_reporter->sectionEnded( testCaseSectionStats );
+
+ TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo();
+
+ Totals deltaTotals;
+ deltaTotals.testCases.failed = 1;
+ m_reporter->testCaseEnded( TestCaseStats( testInfo,
+ deltaTotals,
+ "",
+ "",
+ false ) );
+ m_totals.testCases.failed++;
+ testGroupEnded( "", m_totals, 1, 1 );
+ m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) );
+ }
+
+ public:
+ // !TBD We need to do this another way!
+ bool aborting() const {
+ return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
+ }
+
+ private:
+
+ void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
+ TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo();
+ SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description );
+ m_reporter->sectionStarting( testCaseSection );
+ Counts prevAssertions = m_totals.assertions;
+ double duration = 0;
+ try {
+ m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal );
+
+ seedRng( *m_config );
+
+ Timer timer;
+ timer.start();
+ if( m_reporter->getPreferences().shouldRedirectStdOut ) {
+ StreamRedirect coutRedir( Catch::cout(), redirectedCout );
+ StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr );
+ invokeActiveTestCase();
+ }
+ else {
+ invokeActiveTestCase();
+ }
+ duration = timer.getElapsedSeconds();
+ }
+ catch( TestFailureException& ) {
+ // This just means the test was aborted due to failure
+ }
+ catch(...) {
+ makeUnexpectedResultBuilder().useActiveException();
+ }
+ m_testCaseTracker->close();
+ handleUnfinishedSections();
+ m_messages.clear();
+
+ Counts assertions = m_totals.assertions - prevAssertions;
+ bool missingAssertions = testForMissingAssertions( assertions );
+
+ if( testCaseInfo.okToFail() ) {
+ std::swap( assertions.failedButOk, assertions.failed );
+ m_totals.assertions.failed -= assertions.failedButOk;
+ m_totals.assertions.failedButOk += assertions.failedButOk;
+ }
+
+ SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions );
+ m_reporter->sectionEnded( testCaseSectionStats );
+ }
+
+ void invokeActiveTestCase() {
+ FatalConditionHandler fatalConditionHandler; // Handle signals
+ m_activeTestCase->invoke();
+ fatalConditionHandler.reset();
+ }
+
+ private:
+
+ ResultBuilder makeUnexpectedResultBuilder() const {
+ return ResultBuilder( m_lastAssertionInfo.macroName.c_str(),
+ m_lastAssertionInfo.lineInfo,
+ m_lastAssertionInfo.capturedExpression.c_str(),
+ m_lastAssertionInfo.resultDisposition );
+ }
+
+ void handleUnfinishedSections() {
+ // If sections ended prematurely due to an exception we stored their
+ // infos here so we can tear them down outside the unwind process.
+ for( std::vector<SectionEndInfo>::const_reverse_iterator it = m_unfinishedSections.rbegin(),
+ itEnd = m_unfinishedSections.rend();
+ it != itEnd;
+ ++it )
+ sectionEnded( *it );
+ m_unfinishedSections.clear();
+ }
+
+ TestRunInfo m_runInfo;
+ IMutableContext& m_context;
+ TestCase const* m_activeTestCase;
+ ITracker* m_testCaseTracker;
+ ITracker* m_currentSectionTracker;
+ AssertionResult m_lastResult;
+
+ Ptr<IConfig const> m_config;
+ Totals m_totals;
+ Ptr<IStreamingReporter> m_reporter;
+ std::vector<MessageInfo> m_messages;
+ AssertionInfo m_lastAssertionInfo;
+ std::vector<SectionEndInfo> m_unfinishedSections;
+ std::vector<ITracker*> m_activeSections;
+ TrackerContext m_trackerContext;
+ };
+
+ IResultCapture& getResultCapture() {
+ if( IResultCapture* capture = getCurrentContext().getResultCapture() )
+ return *capture;
+ else
+ throw std::logic_error( "No result capture instance" );
+ }
+
+} // end namespace Catch
+
+// #included from: internal/catch_version.h
+#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED
+
+namespace Catch {
+
+ // Versioning information
+ struct Version {
+ Version( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _patchNumber,
+ std::string const& _branchName,
+ unsigned int _buildNumber );
+
+ unsigned int const majorVersion;
+ unsigned int const minorVersion;
+ unsigned int const patchNumber;
+
+ // buildNumber is only used if branchName is not null
+ std::string const branchName;
+ unsigned int const buildNumber;
+
+ friend std::ostream& operator << ( std::ostream& os, Version const& version );
+
+ private:
+ void operator=( Version const& );
+ };
+
+ extern Version libraryVersion;
+}
+
+#include <fstream>
+#include <stdlib.h>
+#include <limits>
+
+namespace Catch {
+
+ Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
+ Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
+ if( !reporter ) {
+ std::ostringstream oss;
+ oss << "No reporter registered with name: '" << reporterName << "'";
+ throw std::domain_error( oss.str() );
+ }
+ return reporter;
+ }
+
+ Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
+ std::vector<std::string> reporters = config->getReporterNames();
+ if( reporters.empty() )
+ reporters.push_back( "console" );
+
+ Ptr<IStreamingReporter> reporter;
+ for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
+ it != itEnd;
+ ++it )
+ reporter = addReporter( reporter, createReporter( *it, config ) );
+ return reporter;
+ }
+ Ptr<IStreamingReporter> addListeners( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> reporters ) {
+ IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
+ for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
+ it != itEnd;
+ ++it )
+ reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
+ return reporters;
+ }
+
+ Totals runTests( Ptr<Config> const& config ) {
+
+ Ptr<IConfig const> iconfig = config.get();
+
+ Ptr<IStreamingReporter> reporter = makeReporter( config );
+ reporter = addListeners( iconfig, reporter );
+
+ RunContext context( iconfig, reporter );
+
+ Totals totals;
+
+ context.testGroupStarting( config->name(), 1, 1 );
+
+ TestSpec testSpec = config->testSpec();
+ if( !testSpec.hasFilters() )
+ testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
+
+ std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *iconfig );
+ for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
+ it != itEnd;
+ ++it ) {
+ if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) )
+ totals += context.runTest( *it );
+ else
+ reporter->skipTest( *it );
+ }
+
+ context.testGroupEnded( iconfig->name(), totals, 1, 1 );
+ return totals;
+ }
+
+ void applyFilenamesAsTags( IConfig const& config ) {
+ std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
+ for(std::size_t i = 0; i < tests.size(); ++i ) {
+ TestCase& test = const_cast<TestCase&>( tests[i] );
+ std::set<std::string> tags = test.tags;
+
+ std::string filename = test.lineInfo.file;
+ std::string::size_type lastSlash = filename.find_last_of( "\\/" );
+ if( lastSlash != std::string::npos )
+ filename = filename.substr( lastSlash+1 );
+
+ std::string::size_type lastDot = filename.find_last_of( "." );
+ if( lastDot != std::string::npos )
+ filename = filename.substr( 0, lastDot );
+
+ tags.insert( "#" + filename );
+ setTags( test, tags );
+ }
+ }
+
+ class Session : NonCopyable {
+ static bool alreadyInstantiated;
+
+ public:
+
+ struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; };
+
+ Session()
+ : m_cli( makeCommandLineParser() ) {
+ if( alreadyInstantiated ) {
+ std::string msg = "Only one instance of Catch::Session can ever be used";
+ Catch::cerr() << msg << std::endl;
+ throw std::logic_error( msg );
+ }
+ alreadyInstantiated = true;
+ }
+ ~Session() {
+ Catch::cleanUp();
+ }
+
+ void showHelp( std::string const& processName ) {
+ Catch::cout() << "\nCatch v" << libraryVersion << "\n";
+
+ m_cli.usage( Catch::cout(), processName );
+ Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
+ }
+
+ int applyCommandLine( int argc, char const* argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) {
+ try {
+ m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail );
+ m_unusedTokens = m_cli.parseInto( argc, argv, m_configData );
+ if( m_configData.showHelp )
+ showHelp( m_configData.processName );
+ m_config.reset();
+ }
+ catch( std::exception& ex ) {
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr()
+ << "\nError(s) in input:\n"
+ << Text( ex.what(), TextAttributes().setIndent(2) )
+ << "\n\n";
+ }
+ m_cli.usage( Catch::cout(), m_configData.processName );
+ return (std::numeric_limits<int>::max)();
+ }
+ return 0;
+ }
+
+ void useConfigData( ConfigData const& _configData ) {
+ m_configData = _configData;
+ m_config.reset();
+ }
+
+ int run( int argc, char const* argv[] ) {
+
+ int returnCode = applyCommandLine( argc, argv );
+ if( returnCode == 0 )
+ returnCode = run();
+ return returnCode;
+ }
+ int run( int argc, char* argv[] ) {
+ return run( argc, const_cast<char const**>( argv ) );
+ }
+
+ int run() {
+ if( m_configData.showHelp )
+ return 0;
+
+ try
+ {
+ config(); // Force config to be constructed
+
+ seedRng( *m_config );
+
+ if( m_configData.filenamesAsTags )
+ applyFilenamesAsTags( *m_config );
+
+ // Handle list request
+ if( Option<std::size_t> listed = list( config() ) )
+ return static_cast<int>( *listed );
+
+ return static_cast<int>( runTests( m_config ).assertions.failed );
+ }
+ catch( std::exception& ex ) {
+ Catch::cerr() << ex.what() << std::endl;
+ return (std::numeric_limits<int>::max)();
+ }
+ }
+
+ Clara::CommandLine<ConfigData> const& cli() const {
+ return m_cli;
+ }
+ std::vector<Clara::Parser::Token> const& unusedTokens() const {
+ return m_unusedTokens;
+ }
+ ConfigData& configData() {
+ return m_configData;
+ }
+ Config& config() {
+ if( !m_config )
+ m_config = new Config( m_configData );
+ return *m_config;
+ }
+ private:
+ Clara::CommandLine<ConfigData> m_cli;
+ std::vector<Clara::Parser::Token> m_unusedTokens;
+ ConfigData m_configData;
+ Ptr<Config> m_config;
+ };
+
+ bool Session::alreadyInstantiated = false;
+
+} // end namespace Catch
+
+// #included from: catch_registry_hub.hpp
+#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED
+
+// #included from: catch_test_case_registry_impl.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <set>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+
+namespace Catch {
+
+ struct LexSort {
+ bool operator() (TestCase i,TestCase j) const { return (i<j);}
+ };
+ struct RandomNumberGenerator {
+ int operator()( int n ) const { return std::rand() % n; }
+ };
+
+ inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
+
+ std::vector<TestCase> sorted = unsortedTestCases;
+
+ switch( config.runOrder() ) {
+ case RunTests::InLexicographicalOrder:
+ std::sort( sorted.begin(), sorted.end(), LexSort() );
+ break;
+ case RunTests::InRandomOrder:
+ {
+ seedRng( config );
+
+ RandomNumberGenerator rng;
+ std::random_shuffle( sorted.begin(), sorted.end(), rng );
+ }
+ break;
+ case RunTests::InDeclarationOrder:
+ // already in declaration order
+ break;
+ }
+ return sorted;
+ }
+ bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
+ return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
+ }
+
+ void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
+ std::set<TestCase> seenFunctions;
+ for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
+ it != itEnd;
+ ++it ) {
+ std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
+ if( !prev.second ){
+ Catch::cerr()
+ << Colour( Colour::Red )
+ << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
+ << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
+ << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
+ exit(1);
+ }
+ }
+ }
+
+ std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
+ std::vector<TestCase> filtered;
+ filtered.reserve( testCases.size() );
+ for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
+ it != itEnd;
+ ++it )
+ if( matchTest( *it, testSpec, config ) )
+ filtered.push_back( *it );
+ return filtered;
+ }
+ std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
+ return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
+ }
+
+ class TestRegistry : public ITestCaseRegistry {
+ public:
+ TestRegistry()
+ : m_currentSortOrder( RunTests::InDeclarationOrder ),
+ m_unnamedCount( 0 )
+ {}
+ virtual ~TestRegistry();
+
+ virtual void registerTest( TestCase const& testCase ) {
+ std::string name = testCase.getTestCaseInfo().name;
+ if( name == "" ) {
+ std::ostringstream oss;
+ oss << "Anonymous test case " << ++m_unnamedCount;
+ return registerTest( testCase.withName( oss.str() ) );
+ }
+ m_functions.push_back( testCase );
+ }
+
+ virtual std::vector<TestCase> const& getAllTests() const {
+ return m_functions;
+ }
+ virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
+ if( m_sortedFunctions.empty() )
+ enforceNoDuplicateTestCases( m_functions );
+
+ if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
+ m_sortedFunctions = sortTests( config, m_functions );
+ m_currentSortOrder = config.runOrder();
+ }
+ return m_sortedFunctions;
+ }
+
+ private:
+ std::vector<TestCase> m_functions;
+ mutable RunTests::InWhatOrder m_currentSortOrder;
+ mutable std::vector<TestCase> m_sortedFunctions;
+ size_t m_unnamedCount;
+ std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class FreeFunctionTestCase : public SharedImpl<ITestCase> {
+ public:
+
+ FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
+
+ virtual void invoke() const {
+ m_fun();
+ }
+
+ private:
+ virtual ~FreeFunctionTestCase();
+
+ TestFunction m_fun;
+ };
+
+ inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) {
+ std::string className = classOrQualifiedMethodName;
+ if( startsWith( className, "&" ) )
+ {
+ std::size_t lastColons = className.rfind( "::" );
+ std::size_t penultimateColons = className.rfind( "::", lastColons-1 );
+ if( penultimateColons == std::string::npos )
+ penultimateColons = 1;
+ className = className.substr( penultimateColons, lastColons-penultimateColons );
+ }
+ return className;
+ }
+
+ void registerTestCase
+ ( ITestCase* testCase,
+ char const* classOrQualifiedMethodName,
+ NameAndDesc const& nameAndDesc,
+ SourceLineInfo const& lineInfo ) {
+
+ getMutableRegistryHub().registerTest
+ ( makeTestCase
+ ( testCase,
+ extractClassName( classOrQualifiedMethodName ),
+ nameAndDesc.name,
+ nameAndDesc.description,
+ lineInfo ) );
+ }
+ void registerTestCaseFunction
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc ) {
+ registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ AutoReg::AutoReg
+ ( TestFunction function,
+ SourceLineInfo const& lineInfo,
+ NameAndDesc const& nameAndDesc ) {
+ registerTestCaseFunction( function, lineInfo, nameAndDesc );
+ }
+
+ AutoReg::~AutoReg() {}
+
+} // end namespace Catch
+
+// #included from: catch_reporter_registry.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+ class ReporterRegistry : public IReporterRegistry {
+
+ public:
+
+ virtual ~ReporterRegistry() CATCH_OVERRIDE {}
+
+ virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig const> const& config ) const CATCH_OVERRIDE {
+ FactoryMap::const_iterator it = m_factories.find( name );
+ if( it == m_factories.end() )
+ return CATCH_NULL;
+ return it->second->create( ReporterConfig( config ) );
+ }
+
+ void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
+ m_factories.insert( std::make_pair( name, factory ) );
+ }
+ void registerListener( Ptr<IReporterFactory> const& factory ) {
+ m_listeners.push_back( factory );
+ }
+
+ virtual FactoryMap const& getFactories() const CATCH_OVERRIDE {
+ return m_factories;
+ }
+ virtual Listeners const& getListeners() const CATCH_OVERRIDE {
+ return m_listeners;
+ }
+
+ private:
+ FactoryMap m_factories;
+ Listeners m_listeners;
+ };
+}
+
+// #included from: catch_exception_translator_registry.hpp
+#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED
+
+#ifdef __OBJC__
+#import "Foundation/Foundation.h"
+#endif
+
+namespace Catch {
+
+ class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {
+ public:
+ ~ExceptionTranslatorRegistry() {
+ deleteAll( m_translators );
+ }
+
+ virtual void registerTranslator( const IExceptionTranslator* translator ) {
+ m_translators.push_back( translator );
+ }
+
+ virtual std::string translateActiveException() const {
+ try {
+#ifdef __OBJC__
+ // In Objective-C try objective-c exceptions first
+ @try {
+ return tryTranslators();
+ }
+ @catch (NSException *exception) {
+ return Catch::toString( [exception description] );
+ }
+#else
+ return tryTranslators();
+#endif
+ }
+ catch( TestFailureException& ) {
+ throw;
+ }
+ catch( std::exception& ex ) {
+ return ex.what();
+ }
+ catch( std::string& msg ) {
+ return msg;
+ }
+ catch( const char* msg ) {
+ return msg;
+ }
+ catch(...) {
+ return "Unknown exception";
+ }
+ }
+
+ std::string tryTranslators() const {
+ if( m_translators.empty() )
+ throw;
+ else
+ return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() );
+ }
+
+ private:
+ std::vector<const IExceptionTranslator*> m_translators;
+ };
+}
+
+namespace Catch {
+
+ namespace {
+
+ class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
+
+ RegistryHub( RegistryHub const& );
+ void operator=( RegistryHub const& );
+
+ public: // IRegistryHub
+ RegistryHub() {
+ }
+ virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE {
+ return m_reporterRegistry;
+ }
+ virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE {
+ return m_testCaseRegistry;
+ }
+ virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE {
+ return m_exceptionTranslatorRegistry;
+ }
+
+ public: // IMutableRegistryHub
+ virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
+ m_reporterRegistry.registerReporter( name, factory );
+ }
+ virtual void registerListener( Ptr<IReporterFactory> const& factory ) CATCH_OVERRIDE {
+ m_reporterRegistry.registerListener( factory );
+ }
+ virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE {
+ m_testCaseRegistry.registerTest( testInfo );
+ }
+ virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE {
+ m_exceptionTranslatorRegistry.registerTranslator( translator );
+ }
+
+ private:
+ TestRegistry m_testCaseRegistry;
+ ReporterRegistry m_reporterRegistry;
+ ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
+ };
+
+ // Single, global, instance
+ inline RegistryHub*& getTheRegistryHub() {
+ static RegistryHub* theRegistryHub = CATCH_NULL;
+ if( !theRegistryHub )
+ theRegistryHub = new RegistryHub();
+ return theRegistryHub;
+ }
+ }
+
+ IRegistryHub& getRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ IMutableRegistryHub& getMutableRegistryHub() {
+ return *getTheRegistryHub();
+ }
+ void cleanUp() {
+ delete getTheRegistryHub();
+ getTheRegistryHub() = CATCH_NULL;
+ cleanUpContext();
+ }
+ std::string translateActiveException() {
+ return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_notimplemented_exception.hpp
+#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED
+
+#include <ostream>
+
+namespace Catch {
+
+ NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo )
+ : m_lineInfo( lineInfo ) {
+ std::ostringstream oss;
+ oss << lineInfo << ": function ";
+ oss << "not implemented";
+ m_what = oss.str();
+ }
+
+ const char* NotImplementedException::what() const CATCH_NOEXCEPT {
+ return m_what.c_str();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_context_impl.hpp
+#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
+
+// #included from: catch_stream.hpp
+#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
+
+#include <stdexcept>
+#include <cstdio>
+#include <iostream>
+
+namespace Catch {
+
+ template<typename WriterF, size_t bufferSize=256>
+ class StreamBufImpl : public StreamBufBase {
+ char data[bufferSize];
+ WriterF m_writer;
+
+ public:
+ StreamBufImpl() {
+ setp( data, data + sizeof(data) );
+ }
+
+ ~StreamBufImpl() CATCH_NOEXCEPT {
+ sync();
+ }
+
+ private:
+ int overflow( int c ) {
+ sync();
+
+ if( c != EOF ) {
+ if( pbase() == epptr() )
+ m_writer( std::string( 1, static_cast<char>( c ) ) );
+ else
+ sputc( static_cast<char>( c ) );
+ }
+ return 0;
+ }
+
+ int sync() {
+ if( pbase() != pptr() ) {
+ m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );
+ setp( pbase(), epptr() );
+ }
+ return 0;
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ FileStream::FileStream( std::string const& filename ) {
+ m_ofs.open( filename.c_str() );
+ if( m_ofs.fail() ) {
+ std::ostringstream oss;
+ oss << "Unable to open file: '" << filename << "'";
+ throw std::domain_error( oss.str() );
+ }
+ }
+
+ std::ostream& FileStream::stream() const {
+ return m_ofs;
+ }
+
+ struct OutputDebugWriter {
+
+ void operator()( std::string const&str ) {
+ writeToDebugConsole( str );
+ }
+ };
+
+ DebugOutStream::DebugOutStream()
+ : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
+ m_os( m_streamBuf.get() )
+ {}
+
+ std::ostream& DebugOutStream::stream() const {
+ return m_os;
+ }
+
+ // Store the streambuf from cout up-front because
+ // cout may get redirected when running tests
+ CoutStream::CoutStream()
+ : m_os( Catch::cout().rdbuf() )
+ {}
+
+ std::ostream& CoutStream::stream() const {
+ return m_os;
+ }
+
+#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions
+ std::ostream& cout() {
+ return std::cout;
+ }
+ std::ostream& cerr() {
+ return std::cerr;
+ }
+#endif
+}
+
+namespace Catch {
+
+ class Context : public IMutableContext {
+
+ Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {}
+ Context( Context const& );
+ void operator=( Context const& );
+
+ public: // IContext
+ virtual IResultCapture* getResultCapture() {
+ return m_resultCapture;
+ }
+ virtual IRunner* getRunner() {
+ return m_runner;
+ }
+ virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) {
+ return getGeneratorsForCurrentTest()
+ .getGeneratorInfo( fileInfo, totalSize )
+ .getCurrentIndex();
+ }
+ virtual bool advanceGeneratorsForCurrentTest() {
+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+ return generators && generators->moveNext();
+ }
+
+ virtual Ptr<IConfig const> getConfig() const {
+ return m_config;
+ }
+
+ public: // IMutableContext
+ virtual void setResultCapture( IResultCapture* resultCapture ) {
+ m_resultCapture = resultCapture;
+ }
+ virtual void setRunner( IRunner* runner ) {
+ m_runner = runner;
+ }
+ virtual void setConfig( Ptr<IConfig const> const& config ) {
+ m_config = config;
+ }
+
+ friend IMutableContext& getCurrentMutableContext();
+
+ private:
+ IGeneratorsForTest* findGeneratorsForCurrentTest() {
+ std::string testName = getResultCapture()->getCurrentTestName();
+
+ std::map<std::string, IGeneratorsForTest*>::const_iterator it =
+ m_generatorsByTestName.find( testName );
+ return it != m_generatorsByTestName.end()
+ ? it->second
+ : CATCH_NULL;
+ }
+
+ IGeneratorsForTest& getGeneratorsForCurrentTest() {
+ IGeneratorsForTest* generators = findGeneratorsForCurrentTest();
+ if( !generators ) {
+ std::string testName = getResultCapture()->getCurrentTestName();
+ generators = createGeneratorsForTest();
+ m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
+ }
+ return *generators;
+ }
+
+ private:
+ Ptr<IConfig const> m_config;
+ IRunner* m_runner;
+ IResultCapture* m_resultCapture;
+ std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName;
+ };
+
+ namespace {
+ Context* currentContext = CATCH_NULL;
+ }
+ IMutableContext& getCurrentMutableContext() {
+ if( !currentContext )
+ currentContext = new Context();
+ return *currentContext;
+ }
+ IContext& getCurrentContext() {
+ return getCurrentMutableContext();
+ }
+
+ void cleanUpContext() {
+ delete currentContext;
+ currentContext = CATCH_NULL;
+ }
+}
+
+// #included from: catch_console_colour_impl.hpp
+#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED
+
+namespace Catch {
+ namespace {
+
+ struct IColourImpl {
+ virtual ~IColourImpl() {}
+ virtual void use( Colour::Code _colourCode ) = 0;
+ };
+
+ struct NoColourImpl : IColourImpl {
+ void use( Colour::Code ) {}
+
+ static IColourImpl* instance() {
+ static NoColourImpl s_instance;
+ return &s_instance;
+ }
+ };
+
+ } // anon namespace
+} // namespace Catch
+
+#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )
+# ifdef CATCH_PLATFORM_WINDOWS
+# define CATCH_CONFIG_COLOUR_WINDOWS
+# else
+# define CATCH_CONFIG_COLOUR_ANSI
+# endif
+#endif
+
+#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#ifdef __AFXDLL
+#include <AfxWin.h>
+#else
+#include <windows.h>
+#endif
+
+namespace Catch {
+namespace {
+
+ class Win32ColourImpl : public IColourImpl {
+ public:
+ Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )
+ {
+ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
+ GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );
+ originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );
+ originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
+ }
+
+ virtual void use( Colour::Code _colourCode ) {
+ switch( _colourCode ) {
+ case Colour::None: return setTextAttribute( originalForegroundAttributes );
+ case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+ case Colour::Red: return setTextAttribute( FOREGROUND_RED );
+ case Colour::Green: return setTextAttribute( FOREGROUND_GREEN );
+ case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE );
+ case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );
+ case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );
+ case Colour::Grey: return setTextAttribute( 0 );
+
+ case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY );
+ case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );
+ case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );
+ case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );
+
+ case Colour::Bright: throw std::logic_error( "not a colour" );
+ }
+ }
+
+ private:
+ void setTextAttribute( WORD _textAttribute ) {
+ SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );
+ }
+ HANDLE stdoutHandle;
+ WORD originalForegroundAttributes;
+ WORD originalBackgroundAttributes;
+ };
+
+ IColourImpl* platformColourInstance() {
+ static Win32ColourImpl s_instance;
+ return &s_instance;
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////
+
+#include <unistd.h>
+
+namespace Catch {
+namespace {
+
+ // use POSIX/ ANSI console terminal codes
+ // Thanks to Adam Strzelecki for original contribution
+ // (http://github.com/nanoant)
+ // https://github.com/philsquared/Catch/pull/131
+ class PosixColourImpl : public IColourImpl {
+ public:
+ virtual void use( Colour::Code _colourCode ) {
+ switch( _colourCode ) {
+ case Colour::None:
+ case Colour::White: return setColour( "[0m" );
+ case Colour::Red: return setColour( "[0;31m" );
+ case Colour::Green: return setColour( "[0;32m" );
+ case Colour::Blue: return setColour( "[0:34m" );
+ case Colour::Cyan: return setColour( "[0;36m" );
+ case Colour::Yellow: return setColour( "[0;33m" );
+ case Colour::Grey: return setColour( "[1;30m" );
+
+ case Colour::LightGrey: return setColour( "[0;37m" );
+ case Colour::BrightRed: return setColour( "[1;31m" );
+ case Colour::BrightGreen: return setColour( "[1;32m" );
+ case Colour::BrightWhite: return setColour( "[1;37m" );
+
+ case Colour::Bright: throw std::logic_error( "not a colour" );
+ }
+ }
+ static IColourImpl* instance() {
+ static PosixColourImpl s_instance;
+ return &s_instance;
+ }
+
+ private:
+ void setColour( const char* _escapeCode ) {
+ Catch::cout() << '\033' << _escapeCode;
+ }
+ };
+
+ IColourImpl* platformColourInstance() {
+ Ptr<IConfig const> config = getCurrentContext().getConfig();
+ return (config && config->forceColour()) || isatty(STDOUT_FILENO)
+ ? PosixColourImpl::instance()
+ : NoColourImpl::instance();
+ }
+
+} // end anon namespace
+} // end namespace Catch
+
+#else // not Windows or ANSI ///////////////////////////////////////////////
+
+namespace Catch {
+
+ static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }
+
+} // end namespace Catch
+
+#endif // Windows/ ANSI/ None
+
+namespace Catch {
+
+ Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); }
+ Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; }
+ Colour::~Colour(){ if( !m_moved ) use( None ); }
+
+ void Colour::use( Code _colourCode ) {
+ static IColourImpl* impl = isDebuggerActive()
+ ? NoColourImpl::instance()
+ : platformColourInstance();
+ impl->use( _colourCode );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_generators_impl.hpp
+#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED
+
+#include <vector>
+#include <string>
+#include <map>
+
+namespace Catch {
+
+ struct GeneratorInfo : IGeneratorInfo {
+
+ GeneratorInfo( std::size_t size )
+ : m_size( size ),
+ m_currentIndex( 0 )
+ {}
+
+ bool moveNext() {
+ if( ++m_currentIndex == m_size ) {
+ m_currentIndex = 0;
+ return false;
+ }
+ return true;
+ }
+
+ std::size_t getCurrentIndex() const {
+ return m_currentIndex;
+ }
+
+ std::size_t m_size;
+ std::size_t m_currentIndex;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class GeneratorsForTest : public IGeneratorsForTest {
+
+ public:
+ ~GeneratorsForTest() {
+ deleteAll( m_generatorsInOrder );
+ }
+
+ IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) {
+ std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
+ if( it == m_generatorsByName.end() ) {
+ IGeneratorInfo* info = new GeneratorInfo( size );
+ m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
+ m_generatorsInOrder.push_back( info );
+ return *info;
+ }
+ return *it->second;
+ }
+
+ bool moveNext() {
+ std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
+ std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
+ for(; it != itEnd; ++it ) {
+ if( (*it)->moveNext() )
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ std::map<std::string, IGeneratorInfo*> m_generatorsByName;
+ std::vector<IGeneratorInfo*> m_generatorsInOrder;
+ };
+
+ IGeneratorsForTest* createGeneratorsForTest()
+ {
+ return new GeneratorsForTest();
+ }
+
+} // end namespace Catch
+
+// #included from: catch_assertionresult.hpp
+#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED
+
+namespace Catch {
+
+ AssertionInfo::AssertionInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ std::string const& _capturedExpression,
+ ResultDisposition::Flags _resultDisposition )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ capturedExpression( _capturedExpression ),
+ resultDisposition( _resultDisposition )
+ {}
+
+ AssertionResult::AssertionResult() {}
+
+ AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )
+ : m_info( info ),
+ m_resultData( data )
+ {}
+
+ AssertionResult::~AssertionResult() {}
+
+ // Result was a success
+ bool AssertionResult::succeeded() const {
+ return Catch::isOk( m_resultData.resultType );
+ }
+
+ // Result was a success, or failure is suppressed
+ bool AssertionResult::isOk() const {
+ return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );
+ }
+
+ ResultWas::OfType AssertionResult::getResultType() const {
+ return m_resultData.resultType;
+ }
+
+ bool AssertionResult::hasExpression() const {
+ return !m_info.capturedExpression.empty();
+ }
+
+ bool AssertionResult::hasMessage() const {
+ return !m_resultData.message.empty();
+ }
+
+ std::string AssertionResult::getExpression() const {
+ if( isFalseTest( m_info.resultDisposition ) )
+ return "!" + m_info.capturedExpression;
+ else
+ return m_info.capturedExpression;
+ }
+ std::string AssertionResult::getExpressionInMacro() const {
+ if( m_info.macroName.empty() )
+ return m_info.capturedExpression;
+ else
+ return m_info.macroName + "( " + m_info.capturedExpression + " )";
+ }
+
+ bool AssertionResult::hasExpandedExpression() const {
+ return hasExpression() && getExpandedExpression() != getExpression();
+ }
+
+ std::string AssertionResult::getExpandedExpression() const {
+ return m_resultData.reconstructedExpression;
+ }
+
+ std::string AssertionResult::getMessage() const {
+ return m_resultData.message;
+ }
+ SourceLineInfo AssertionResult::getSourceInfo() const {
+ return m_info.lineInfo;
+ }
+
+ std::string AssertionResult::getTestMacroName() const {
+ return m_info.macroName;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_test_case_info.hpp
+#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
+
+namespace Catch {
+
+ inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {
+ if( startsWith( tag, "." ) ||
+ tag == "hide" ||
+ tag == "!hide" )
+ return TestCaseInfo::IsHidden;
+ else if( tag == "!throws" )
+ return TestCaseInfo::Throws;
+ else if( tag == "!shouldfail" )
+ return TestCaseInfo::ShouldFail;
+ else if( tag == "!mayfail" )
+ return TestCaseInfo::MayFail;
+ else
+ return TestCaseInfo::None;
+ }
+ inline bool isReservedTag( std::string const& tag ) {
+ return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] );
+ }
+ inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {
+ if( isReservedTag( tag ) ) {
+ {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr()
+ << "Tag name [" << tag << "] not allowed.\n"
+ << "Tag names starting with non alpha-numeric characters are reserved\n";
+ }
+ {
+ Colour colourGuard( Colour::FileName );
+ Catch::cerr() << _lineInfo << std::endl;
+ }
+ exit(1);
+ }
+ }
+
+ TestCase makeTestCase( ITestCase* _testCase,
+ std::string const& _className,
+ std::string const& _name,
+ std::string const& _descOrTags,
+ SourceLineInfo const& _lineInfo )
+ {
+ bool isHidden( startsWith( _name, "./" ) ); // Legacy support
+
+ // Parse out tags
+ std::set<std::string> tags;
+ std::string desc, tag;
+ bool inTag = false;
+ for( std::size_t i = 0; i < _descOrTags.size(); ++i ) {
+ char c = _descOrTags[i];
+ if( !inTag ) {
+ if( c == '[' )
+ inTag = true;
+ else
+ desc += c;
+ }
+ else {
+ if( c == ']' ) {
+ TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );
+ if( prop == TestCaseInfo::IsHidden )
+ isHidden = true;
+ else if( prop == TestCaseInfo::None )
+ enforceNotReservedTag( tag, _lineInfo );
+
+ tags.insert( tag );
+ tag.clear();
+ inTag = false;
+ }
+ else
+ tag += c;
+ }
+ }
+ if( isHidden ) {
+ tags.insert( "hide" );
+ tags.insert( "." );
+ }
+
+ TestCaseInfo info( _name, _className, desc, tags, _lineInfo );
+ return TestCase( _testCase, info );
+ }
+
+ void setTags( TestCaseInfo& testCaseInfo, std::set<std::string> const& tags )
+ {
+ testCaseInfo.tags = tags;
+ testCaseInfo.lcaseTags.clear();
+
+ std::ostringstream oss;
+ for( std::set<std::string>::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) {
+ oss << "[" << *it << "]";
+ std::string lcaseTag = toLower( *it );
+ testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );
+ testCaseInfo.lcaseTags.insert( lcaseTag );
+ }
+ testCaseInfo.tagsAsString = oss.str();
+ }
+
+ TestCaseInfo::TestCaseInfo( std::string const& _name,
+ std::string const& _className,
+ std::string const& _description,
+ std::set<std::string> const& _tags,
+ SourceLineInfo const& _lineInfo )
+ : name( _name ),
+ className( _className ),
+ description( _description ),
+ lineInfo( _lineInfo ),
+ properties( None )
+ {
+ setTags( *this, _tags );
+ }
+
+ TestCaseInfo::TestCaseInfo( TestCaseInfo const& other )
+ : name( other.name ),
+ className( other.className ),
+ description( other.description ),
+ tags( other.tags ),
+ lcaseTags( other.lcaseTags ),
+ tagsAsString( other.tagsAsString ),
+ lineInfo( other.lineInfo ),
+ properties( other.properties )
+ {}
+
+ bool TestCaseInfo::isHidden() const {
+ return ( properties & IsHidden ) != 0;
+ }
+ bool TestCaseInfo::throws() const {
+ return ( properties & Throws ) != 0;
+ }
+ bool TestCaseInfo::okToFail() const {
+ return ( properties & (ShouldFail | MayFail ) ) != 0;
+ }
+ bool TestCaseInfo::expectedToFail() const {
+ return ( properties & (ShouldFail ) ) != 0;
+ }
+
+ TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {}
+
+ TestCase::TestCase( TestCase const& other )
+ : TestCaseInfo( other ),
+ test( other.test )
+ {}
+
+ TestCase TestCase::withName( std::string const& _newName ) const {
+ TestCase other( *this );
+ other.name = _newName;
+ return other;
+ }
+
+ void TestCase::swap( TestCase& other ) {
+ test.swap( other.test );
+ name.swap( other.name );
+ className.swap( other.className );
+ description.swap( other.description );
+ tags.swap( other.tags );
+ lcaseTags.swap( other.lcaseTags );
+ tagsAsString.swap( other.tagsAsString );
+ std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties );
+ std::swap( lineInfo, other.lineInfo );
+ }
+
+ void TestCase::invoke() const {
+ test->invoke();
+ }
+
+ bool TestCase::operator == ( TestCase const& other ) const {
+ return test.get() == other.test.get() &&
+ name == other.name &&
+ className == other.className;
+ }
+
+ bool TestCase::operator < ( TestCase const& other ) const {
+ return name < other.name;
+ }
+ TestCase& TestCase::operator = ( TestCase const& other ) {
+ TestCase temp( other );
+ swap( temp );
+ return *this;
+ }
+
+ TestCaseInfo const& TestCase::getTestCaseInfo() const
+ {
+ return *this;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_version.hpp
+#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
+
+namespace Catch {
+
+ Version::Version
+ ( unsigned int _majorVersion,
+ unsigned int _minorVersion,
+ unsigned int _patchNumber,
+ std::string const& _branchName,
+ unsigned int _buildNumber )
+ : majorVersion( _majorVersion ),
+ minorVersion( _minorVersion ),
+ patchNumber( _patchNumber ),
+ branchName( _branchName ),
+ buildNumber( _buildNumber )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, Version const& version ) {
+ os << version.majorVersion << "."
+ << version.minorVersion << "."
+ << version.patchNumber;
+
+ if( !version.branchName.empty() ) {
+ os << "-" << version.branchName
+ << "." << version.buildNumber;
+ }
+ return os;
+ }
+
+ Version libraryVersion( 1, 3, 4, "", 0 );
+
+}
+
+// #included from: catch_message.hpp
+#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED
+
+namespace Catch {
+
+ MessageInfo::MessageInfo( std::string const& _macroName,
+ SourceLineInfo const& _lineInfo,
+ ResultWas::OfType _type )
+ : macroName( _macroName ),
+ lineInfo( _lineInfo ),
+ type( _type ),
+ sequence( ++globalCount )
+ {}
+
+ // This may need protecting if threading support is added
+ unsigned int MessageInfo::globalCount = 0;
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ ScopedMessage::ScopedMessage( MessageBuilder const& builder )
+ : m_info( builder.m_info )
+ {
+ m_info.message = builder.m_stream.str();
+ getResultCapture().pushScopedMessage( m_info );
+ }
+ ScopedMessage::ScopedMessage( ScopedMessage const& other )
+ : m_info( other.m_info )
+ {}
+
+ ScopedMessage::~ScopedMessage() {
+ getResultCapture().popScopedMessage( m_info );
+ }
+
+} // end namespace Catch
+
+// #included from: catch_legacy_reporter_adapter.hpp
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED
+
+// #included from: catch_legacy_reporter_adapter.h
+#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED
+
+namespace Catch
+{
+ // Deprecated
+ struct IReporter : IShared {
+ virtual ~IReporter();
+
+ virtual bool shouldRedirectStdout() const = 0;
+
+ virtual void StartTesting() = 0;
+ virtual void EndTesting( Totals const& totals ) = 0;
+ virtual void StartGroup( std::string const& groupName ) = 0;
+ virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
+ virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
+ virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
+ virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
+ virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
+ virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
+ virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
+ virtual void Aborted() = 0;
+ virtual void Result( AssertionResult const& result ) = 0;
+ };
+
+ class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
+ {
+ public:
+ LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter );
+ virtual ~LegacyReporterAdapter();
+
+ virtual ReporterPreferences getPreferences() const;
+ virtual void noMatchingTestCases( std::string const& );
+ virtual void testRunStarting( TestRunInfo const& );
+ virtual void testGroupStarting( GroupInfo const& groupInfo );
+ virtual void testCaseStarting( TestCaseInfo const& testInfo );
+ virtual void sectionStarting( SectionInfo const& sectionInfo );
+ virtual void assertionStarting( AssertionInfo const& );
+ virtual bool assertionEnded( AssertionStats const& assertionStats );
+ virtual void sectionEnded( SectionStats const& sectionStats );
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats );
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats );
+ virtual void testRunEnded( TestRunStats const& testRunStats );
+ virtual void skipTest( TestCaseInfo const& );
+
+ private:
+ Ptr<IReporter> m_legacyReporter;
+ };
+}
+
+namespace Catch
+{
+ LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter )
+ : m_legacyReporter( legacyReporter )
+ {}
+ LegacyReporterAdapter::~LegacyReporterAdapter() {}
+
+ ReporterPreferences LegacyReporterAdapter::getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout();
+ return prefs;
+ }
+
+ void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {}
+ void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) {
+ m_legacyReporter->StartTesting();
+ }
+ void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) {
+ m_legacyReporter->StartGroup( groupInfo.name );
+ }
+ void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) {
+ m_legacyReporter->StartTestCase( testInfo );
+ }
+ void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) {
+ m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description );
+ }
+ void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) {
+ // Not on legacy interface
+ }
+
+ bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) {
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal );
+ rb << it->message;
+ rb.setResultType( ResultWas::Info );
+ AssertionResult result = rb.build();
+ m_legacyReporter->Result( result );
+ }
+ }
+ }
+ m_legacyReporter->Result( assertionStats.assertionResult );
+ return true;
+ }
+ void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) {
+ if( sectionStats.missingAssertions )
+ m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name );
+ m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions );
+ }
+ void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) {
+ m_legacyReporter->EndTestCase
+ ( testCaseStats.testInfo,
+ testCaseStats.totals,
+ testCaseStats.stdOut,
+ testCaseStats.stdErr );
+ }
+ void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) {
+ if( testGroupStats.aborting )
+ m_legacyReporter->Aborted();
+ m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals );
+ }
+ void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) {
+ m_legacyReporter->EndTesting( testRunStats.totals );
+ }
+ void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) {
+ }
+}
+
+// #included from: catch_timer.hpp
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#endif
+
+#ifdef CATCH_PLATFORM_WINDOWS
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+namespace Catch {
+
+ namespace {
+#ifdef CATCH_PLATFORM_WINDOWS
+ uint64_t getCurrentTicks() {
+ static uint64_t hz=0, hzo=0;
+ if (!hz) {
+ QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) );
+ QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) );
+ }
+ uint64_t t;
+ QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) );
+ return ((t-hzo)*1000000)/hz;
+ }
+#else
+ uint64_t getCurrentTicks() {
+ timeval t;
+ gettimeofday(&t,CATCH_NULL);
+ return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec );
+ }
+#endif
+ }
+
+ void Timer::start() {
+ m_ticks = getCurrentTicks();
+ }
+ unsigned int Timer::getElapsedMicroseconds() const {
+ return static_cast<unsigned int>(getCurrentTicks() - m_ticks);
+ }
+ unsigned int Timer::getElapsedMilliseconds() const {
+ return static_cast<unsigned int>(getElapsedMicroseconds()/1000);
+ }
+ double Timer::getElapsedSeconds() const {
+ return getElapsedMicroseconds()/1000000.0;
+ }
+
+} // namespace Catch
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+// #included from: catch_common.hpp
+#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
+
+namespace Catch {
+
+ bool startsWith( std::string const& s, std::string const& prefix ) {
+ return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
+ }
+ bool endsWith( std::string const& s, std::string const& suffix ) {
+ return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
+ }
+ bool contains( std::string const& s, std::string const& infix ) {
+ return s.find( infix ) != std::string::npos;
+ }
+ void toLowerInPlace( std::string& s ) {
+ std::transform( s.begin(), s.end(), s.begin(), ::tolower );
+ }
+ std::string toLower( std::string const& s ) {
+ std::string lc = s;
+ toLowerInPlace( lc );
+ return lc;
+ }
+ std::string trim( std::string const& str ) {
+ static char const* whitespaceChars = "\n\r\t ";
+ std::string::size_type start = str.find_first_not_of( whitespaceChars );
+ std::string::size_type end = str.find_last_not_of( whitespaceChars );
+
+ return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
+ }
+
+ bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {
+ bool replaced = false;
+ std::size_t i = str.find( replaceThis );
+ while( i != std::string::npos ) {
+ replaced = true;
+ str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );
+ if( i < str.size()-withThis.size() )
+ i = str.find( replaceThis, i+withThis.size() );
+ else
+ i = std::string::npos;
+ }
+ return replaced;
+ }
+
+ pluralise::pluralise( std::size_t count, std::string const& label )
+ : m_count( count ),
+ m_label( label )
+ {}
+
+ std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
+ os << pluraliser.m_count << " " << pluraliser.m_label;
+ if( pluraliser.m_count != 1 )
+ os << "s";
+ return os;
+ }
+
+ SourceLineInfo::SourceLineInfo() : line( 0 ){}
+ SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
+ : file( _file ),
+ line( _line )
+ {}
+ SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
+ : file( other.file ),
+ line( other.line )
+ {}
+ bool SourceLineInfo::empty() const {
+ return file.empty();
+ }
+ bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
+ return line == other.line && file == other.file;
+ }
+ bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const {
+ return line < other.line || ( line == other.line && file < other.file );
+ }
+
+ void seedRng( IConfig const& config ) {
+ if( config.rngSeed() != 0 )
+ std::srand( config.rngSeed() );
+ }
+ unsigned int rngSeed() {
+ return getCurrentContext().getConfig()->rngSeed();
+ }
+
+ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
+#ifndef __GNUG__
+ os << info.file << "(" << info.line << ")";
+#else
+ os << info.file << ":" << info.line;
+#endif
+ return os;
+ }
+
+ void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
+ std::ostringstream oss;
+ oss << locationInfo << ": Internal Catch error: '" << message << "'";
+ if( alwaysTrue() )
+ throw std::logic_error( oss.str() );
+ }
+}
+
+// #included from: catch_section.hpp
+#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
+
+namespace Catch {
+
+ SectionInfo::SectionInfo
+ ( SourceLineInfo const& _lineInfo,
+ std::string const& _name,
+ std::string const& _description )
+ : name( _name ),
+ description( _description ),
+ lineInfo( _lineInfo )
+ {}
+
+ Section::Section( SectionInfo const& info )
+ : m_info( info ),
+ m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )
+ {
+ m_timer.start();
+ }
+
+ Section::~Section() {
+ if( m_sectionIncluded ) {
+ SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
+ if( std::uncaught_exception() )
+ getResultCapture().sectionEndedEarly( endInfo );
+ else
+ getResultCapture().sectionEnded( endInfo );
+ }
+ }
+
+ // This indicates whether the section should be executed or not
+ Section::operator bool() const {
+ return m_sectionIncluded;
+ }
+
+} // end namespace Catch
+
+// #included from: catch_debugger.hpp
+#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
+
+#include <iostream>
+
+#ifdef CATCH_PLATFORM_MAC
+
+ #include <assert.h>
+ #include <stdbool.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <sys/sysctl.h>
+
+ namespace Catch{
+
+ // The following function is taken directly from the following technical note:
+ // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html
+
+ // Returns true if the current process is being debugged (either
+ // running under the debugger or has a debugger attached post facto).
+ bool isDebuggerActive(){
+
+ int mib[4];
+ struct kinfo_proc info;
+ size_t size;
+
+ // Initialize the flags so that, if sysctl fails for some bizarre
+ // reason, we get a predictable result.
+
+ info.kp_proc.p_flag = 0;
+
+ // Initialize mib, which tells sysctl the info we want, in this case
+ // we're looking for information about a specific process ID.
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = getpid();
+
+ // Call sysctl.
+
+ size = sizeof(info);
+ if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) {
+ Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl;
+ return false;
+ }
+
+ // We're being debugged if the P_TRACED flag is set.
+
+ return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
+ }
+ } // namespace Catch
+
+#elif defined(_MSC_VER)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#elif defined(__MINGW32__)
+ extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
+ namespace Catch {
+ bool isDebuggerActive() {
+ return IsDebuggerPresent() != 0;
+ }
+ }
+#else
+ namespace Catch {
+ inline bool isDebuggerActive() { return false; }
+ }
+#endif // Platform
+
+#ifdef CATCH_PLATFORM_WINDOWS
+ extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ ::OutputDebugStringA( text.c_str() );
+ }
+ }
+#else
+ namespace Catch {
+ void writeToDebugConsole( std::string const& text ) {
+ // !TBD: Need a version for Mac/ XCode and other IDEs
+ Catch::cout() << text;
+ }
+ }
+#endif // Platform
+
+// #included from: catch_tostring.hpp
+#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED
+
+namespace Catch {
+
+namespace Detail {
+
+ const std::string unprintableString = "{?}";
+
+ namespace {
+ const int hexThreshold = 255;
+
+ struct Endianness {
+ enum Arch { Big, Little };
+
+ static Arch which() {
+ union _{
+ int asInt;
+ char asChar[sizeof (int)];
+ } u;
+
+ u.asInt = 1;
+ return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little;
+ }
+ };
+ }
+
+ std::string rawMemoryToString( const void *object, std::size_t size )
+ {
+ // Reverse order for little endian architectures
+ int i = 0, end = static_cast<int>( size ), inc = 1;
+ if( Endianness::which() == Endianness::Little ) {
+ i = end-1;
+ end = inc = -1;
+ }
+
+ unsigned char const *bytes = static_cast<unsigned char const *>(object);
+ std::ostringstream os;
+ os << "0x" << std::setfill('0') << std::hex;
+ for( ; i != end; i += inc )
+ os << std::setw(2) << static_cast<unsigned>(bytes[i]);
+ return os.str();
+ }
+}
+
+std::string toString( std::string const& value ) {
+ std::string s = value;
+ if( getCurrentContext().getConfig()->showInvisibles() ) {
+ for(size_t i = 0; i < s.size(); ++i ) {
+ std::string subs;
+ switch( s[i] ) {
+ case '\n': subs = "\\n"; break;
+ case '\t': subs = "\\t"; break;
+ default: break;
+ }
+ if( !subs.empty() ) {
+ s = s.substr( 0, i ) + subs + s.substr( i+1 );
+ ++i;
+ }
+ }
+ }
+ return "\"" + s + "\"";
+}
+std::string toString( std::wstring const& value ) {
+
+ std::string s;
+ s.reserve( value.size() );
+ for(size_t i = 0; i < value.size(); ++i )
+ s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?';
+ return Catch::toString( s );
+}
+
+std::string toString( const char* const value ) {
+ return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" );
+}
+
+std::string toString( char* const value ) {
+ return Catch::toString( static_cast<const char*>( value ) );
+}
+
+std::string toString( const wchar_t* const value )
+{
+ return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" );
+}
+
+std::string toString( wchar_t* const value )
+{
+ return Catch::toString( static_cast<const wchar_t*>( value ) );
+}
+
+std::string toString( int value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+
+std::string toString( unsigned long value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+
+std::string toString( unsigned int value ) {
+ return Catch::toString( static_cast<unsigned long>( value ) );
+}
+
+template<typename T>
+std::string fpToString( T value, int precision ) {
+ std::ostringstream oss;
+ oss << std::setprecision( precision )
+ << std::fixed
+ << value;
+ std::string d = oss.str();
+ std::size_t i = d.find_last_not_of( '0' );
+ if( i != std::string::npos && i != d.size()-1 ) {
+ if( d[i] == '.' )
+ i++;
+ d = d.substr( 0, i+1 );
+ }
+ return d;
+}
+
+std::string toString( const double value ) {
+ return fpToString( value, 10 );
+}
+std::string toString( const float value ) {
+ return fpToString( value, 5 ) + "f";
+}
+
+std::string toString( bool value ) {
+ return value ? "true" : "false";
+}
+
+std::string toString( char value ) {
+ return value < ' '
+ ? toString( static_cast<unsigned int>( value ) )
+ : Detail::makeString( value );
+}
+
+std::string toString( signed char value ) {
+ return toString( static_cast<char>( value ) );
+}
+
+std::string toString( unsigned char value ) {
+ return toString( static_cast<char>( value ) );
+}
+
+#ifdef CATCH_CONFIG_CPP11_LONG_LONG
+std::string toString( long long value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+std::string toString( unsigned long long value ) {
+ std::ostringstream oss;
+ oss << value;
+ if( value > Detail::hexThreshold )
+ oss << " (0x" << std::hex << value << ")";
+ return oss.str();
+}
+#endif
+
+#ifdef CATCH_CONFIG_CPP11_NULLPTR
+std::string toString( std::nullptr_t ) {
+ return "nullptr";
+}
+#endif
+
+#ifdef __OBJC__
+ std::string toString( NSString const * const& nsstring ) {
+ if( !nsstring )
+ return "nil";
+ return "@" + toString([nsstring UTF8String]);
+ }
+ std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) {
+ if( !nsstring )
+ return "nil";
+ return "@" + toString([nsstring UTF8String]);
+ }
+ std::string toString( NSObject* const& nsObject ) {
+ return toString( [nsObject description] );
+ }
+#endif
+
+} // end namespace Catch
+
+// #included from: catch_result_builder.hpp
+#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
+
+namespace Catch {
+
+ std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) {
+ return secondArg.empty() || secondArg == "\"\""
+ ? capturedExpression
+ : capturedExpression + ", " + secondArg;
+ }
+ ResultBuilder::ResultBuilder( char const* macroName,
+ SourceLineInfo const& lineInfo,
+ char const* capturedExpression,
+ ResultDisposition::Flags resultDisposition,
+ char const* secondArg )
+ : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ),
+ m_shouldDebugBreak( false ),
+ m_shouldThrow( false )
+ {}
+
+ ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) {
+ m_data.resultType = result;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setResultType( bool result ) {
+ m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) {
+ m_exprComponents.lhs = lhs;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) {
+ m_exprComponents.rhs = rhs;
+ return *this;
+ }
+ ResultBuilder& ResultBuilder::setOp( std::string const& op ) {
+ m_exprComponents.op = op;
+ return *this;
+ }
+
+ void ResultBuilder::endExpression() {
+ m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition );
+ captureExpression();
+ }
+
+ void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) {
+ m_assertionInfo.resultDisposition = resultDisposition;
+ m_stream.oss << Catch::translateActiveException();
+ captureResult( ResultWas::ThrewException );
+ }
+
+ void ResultBuilder::captureResult( ResultWas::OfType resultType ) {
+ setResultType( resultType );
+ captureExpression();
+ }
+ void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) {
+ if( expectedMessage.empty() )
+ captureExpectedException( Matchers::Impl::Generic::AllOf<std::string>() );
+ else
+ captureExpectedException( Matchers::Equals( expectedMessage ) );
+ }
+
+ void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher<std::string> const& matcher ) {
+
+ assert( m_exprComponents.testFalse == false );
+ AssertionResultData data = m_data;
+ data.resultType = ResultWas::Ok;
+ data.reconstructedExpression = m_assertionInfo.capturedExpression;
+
+ std::string actualMessage = Catch::translateActiveException();
+ if( !matcher.match( actualMessage ) ) {
+ data.resultType = ResultWas::ExpressionFailed;
+ data.reconstructedExpression = actualMessage;
+ }
+ AssertionResult result( m_assertionInfo, data );
+ handleResult( result );
+ }
+
+ void ResultBuilder::captureExpression() {
+ AssertionResult result = build();
+ handleResult( result );
+ }
+ void ResultBuilder::handleResult( AssertionResult const& result )
+ {
+ getResultCapture().assertionEnded( result );
+
+ if( !result.isOk() ) {
+ if( getCurrentContext().getConfig()->shouldDebugBreak() )
+ m_shouldDebugBreak = true;
+ if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) )
+ m_shouldThrow = true;
+ }
+ }
+ void ResultBuilder::react() {
+ if( m_shouldThrow )
+ throw Catch::TestFailureException();
+ }
+
+ bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; }
+ bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); }
+
+ AssertionResult ResultBuilder::build() const
+ {
+ assert( m_data.resultType != ResultWas::Unknown );
+
+ AssertionResultData data = m_data;
+
+ // Flip bool results if testFalse is set
+ if( m_exprComponents.testFalse ) {
+ if( data.resultType == ResultWas::Ok )
+ data.resultType = ResultWas::ExpressionFailed;
+ else if( data.resultType == ResultWas::ExpressionFailed )
+ data.resultType = ResultWas::Ok;
+ }
+
+ data.message = m_stream.oss.str();
+ data.reconstructedExpression = reconstructExpression();
+ if( m_exprComponents.testFalse ) {
+ if( m_exprComponents.op == "" )
+ data.reconstructedExpression = "!" + data.reconstructedExpression;
+ else
+ data.reconstructedExpression = "!(" + data.reconstructedExpression + ")";
+ }
+ return AssertionResult( m_assertionInfo, data );
+ }
+ std::string ResultBuilder::reconstructExpression() const {
+ if( m_exprComponents.op == "" )
+ return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs;
+ else if( m_exprComponents.op == "matches" )
+ return m_exprComponents.lhs + " " + m_exprComponents.rhs;
+ else if( m_exprComponents.op != "!" ) {
+ if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 &&
+ m_exprComponents.lhs.find("\n") == std::string::npos &&
+ m_exprComponents.rhs.find("\n") == std::string::npos )
+ return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs;
+ else
+ return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs;
+ }
+ else
+ return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}";
+ }
+
+} // end namespace Catch
+
+// #included from: catch_tag_alias_registry.hpp
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED
+
+// #included from: catch_tag_alias_registry.h
+#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED
+
+#include <map>
+
+namespace Catch {
+
+ class TagAliasRegistry : public ITagAliasRegistry {
+ public:
+ virtual ~TagAliasRegistry();
+ virtual Option<TagAlias> find( std::string const& alias ) const;
+ virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const;
+ void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo );
+ static TagAliasRegistry& get();
+
+ private:
+ std::map<std::string, TagAlias> m_registry;
+ };
+
+} // end namespace Catch
+
+#include <map>
+#include <iostream>
+
+namespace Catch {
+
+ TagAliasRegistry::~TagAliasRegistry() {}
+
+ Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const {
+ std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias );
+ if( it != m_registry.end() )
+ return it->second;
+ else
+ return Option<TagAlias>();
+ }
+
+ std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {
+ std::string expandedTestSpec = unexpandedTestSpec;
+ for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end();
+ it != itEnd;
+ ++it ) {
+ std::size_t pos = expandedTestSpec.find( it->first );
+ if( pos != std::string::npos ) {
+ expandedTestSpec = expandedTestSpec.substr( 0, pos ) +
+ it->second.tag +
+ expandedTestSpec.substr( pos + it->first.size() );
+ }
+ }
+ return expandedTestSpec;
+ }
+
+ void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+
+ if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) {
+ std::ostringstream oss;
+ oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo;
+ throw std::domain_error( oss.str().c_str() );
+ }
+ if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) {
+ std::ostringstream oss;
+ oss << "error: tag alias, \"" << alias << "\" already registered.\n"
+ << "\tFirst seen at " << find(alias)->lineInfo << "\n"
+ << "\tRedefined at " << lineInfo;
+ throw std::domain_error( oss.str().c_str() );
+ }
+ }
+
+ TagAliasRegistry& TagAliasRegistry::get() {
+ static TagAliasRegistry instance;
+ return instance;
+
+ }
+
+ ITagAliasRegistry::~ITagAliasRegistry() {}
+ ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); }
+
+ RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) {
+ try {
+ TagAliasRegistry::get().add( alias, tag, lineInfo );
+ }
+ catch( std::exception& ex ) {
+ Colour colourGuard( Colour::Red );
+ Catch::cerr() << ex.what() << std::endl;
+ exit(1);
+ }
+ }
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_multi.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
+
+namespace Catch {
+
+class MultipleReporters : public SharedImpl<IStreamingReporter> {
+ typedef std::vector<Ptr<IStreamingReporter> > Reporters;
+ Reporters m_reporters;
+
+public:
+ void add( Ptr<IStreamingReporter> const& reporter ) {
+ m_reporters.push_back( reporter );
+ }
+
+public: // IStreamingReporter
+
+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+ return m_reporters[0]->getPreferences();
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->noMatchingTestCases( spec );
+ }
+
+ virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testRunStarting( testRunInfo );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testGroupStarting( groupInfo );
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testCaseStarting( testInfo );
+ }
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->sectionStarting( sectionInfo );
+ }
+
+ virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->assertionStarting( assertionInfo );
+ }
+
+ // The return value indicates if the messages buffer should be cleared:
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+ bool clearBuffer = false;
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ clearBuffer |= (*it)->assertionEnded( assertionStats );
+ return clearBuffer;
+ }
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->sectionEnded( sectionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testCaseEnded( testCaseStats );
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testGroupEnded( testGroupStats );
+ }
+
+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->testRunEnded( testRunStats );
+ }
+
+ virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+ for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
+ it != itEnd;
+ ++it )
+ (*it)->skipTest( testInfo );
+ }
+};
+
+Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
+ Ptr<IStreamingReporter> resultingReporter;
+
+ if( existingReporter ) {
+ MultipleReporters* multi = dynamic_cast<MultipleReporters*>( existingReporter.get() );
+ if( !multi ) {
+ multi = new MultipleReporters;
+ resultingReporter = Ptr<IStreamingReporter>( multi );
+ if( existingReporter )
+ multi->add( existingReporter );
+ }
+ else
+ resultingReporter = existingReporter;
+ multi->add( additionalReporter );
+ }
+ else
+ resultingReporter = additionalReporter;
+
+ return resultingReporter;
+}
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_xml.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
+
+// #included from: catch_reporter_bases.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
+
+#include <cstring>
+
+namespace Catch {
+
+ struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
+
+ StreamingReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = false;
+ }
+
+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+ return m_reporterPrefs;
+ }
+
+ virtual ~StreamingReporterBase() CATCH_OVERRIDE;
+
+ virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
+
+ virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
+ currentTestRunInfo = _testRunInfo;
+ }
+ virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
+ currentGroupInfo = _groupInfo;
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
+ currentTestCaseInfo = _testInfo;
+ }
+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
+ m_sectionStack.push_back( _sectionInfo );
+ }
+
+ virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
+ m_sectionStack.pop_back();
+ }
+ virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
+ currentTestCaseInfo.reset();
+ }
+ virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
+ currentGroupInfo.reset();
+ }
+ virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
+ currentTestCaseInfo.reset();
+ currentGroupInfo.reset();
+ currentTestRunInfo.reset();
+ }
+
+ virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
+ // Don't do anything with this by default.
+ // It can optionally be overridden in the derived class.
+ }
+
+ Ptr<IConfig const> m_config;
+ std::ostream& stream;
+
+ LazyStat<TestRunInfo> currentTestRunInfo;
+ LazyStat<GroupInfo> currentGroupInfo;
+ LazyStat<TestCaseInfo> currentTestCaseInfo;
+
+ std::vector<SectionInfo> m_sectionStack;
+ ReporterPreferences m_reporterPrefs;
+ };
+
+ struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
+ template<typename T, typename ChildNodeT>
+ struct Node : SharedImpl<> {
+ explicit Node( T const& _value ) : value( _value ) {}
+ virtual ~Node() {}
+
+ typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
+ T value;
+ ChildNodes children;
+ };
+ struct SectionNode : SharedImpl<> {
+ explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
+ virtual ~SectionNode();
+
+ bool operator == ( SectionNode const& other ) const {
+ return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
+ }
+ bool operator == ( Ptr<SectionNode> const& other ) const {
+ return operator==( *other );
+ }
+
+ SectionStats stats;
+ typedef std::vector<Ptr<SectionNode> > ChildSections;
+ typedef std::vector<AssertionStats> Assertions;
+ ChildSections childSections;
+ Assertions assertions;
+ std::string stdOut;
+ std::string stdErr;
+ };
+
+ struct BySectionInfo {
+ BySectionInfo( SectionInfo const& other ) : m_other( other ) {}
+ BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}
+ bool operator() ( Ptr<SectionNode> const& node ) const {
+ return node->stats.sectionInfo.lineInfo == m_other.lineInfo;
+ }
+ private:
+ void operator=( BySectionInfo const& );
+ SectionInfo const& m_other;
+ };
+
+ typedef Node<TestCaseStats, SectionNode> TestCaseNode;
+ typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
+ typedef Node<TestRunStats, TestGroupNode> TestRunNode;
+
+ CumulativeReporterBase( ReporterConfig const& _config )
+ : m_config( _config.fullConfig() ),
+ stream( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = false;
+ }
+ ~CumulativeReporterBase();
+
+ virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
+ return m_reporterPrefs;
+ }
+
+ virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
+ virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
+
+ virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+ SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
+ Ptr<SectionNode> node;
+ if( m_sectionStack.empty() ) {
+ if( !m_rootSection )
+ m_rootSection = new SectionNode( incompleteStats );
+ node = m_rootSection;
+ }
+ else {
+ SectionNode& parentNode = *m_sectionStack.back();
+ SectionNode::ChildSections::const_iterator it =
+ std::find_if( parentNode.childSections.begin(),
+ parentNode.childSections.end(),
+ BySectionInfo( sectionInfo ) );
+ if( it == parentNode.childSections.end() ) {
+ node = new SectionNode( incompleteStats );
+ parentNode.childSections.push_back( node );
+ }
+ else
+ node = *it;
+ }
+ m_sectionStack.push_back( node );
+ m_deepestSection = node;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) {
+ assert( !m_sectionStack.empty() );
+ SectionNode& sectionNode = *m_sectionStack.back();
+ sectionNode.assertions.push_back( assertionStats );
+ return true;
+ }
+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+ assert( !m_sectionStack.empty() );
+ SectionNode& node = *m_sectionStack.back();
+ node.stats = sectionStats;
+ m_sectionStack.pop_back();
+ }
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
+ assert( m_sectionStack.size() == 0 );
+ node->children.push_back( m_rootSection );
+ m_testCases.push_back( node );
+ m_rootSection.reset();
+
+ assert( m_deepestSection );
+ m_deepestSection->stdOut = testCaseStats.stdOut;
+ m_deepestSection->stdErr = testCaseStats.stdErr;
+ }
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
+ node->children.swap( m_testCases );
+ m_testGroups.push_back( node );
+ }
+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+ Ptr<TestRunNode> node = new TestRunNode( testRunStats );
+ node->children.swap( m_testGroups );
+ m_testRuns.push_back( node );
+ testRunEndedCumulative();
+ }
+ virtual void testRunEndedCumulative() = 0;
+
+ virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
+
+ Ptr<IConfig const> m_config;
+ std::ostream& stream;
+ std::vector<AssertionStats> m_assertions;
+ std::vector<std::vector<Ptr<SectionNode> > > m_sections;
+ std::vector<Ptr<TestCaseNode> > m_testCases;
+ std::vector<Ptr<TestGroupNode> > m_testGroups;
+
+ std::vector<Ptr<TestRunNode> > m_testRuns;
+
+ Ptr<SectionNode> m_rootSection;
+ Ptr<SectionNode> m_deepestSection;
+ std::vector<Ptr<SectionNode> > m_sectionStack;
+ ReporterPreferences m_reporterPrefs;
+
+ };
+
+ template<char C>
+ char const* getLineOfChars() {
+ static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};
+ if( !*line ) {
+ memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );
+ line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;
+ }
+ return line;
+ }
+
+ struct TestEventListenerBase : StreamingReporterBase {
+ TestEventListenerBase( ReporterConfig const& _config )
+ : StreamingReporterBase( _config )
+ {}
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
+ virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE {
+ return false;
+ }
+ };
+
+} // end namespace Catch
+
+// #included from: ../internal/catch_reporter_registrars.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
+
+namespace Catch {
+
+ template<typename T>
+ class LegacyReporterRegistrar {
+
+ class ReporterFactory : public IReporterFactory {
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new LegacyReporterAdapter( new T( config ) );
+ }
+
+ virtual std::string getDescription() const {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ LegacyReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+ }
+ };
+
+ template<typename T>
+ class ReporterRegistrar {
+
+ class ReporterFactory : public SharedImpl<IReporterFactory> {
+
+ // *** Please Note ***:
+ // - If you end up here looking at a compiler error because it's trying to register
+ // your custom reporter class be aware that the native reporter interface has changed
+ // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via
+ // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter.
+ // However please consider updating to the new interface as the old one is now
+ // deprecated and will probably be removed quite soon!
+ // Please contact me via github if you have any questions at all about this.
+ // In fact, ideally, please contact me anyway to let me know you've hit this - as I have
+ // no idea who is actually using custom reporters at all (possibly no-one!).
+ // The new interface is designed to minimise exposure to interface changes in the future.
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new T( config );
+ }
+
+ virtual std::string getDescription() const {
+ return T::getDescription();
+ }
+ };
+
+ public:
+
+ ReporterRegistrar( std::string const& name ) {
+ getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
+ }
+ };
+
+ template<typename T>
+ class ListenerRegistrar {
+
+ class ListenerFactory : public SharedImpl<IReporterFactory> {
+
+ virtual IStreamingReporter* create( ReporterConfig const& config ) const {
+ return new T( config );
+ }
+ virtual std::string getDescription() const {
+ return "";
+ }
+ };
+
+ public:
+
+ ListenerRegistrar() {
+ getMutableRegistryHub().registerListener( new ListenerFactory() );
+ }
+ };
+}
+
+#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
+ namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+
+#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
+ namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
+
+#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
+ namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
+
+// #included from: ../internal/catch_xmlwriter.hpp
+#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <iomanip>
+
+namespace Catch {
+
+ class XmlEncode {
+ public:
+ enum ForWhat { ForTextNodes, ForAttributes };
+
+ XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
+ : m_str( str ),
+ m_forWhat( forWhat )
+ {}
+
+ void encodeTo( std::ostream& os ) const {
+
+ // Apostrophe escaping not necessary if we always use " to write attributes
+ // (see: http://www.w3.org/TR/xml/#syntax)
+
+ for( std::size_t i = 0; i < m_str.size(); ++ i ) {
+ char c = m_str[i];
+ switch( c ) {
+ case '<': os << "&lt;"; break;
+ case '&': os << "&amp;"; break;
+
+ case '>':
+ // See: http://www.w3.org/TR/xml/#syntax
+ if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
+ os << "&gt;";
+ else
+ os << c;
+ break;
+
+ case '\"':
+ if( m_forWhat == ForAttributes )
+ os << "&quot;";
+ else
+ os << c;
+ break;
+
+ default:
+ // Escape control chars - based on contribution by @espenalb in PR #465
+ if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
+ os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
+ else
+ os << c;
+ }
+ }
+ }
+
+ friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
+ xmlEncode.encodeTo( os );
+ return os;
+ }
+
+ private:
+ std::string m_str;
+ ForWhat m_forWhat;
+ };
+
+ class XmlWriter {
+ public:
+
+ class ScopedElement {
+ public:
+ ScopedElement( XmlWriter* writer )
+ : m_writer( writer )
+ {}
+
+ ScopedElement( ScopedElement const& other )
+ : m_writer( other.m_writer ){
+ other.m_writer = CATCH_NULL;
+ }
+
+ ~ScopedElement() {
+ if( m_writer )
+ m_writer->endElement();
+ }
+
+ ScopedElement& writeText( std::string const& text, bool indent = true ) {
+ m_writer->writeText( text, indent );
+ return *this;
+ }
+
+ template<typename T>
+ ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
+ m_writer->writeAttribute( name, attribute );
+ return *this;
+ }
+
+ private:
+ mutable XmlWriter* m_writer;
+ };
+
+ XmlWriter()
+ : m_tagIsOpen( false ),
+ m_needsNewline( false ),
+ m_os( &Catch::cout() )
+ {}
+
+ XmlWriter( std::ostream& os )
+ : m_tagIsOpen( false ),
+ m_needsNewline( false ),
+ m_os( &os )
+ {}
+
+ ~XmlWriter() {
+ while( !m_tags.empty() )
+ endElement();
+ }
+
+ XmlWriter& startElement( std::string const& name ) {
+ ensureTagClosed();
+ newlineIfNecessary();
+ stream() << m_indent << "<" << name;
+ m_tags.push_back( name );
+ m_indent += " ";
+ m_tagIsOpen = true;
+ return *this;
+ }
+
+ ScopedElement scopedElement( std::string const& name ) {
+ ScopedElement scoped( this );
+ startElement( name );
+ return scoped;
+ }
+
+ XmlWriter& endElement() {
+ newlineIfNecessary();
+ m_indent = m_indent.substr( 0, m_indent.size()-2 );
+ if( m_tagIsOpen ) {
+ stream() << "/>\n";
+ m_tagIsOpen = false;
+ }
+ else {
+ stream() << m_indent << "</" << m_tags.back() << ">\n";
+ }
+ m_tags.pop_back();
+ return *this;
+ }
+
+ XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
+ if( !name.empty() && !attribute.empty() )
+ stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
+ return *this;
+ }
+
+ XmlWriter& writeAttribute( std::string const& name, bool attribute ) {
+ stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\"";
+ return *this;
+ }
+
+ template<typename T>
+ XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
+ std::ostringstream oss;
+ oss << attribute;
+ return writeAttribute( name, oss.str() );
+ }
+
+ XmlWriter& writeText( std::string const& text, bool indent = true ) {
+ if( !text.empty() ){
+ bool tagWasOpen = m_tagIsOpen;
+ ensureTagClosed();
+ if( tagWasOpen && indent )
+ stream() << m_indent;
+ stream() << XmlEncode( text );
+ m_needsNewline = true;
+ }
+ return *this;
+ }
+
+ XmlWriter& writeComment( std::string const& text ) {
+ ensureTagClosed();
+ stream() << m_indent << "<!--" << text << "-->";
+ m_needsNewline = true;
+ return *this;
+ }
+
+ XmlWriter& writeBlankLine() {
+ ensureTagClosed();
+ stream() << "\n";
+ return *this;
+ }
+
+ void setStream( std::ostream& os ) {
+ m_os = &os;
+ }
+
+ private:
+ XmlWriter( XmlWriter const& );
+ void operator=( XmlWriter const& );
+
+ std::ostream& stream() {
+ return *m_os;
+ }
+
+ void ensureTagClosed() {
+ if( m_tagIsOpen ) {
+ stream() << ">\n";
+ m_tagIsOpen = false;
+ }
+ }
+
+ void newlineIfNecessary() {
+ if( m_needsNewline ) {
+ stream() << "\n";
+ m_needsNewline = false;
+ }
+ }
+
+ bool m_tagIsOpen;
+ bool m_needsNewline;
+ std::vector<std::string> m_tags;
+ std::string m_indent;
+ std::ostream* m_os;
+ };
+
+}
+// #included from: catch_reenable_warnings.h
+
+#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED
+
+#ifdef __clang__
+# ifdef __ICC // icpc defines the __clang__ macro
+# pragma warning(pop)
+# else
+# pragma clang diagnostic pop
+# endif
+#elif defined __GNUC__
+# pragma GCC diagnostic pop
+#endif
+
+
+namespace Catch {
+ class XmlReporter : public StreamingReporterBase {
+ public:
+ XmlReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_sectionDepth( 0 )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = true;
+ }
+
+ virtual ~XmlReporter() CATCH_OVERRIDE;
+
+ static std::string getDescription() {
+ return "Reports test results as an XML document";
+ }
+
+ public: // StreamingReporterBase
+
+ virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
+ StreamingReporterBase::noMatchingTestCases( s );
+ }
+
+ virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::testRunStarting( testInfo );
+ m_xml.setStream( stream );
+ m_xml.startElement( "Catch" );
+ if( !m_config->name().empty() )
+ m_xml.writeAttribute( "name", m_config->name() );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::testGroupStarting( groupInfo );
+ m_xml.startElement( "Group" )
+ .writeAttribute( "name", groupInfo.name );
+ }
+
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::testCaseStarting(testInfo);
+ m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ m_testCaseTimer.start();
+ }
+
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
+ StreamingReporterBase::sectionStarting( sectionInfo );
+ if( m_sectionDepth++ > 0 ) {
+ m_xml.startElement( "Section" )
+ .writeAttribute( "name", trim( sectionInfo.name ) )
+ .writeAttribute( "description", sectionInfo.description );
+ }
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+ const AssertionResult& assertionResult = assertionStats.assertionResult;
+
+ // Print any info messages in <Info> tags.
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ m_xml.scopedElement( "Info" )
+ .writeText( it->message );
+ } else if ( it->type == ResultWas::Warning ) {
+ m_xml.scopedElement( "Warning" )
+ .writeText( it->message );
+ }
+ }
+ }
+
+ // Drop out if result was successful but we're not printing them.
+ if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
+ return true;
+
+ // Print the expression if there is one.
+ if( assertionResult.hasExpression() ) {
+ m_xml.startElement( "Expression" )
+ .writeAttribute( "success", assertionResult.succeeded() )
+ .writeAttribute( "type", assertionResult.getTestMacroName() )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line );
+
+ m_xml.scopedElement( "Original" )
+ .writeText( assertionResult.getExpression() );
+ m_xml.scopedElement( "Expanded" )
+ .writeText( assertionResult.getExpandedExpression() );
+ }
+
+ // And... Print a result applicable to each result type.
+ switch( assertionResult.getResultType() ) {
+ case ResultWas::ThrewException:
+ m_xml.scopedElement( "Exception" )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::FatalErrorCondition:
+ m_xml.scopedElement( "Fatal Error Condition" )
+ .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+ .writeAttribute( "line", assertionResult.getSourceInfo().line )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::Info:
+ m_xml.scopedElement( "Info" )
+ .writeText( assertionResult.getMessage() );
+ break;
+ case ResultWas::Warning:
+ // Warning will already have been written
+ break;
+ case ResultWas::ExplicitFailure:
+ m_xml.scopedElement( "Failure" )
+ .writeText( assertionResult.getMessage() );
+ break;
+ default:
+ break;
+ }
+
+ if( assertionResult.hasExpression() )
+ m_xml.endElement();
+
+ return true;
+ }
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::sectionEnded( sectionStats );
+ if( --m_sectionDepth > 0 ) {
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
+ e.writeAttribute( "successes", sectionStats.assertions.passed );
+ e.writeAttribute( "failures", sectionStats.assertions.failed );
+ e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
+
+ m_xml.endElement();
+ }
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testCaseEnded( testCaseStats );
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
+ e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
+
+ m_xml.endElement();
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testGroupEnded( testGroupStats );
+ // TODO: Check testGroupStats.aborting and act accordingly.
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
+ .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testRunEnded( testRunStats );
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testRunStats.totals.assertions.passed )
+ .writeAttribute( "failures", testRunStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ private:
+ Timer m_testCaseTimer;
+ XmlWriter m_xml;
+ int m_sectionDepth;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_junit.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
+
+#include <assert.h>
+
+namespace Catch {
+
+ class JunitReporter : public CumulativeReporterBase {
+ public:
+ JunitReporter( ReporterConfig const& _config )
+ : CumulativeReporterBase( _config ),
+ xml( _config.stream() )
+ {
+ m_reporterPrefs.shouldRedirectStdOut = true;
+ }
+
+ virtual ~JunitReporter() CATCH_OVERRIDE;
+
+ static std::string getDescription() {
+ return "Reports test results in an XML format that looks like Ant's junitreport target";
+ }
+
+ virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
+
+ virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
+ CumulativeReporterBase::testRunStarting( runInfo );
+ xml.startElement( "testsuites" );
+ }
+
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
+ suiteTimer.start();
+ stdOutForSuite.str("");
+ stdErrForSuite.str("");
+ unexpectedExceptions = 0;
+ CumulativeReporterBase::testGroupStarting( groupInfo );
+ }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
+ if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
+ unexpectedExceptions++;
+ return CumulativeReporterBase::assertionEnded( assertionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
+ stdOutForSuite << testCaseStats.stdOut;
+ stdErrForSuite << testCaseStats.stdErr;
+ CumulativeReporterBase::testCaseEnded( testCaseStats );
+ }
+
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
+ double suiteTime = suiteTimer.getElapsedSeconds();
+ CumulativeReporterBase::testGroupEnded( testGroupStats );
+ writeGroup( *m_testGroups.back(), suiteTime );
+ }
+
+ virtual void testRunEndedCumulative() CATCH_OVERRIDE {
+ xml.endElement();
+ }
+
+ void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
+ TestGroupStats const& stats = groupNode.value;
+ xml.writeAttribute( "name", stats.groupInfo.name );
+ xml.writeAttribute( "errors", unexpectedExceptions );
+ xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions );
+ xml.writeAttribute( "tests", stats.totals.assertions.total() );
+ xml.writeAttribute( "hostname", "tbd" ); // !TBD
+ if( m_config->showDurations() == ShowDurations::Never )
+ xml.writeAttribute( "time", "" );
+ else
+ xml.writeAttribute( "time", suiteTime );
+ xml.writeAttribute( "timestamp", "tbd" ); // !TBD
+
+ // Write test cases
+ for( TestGroupNode::ChildNodes::const_iterator
+ it = groupNode.children.begin(), itEnd = groupNode.children.end();
+ it != itEnd;
+ ++it )
+ writeTestCase( **it );
+
+ xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
+ xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
+ }
+
+ void writeTestCase( TestCaseNode const& testCaseNode ) {
+ TestCaseStats const& stats = testCaseNode.value;
+
+ // All test cases have exactly one section - which represents the
+ // test case itself. That section may have 0-n nested sections
+ assert( testCaseNode.children.size() == 1 );
+ SectionNode const& rootSection = *testCaseNode.children.front();
+
+ std::string className = stats.testInfo.className;
+
+ if( className.empty() ) {
+ if( rootSection.childSections.empty() )
+ className = "global";
+ }
+ writeSection( className, "", rootSection );
+ }
+
+ void writeSection( std::string const& className,
+ std::string const& rootName,
+ SectionNode const& sectionNode ) {
+ std::string name = trim( sectionNode.stats.sectionInfo.name );
+ if( !rootName.empty() )
+ name = rootName + "/" + name;
+
+ if( !sectionNode.assertions.empty() ||
+ !sectionNode.stdOut.empty() ||
+ !sectionNode.stdErr.empty() ) {
+ XmlWriter::ScopedElement e = xml.scopedElement( "testcase" );
+ if( className.empty() ) {
+ xml.writeAttribute( "classname", name );
+ xml.writeAttribute( "name", "root" );
+ }
+ else {
+ xml.writeAttribute( "classname", className );
+ xml.writeAttribute( "name", name );
+ }
+ xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) );
+
+ writeAssertions( sectionNode );
+
+ if( !sectionNode.stdOut.empty() )
+ xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false );
+ if( !sectionNode.stdErr.empty() )
+ xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false );
+ }
+ for( SectionNode::ChildSections::const_iterator
+ it = sectionNode.childSections.begin(),
+ itEnd = sectionNode.childSections.end();
+ it != itEnd;
+ ++it )
+ if( className.empty() )
+ writeSection( name, "", **it );
+ else
+ writeSection( className, name, **it );
+ }
+
+ void writeAssertions( SectionNode const& sectionNode ) {
+ for( SectionNode::Assertions::const_iterator
+ it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end();
+ it != itEnd;
+ ++it )
+ writeAssertion( *it );
+ }
+ void writeAssertion( AssertionStats const& stats ) {
+ AssertionResult const& result = stats.assertionResult;
+ if( !result.isOk() ) {
+ std::string elementName;
+ switch( result.getResultType() ) {
+ case ResultWas::ThrewException:
+ case ResultWas::FatalErrorCondition:
+ elementName = "error";
+ break;
+ case ResultWas::ExplicitFailure:
+ elementName = "failure";
+ break;
+ case ResultWas::ExpressionFailed:
+ elementName = "failure";
+ break;
+ case ResultWas::DidntThrowException:
+ elementName = "failure";
+ break;
+
+ // We should never see these here:
+ case ResultWas::Info:
+ case ResultWas::Warning:
+ case ResultWas::Ok:
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ elementName = "internalError";
+ break;
+ }
+
+ XmlWriter::ScopedElement e = xml.scopedElement( elementName );
+
+ xml.writeAttribute( "message", result.getExpandedExpression() );
+ xml.writeAttribute( "type", result.getTestMacroName() );
+
+ std::ostringstream oss;
+ if( !result.getMessage().empty() )
+ oss << result.getMessage() << "\n";
+ for( std::vector<MessageInfo>::const_iterator
+ it = stats.infoMessages.begin(),
+ itEnd = stats.infoMessages.end();
+ it != itEnd;
+ ++it )
+ if( it->type == ResultWas::Info )
+ oss << it->message << "\n";
+
+ oss << "at " << result.getSourceInfo();
+ xml.writeText( oss.str(), false );
+ }
+ }
+
+ XmlWriter xml;
+ Timer suiteTimer;
+ std::ostringstream stdOutForSuite;
+ std::ostringstream stdErrForSuite;
+ unsigned int unexpectedExceptions;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_console.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
+
+namespace Catch {
+
+ struct ConsoleReporter : StreamingReporterBase {
+ ConsoleReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_headerPrinted( false )
+ {}
+
+ virtual ~ConsoleReporter() CATCH_OVERRIDE;
+ static std::string getDescription() {
+ return "Reports test results as plain lines of text";
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
+ stream << "No test cases matched '" << spec << "'" << std::endl;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
+ }
+
+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ lazyPrint();
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+ stream << std::endl;
+ return true;
+ }
+
+ virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
+ m_headerPrinted = false;
+ StreamingReporterBase::sectionStarting( _sectionInfo );
+ }
+ virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
+ if( _sectionStats.missingAssertions ) {
+ lazyPrint();
+ Colour colour( Colour::ResultError );
+ if( m_sectionStack.size() > 1 )
+ stream << "\nNo assertions in section";
+ else
+ stream << "\nNo assertions in test case";
+ stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl;
+ }
+ if( m_headerPrinted ) {
+ if( m_config->showDurations() == ShowDurations::Always )
+ stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
+ m_headerPrinted = false;
+ }
+ else {
+ if( m_config->showDurations() == ShowDurations::Always )
+ stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl;
+ }
+ StreamingReporterBase::sectionEnded( _sectionStats );
+ }
+
+ virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
+ StreamingReporterBase::testCaseEnded( _testCaseStats );
+ m_headerPrinted = false;
+ }
+ virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
+ if( currentGroupInfo.used ) {
+ printSummaryDivider();
+ stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
+ printTotals( _testGroupStats.totals );
+ stream << "\n" << std::endl;
+ }
+ StreamingReporterBase::testGroupEnded( _testGroupStats );
+ }
+ virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
+ printTotalsDivider( _testRunStats.totals );
+ printTotals( _testRunStats.totals );
+ stream << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ private:
+
+ class AssertionPrinter {
+ void operator= ( AssertionPrinter const& );
+ public:
+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+ : stream( _stream ),
+ stats( _stats ),
+ result( _stats.assertionResult ),
+ colour( Colour::None ),
+ message( result.getMessage() ),
+ messages( _stats.infoMessages ),
+ printInfoMessages( _printInfoMessages )
+ {
+ switch( result.getResultType() ) {
+ case ResultWas::Ok:
+ colour = Colour::Success;
+ passOrFail = "PASSED";
+ //if( result.hasMessage() )
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ExpressionFailed:
+ if( result.isOk() ) {
+ colour = Colour::Success;
+ passOrFail = "FAILED - but was ok";
+ }
+ else {
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ }
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "with messages";
+ break;
+ case ResultWas::ThrewException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to unexpected exception with message";
+ break;
+ case ResultWas::FatalErrorCondition:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "due to a fatal error condition";
+ break;
+ case ResultWas::DidntThrowException:
+ colour = Colour::Error;
+ passOrFail = "FAILED";
+ messageLabel = "because no exception was thrown where one was expected";
+ break;
+ case ResultWas::Info:
+ messageLabel = "info";
+ break;
+ case ResultWas::Warning:
+ messageLabel = "warning";
+ break;
+ case ResultWas::ExplicitFailure:
+ passOrFail = "FAILED";
+ colour = Colour::Error;
+ if( _stats.infoMessages.size() == 1 )
+ messageLabel = "explicitly with message";
+ if( _stats.infoMessages.size() > 1 )
+ messageLabel = "explicitly with messages";
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ passOrFail = "** internal error **";
+ colour = Colour::Error;
+ break;
+ }
+ }
+
+ void print() const {
+ printSourceInfo();
+ if( stats.totals.assertions.total() > 0 ) {
+ if( result.isOk() )
+ stream << "\n";
+ printResultType();
+ printOriginalExpression();
+ printReconstructedExpression();
+ }
+ else {
+ stream << "\n";
+ }
+ printMessage();
+ }
+
+ private:
+ void printResultType() const {
+ if( !passOrFail.empty() ) {
+ Colour colourGuard( colour );
+ stream << passOrFail << ":\n";
+ }
+ }
+ void printOriginalExpression() const {
+ if( result.hasExpression() ) {
+ Colour colourGuard( Colour::OriginalExpression );
+ stream << " ";
+ stream << result.getExpressionInMacro();
+ stream << "\n";
+ }
+ }
+ void printReconstructedExpression() const {
+ if( result.hasExpandedExpression() ) {
+ stream << "with expansion:\n";
+ Colour colourGuard( Colour::ReconstructedExpression );
+ stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n";
+ }
+ }
+ void printMessage() const {
+ if( !messageLabel.empty() )
+ stream << messageLabel << ":" << "\n";
+ for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end();
+ it != itEnd;
+ ++it ) {
+ // If this assertion is a warning ignore any INFO messages
+ if( printInfoMessages || it->type != ResultWas::Info )
+ stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n";
+ }
+ }
+ void printSourceInfo() const {
+ Colour colourGuard( Colour::FileName );
+ stream << result.getSourceInfo() << ": ";
+ }
+
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ Colour::Code colour;
+ std::string passOrFail;
+ std::string messageLabel;
+ std::string message;
+ std::vector<MessageInfo> messages;
+ bool printInfoMessages;
+ };
+
+ void lazyPrint() {
+
+ if( !currentTestRunInfo.used )
+ lazyPrintRunInfo();
+ if( !currentGroupInfo.used )
+ lazyPrintGroupInfo();
+
+ if( !m_headerPrinted ) {
+ printTestCaseAndSectionHeader();
+ m_headerPrinted = true;
+ }
+ }
+ void lazyPrintRunInfo() {
+ stream << "\n" << getLineOfChars<'~'>() << "\n";
+ Colour colour( Colour::SecondaryText );
+ stream << currentTestRunInfo->name
+ << " is a Catch v" << libraryVersion << " host application.\n"
+ << "Run with -? for options\n\n";
+
+ if( m_config->rngSeed() != 0 )
+ stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n";
+
+ currentTestRunInfo.used = true;
+ }
+ void lazyPrintGroupInfo() {
+ if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) {
+ printClosedHeader( "Group: " + currentGroupInfo->name );
+ currentGroupInfo.used = true;
+ }
+ }
+ void printTestCaseAndSectionHeader() {
+ assert( !m_sectionStack.empty() );
+ printOpenHeader( currentTestCaseInfo->name );
+
+ if( m_sectionStack.size() > 1 ) {
+ Colour colourGuard( Colour::Headers );
+
+ std::vector<SectionInfo>::const_iterator
+ it = m_sectionStack.begin()+1, // Skip first section (test case)
+ itEnd = m_sectionStack.end();
+ for( ; it != itEnd; ++it )
+ printHeaderString( it->name, 2 );
+ }
+
+ SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
+
+ if( !lineInfo.empty() ){
+ stream << getLineOfChars<'-'>() << "\n";
+ Colour colourGuard( Colour::FileName );
+ stream << lineInfo << "\n";
+ }
+ stream << getLineOfChars<'.'>() << "\n" << std::endl;
+ }
+
+ void printClosedHeader( std::string const& _name ) {
+ printOpenHeader( _name );
+ stream << getLineOfChars<'.'>() << "\n";
+ }
+ void printOpenHeader( std::string const& _name ) {
+ stream << getLineOfChars<'-'>() << "\n";
+ {
+ Colour colourGuard( Colour::Headers );
+ printHeaderString( _name );
+ }
+ }
+
+ // if string has a : in first line will set indent to follow it on
+ // subsequent lines
+ void printHeaderString( std::string const& _string, std::size_t indent = 0 ) {
+ std::size_t i = _string.find( ": " );
+ if( i != std::string::npos )
+ i+=2;
+ else
+ i = 0;
+ stream << Text( _string, TextAttributes()
+ .setIndent( indent+i)
+ .setInitialIndent( indent ) ) << "\n";
+ }
+
+ struct SummaryColumn {
+
+ SummaryColumn( std::string const& _label, Colour::Code _colour )
+ : label( _label ),
+ colour( _colour )
+ {}
+ SummaryColumn addRow( std::size_t count ) {
+ std::ostringstream oss;
+ oss << count;
+ std::string row = oss.str();
+ for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) {
+ while( it->size() < row.size() )
+ *it = " " + *it;
+ while( it->size() > row.size() )
+ row = " " + row;
+ }
+ rows.push_back( row );
+ return *this;
+ }
+
+ std::string label;
+ Colour::Code colour;
+ std::vector<std::string> rows;
+
+ };
+
+ void printTotals( Totals const& totals ) {
+ if( totals.testCases.total() == 0 ) {
+ stream << Colour( Colour::Warning ) << "No tests ran\n";
+ }
+ else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) {
+ stream << Colour( Colour::ResultSuccess ) << "All tests passed";
+ stream << " ("
+ << pluralise( totals.assertions.passed, "assertion" ) << " in "
+ << pluralise( totals.testCases.passed, "test case" ) << ")"
+ << "\n";
+ }
+ else {
+
+ std::vector<SummaryColumn> columns;
+ columns.push_back( SummaryColumn( "", Colour::None )
+ .addRow( totals.testCases.total() )
+ .addRow( totals.assertions.total() ) );
+ columns.push_back( SummaryColumn( "passed", Colour::Success )
+ .addRow( totals.testCases.passed )
+ .addRow( totals.assertions.passed ) );
+ columns.push_back( SummaryColumn( "failed", Colour::ResultError )
+ .addRow( totals.testCases.failed )
+ .addRow( totals.assertions.failed ) );
+ columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure )
+ .addRow( totals.testCases.failedButOk )
+ .addRow( totals.assertions.failedButOk ) );
+
+ printSummaryRow( "test cases", columns, 0 );
+ printSummaryRow( "assertions", columns, 1 );
+ }
+ }
+ void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) {
+ for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) {
+ std::string value = it->rows[row];
+ if( it->label.empty() ) {
+ stream << label << ": ";
+ if( value != "0" )
+ stream << value;
+ else
+ stream << Colour( Colour::Warning ) << "- none -";
+ }
+ else if( value != "0" ) {
+ stream << Colour( Colour::LightGrey ) << " | ";
+ stream << Colour( it->colour )
+ << value << " " << it->label;
+ }
+ }
+ stream << "\n";
+ }
+
+ static std::size_t makeRatio( std::size_t number, std::size_t total ) {
+ std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0;
+ return ( ratio == 0 && number > 0 ) ? 1 : ratio;
+ }
+ static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) {
+ if( i > j && i > k )
+ return i;
+ else if( j > k )
+ return j;
+ else
+ return k;
+ }
+
+ void printTotalsDivider( Totals const& totals ) {
+ if( totals.testCases.total() > 0 ) {
+ std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() );
+ std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() );
+ std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() );
+ while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 )
+ findMax( failedRatio, failedButOkRatio, passedRatio )++;
+ while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 )
+ findMax( failedRatio, failedButOkRatio, passedRatio )--;
+
+ stream << Colour( Colour::Error ) << std::string( failedRatio, '=' );
+ stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' );
+ if( totals.testCases.allPassed() )
+ stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' );
+ else
+ stream << Colour( Colour::Success ) << std::string( passedRatio, '=' );
+ }
+ else {
+ stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' );
+ }
+ stream << "\n";
+ }
+ void printSummaryDivider() {
+ stream << getLineOfChars<'-'>() << "\n";
+ }
+
+ private:
+ bool m_headerPrinted;
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter )
+
+} // end namespace Catch
+
+// #included from: ../reporters/catch_reporter_compact.hpp
+#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED
+
+namespace Catch {
+
+ struct CompactReporter : StreamingReporterBase {
+
+ CompactReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config )
+ {}
+
+ virtual ~CompactReporter();
+
+ static std::string getDescription() {
+ return "Reports test results on a single line, suitable for IDEs";
+ }
+
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = false;
+ return prefs;
+ }
+
+ virtual void noMatchingTestCases( std::string const& spec ) {
+ stream << "No test cases matched '" << spec << "'" << std::endl;
+ }
+
+ virtual void assertionStarting( AssertionInfo const& ) {
+ }
+
+ virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
+ AssertionResult const& result = _assertionStats.assertionResult;
+
+ bool printInfoMessages = true;
+
+ // Drop out if result was successful and we're not printing those
+ if( !m_config->includeSuccessfulResults() && result.isOk() ) {
+ if( result.getResultType() != ResultWas::Warning )
+ return false;
+ printInfoMessages = false;
+ }
+
+ AssertionPrinter printer( stream, _assertionStats, printInfoMessages );
+ printer.print();
+
+ stream << std::endl;
+ return true;
+ }
+
+ virtual void testRunEnded( TestRunStats const& _testRunStats ) {
+ printTotals( _testRunStats.totals );
+ stream << "\n" << std::endl;
+ StreamingReporterBase::testRunEnded( _testRunStats );
+ }
+
+ private:
+ class AssertionPrinter {
+ void operator= ( AssertionPrinter const& );
+ public:
+ AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages )
+ : stream( _stream )
+ , stats( _stats )
+ , result( _stats.assertionResult )
+ , messages( _stats.infoMessages )
+ , itMessage( _stats.infoMessages.begin() )
+ , printInfoMessages( _printInfoMessages )
+ {}
+
+ void print() {
+ printSourceInfo();
+
+ itMessage = messages.begin();
+
+ switch( result.getResultType() ) {
+ case ResultWas::Ok:
+ printResultType( Colour::ResultSuccess, passedString() );
+ printOriginalExpression();
+ printReconstructedExpression();
+ if ( ! result.hasExpression() )
+ printRemainingMessages( Colour::None );
+ else
+ printRemainingMessages();
+ break;
+ case ResultWas::ExpressionFailed:
+ if( result.isOk() )
+ printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) );
+ else
+ printResultType( Colour::Error, failedString() );
+ printOriginalExpression();
+ printReconstructedExpression();
+ printRemainingMessages();
+ break;
+ case ResultWas::ThrewException:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "unexpected exception with message:" );
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::FatalErrorCondition:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "fatal error condition with message:" );
+ printMessage();
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::DidntThrowException:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "expected exception, got none" );
+ printExpressionWas();
+ printRemainingMessages();
+ break;
+ case ResultWas::Info:
+ printResultType( Colour::None, "info" );
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::Warning:
+ printResultType( Colour::None, "warning" );
+ printMessage();
+ printRemainingMessages();
+ break;
+ case ResultWas::ExplicitFailure:
+ printResultType( Colour::Error, failedString() );
+ printIssue( "explicitly" );
+ printRemainingMessages( Colour::None );
+ break;
+ // These cases are here to prevent compiler warnings
+ case ResultWas::Unknown:
+ case ResultWas::FailureBit:
+ case ResultWas::Exception:
+ printResultType( Colour::Error, "** internal error **" );
+ break;
+ }
+ }
+
+ private:
+ // Colour::LightGrey
+
+ static Colour::Code dimColour() { return Colour::FileName; }
+
+#ifdef CATCH_PLATFORM_MAC
+ static const char* failedString() { return "FAILED"; }
+ static const char* passedString() { return "PASSED"; }
+#else
+ static const char* failedString() { return "failed"; }
+ static const char* passedString() { return "passed"; }
+#endif
+
+ void printSourceInfo() const {
+ Colour colourGuard( Colour::FileName );
+ stream << result.getSourceInfo() << ":";
+ }
+
+ void printResultType( Colour::Code colour, std::string passOrFail ) const {
+ if( !passOrFail.empty() ) {
+ {
+ Colour colourGuard( colour );
+ stream << " " << passOrFail;
+ }
+ stream << ":";
+ }
+ }
+
+ void printIssue( std::string issue ) const {
+ stream << " " << issue;
+ }
+
+ void printExpressionWas() {
+ if( result.hasExpression() ) {
+ stream << ";";
+ {
+ Colour colour( dimColour() );
+ stream << " expression was:";
+ }
+ printOriginalExpression();
+ }
+ }
+
+ void printOriginalExpression() const {
+ if( result.hasExpression() ) {
+ stream << " " << result.getExpression();
+ }
+ }
+
+ void printReconstructedExpression() const {
+ if( result.hasExpandedExpression() ) {
+ {
+ Colour colour( dimColour() );
+ stream << " for: ";
+ }
+ stream << result.getExpandedExpression();
+ }
+ }
+
+ void printMessage() {
+ if ( itMessage != messages.end() ) {
+ stream << " '" << itMessage->message << "'";
+ ++itMessage;
+ }
+ }
+
+ void printRemainingMessages( Colour::Code colour = dimColour() ) {
+ if ( itMessage == messages.end() )
+ return;
+
+ // using messages.end() directly yields compilation error:
+ std::vector<MessageInfo>::const_iterator itEnd = messages.end();
+ const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
+
+ {
+ Colour colourGuard( colour );
+ stream << " with " << pluralise( N, "message" ) << ":";
+ }
+
+ for(; itMessage != itEnd; ) {
+ // If this assertion is a warning ignore any INFO messages
+ if( printInfoMessages || itMessage->type != ResultWas::Info ) {
+ stream << " '" << itMessage->message << "'";
+ if ( ++itMessage != itEnd ) {
+ Colour colourGuard( dimColour() );
+ stream << " and";
+ }
+ }
+ }
+ }
+
+ private:
+ std::ostream& stream;
+ AssertionStats const& stats;
+ AssertionResult const& result;
+ std::vector<MessageInfo> messages;
+ std::vector<MessageInfo>::const_iterator itMessage;
+ bool printInfoMessages;
+ };
+
+ // Colour, message variants:
+ // - white: No tests ran.
+ // - red: Failed [both/all] N test cases, failed [both/all] M assertions.
+ // - white: Passed [both/all] N test cases (no assertions).
+ // - red: Failed N tests cases, failed M assertions.
+ // - green: Passed [both/all] N tests cases with M assertions.
+
+ std::string bothOrAll( std::size_t count ) const {
+ return count == 1 ? "" : count == 2 ? "both " : "all " ;
+ }
+
+ void printTotals( const Totals& totals ) const {
+ if( totals.testCases.total() == 0 ) {
+ stream << "No tests ran.";
+ }
+ else if( totals.testCases.failed == totals.testCases.total() ) {
+ Colour colour( Colour::ResultError );
+ const std::string qualify_assertions_failed =
+ totals.assertions.failed == totals.assertions.total() ?
+ bothOrAll( totals.assertions.failed ) : "";
+ stream <<
+ "Failed " << bothOrAll( totals.testCases.failed )
+ << pluralise( totals.testCases.failed, "test case" ) << ", "
+ "failed " << qualify_assertions_failed <<
+ pluralise( totals.assertions.failed, "assertion" ) << ".";
+ }
+ else if( totals.assertions.total() == 0 ) {
+ stream <<
+ "Passed " << bothOrAll( totals.testCases.total() )
+ << pluralise( totals.testCases.total(), "test case" )
+ << " (no assertions).";
+ }
+ else if( totals.assertions.failed ) {
+ Colour colour( Colour::ResultError );
+ stream <<
+ "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
+ "failed " << pluralise( totals.assertions.failed, "assertion" ) << ".";
+ }
+ else {
+ Colour colour( Colour::ResultSuccess );
+ stream <<
+ "Passed " << bothOrAll( totals.testCases.passed )
+ << pluralise( totals.testCases.passed, "test case" ) <<
+ " with " << pluralise( totals.assertions.passed, "assertion" ) << ".";
+ }
+ }
+ };
+
+ INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter )
+
+} // end namespace Catch
+
+namespace Catch {
+ // These are all here to avoid warnings about not having any out of line
+ // virtual methods
+ NonCopyable::~NonCopyable() {}
+ IShared::~IShared() {}
+ IStream::~IStream() CATCH_NOEXCEPT {}
+ FileStream::~FileStream() CATCH_NOEXCEPT {}
+ CoutStream::~CoutStream() CATCH_NOEXCEPT {}
+ DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {}
+ StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
+ IContext::~IContext() {}
+ IResultCapture::~IResultCapture() {}
+ ITestCase::~ITestCase() {}
+ ITestCaseRegistry::~ITestCaseRegistry() {}
+ IRegistryHub::~IRegistryHub() {}
+ IMutableRegistryHub::~IMutableRegistryHub() {}
+ IExceptionTranslator::~IExceptionTranslator() {}
+ IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
+ IReporter::~IReporter() {}
+ IReporterFactory::~IReporterFactory() {}
+ IReporterRegistry::~IReporterRegistry() {}
+ IStreamingReporter::~IStreamingReporter() {}
+ AssertionStats::~AssertionStats() {}
+ SectionStats::~SectionStats() {}
+ TestCaseStats::~TestCaseStats() {}
+ TestGroupStats::~TestGroupStats() {}
+ TestRunStats::~TestRunStats() {}
+ CumulativeReporterBase::SectionNode::~SectionNode() {}
+ CumulativeReporterBase::~CumulativeReporterBase() {}
+
+ StreamingReporterBase::~StreamingReporterBase() {}
+ ConsoleReporter::~ConsoleReporter() {}
+ CompactReporter::~CompactReporter() {}
+ IRunner::~IRunner() {}
+ IMutableContext::~IMutableContext() {}
+ IConfig::~IConfig() {}
+ XmlReporter::~XmlReporter() {}
+ JunitReporter::~JunitReporter() {}
+ TestRegistry::~TestRegistry() {}
+ FreeFunctionTestCase::~FreeFunctionTestCase() {}
+ IGeneratorInfo::~IGeneratorInfo() {}
+ IGeneratorsForTest::~IGeneratorsForTest() {}
+ WildcardPattern::~WildcardPattern() {}
+ TestSpec::Pattern::~Pattern() {}
+ TestSpec::NamePattern::~NamePattern() {}
+ TestSpec::TagPattern::~TagPattern() {}
+ TestSpec::ExcludedPattern::~ExcludedPattern() {}
+
+ Matchers::Impl::StdString::Equals::~Equals() {}
+ Matchers::Impl::StdString::Contains::~Contains() {}
+ Matchers::Impl::StdString::StartsWith::~StartsWith() {}
+ Matchers::Impl::StdString::EndsWith::~EndsWith() {}
+
+ void Config::dummy() {}
+
+ namespace TestCaseTracking {
+ ITracker::~ITracker() {}
+ TrackerBase::~TrackerBase() {}
+ SectionTracker::~SectionTracker() {}
+ IndexTracker::~IndexTracker() {}
+ }
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif
+
+#ifdef CATCH_CONFIG_MAIN
+// #included from: internal/catch_default_main.hpp
+#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED
+
+#ifndef __OBJC__
+
+// Standard C/C++ main entry point
+int main (int argc, char * argv[]) {
+ return Catch::Session().run( argc, argv );
+}
+
+#else // __OBJC__
+
+// Objective-C entry point
+int main (int argc, char * const argv[]) {
+#if !CATCH_ARC_ENABLED
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+#endif
+
+ Catch::registerTestMethods();
+ int result = Catch::Session().run( argc, (char* const*)argv );
+
+#if !CATCH_ARC_ENABLED
+ [pool drain];
+#endif
+
+ return result;
+}
+
+#endif // __OBJC__
+
+#endif
+
+#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED
+# undef CLARA_CONFIG_MAIN
+#endif
+
+//////
+
+// If this config identifier is defined then all CATCH macros are prefixed with CATCH_
+#ifdef CATCH_CONFIG_PREFIX_ALL
+
+#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" )
+#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" )
+
+#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" )
+#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" )
+#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" )
+#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" )
+
+#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" )
+#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" )
+#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" )
+#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" )
+#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" )
+
+#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" )
+#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" )
+#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" )
+#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" )
+#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" )
+
+#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
+#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg )
+#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" )
+#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
+#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+ #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+ #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+ #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+ #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+ #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ )
+ #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ )
+#else
+ #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+ #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+ #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+ #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description )
+ #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+ #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg )
+ #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg )
+#endif
+#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
+#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" )
+#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" )
+#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
+#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" )
+#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
+
+// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
+#else
+
+#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" )
+#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" )
+
+#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" )
+#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" )
+#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" )
+#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" )
+
+#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
+#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" )
+#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" )
+#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" )
+#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" )
+
+#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" )
+#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" )
+#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" )
+#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" )
+
+#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" )
+#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" )
+
+#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
+#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg )
+#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" )
+#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
+#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" )
+
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+ #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
+ #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )
+ #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )
+ #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )
+ #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )
+ #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ )
+ #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ )
+#else
+ #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description )
+ #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description )
+ #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description )
+ #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description )
+ #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description )
+ #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg )
+ #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg )
+#endif
+#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" )
+
+#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType )
+#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType )
+
+#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr )
+
+#endif
+
+#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
+
+// "BDD-style" convenience wrappers
+#ifdef CATCH_CONFIG_VARIADIC_MACROS
+#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ )
+#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
+#else
+#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
+#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
+#endif
+#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" )
+#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" )
+#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
+#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" )
+#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" )
+
+using Catch::Detail::Approx;
+
+#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
+
diff --git a/3rdparty/sol2/LICENSE.txt b/3rdparty/sol2/LICENSE.txt
new file mode 100644
index 00000000000..1b5ff3c1af3
--- /dev/null
+++ b/3rdparty/sol2/LICENSE.txt
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-2016 Rapptz and contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/3rdparty/sol2/Optional/CMakeLists.txt b/3rdparty/sol2/Optional/CMakeLists.txt
new file mode 100644
index 00000000000..07f38f79932
--- /dev/null
+++ b/3rdparty/sol2/Optional/CMakeLists.txt
@@ -0,0 +1,11 @@
+project(optional)
+cmake_minimum_required(VERSION 2.8)
+enable_testing()
+
+set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra")
+
+add_executable(test_optional test_optional.cpp)
+add_executable(test_type_traits test_type_traits.cpp)
+
+add_test(test_optional test_optional)
+add_test(test_type_traits test_type_traits)
diff --git a/3rdparty/sol2/Optional/LICENSE_1_0.txt b/3rdparty/sol2/Optional/LICENSE_1_0.txt
new file mode 100644
index 00000000000..36b7cd93cdf
--- /dev/null
+++ b/3rdparty/sol2/Optional/LICENSE_1_0.txt
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/3rdparty/sol2/Optional/README.md b/3rdparty/sol2/Optional/README.md
new file mode 100644
index 00000000000..948516d1ba7
--- /dev/null
+++ b/3rdparty/sol2/Optional/README.md
@@ -0,0 +1,39 @@
+Optional
+========
+
+A single-header header-only library for representing optional (nullable) objects for C++14 (and C++11 to some extent) and passing them by value. This is the reference implementation of proposal N3793 (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3793.html). Optional is now accepted into Library Fundamentals Technical Specification (see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3848.html). The interface is based on Fernando Cacciola's Boost.Optional library (see http://www.boost.org/doc/libs/1_52_0/libs/optional/doc/html/index.html)
+
+
+Usage
+-----
+
+```cpp
+optional<int> readInt(); // this function may return int or a not-an-int
+
+if (optional<int> oi = readInt()) // did I get a real int
+ cout << "my int is: " << *oi; // use my int
+else
+ cout << "I have no int";
+```
+
+For more usage examples and the overview see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3527.html
+
+
+Supported compilers
+-------------------
+
+Clang 3.2, Clang 3.4, G++ 4.7.2, G++ 4.8.1. Tested only with libstdc++, versions 20130531, 20120920, 20110428. Others have reported it also works with libc++.
+
+
+
+Known Issues
+------------
+
+ - Currently, the reference (and the only known) implementation of certain pieces of functionality explore what C++11 identifies as undefined behavior (see national body comment FI 15: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3770.html#FI15). This is mostly why Optional was removed from C++14 and put into Library Fundamentals TS. Luckily what the Standard identifies as UB is well defined on all known platforms. We expect that the C++14 wil fix this problem, so that our trick becomes well-defined.
+ - In libstdc++ versions below 20130531 the constructor taking `initializer_list` argument is not `constexpr`. This is because `initializer_list` operations are not `constexpr` in C++11. This works however in version 20130531. It is also not enabled for libc++ because I do not have access to it and do nto know if it provides `constexpr` `initializer_list`.
+ - In G++ 4.7.2 and 4.8.0 member function `value_or` does not have rvalue reference overload. These compilers do not support rvalue overloding on `*this`.
+ - In order for the library to work with slightly older compilers, we emulate some missing type traits. On some platforms we cannot correctly detect the available features, and attempts at workarounds for missing type trait definitions can cause compile-time errors. Define macro `TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS` if you know that all the necessary type traits are defined, and no emulation is required.
+
+License
+-------
+Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
diff --git a/3rdparty/sol2/Optional/copyright.txt b/3rdparty/sol2/Optional/copyright.txt
new file mode 100644
index 00000000000..1641c3cdd0a
--- /dev/null
+++ b/3rdparty/sol2/Optional/copyright.txt
@@ -0,0 +1,10 @@
+Copyright (C) 2011-2012 Andrzej Krzemienski
+
+Distributed under the Boost Software License, Version 1.0
+(see accompanying file LICENSE_1_0.txt or a copy at
+http://www.boost.org/LICENSE_1_0.txt)
+
+The idea and interface is based on Boost.Optional library
+authored by Fernando Luis Cacciola Carballal
+
+Home at https://github.com/akrzemi1/Optional \ No newline at end of file
diff --git a/3rdparty/sol2/Optional/optional.hpp b/3rdparty/sol2/Optional/optional.hpp
new file mode 100644
index 00000000000..55b8306d013
--- /dev/null
+++ b/3rdparty/sol2/Optional/optional.hpp
@@ -0,0 +1,1064 @@
+// Copyright (C) 2011 - 2012 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// The idea and interface is based on Boost.Optional library
+// authored by Fernando Luis Cacciola Carballal
+
+# ifndef ___SOL_OPTIONAL_HPP___
+# define ___SOL_OPTIONAL_HPP___
+
+# include <utility>
+# include <type_traits>
+# include <initializer_list>
+# include <cassert>
+# include <functional>
+# include <string>
+# include <stdexcept>
+
+# define TR2_OPTIONAL_REQUIRES(...) typename ::std::enable_if<__VA_ARGS__::value, bool>::type = false
+
+# if defined __GNUC__ // NOTE: GNUC is also defined for Clang
+# if (__GNUC__ >= 5)
+# define TR2_OPTIONAL_GCC_5_0_AND_HIGHER___
+# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
+# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+# elif (__GNUC__ > 4)
+# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+# endif
+#
+# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)
+# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
+# elif (__GNUC__ > 4)
+# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
+# endif
+#
+# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1)
+# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
+# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# elif (__GNUC__ > 4)
+# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# endif
+# endif
+#
+# if defined __clang_major__
+# if (__clang_major__ == 3 && __clang_minor__ >= 5)
+# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
+# elif (__clang_major__ > 3)
+# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
+# endif
+# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
+# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+# elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2)
+# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+# endif
+# endif
+#
+# if defined _MSC_VER
+# if (_MSC_VER >= 1900)
+# define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+# endif
+# endif
+
+# if defined __clang__
+# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9)
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
+# else
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
+# endif
+# elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
+# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
+# else
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
+# endif
+
+
+# if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1
+# define OPTIONAL_CONSTEXPR_INIT_LIST constexpr
+# else
+# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0
+# define OPTIONAL_CONSTEXPR_INIT_LIST
+# endif
+
+# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L)
+# define OPTIONAL_HAS_MOVE_ACCESSORS 1
+# else
+# define OPTIONAL_HAS_MOVE_ACCESSORS 0
+# endif
+
+# // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr
+# if (defined __cplusplus) && (__cplusplus == 201103L)
+# define OPTIONAL_MUTABLE_CONSTEXPR
+# else
+# define OPTIONAL_MUTABLE_CONSTEXPR constexpr
+# endif
+
+namespace sol{
+
+// BEGIN workaround for missing is_trivially_destructible
+# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
+ // leave it: the user doesn't want it
+# else
+ template <typename T>
+ using is_trivially_destructible = ::std::has_trivial_destructor<T>;
+# endif
+// END workaround for missing is_trivially_destructible
+
+# if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___)
+ // leave it; our metafunctions are already defined.
+# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+ // leave it; our metafunctions are already defined.
+# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
+ // leave it: the user doesn't want it
+# else
+
+
+// workaround for missing traits in GCC and CLANG
+template <class T>
+struct is_nothrow_move_constructible
+{
+ constexpr static bool value = ::std::is_nothrow_constructible<T, T&&>::value;
+};
+
+
+template <class T, class U>
+struct is_assignable
+{
+ template <class X, class Y>
+ constexpr static bool has_assign(...) { return false; }
+
+ template <class X, class Y, size_t S = sizeof((::std::declval<X>() = ::std::declval<Y>(), true)) >
+ // the comma operator is necessary for the cases where operator= returns void
+ constexpr static bool has_assign(bool) { return true; }
+
+ constexpr static bool value = has_assign<T, U>(true);
+};
+
+
+template <class T>
+struct is_nothrow_move_assignable
+{
+ template <class X, bool has_any_move_assign>
+ struct has_nothrow_move_assign {
+ constexpr static bool value = false;
+ };
+
+ template <class X>
+ struct has_nothrow_move_assign<X, true> {
+ constexpr static bool value = noexcept( ::std::declval<X&>() = ::std::declval<X&&>() );
+ };
+
+ constexpr static bool value = has_nothrow_move_assign<T, is_assignable<T&, T&&>::value>::value;
+};
+// end workaround
+
+
+# endif
+
+
+
+// 20.5.4, optional for object types
+template <class T> class optional;
+
+// 20.5.5, optional for lvalue reference types
+template <class T> class optional<T&>;
+
+
+// workaround: std utility functions aren't constexpr yet
+template <class T> inline constexpr T&& constexpr_forward(typename ::std::remove_reference<T>::type& t) noexcept
+{
+ return static_cast<T&&>(t);
+}
+
+template <class T> inline constexpr T&& constexpr_forward(typename ::std::remove_reference<T>::type&& t) noexcept
+{
+ static_assert(!::std::is_lvalue_reference<T>::value, "!!");
+ return static_cast<T&&>(t);
+}
+
+template <class T> inline constexpr typename ::std::remove_reference<T>::type&& constexpr_move(T&& t) noexcept
+{
+ return static_cast<typename ::std::remove_reference<T>::type&&>(t);
+}
+
+
+#if defined NDEBUG
+# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
+#else
+# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR)))
+#endif
+
+
+namespace detail_
+{
+
+// static_addressof: a constexpr version of addressof
+template <typename T>
+struct has_overloaded_addressof
+{
+ template <class X>
+ constexpr static bool has_overload(...) { return false; }
+
+ template <class X, size_t S = sizeof(::std::declval<X&>().operator&()) >
+ constexpr static bool has_overload(bool) { return true; }
+
+ constexpr static bool value = has_overload<T>(true);
+};
+
+template <typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
+constexpr T* static_addressof(T& ref)
+{
+ return &ref;
+}
+
+template <typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
+T* static_addressof(T& ref)
+{
+ return ::std::addressof(ref);
+}
+
+
+// the call to convert<A>(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A
+template <class U>
+constexpr U convert(U v) { return v; }
+
+} // namespace detail_
+
+constexpr struct trivial_init_t {} trivial_init{};
+
+// 20.5.7, Disengaged state indicator
+struct nullopt_t
+{
+ struct init{};
+ constexpr explicit nullopt_t(init){}
+};
+constexpr nullopt_t nullopt{nullopt_t::init()};
+
+
+// 20.5.8, class bad_optional_access
+class bad_optional_access : public ::std::logic_error {
+public:
+ explicit bad_optional_access(const ::std::string& what_arg) : ::std::logic_error{what_arg} {}
+ explicit bad_optional_access(const char* what_arg) : ::std::logic_error{what_arg} {}
+};
+
+
+template <class T>
+struct optional_base
+{
+ bool init_;
+ char storage_[sizeof(T)];
+
+ constexpr optional_base() noexcept : init_(false), storage_() {};
+
+ explicit optional_base(const T& v) : init_(true), storage_() {
+ new (&storage())T(v);
+ }
+
+ explicit optional_base(T&& v) : init_(true), storage_() {
+ new (&storage())T(constexpr_move(v));
+ }
+
+ template <class... Args> explicit optional_base(in_place_t, Args&&... args)
+ : init_(true), storage_() {
+ new (&storage())T(constexpr_forward<Args>(args)...);
+ }
+
+ template <class U, class... Args, TR2_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
+ explicit optional_base(in_place_t, ::std::initializer_list<U> il, Args&&... args)
+ : init_(true), storage_() {
+ new (&storage())T(il, constexpr_forward<Args>(args)...);
+ }
+#if defined __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif
+ T& storage() {
+ return *reinterpret_cast<T*>(&storage_[0]);
+ }
+
+ constexpr const T& storage() const {
+ return *reinterpret_cast<T const*>(&storage_[0]);
+ }
+#if defined __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+ ~optional_base() { if (init_) { storage().T::~T(); } }
+};
+
+#if defined __GNUC__ && !defined TR2_OPTIONAL_GCC_5_0_AND_HIGHER___
+// Sorry, GCC 4.x; you're just a piece of shit
+template <typename T>
+using constexpr_optional_base = optional_base<T>;
+#else
+template <class T>
+struct constexpr_optional_base
+{
+ bool init_;
+ char storage_[sizeof(T)];
+ constexpr constexpr_optional_base() noexcept : init_(false), storage_() {}
+
+ explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_() {
+ new (&storage())T(v);
+ }
+
+ explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_() {
+ new (&storage())T(constexpr_move(v));
+ }
+
+ template <class... Args> explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
+ : init_(true), storage_() {
+ new (&storage())T(constexpr_forward<Args>(args)...);
+ }
+
+ template <class U, class... Args, TR2_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
+ OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, ::std::initializer_list<U> il, Args&&... args)
+ : init_(true), storage_() {
+ new (&storage())T(il, constexpr_forward<Args>(args)...);
+ }
+
+#if defined __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif
+ T& storage() {
+ return (*reinterpret_cast<T*>(&storage_[0]));
+ }
+
+ constexpr const T& storage() const {
+ return (*reinterpret_cast<T const*>(&storage_[0]));
+ }
+#if defined __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+ ~constexpr_optional_base() = default;
+};
+#endif
+
+template <class T>
+using OptionalBase = typename ::std::conditional<
+ ::std::is_trivially_destructible<T>::value,
+ constexpr_optional_base<typename ::std::remove_const<T>::type>,
+ optional_base<typename ::std::remove_const<T>::type>
+>::type;
+
+
+
+template <class T>
+class optional : private OptionalBase<T>
+{
+ static_assert( !::std::is_same<typename ::std::decay<T>::type, nullopt_t>::value, "bad T" );
+ static_assert( !::std::is_same<typename ::std::decay<T>::type, in_place_t>::value, "bad T" );
+
+
+ constexpr bool initialized() const noexcept { return OptionalBase<T>::init_; }
+ typename ::std::remove_const<T>::type* dataptr() { return ::std::addressof(OptionalBase<T>::storage()); }
+ constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage()); }
+
+# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
+ constexpr const T& contained_val() const& { return OptionalBase<T>::storage(); }
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+ OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return ::std::move(OptionalBase<T>::storage()); }
+ OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase<T>::storage(); }
+# else
+ T& contained_val() & { return OptionalBase<T>::storage(); }
+ T&& contained_val() && { return ::std::move(OptionalBase<T>::storage()); }
+# endif
+# else
+ constexpr const T& contained_val() const { return OptionalBase<T>::storage(); }
+ T& contained_val() { return OptionalBase<T>::storage(); }
+# endif
+
+ void clear() noexcept {
+ if (initialized()) dataptr()->T::~T();
+ OptionalBase<T>::init_ = false;
+ }
+
+ template <class... Args>
+ void initialize(Args&&... args) noexcept(noexcept(T(::std::forward<Args>(args)...)))
+ {
+ assert(!OptionalBase<T>::init_);
+ ::new (static_cast<void*>(dataptr())) T(::std::forward<Args>(args)...);
+ OptionalBase<T>::init_ = true;
+ }
+
+ template <class U, class... Args>
+ void initialize(::std::initializer_list<U> il, Args&&... args) noexcept(noexcept(T(il, ::std::forward<Args>(args)...)))
+ {
+ assert(!OptionalBase<T>::init_);
+ ::new (static_cast<void*>(dataptr())) T(il, ::std::forward<Args>(args)...);
+ OptionalBase<T>::init_ = true;
+ }
+
+public:
+ typedef T value_type;
+
+ // 20.5.5.1, constructors
+ constexpr optional() noexcept : OptionalBase<T>() {};
+ constexpr optional(nullopt_t) noexcept : OptionalBase<T>() {};
+
+ optional(const optional& rhs)
+ : OptionalBase<T>()
+ {
+ if (rhs.initialized()) {
+ ::new (static_cast<void*>(dataptr())) T(*rhs);
+ OptionalBase<T>::init_ = true;
+ }
+ }
+
+ optional(const optional<T&>& rhs) : optional()
+ {
+ if (rhs) {
+ ::new (static_cast<void*>(dataptr())) T(*rhs);
+ OptionalBase<T>::init_ = true;
+ }
+ }
+
+
+ optional(optional&& rhs) noexcept(::std::is_nothrow_move_constructible<T>::value)
+ : OptionalBase<T>()
+ {
+ if (rhs.initialized()) {
+ ::new (static_cast<void*>(dataptr())) T(::std::move(*rhs));
+ OptionalBase<T>::init_ = true;
+ }
+ }
+
+ constexpr optional(const T& v) : OptionalBase<T>(v) {}
+
+ constexpr optional(T&& v) : OptionalBase<T>(constexpr_move(v)) {}
+
+ template <class... Args>
+ explicit constexpr optional(in_place_t, Args&&... args)
+ : OptionalBase<T>(in_place, constexpr_forward<Args>(args)...) {}
+
+ template <class U, class... Args, TR2_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
+ OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, ::std::initializer_list<U> il, Args&&... args)
+ : OptionalBase<T>(in_place, il, constexpr_forward<Args>(args)...) {}
+
+ // 20.5.4.2, Destructor
+ ~optional() = default;
+
+ // 20.5.4.3, assignment
+ optional& operator=(nullopt_t) noexcept
+ {
+ clear();
+ return *this;
+ }
+
+ optional& operator=(const optional& rhs)
+ {
+ if (initialized() == true && rhs.initialized() == false) clear();
+ else if (initialized() == false && rhs.initialized() == true) initialize(*rhs);
+ else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs;
+ return *this;
+ }
+
+ optional& operator=(optional&& rhs)
+ noexcept(::std::is_nothrow_move_assignable<T>::value && ::std::is_nothrow_move_constructible<T>::value)
+ {
+ if (initialized() == true && rhs.initialized() == false) clear();
+ else if (initialized() == false && rhs.initialized() == true) initialize(::std::move(*rhs));
+ else if (initialized() == true && rhs.initialized() == true) contained_val() = ::std::move(*rhs);
+ return *this;
+ }
+
+ template <class U>
+ auto operator=(U&& v)
+ -> typename ::std::enable_if
+ <
+ ::std::is_same<typename ::std::decay<U>::type, T>::value,
+ optional&
+ >::type
+ {
+ if (initialized()) { contained_val() = ::std::forward<U>(v); }
+ else { initialize(::std::forward<U>(v)); }
+ return *this;
+ }
+
+
+ template <class... Args>
+ void emplace(Args&&... args)
+ {
+ clear();
+ initialize(::std::forward<Args>(args)...);
+ }
+
+ template <class U, class... Args>
+ void emplace(::std::initializer_list<U> il, Args&&... args)
+ {
+ clear();
+ initialize<U, Args...>(il, ::std::forward<Args>(args)...);
+ }
+
+ // 20.5.4.4, Swap
+ void swap(optional<T>& rhs) noexcept(::std::is_nothrow_move_constructible<T>::value && noexcept(swap(::std::declval<T&>(), ::std::declval<T&>())))
+ {
+ if (initialized() == true && rhs.initialized() == false) { rhs.initialize(::std::move(**this)); clear(); }
+ else if (initialized() == false && rhs.initialized() == true) { initialize(::std::move(*rhs)); rhs.clear(); }
+ else if (initialized() == true && rhs.initialized() == true) { using ::std::swap; swap(**this, *rhs); }
+ }
+
+ // 20.5.4.5, Observers
+
+ explicit constexpr operator bool() const noexcept { return initialized(); }
+
+ constexpr T const* operator ->() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr());
+ }
+
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+
+ OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
+ assert (initialized());
+ return dataptr();
+ }
+
+ constexpr T const& operator *() const& {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
+ assert (initialized());
+ return contained_val();
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
+ assert (initialized());
+ return constexpr_move(contained_val());
+ }
+
+ constexpr T const& value() const& {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
+ if (!initialized()) throw bad_optional_access("bad optional access");
+ return ::std::move(contained_val());
+ }
+
+# else
+
+ T* operator ->() {
+ assert (initialized());
+ return dataptr();
+ }
+
+ constexpr T const& operator *() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
+ }
+
+ T& operator *() {
+ assert (initialized());
+ return contained_val();
+ }
+
+ constexpr T const& value() const {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+ T& value() {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+# endif
+
+# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
+
+ template <class V>
+ constexpr T value_or(V&& v) const&
+ {
+ return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+
+ template <class V>
+ OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) &&
+ {
+ return *this ? constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# else
+
+ template <class V>
+ T value_or(V&& v) &&
+ {
+ return *this ? constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# endif
+
+# else
+
+ template <class V>
+ constexpr T value_or(V&& v) const
+ {
+ return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# endif
+
+};
+
+
+template <class T>
+class optional<T&>
+{
+ static_assert( !::std::is_same<T, nullopt_t>::value, "bad T" );
+ static_assert( !::std::is_same<T, in_place_t>::value, "bad T" );
+ T* ref;
+
+public:
+
+ // 20.5.5.1, construction/destruction
+ constexpr optional() noexcept : ref(nullptr) {}
+
+ constexpr optional(nullopt_t) noexcept : ref(nullptr) {}
+
+ constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {}
+
+ optional(T&&) = delete;
+
+ constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {}
+
+ explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {}
+
+ explicit optional(in_place_t, T&&) = delete;
+
+ ~optional() = default;
+
+ // 20.5.5.2, mutation
+ optional& operator=(nullopt_t) noexcept {
+ ref = nullptr;
+ return *this;
+ }
+
+ // optional& operator=(const optional& rhs) noexcept {
+ // ref = rhs.ref;
+ // return *this;
+ // }
+
+ // optional& operator=(optional&& rhs) noexcept {
+ // ref = rhs.ref;
+ // return *this;
+ // }
+
+ template <typename U>
+ auto operator=(U&& rhs) noexcept
+ -> typename ::std::enable_if
+ <
+ ::std::is_same<typename ::std::decay<U>::type, optional<T&>>::value,
+ optional&
+ >::type
+ {
+ ref = rhs.ref;
+ return *this;
+ }
+
+ template <typename U>
+ auto operator=(U&& rhs) noexcept
+ -> typename ::std::enable_if
+ <
+ !::std::is_same<typename ::std::decay<U>::type, optional<T&>>::value,
+ optional&
+ >::type
+ = delete;
+
+ void emplace(T& v) noexcept {
+ ref = detail_::static_addressof(v);
+ }
+
+ void emplace(T&&) = delete;
+
+
+ void swap(optional<T&>& rhs) noexcept
+ {
+ ::std::swap(ref, rhs.ref);
+ }
+
+ // 20.5.5.3, observers
+ constexpr T* operator->() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
+ }
+
+ constexpr T& operator*() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
+ }
+
+ constexpr T& value() const {
+ return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
+ }
+
+ explicit constexpr operator bool() const noexcept {
+ return ref != nullptr;
+ }
+
+ template <typename V>
+ constexpr T& value_or(V&& v) const
+ {
+ return *this ? **this : detail_::convert<T&>(constexpr_forward<V>(v));
+ }
+};
+
+
+template <class T>
+class optional<T&&>
+{
+ static_assert( sizeof(T) == 0, "optional rvalue references disallowed" );
+};
+
+
+// 20.5.8, Relational operators
+template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y)
+{
+ return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
+}
+
+template <class T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y)
+{
+ return !(x == y);
+}
+
+template <class T> constexpr bool operator<(const optional<T>& x, const optional<T>& y)
+{
+ return (!y) ? false : (!x) ? true : *x < *y;
+}
+
+template <class T> constexpr bool operator>(const optional<T>& x, const optional<T>& y)
+{
+ return (y < x);
+}
+
+template <class T> constexpr bool operator<=(const optional<T>& x, const optional<T>& y)
+{
+ return !(y < x);
+}
+
+template <class T> constexpr bool operator>=(const optional<T>& x, const optional<T>& y)
+{
+ return !(x < y);
+}
+
+
+// 20.5.9, Comparison with nullopt
+template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept
+{
+ return (!x);
+}
+
+template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept
+{
+ return (!x);
+}
+
+template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept
+{
+ return false;
+}
+
+template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept
+{
+ return (!x);
+}
+
+template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept
+{
+ return true;
+}
+
+template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept
+{
+ return false;
+}
+
+template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept
+{
+ return true;
+}
+
+template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept
+{
+ return (!x);
+}
+
+
+
+// 20.5.10, Comparison with T
+template <class T> constexpr bool operator==(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x == v : false;
+}
+
+template <class T> constexpr bool operator==(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v == *x : false;
+}
+
+template <class T> constexpr bool operator!=(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x != v : true;
+}
+
+template <class T> constexpr bool operator!=(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v != *x : true;
+}
+
+template <class T> constexpr bool operator<(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x < v : true;
+}
+
+template <class T> constexpr bool operator>(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v > *x : true;
+}
+
+template <class T> constexpr bool operator>(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x > v : false;
+}
+
+template <class T> constexpr bool operator<(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v < *x : false;
+}
+
+template <class T> constexpr bool operator>=(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x >= v : false;
+}
+
+template <class T> constexpr bool operator<=(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v <= *x : false;
+}
+
+template <class T> constexpr bool operator<=(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x <= v : true;
+}
+
+template <class T> constexpr bool operator>=(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v >= *x : true;
+}
+
+
+// Comparison of optional<T&> with T
+template <class T> constexpr bool operator==(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x == v : false;
+}
+
+template <class T> constexpr bool operator==(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v == *x : false;
+}
+
+template <class T> constexpr bool operator!=(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x != v : true;
+}
+
+template <class T> constexpr bool operator!=(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v != *x : true;
+}
+
+template <class T> constexpr bool operator<(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x < v : true;
+}
+
+template <class T> constexpr bool operator>(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v > *x : true;
+}
+
+template <class T> constexpr bool operator>(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x > v : false;
+}
+
+template <class T> constexpr bool operator<(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v < *x : false;
+}
+
+template <class T> constexpr bool operator>=(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x >= v : false;
+}
+
+template <class T> constexpr bool operator<=(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v <= *x : false;
+}
+
+template <class T> constexpr bool operator<=(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x <= v : true;
+}
+
+template <class T> constexpr bool operator>=(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v >= *x : true;
+}
+
+// Comparison of optional<T const&> with T
+template <class T> constexpr bool operator==(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x == v : false;
+}
+
+template <class T> constexpr bool operator==(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v == *x : false;
+}
+
+template <class T> constexpr bool operator!=(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x != v : true;
+}
+
+template <class T> constexpr bool operator!=(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v != *x : true;
+}
+
+template <class T> constexpr bool operator<(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x < v : true;
+}
+
+template <class T> constexpr bool operator>(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v > *x : true;
+}
+
+template <class T> constexpr bool operator>(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x > v : false;
+}
+
+template <class T> constexpr bool operator<(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v < *x : false;
+}
+
+template <class T> constexpr bool operator>=(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x >= v : false;
+}
+
+template <class T> constexpr bool operator<=(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v <= *x : false;
+}
+
+template <class T> constexpr bool operator<=(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x <= v : true;
+}
+
+template <class T> constexpr bool operator>=(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v >= *x : true;
+}
+
+
+// 20.5.12, Specialized algorithms
+template <class T>
+void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)))
+{
+ x.swap(y);
+}
+
+
+template <class T>
+constexpr optional<typename ::std::decay<T>::type> make_optional(T&& v)
+{
+ return optional<typename ::std::decay<T>::type>(constexpr_forward<T>(v));
+}
+
+template <class X>
+constexpr optional<X&> make_optional(::std::reference_wrapper<X> v)
+{
+ return optional<X&>(v.get());
+}
+
+
+} // namespace
+
+namespace std
+{
+ template <typename T>
+ struct hash<sol::optional<T>>
+ {
+ typedef typename hash<T>::result_type result_type;
+ typedef sol::optional<T> argument_type;
+
+ constexpr result_type operator()(argument_type const& arg) const {
+ return arg ? ::std::hash<T>{}(*arg) : result_type{};
+ }
+ };
+
+ template <typename T>
+ struct hash<sol::optional<T&>>
+ {
+ typedef typename hash<T>::result_type result_type;
+ typedef sol::optional<T&> argument_type;
+
+ constexpr result_type operator()(argument_type const& arg) const {
+ return arg ? ::std::hash<T>{}(*arg) : result_type{};
+ }
+ };
+}
+
+# undef TR2_OPTIONAL_REQUIRES
+# undef TR2_OPTIONAL_ASSERTED_EXPRESSION
+
+# endif //___SOL_OPTIONAL_HPP___
diff --git a/3rdparty/sol2/Optional/test_optional.cpp b/3rdparty/sol2/Optional/test_optional.cpp
new file mode 100644
index 00000000000..8ed356a562b
--- /dev/null
+++ b/3rdparty/sol2/Optional/test_optional.cpp
@@ -0,0 +1,1459 @@
+// Copyright (C) 2011 - 2012 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// The idea and interface is based on Boost.Optional library
+// authored by Fernando Luis Cacciola Carballal
+
+# include "optional.hpp"
+# include <vector>
+# include <iostream>
+# include <functional>
+# include <complex>
+
+
+
+struct caller {
+ template <class T> caller(T fun) { fun(); }
+};
+# define CAT2(X, Y) X ## Y
+# define CAT(X, Y) CAT2(X, Y)
+# define TEST(NAME) caller CAT(__VAR, __LINE__) = []
+
+enum State
+{
+ sDefaultConstructed,
+ sValueCopyConstructed,
+ sValueMoveConstructed,
+ sCopyConstructed,
+ sMoveConstructed,
+ sMoveAssigned,
+ sCopyAssigned,
+ sValueCopyAssigned,
+ sValueMoveAssigned,
+ sMovedFrom,
+ sValueConstructed
+};
+
+struct OracleVal
+{
+ State s;
+ int i;
+ OracleVal(int i = 0) : s(sValueConstructed), i(i) {}
+};
+
+struct Oracle
+{
+ State s;
+ OracleVal val;
+
+ Oracle() : s(sDefaultConstructed) {}
+ Oracle(const OracleVal& v) : s(sValueCopyConstructed), val(v) {}
+ Oracle(OracleVal&& v) : s(sValueMoveConstructed), val(std::move(v)) {v.s = sMovedFrom;}
+ Oracle(const Oracle& o) : s(sCopyConstructed), val(o.val) {}
+ Oracle(Oracle&& o) : s(sMoveConstructed), val(std::move(o.val)) {o.s = sMovedFrom;}
+
+ Oracle& operator=(const OracleVal& v) { s = sValueCopyConstructed; val = v; return *this; }
+ Oracle& operator=(OracleVal&& v) { s = sValueMoveConstructed; val = std::move(v); v.s = sMovedFrom; return *this; }
+ Oracle& operator=(const Oracle& o) { s = sCopyConstructed; val = o.val; return *this; }
+ Oracle& operator=(Oracle&& o) { s = sMoveConstructed; val = std::move(o.val); o.s = sMovedFrom; return *this; }
+};
+
+struct Guard
+{
+ std::string val;
+ Guard() : val{} {}
+ explicit Guard(std::string s, int = 0) : val(s) {}
+ Guard(const Guard&) = delete;
+ Guard(Guard&&) = delete;
+ void operator=(const Guard&) = delete;
+ void operator=(Guard&&) = delete;
+};
+
+struct ExplicitStr
+{
+ std::string s;
+ explicit ExplicitStr(const char* chp) : s(chp) {};
+};
+
+struct Date
+{
+ int i;
+ Date() = delete;
+ Date(int i) : i{i} {};
+ Date(Date&& d) : i(d.i) { d.i = 0; }
+ Date(const Date&) = delete;
+ Date& operator=(const Date&) = delete;
+ Date& operator=(Date&& d) { i = d.i; d.i = 0; return *this;};
+};
+
+bool operator==( Oracle const& a, Oracle const& b ) { return a.val.i == b.val.i; }
+bool operator!=( Oracle const& a, Oracle const& b ) { return a.val.i != b.val.i; }
+
+
+namespace tr2 = std::experimental;
+
+
+TEST(disengaged_ctor)
+{
+ tr2::optional<int> o1;
+ assert (!o1);
+
+ tr2::optional<int> o2 = tr2::nullopt;
+ assert (!o2);
+
+ tr2::optional<int> o3 = o2;
+ assert (!o3);
+
+ assert (o1 == tr2::nullopt);
+ assert (o1 == tr2::optional<int>{});
+ assert (!o1);
+ assert (bool(o1) == false);
+
+ assert (o2 == tr2::nullopt);
+ assert (o2 == tr2::optional<int>{});
+ assert (!o2);
+ assert (bool(o2) == false);
+
+ assert (o3 == tr2::nullopt);
+ assert (o3 == tr2::optional<int>{});
+ assert (!o3);
+ assert (bool(o3) == false);
+
+ assert (o1 == o2);
+ assert (o2 == o1);
+ assert (o1 == o3);
+ assert (o3 == o1);
+ assert (o2 == o3);
+ assert (o3 == o2);
+};
+
+
+TEST(value_ctor)
+{
+ OracleVal v;
+ tr2::optional<Oracle> oo1(v);
+ assert (oo1 != tr2::nullopt);
+ assert (oo1 != tr2::optional<Oracle>{});
+ assert (oo1 == tr2::optional<Oracle>{v});
+ assert (!!oo1);
+ assert (bool(oo1));
+ // NA: assert (oo1->s == sValueCopyConstructed);
+ assert (oo1->s == sMoveConstructed);
+ assert (v.s == sValueConstructed);
+
+ tr2::optional<Oracle> oo2(std::move(v));
+ assert (oo2 != tr2::nullopt);
+ assert (oo2 != tr2::optional<Oracle>{});
+ assert (oo2 == oo1);
+ assert (!!oo2);
+ assert (bool(oo2));
+ // NA: assert (oo2->s == sValueMoveConstructed);
+ assert (oo2->s == sMoveConstructed);
+ assert (v.s == sMovedFrom);
+
+ {
+ OracleVal v;
+ tr2::optional<Oracle> oo1{tr2::in_place, v};
+ assert (oo1 != tr2::nullopt);
+ assert (oo1 != tr2::optional<Oracle>{});
+ assert (oo1 == tr2::optional<Oracle>{v});
+ assert (!!oo1);
+ assert (bool(oo1));
+ assert (oo1->s == sValueCopyConstructed);
+ assert (v.s == sValueConstructed);
+
+ tr2::optional<Oracle> oo2{tr2::in_place, std::move(v)};
+ assert (oo2 != tr2::nullopt);
+ assert (oo2 != tr2::optional<Oracle>{});
+ assert (oo2 == oo1);
+ assert (!!oo2);
+ assert (bool(oo2));
+ assert (oo2->s == sValueMoveConstructed);
+ assert (v.s == sMovedFrom);
+ }
+};
+
+
+TEST(assignment)
+{
+ tr2::optional<int> oi;
+ oi = tr2::optional<int>{1};
+ assert (*oi == 1);
+
+ oi = tr2::nullopt;
+ assert (!oi);
+
+ oi = 2;
+ assert (*oi == 2);
+
+ oi = {};
+ assert (!oi);
+};
+
+
+template <class T>
+struct MoveAware
+{
+ T val;
+ bool moved;
+ MoveAware(T val) : val(val), moved(false) {}
+ MoveAware(MoveAware const&) = delete;
+ MoveAware(MoveAware&& rhs) : val(rhs.val), moved(rhs.moved) {
+ rhs.moved = true;
+ }
+ MoveAware& operator=(MoveAware const&) = delete;
+ MoveAware& operator=(MoveAware&& rhs) {
+ val = (rhs.val);
+ moved = (rhs.moved);
+ rhs.moved = true;
+ return *this;
+ }
+};
+
+TEST(moved_from_state)
+{
+ // first, test mock:
+ MoveAware<int> i{1}, j{2};
+ assert (i.val == 1);
+ assert (!i.moved);
+ assert (j.val == 2);
+ assert (!j.moved);
+
+ MoveAware<int> k = std::move(i);
+ assert (k.val == 1);
+ assert (!k.moved);
+ assert (i.val == 1);
+ assert (i.moved);
+
+ k = std::move(j);
+ assert (k.val == 2);
+ assert (!k.moved);
+ assert (j.val == 2);
+ assert (j.moved);
+
+ // now, test optional
+ tr2::optional<MoveAware<int>> oi{1}, oj{2};
+ assert (oi);
+ assert (!oi->moved);
+ assert (oj);
+ assert (!oj->moved);
+
+ tr2::optional<MoveAware<int>> ok = std::move(oi);
+ assert (ok);
+ assert (!ok->moved);
+ assert (oi);
+ assert (oi->moved);
+
+ ok = std::move(oj);
+ assert (ok);
+ assert (!ok->moved);
+ assert (oj);
+ assert (oj->moved);
+};
+
+
+TEST(copy_move_ctor_optional_int)
+{
+ tr2::optional<int> oi;
+ tr2::optional<int> oj = oi;
+
+ assert (!oj);
+ assert (oj == oi);
+ assert (oj == tr2::nullopt);
+ assert (!bool(oj));
+
+ oi = 1;
+ tr2::optional<int> ok = oi;
+ assert (!!ok);
+ assert (bool(ok));
+ assert (ok == oi);
+ assert (ok != oj);
+ assert (*ok == 1);
+
+ tr2::optional<int> ol = std::move(oi);
+ assert (!!ol);
+ assert (bool(ol));
+ assert (ol == oi);
+ assert (ol != oj);
+ assert (*ol == 1);
+};
+
+
+TEST(optional_optional)
+{
+ tr2::optional<tr2::optional<int>> oi1 = tr2::nullopt;
+ assert (oi1 == tr2::nullopt);
+ assert (!oi1);
+
+ {
+ tr2::optional<tr2::optional<int>> oi2 {tr2::in_place};
+ assert (oi2 != tr2::nullopt);
+ assert (bool(oi2));
+ assert (*oi2 == tr2::nullopt);
+ //assert (!(*oi2));
+ //std::cout << typeid(**oi2).name() << std::endl;
+ }
+
+ {
+ tr2::optional<tr2::optional<int>> oi2 {tr2::in_place, tr2::nullopt};
+ assert (oi2 != tr2::nullopt);
+ assert (bool(oi2));
+ assert (*oi2 == tr2::nullopt);
+ assert (!*oi2);
+ }
+
+ {
+ tr2::optional<tr2::optional<int>> oi2 {tr2::optional<int>{}};
+ assert (oi2 != tr2::nullopt);
+ assert (bool(oi2));
+ assert (*oi2 == tr2::nullopt);
+ assert (!*oi2);
+ }
+
+ tr2::optional<int> oi;
+ auto ooi = tr2::make_optional(oi);
+ static_assert( std::is_same<tr2::optional<tr2::optional<int>>, decltype(ooi)>::value, "");
+
+};
+
+TEST(example_guard)
+{
+ using namespace tr2;
+ //FAILS: optional<Guard> ogx(Guard("res1"));
+ //FAILS: optional<Guard> ogx = "res1";
+ //FAILS: optional<Guard> ogx("res1");
+ optional<Guard> oga; // Guard is non-copyable (and non-moveable)
+ optional<Guard> ogb(in_place, "res1"); // initialzes the contained value with "res1"
+ assert (bool(ogb));
+ assert (ogb->val == "res1");
+
+ optional<Guard> ogc(in_place); // default-constructs the contained value
+ assert (bool(ogc));
+ assert (ogc->val == "");
+
+ oga.emplace("res1"); // initialzes the contained value with "res1"
+ assert (bool(oga));
+ assert (oga->val == "res1");
+
+ oga.emplace(); // destroys the contained value and
+ // default-constructs the new one
+ assert (bool(oga));
+ assert (oga->val == "");
+
+ oga = nullopt; // OK: make disengaged the optional Guard
+ assert (!(oga));
+ //FAILS: ogb = {}; // ERROR: Guard is not Moveable
+};
+
+
+void process(){}
+void process(int ){}
+void processNil(){}
+
+
+TEST(example1)
+{
+ using namespace tr2;
+ optional<int> oi; // create disengaged object
+ optional<int> oj = nullopt; // alternative syntax
+ oi = oj; // assign disengaged object
+ optional<int> ok = oj; // ok is disengaged
+
+ if (oi) assert(false); // 'if oi is engaged...'
+ if (!oi) assert(true); // 'if oi is disengaged...'
+
+ if (oi != nullopt) assert(false); // 'if oi is engaged...'
+ if (oi == nullopt) assert(true); // 'if oi is disengaged...'
+
+ assert(oi == ok); // two disengaged optionals compare equal
+
+ ///////////////////////////////////////////////////////////////////////////
+ optional<int> ol{1}; // ol is engaged; its contained value is 1
+ ok = 2; // ok becomes engaged; its contained value is 2
+ oj = ol; // oj becomes engaged; its contained value is 1
+
+ assert(oi != ol); // disengaged != engaged
+ assert(ok != ol); // different contained values
+ assert(oj == ol); // same contained value
+ assert(oi < ol); // disengaged < engaged
+ assert(ol < ok); // less by contained value
+
+ /////////////////////////////////////////////////////////////////////////////
+ optional<int> om{1}; // om is engaged; its contained value is 1
+ optional<int> on = om; // on is engaged; its contained value is 1
+ om = 2; // om is engaged; its contained value is 2
+ assert (on != om); // on still contains 3. They are not pointers
+
+ /////////////////////////////////////////////////////////////////////////////
+ int i = *ol; // i obtains the value contained in ol
+ assert (i == 1);
+ *ol = 9; // the object contained in ol becomes 9
+ assert(*ol == 9);
+ assert(ol == make_optional(9));
+
+ ///////////////////////////////////
+ int p = 1;
+ optional<int> op = p;
+ assert(*op == 1);
+ p = 2;
+ assert(*op == 1); // value contained in op is separated from p
+
+ ////////////////////////////////
+ if (ol)
+ process(*ol); // use contained value if present
+ else
+ process(); // proceed without contained value
+
+ if (!om)
+ processNil();
+ else
+ process(*om);
+
+ /////////////////////////////////////////
+ process(ol.value_or(0)); // use 0 if ol is disengaged
+
+ ////////////////////////////////////////////
+ ok = nullopt; // if ok was engaged calls T's dtor
+ oj = {}; // assigns a temporary disengaged optional
+};
+
+
+TEST(example_guard)
+{
+ using std::experimental::optional;
+ const optional<int> c = 4;
+ int i = *c; // i becomes 4
+ assert (i == 4);
+ // FAILS: *c = i; // ERROR: cannot assign to const int&
+};
+
+
+TEST(example_ref)
+{
+ using namespace std::experimental;
+ int i = 1;
+ int j = 2;
+ optional<int&> ora; // disengaged optional reference to int
+ optional<int&> orb = i; // contained reference refers to object i
+
+ *orb = 3; // i becomes 3
+ // FAILS: ora = j; // ERROR: optional refs do not have assignment from T
+ // FAILS: ora = {j}; // ERROR: optional refs do not have copy/move assignment
+ // FAILS: ora = orb; // ERROR: no copy/move assignment
+ ora.emplace(j); // OK: contained reference refers to object j
+ ora.emplace(i); // OK: contained reference now refers to object i
+
+ ora = nullopt; // OK: ora becomes disengaged
+};
+
+
+template <typename T>
+T getValue( tr2::optional<T> newVal = tr2::nullopt, tr2::optional<T&> storeHere = tr2::nullopt )
+{
+ T cached{};
+
+ if (newVal) {
+ cached = *newVal;
+
+ if (storeHere) {
+ *storeHere = *newVal; // LEGAL: assigning T to T
+ }
+ }
+ return cached;
+}
+
+TEST(example_optional_arg)
+{
+ int iii = 0;
+ iii = getValue<int>(iii, iii);
+ iii = getValue<int>(iii);
+ iii = getValue<int>();
+
+ {
+ using namespace std::experimental;
+ optional<Guard> grd1{in_place, "res1", 1}; // guard 1 initialized
+ optional<Guard> grd2;
+
+ grd2.emplace("res2", 2); // guard 2 initialized
+ grd1 = nullopt; // guard 1 released
+
+ } // guard 2 released (in dtor)
+};
+
+
+std::tuple<Date, Date, Date> getStartMidEnd() { return std::tuple<Date, Date, Date>{Date{1}, Date{2}, Date{3}}; }
+void run(Date const&, Date const&, Date const&) {}
+
+TEST(example_date)
+{
+ using namespace std::experimental;
+ optional<Date> start, mid, end; // Date doesn't have default ctor (no good default date)
+
+ std::tie(start, mid, end) = getStartMidEnd();
+ run(*start, *mid, *end);
+};
+
+
+std::experimental::optional<char> readNextChar(){ return{}; }
+
+void run(std::experimental::optional<std::string>) {}
+void run(std::complex<double>) {}
+
+
+template <class T>
+void assign_norebind(tr2::optional<T&>& optref, T& obj)
+{
+ if (optref) *optref = obj;
+ else optref.emplace(obj);
+}
+
+template <typename T> void unused(T&&) {}
+
+TEST(example_conceptual_model)
+{
+ using namespace std::experimental;
+
+ optional<int> oi = 0;
+ optional<int> oj = 1;
+ optional<int> ok = nullopt;
+
+ oi = 1;
+ oj = nullopt;
+ ok = 0;
+
+ unused(oi == nullopt);
+ unused(oj == 0);
+ unused(ok == 1);
+};
+
+TEST(example_rationale)
+{
+ using namespace std::experimental;
+ if (optional<char> ch = readNextChar()) {
+ unused(ch);
+ // ...
+ }
+
+ //////////////////////////////////
+ optional<int> opt1 = nullopt;
+ optional<int> opt2 = {};
+
+ opt1 = nullopt;
+ opt2 = {};
+
+ if (opt1 == nullopt) {}
+ if (!opt2) {}
+ if (opt2 == optional<int>{}) {}
+
+
+
+ ////////////////////////////////
+
+ run(nullopt); // pick the second overload
+ // FAILS: run({}); // ambiguous
+
+ if (opt1 == nullopt) {} // fine
+ // FAILS: if (opt2 == {}) {} // ilegal
+
+ ////////////////////////////////
+ assert (optional<unsigned>{} < optional<unsigned>{0});
+ assert (optional<unsigned>{0} < optional<unsigned>{1});
+ assert (!(optional<unsigned>{} < optional<unsigned>{}) );
+ assert (!(optional<unsigned>{1} < optional<unsigned>{1}));
+
+ assert (optional<unsigned>{} != optional<unsigned>{0});
+ assert (optional<unsigned>{0} != optional<unsigned>{1});
+ assert (optional<unsigned>{} == optional<unsigned>{} );
+ assert (optional<unsigned>{0} == optional<unsigned>{0});
+
+ /////////////////////////////////
+ optional<int> o;
+ o = make_optional(1); // copy/move assignment
+ o = 1; // assignment from T
+ o.emplace(1); // emplacement
+
+ ////////////////////////////////////
+ int isas = 0, i = 9;
+ optional<int&> asas = i;
+ assign_norebind(asas, isas);
+
+ /////////////////////////////////////
+ ////tr2::optional<std::vector<int>> ov2 = {2, 3};
+ ////assert (bool(ov2));
+ ////assert ((*ov2)[1] == 3);
+ ////
+ ////////////////////////////////
+ ////std::vector<int> v = {1, 2, 4, 8};
+ ////optional<std::vector<int>> ov = {1, 2, 4, 8};
+
+ ////assert (v == *ov);
+ ////
+ ////ov = {1, 2, 4, 8};
+
+ ////std::allocator<int> a;
+ ////optional<std::vector<int>> ou { in_place, {1, 2, 4, 8}, a };
+
+ ////assert (ou == ov);
+
+ //////////////////////////////
+ // inconvenient syntax:
+ {
+
+ tr2::optional<std::vector<int>> ov2{tr2::in_place, {2, 3}};
+
+ assert (bool(ov2));
+ assert ((*ov2)[1] == 3);
+
+ ////////////////////////////
+
+ std::vector<int> v = {1, 2, 4, 8};
+ optional<std::vector<int>> ov{tr2::in_place, {1, 2, 4, 8}};
+
+ assert (v == *ov);
+
+ ov.emplace({1, 2, 4, 8});
+/*
+ std::allocator<int> a;
+ optional<std::vector<int>> ou { in_place, {1, 2, 4, 8}, a };
+
+ assert (ou == ov);
+*/
+ }
+
+ /////////////////////////////////
+ {
+ typedef int T;
+ optional<optional<T>> ot {in_place};
+ optional<optional<T>> ou {in_place, nullopt};
+ optional<optional<T>> ov {optional<T>{}};
+
+ optional<int> oi;
+ auto ooi = make_optional(oi);
+ static_assert( std::is_same<optional<optional<int>>, decltype(ooi)>::value, "");
+ }
+};
+
+
+bool fun(std::string , std::experimental::optional<int> oi = std::experimental::nullopt)
+{
+ return bool(oi);
+}
+
+TEST(example_converting_ctor)
+{
+ using namespace std::experimental;
+
+ assert (true == fun("dog", 2));
+ assert (false == fun("dog"));
+ assert (false == fun("dog", nullopt)); // just to be explicit
+};
+
+
+TEST(bad_comparison)
+{
+ tr2::optional<int> oi, oj;
+ int i;
+ bool b = (oi == oj);
+ b = (oi >= i);
+ b = (oi == i);
+ unused(b);
+};
+
+
+//// NOT APPLICABLE ANYMORE
+////TEST(perfect_ctor)
+////{
+//// //tr2::optional<std::string> ois = "OS";
+//// assert (*ois == "OS");
+////
+//// // FAILS: tr2::optional<ExplicitStr> oes = "OS";
+//// tr2::optional<ExplicitStr> oes{"OS"};
+//// assert (oes->s == "OS");
+////};
+
+TEST(value_or)
+{
+ tr2::optional<int> oi = 1;
+ int i = oi.value_or(0);
+ assert (i == 1);
+
+ oi = tr2::nullopt;
+ assert (oi.value_or(3) == 3);
+
+ tr2::optional<std::string> os{"AAA"};
+ assert (os.value_or("BBB") == "AAA");
+ os = {};
+ assert (os.value_or("BBB") == "BBB");
+};
+
+TEST(mixed_order)
+{
+ using namespace std::experimental;
+
+ optional<int> oN {nullopt};
+ optional<int> o0 {0};
+ optional<int> o1 {1};
+
+ assert ( (oN < 0));
+ assert ( (oN < 1));
+ assert (!(o0 < 0));
+ assert ( (o0 < 1));
+ assert (!(o1 < 0));
+ assert (!(o1 < 1));
+
+ assert (!(oN >= 0));
+ assert (!(oN >= 1));
+ assert ( (o0 >= 0));
+ assert (!(o0 >= 1));
+ assert ( (o1 >= 0));
+ assert ( (o1 >= 1));
+
+ assert (!(oN > 0));
+ assert (!(oN > 1));
+ assert (!(o0 > 0));
+ assert (!(o0 > 1));
+ assert ( (o1 > 0));
+ assert (!(o1 > 1));
+
+ assert ( (oN <= 0));
+ assert ( (oN <= 1));
+ assert ( (o0 <= 0));
+ assert ( (o0 <= 1));
+ assert (!(o1 <= 0));
+ assert ( (o1 <= 1));
+
+ assert ( (0 > oN));
+ assert ( (1 > oN));
+ assert (!(0 > o0));
+ assert ( (1 > o0));
+ assert (!(0 > o1));
+ assert (!(1 > o1));
+
+ assert (!(0 <= oN));
+ assert (!(1 <= oN));
+ assert ( (0 <= o0));
+ assert (!(1 <= o0));
+ assert ( (0 <= o1));
+ assert ( (1 <= o1));
+
+ assert (!(0 < oN));
+ assert (!(1 < oN));
+ assert (!(0 < o0));
+ assert (!(1 < o0));
+ assert ( (0 < o1));
+ assert (!(1 < o1));
+
+ assert ( (0 >= oN));
+ assert ( (1 >= oN));
+ assert ( (0 >= o0));
+ assert ( (1 >= o0));
+ assert (!(0 >= o1));
+ assert ( (1 >= o1));
+};
+
+struct BadRelops
+{
+ int i;
+};
+
+constexpr bool operator<(BadRelops a, BadRelops b) { return a.i < b.i; }
+constexpr bool operator>(BadRelops a, BadRelops b) { return a.i < b.i; } // intentional error!
+
+TEST(bad_relops)
+{
+ using namespace std::experimental;
+ BadRelops a{1}, b{2};
+ assert (a < b);
+ assert (a > b);
+
+ optional<BadRelops> oa = a, ob = b;
+ assert (oa < ob);
+ assert (!(oa > ob));
+
+ assert (oa < b);
+ assert (oa > b);
+
+ optional<BadRelops&> ra = a, rb = b;
+ assert (ra < rb);
+ assert (!(ra > rb));
+
+ assert (ra < b);
+ assert (ra > b);
+};
+
+
+TEST(mixed_equality)
+{
+ using namespace std::experimental;
+
+ assert (make_optional(0) == 0);
+ assert (make_optional(1) == 1);
+ assert (make_optional(0) != 1);
+ assert (make_optional(1) != 0);
+
+ optional<int> oN {nullopt};
+ optional<int> o0 {0};
+ optional<int> o1 {1};
+
+ assert (o0 == 0);
+ assert ( 0 == o0);
+ assert (o1 == 1);
+ assert ( 1 == o1);
+ assert (o1 != 0);
+ assert ( 0 != o1);
+ assert (o0 != 1);
+ assert ( 1 != o0);
+
+ assert ( 1 != oN);
+ assert ( 0 != oN);
+ assert (oN != 1);
+ assert (oN != 0);
+ assert (!( 1 == oN));
+ assert (!( 0 == oN));
+ assert (!(oN == 1));
+ assert (!(oN == 0));
+
+ std::string cat{"cat"}, dog{"dog"};
+ optional<std::string> oNil{}, oDog{"dog"}, oCat{"cat"};
+
+ assert (oCat == cat);
+ assert ( cat == oCat);
+ assert (oDog == dog);
+ assert ( dog == oDog);
+ assert (oDog != cat);
+ assert ( cat != oDog);
+ assert (oCat != dog);
+ assert ( dog != oCat);
+
+ assert ( dog != oNil);
+ assert ( cat != oNil);
+ assert (oNil != dog);
+ assert (oNil != cat);
+ assert (!( dog == oNil));
+ assert (!( cat == oNil));
+ assert (!(oNil == dog));
+ assert (!(oNil == cat));
+};
+
+TEST(const_propagation)
+{
+ using namespace std::experimental;
+
+ optional<int> mmi{0};
+ static_assert(std::is_same<decltype(*mmi), int&>::value, "WTF");
+
+ const optional<int> cmi{0};
+ static_assert(std::is_same<decltype(*cmi), const int&>::value, "WTF");
+
+ optional<const int> mci{0};
+ static_assert(std::is_same<decltype(*mci), const int&>::value, "WTF");
+
+ optional<const int> cci{0};
+ static_assert(std::is_same<decltype(*cci), const int&>::value, "WTF");
+};
+
+
+static_assert(std::is_base_of<std::logic_error, std::experimental::bad_optional_access>::value, "");
+
+TEST(safe_value)
+{
+ using namespace std::experimental;
+
+ try {
+ optional<int> ovN{}, ov1{1};
+
+ int& r1 = ov1.value();
+ assert (r1 == 1);
+
+ try {
+ ovN.value();
+ assert (false);
+ }
+ catch (bad_optional_access const&) {
+ }
+
+ { // ref variant
+ int i1 = 1;
+ optional<int&> orN{}, or1{i1};
+
+ int& r2 = or1.value();
+ assert (r2 == 1);
+
+ try {
+ orN.value();
+ assert (false);
+ }
+ catch (bad_optional_access const&) {
+ }
+ }
+ }
+ catch(...) {
+ assert (false);
+ }
+};
+
+TEST(optional_ref)
+{
+ using namespace tr2;
+ // FAILS: optional<int&&> orr;
+ // FAILS: optional<nullopt_t&> on;
+ int i = 8;
+ optional<int&> ori;
+ assert (!ori);
+ ori.emplace(i);
+ assert (bool(ori));
+ assert (*ori == 8);
+ assert (&*ori == &i);
+ *ori = 9;
+ assert (i == 9);
+
+ // FAILS: int& ir = ori.value_or(i);
+ int ii = ori.value_or(i);
+ assert (ii == 9);
+ ii = 7;
+ assert (*ori == 9);
+
+ int j = 22;
+ auto&& oj = make_optional(std::ref(j));
+ *oj = 23;
+ assert (&*oj == &j);
+ assert (j == 23);
+};
+
+TEST(optional_ref_const_propagation)
+{
+ using namespace std::experimental;
+
+ int i = 9;
+ const optional<int&> mi = i;
+ int& r = *mi;
+ optional<const int&> ci = i;
+ static_assert(std::is_same<decltype(*mi), int&>::value, "WTF");
+ static_assert(std::is_same<decltype(*ci), const int&>::value, "WTF");
+
+ unused(r);
+};
+
+TEST(optional_ref_assign)
+{
+ using namespace std::experimental;
+
+ int i = 9;
+ optional<int&> ori = i;
+
+ int j = 1;
+ ori = optional<int&>{j};
+ ori = {j};
+ // FAILS: ori = j;
+
+ optional<int&> orx = ori;
+ ori = orx;
+
+ optional<int&> orj = j;
+
+ assert (ori);
+ assert (*ori == 1);
+ assert (ori == orj);
+ assert (i == 9);
+
+ *ori = 2;
+ assert (*ori == 2);
+ assert (ori == 2);
+ assert (2 == ori);
+ assert (ori != 3);
+
+ assert (ori == orj);
+ assert (j == 2);
+ assert (i == 9);
+
+ ori = {};
+ assert (!ori);
+ assert (ori != orj);
+ assert (j == 2);
+ assert (i == 9);
+};
+
+
+TEST(optional_ref_swap)
+{
+ using namespace std::experimental;
+ int i = 0;
+ int j = 1;
+ optional<int&> oi = i;
+ optional<int&> oj = j;
+
+ assert (&*oi == &i);
+ assert (&*oj == &j);
+
+ swap(oi, oj);
+ assert (&*oi == &j);
+ assert (&*oj == &i);
+};
+
+TEST(optional_initialization)
+{
+ using namespace tr2;
+ using std::string;
+ string s = "STR";
+
+ optional<string> os{s};
+ optional<string> ot = s;
+ optional<string> ou{"STR"};
+ optional<string> ov = string{"STR"};
+
+};
+
+#include <unordered_set>
+
+TEST(optional_hashing)
+{
+ using namespace tr2;
+ using std::string;
+
+ std::hash<int> hi;
+ std::hash<optional<int>> hoi;
+ std::hash<string> hs;
+ std::hash<optional<string>> hos;
+
+ assert (hi(0) == hoi(optional<int>{0}));
+ assert (hi(1) == hoi(optional<int>{1}));
+ assert (hi(3198) == hoi(optional<int>{3198}));
+
+ assert (hs("") == hos(optional<string>{""}));
+ assert (hs("0") == hos(optional<string>{"0"}));
+ assert (hs("Qa1#") == hos(optional<string>{"Qa1#"}));
+
+ std::unordered_set<optional<string>> set;
+ assert(set.find({"Qa1#"}) == set.end());
+
+ set.insert({"0"});
+ assert(set.find({"Qa1#"}) == set.end());
+
+ set.insert({"Qa1#"});
+ assert(set.find({"Qa1#"}) != set.end());
+};
+
+
+// optional_ref_emulation
+template <class T>
+struct generic
+{
+ typedef T type;
+};
+
+template <class U>
+struct generic<U&>
+{
+ typedef std::reference_wrapper<U> type;
+};
+
+template <class T>
+using Generic = typename generic<T>::type;
+
+template <class X>
+bool generic_fun()
+{
+ std::experimental::optional<Generic<X>> op;
+ return bool(op);
+}
+
+TEST(optional_ref_emulation)
+{
+ using namespace std::experimental;
+ optional<Generic<int>> oi = 1;
+ assert (*oi == 1);
+
+ int i = 8;
+ int j = 4;
+ optional<Generic<int&>> ori {i};
+ assert (*ori == 8);
+ assert ((void*)&*ori != (void*)&i); // !DIFFERENT THAN optional<T&>
+
+ *ori = j;
+ assert (*ori == 4);
+};
+
+
+# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
+TEST(moved_on_value_or)
+{
+ using namespace tr2;
+ optional<Oracle> oo{in_place};
+
+ assert (oo);
+ assert (oo->s == sDefaultConstructed);
+
+ Oracle o = std::move(oo).value_or( Oracle{OracleVal{}} );
+ assert (oo);
+ assert (oo->s == sMovedFrom);
+ assert (o.s == sMoveConstructed);
+
+ optional<MoveAware<int>> om {in_place, 1};
+ assert (om);
+ assert (om->moved == false);
+
+ /*MoveAware<int> m =*/ std::move(om).value_or( MoveAware<int>{1} );
+ assert (om);
+ assert (om->moved == true);
+
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+ {
+ Date d = optional<Date>{in_place, 1}.value();
+ assert (d.i); // to silence compiler warning
+
+ Date d2 = *optional<Date>{in_place, 1};
+ assert (d2.i); // to silence compiler warning
+ }
+# endif
+};
+# endif
+
+
+TEST(optional_ref_hashing)
+{
+ using namespace tr2;
+ using std::string;
+
+ std::hash<int> hi;
+ std::hash<optional<int&>> hoi;
+ std::hash<string> hs;
+ std::hash<optional<string&>> hos;
+
+ int i0 = 0;
+ int i1 = 1;
+ assert (hi(0) == hoi(optional<int&>{i0}));
+ assert (hi(1) == hoi(optional<int&>{i1}));
+
+ string s{""};
+ string s0{"0"};
+ string sCAT{"CAT"};
+ assert (hs("") == hos(optional<string&>{s}));
+ assert (hs("0") == hos(optional<string&>{s0}));
+ assert (hs("CAT") == hos(optional<string&>{sCAT}));
+
+ std::unordered_set<optional<string&>> set;
+ assert(set.find({sCAT}) == set.end());
+
+ set.insert({s0});
+ assert(set.find({sCAT}) == set.end());
+
+ set.insert({sCAT});
+ assert(set.find({sCAT}) != set.end());
+};
+
+struct Combined
+{
+ int m = 0;
+ int n = 1;
+
+ constexpr Combined() : m{5}, n{6} {}
+ constexpr Combined(int m, int n) : m{m}, n{n} {}
+};
+
+struct Nasty
+{
+ int m = 0;
+ int n = 1;
+
+ constexpr Nasty() : m{5}, n{6} {}
+ constexpr Nasty(int m, int n) : m{m}, n{n} {}
+
+ int operator&() { return n; }
+ int operator&() const { return n; }
+};
+
+TEST(arrow_operator)
+{
+ using namespace std::experimental;
+
+ optional<Combined> oc1{in_place, 1, 2};
+ assert (oc1);
+ assert (oc1->m == 1);
+ assert (oc1->n == 2);
+
+ optional<Nasty> on{in_place, 1, 2};
+ assert (on);
+ assert (on->m == 1);
+ assert (on->n == 2);
+};
+
+TEST(arrow_wit_optional_ref)
+{
+ using namespace std::experimental;
+
+ Combined c{1, 2};
+ optional<Combined&> oc = c;
+ assert (oc);
+ assert (oc->m == 1);
+ assert (oc->n == 2);
+
+ Nasty n{1, 2};
+ Nasty m{3, 4};
+ Nasty p{5, 6};
+
+ optional<Nasty&> on{n};
+ assert (on);
+ assert (on->m == 1);
+ assert (on->n == 2);
+
+ on = {m};
+ assert (on);
+ assert (on->m == 3);
+ assert (on->n == 4);
+
+ on.emplace(p);
+ assert (on);
+ assert (on->m == 5);
+ assert (on->n == 6);
+
+ optional<Nasty&> om{in_place, n};
+ assert (om);
+ assert (om->m == 1);
+ assert (om->n == 2);
+};
+
+TEST(no_dangling_reference_in_value)
+{
+ // this mostly tests compiler warnings
+ using namespace std::experimental;
+ optional<int> oi {2};
+ unused (oi.value());
+ const optional<int> coi {3};
+ unused (coi.value());
+};
+
+struct CountedObject
+{
+ static int _counter;
+ bool _throw;
+ CountedObject(bool b) : _throw(b) { ++_counter; }
+ CountedObject(CountedObject const& rhs) : _throw(rhs._throw) { if (_throw) throw int(); }
+ ~CountedObject() { --_counter; }
+};
+
+int CountedObject::_counter = 0;
+
+TEST(exception_safety)
+{
+ using namespace std::experimental;
+ try {
+ optional<CountedObject> oo(in_place, true); // throw
+ optional<CountedObject> o1(oo);
+ }
+ catch(...)
+ {
+ //
+ }
+ assert(CountedObject::_counter == 0);
+
+ try {
+ optional<CountedObject> oo(in_place, true); // throw
+ optional<CountedObject> o1(std::move(oo)); // now move
+ }
+ catch(...)
+ {
+ //
+ }
+ assert(CountedObject::_counter == 0);
+};
+
+//// constexpr tests
+
+// these 4 classes have different noexcept signatures in move operations
+struct NothrowBoth {
+ NothrowBoth(NothrowBoth&&) noexcept(true) {};
+ void operator=(NothrowBoth&&) noexcept(true) {};
+};
+struct NothrowCtor {
+ NothrowCtor(NothrowCtor&&) noexcept(true) {};
+ void operator=(NothrowCtor&&) noexcept(false) {};
+};
+struct NothrowAssign {
+ NothrowAssign(NothrowAssign&&) noexcept(false) {};
+ void operator=(NothrowAssign&&) noexcept(true) {};
+};
+struct NothrowNone {
+ NothrowNone(NothrowNone&&) noexcept(false) {};
+ void operator=(NothrowNone&&) noexcept(false) {};
+};
+
+void test_noexcept()
+{
+ {
+ tr2::optional<NothrowBoth> b1, b2;
+ static_assert(noexcept(tr2::optional<NothrowBoth>{tr2::constexpr_move(b1)}), "bad noexcept!");
+ static_assert(noexcept(b1 = tr2::constexpr_move(b2)), "bad noexcept!");
+ }
+ {
+ tr2::optional<NothrowCtor> c1, c2;
+ static_assert(noexcept(tr2::optional<NothrowCtor>{tr2::constexpr_move(c1)}), "bad noexcept!");
+ static_assert(!noexcept(c1 = tr2::constexpr_move(c2)), "bad noexcept!");
+ }
+ {
+ tr2::optional<NothrowAssign> a1, a2;
+ static_assert(!noexcept(tr2::optional<NothrowAssign>{tr2::constexpr_move(a1)}), "bad noexcept!");
+ static_assert(!noexcept(a1 = tr2::constexpr_move(a2)), "bad noexcept!");
+ }
+ {
+ tr2::optional<NothrowNone> n1, n2;
+ static_assert(!noexcept(tr2::optional<NothrowNone>{tr2::constexpr_move(n1)}), "bad noexcept!");
+ static_assert(!noexcept(n1 = tr2::constexpr_move(n2)), "bad noexcept!");
+ }
+}
+
+
+void constexpr_test_disengaged()
+{
+ constexpr tr2::optional<int> g0{};
+ constexpr tr2::optional<int> g1{tr2::nullopt};
+ static_assert( !g0, "initialized!" );
+ static_assert( !g1, "initialized!" );
+
+ static_assert( bool(g1) == bool(g0), "ne!" );
+
+ static_assert( g1 == g0, "ne!" );
+ static_assert( !(g1 != g0), "ne!" );
+ static_assert( g1 >= g0, "ne!" );
+ static_assert( !(g1 > g0), "ne!" );
+ static_assert( g1 <= g0, "ne!" );
+ static_assert( !(g1 <g0), "ne!" );
+
+ static_assert( g1 == tr2::nullopt, "!" );
+ static_assert( !(g1 != tr2::nullopt), "!" );
+ static_assert( g1 <= tr2::nullopt, "!" );
+ static_assert( !(g1 < tr2::nullopt), "!" );
+ static_assert( g1 >= tr2::nullopt, "!" );
+ static_assert( !(g1 > tr2::nullopt), "!" );
+
+ static_assert( (tr2::nullopt == g0), "!" );
+ static_assert( !(tr2::nullopt != g0), "!" );
+ static_assert( (tr2::nullopt >= g0), "!" );
+ static_assert( !(tr2::nullopt > g0), "!" );
+ static_assert( (tr2::nullopt <= g0), "!" );
+ static_assert( !(tr2::nullopt < g0), "!" );
+
+ static_assert( (g1 != tr2::optional<int>(1)), "!" );
+ static_assert( !(g1 == tr2::optional<int>(1)), "!" );
+ static_assert( (g1 < tr2::optional<int>(1)), "!" );
+ static_assert( (g1 <= tr2::optional<int>(1)), "!" );
+ static_assert( !(g1 > tr2::optional<int>(1)), "!" );
+ static_assert( !(g1 > tr2::optional<int>(1)), "!" );
+}
+
+
+constexpr tr2::optional<int> g0{};
+constexpr tr2::optional<int> g2{2};
+static_assert( g2, "not initialized!" );
+static_assert( *g2 == 2, "not 2!" );
+static_assert( g2 == tr2::optional<int>(2), "not 2!" );
+static_assert( g2 != g0, "eq!" );
+
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+static_assert( *tr2::optional<int>{3} == 3, "WTF!" );
+static_assert( tr2::optional<int>{3}.value() == 3, "WTF!" );
+static_assert( tr2::optional<int>{3}.value_or(1) == 3, "WTF!" );
+static_assert( tr2::optional<int>{}.value_or(4) == 4, "WTF!" );
+# endif
+
+constexpr tr2::optional<Combined> gc0{tr2::in_place};
+static_assert(gc0->n == 6, "WTF!");
+
+// optional refs
+int gi = 0;
+constexpr tr2::optional<int&> gori = gi;
+constexpr tr2::optional<int&> gorn{};
+constexpr int& gri = *gori;
+static_assert(gori, "WTF");
+static_assert(!gorn, "WTF");
+static_assert(gori != tr2::nullopt, "WTF");
+static_assert(gorn == tr2::nullopt, "WTF");
+static_assert(&gri == &*gori, "WTF");
+
+constexpr int gci = 1;
+constexpr tr2::optional<int const&> gorci = gci;
+constexpr tr2::optional<int const&> gorcn{};
+
+static_assert(gorcn < gorci, "WTF");
+static_assert(gorcn <= gorci, "WTF");
+static_assert(gorci == gorci, "WTF");
+static_assert(*gorci == 1, "WTF");
+static_assert(gorci == gci, "WTF");
+
+namespace constexpr_optional_ref_and_arrow
+{
+ using namespace std::experimental;
+ constexpr Combined c{1, 2};
+ constexpr optional<Combined const&> oc = c;
+ static_assert(oc, "WTF!");
+ static_assert(oc->m == 1, "WTF!");
+ static_assert(oc->n == 2, "WTF!");
+}
+
+#if OPTIONAL_HAS_CONSTEXPR_INIT_LIST
+
+namespace InitList
+{
+ using namespace std::experimental;
+
+ struct ConstInitLister
+ {
+ template <typename T>
+ constexpr ConstInitLister(std::initializer_list<T> il) : len (il.size()) {}
+ size_t len;
+ };
+
+ constexpr ConstInitLister CIL {2, 3, 4};
+ static_assert(CIL.len == 3, "WTF!");
+
+ constexpr optional<ConstInitLister> oil {in_place, {4, 5, 6, 7}};
+ static_assert(oil, "WTF!");
+ static_assert(oil->len == 4, "WTF!");
+}
+
+#endif // OPTIONAL_HAS_CONSTEXPR_INIT_LIST
+
+// end constexpr tests
+
+
+#include <string>
+
+
+struct VEC
+{
+ std::vector<int> v;
+ template <typename... X>
+ VEC( X&&...x) : v(std::forward<X>(x)...) {}
+
+ template <typename U, typename... X>
+ VEC(std::initializer_list<U> il, X&&...x) : v(il, std::forward<X>(x)...) {}
+};
+
+
+
+int main() {
+ tr2::optional<int> oi = 1;
+ assert (bool(oi));
+ oi.operator=({});
+ assert (!oi);
+
+ VEC v = {5, 6};
+
+ if (OPTIONAL_HAS_THIS_RVALUE_REFS)
+ std::cout << "Optional has rvalue references for *this" << std::endl;
+ else
+ std::cout << "Optional doesn't have rvalue references for *this" << std::endl;
+
+ if (OPTIONAL_HAS_CONSTEXPR_INIT_LIST)
+ std::cout << "Optional has constexpr initializer_list" << std::endl;
+ else
+ std::cout << "Optional doesn't have constexpr initializer_list" << std::endl;
+
+ if (OPTIONAL_HAS_MOVE_ACCESSORS)
+ std::cout << "Optional has constexpr move accessors" << std::endl;
+ else
+ std::cout << "Optional doesn't have constexpr move accessors" << std::endl;
+}
+
diff --git a/3rdparty/sol2/Optional/test_type_traits.cpp b/3rdparty/sol2/Optional/test_type_traits.cpp
new file mode 100644
index 00000000000..8ec82b70871
--- /dev/null
+++ b/3rdparty/sol2/Optional/test_type_traits.cpp
@@ -0,0 +1,66 @@
+// Copyright (C) 2011 - 2012 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#if (defined __clang__)
+ namespace std { class type_info; }
+#endif
+
+# include "optional.hpp"
+
+namespace std { namespace experimental {
+
+struct Val
+{
+ Val(){}
+ Val( Val const & ){}
+ Val( Val && ) noexcept {}
+
+ Val & operator=( Val const & ) = delete;
+ Val & operator=( Val && ) noexcept = delete;
+};
+
+struct Safe
+{
+ Safe(){}
+ Safe( Safe const & ){}
+ Safe( Safe && ) noexcept {}
+
+ Safe & operator=( Safe const & ){ return *this; }
+ Safe & operator=( Safe && ) noexcept { return *this; }
+};
+
+struct Unsafe
+{
+ Unsafe(){}
+ Unsafe( Unsafe const & ){}
+ Unsafe( Unsafe && ){}
+
+ Unsafe & operator=( Unsafe const & ){ return *this; }
+ Unsafe & operator=( Unsafe && ) { return *this; }
+};
+
+struct VoidNothrowBoth
+{
+ VoidNothrowBoth(VoidNothrowBoth&&) noexcept(true) {};
+ void operator=(VoidNothrowBoth&&) noexcept(true) {}; // note void return type
+};
+
+
+static_assert(is_nothrow_move_constructible<Safe>::value, "WTF!");
+static_assert(!is_nothrow_move_constructible<Unsafe>::value, "WTF!");
+
+static_assert(is_assignable<Safe&, Safe&&>::value, "WTF!");
+static_assert(!is_assignable<Val&, Val&&>::value, "WTF!");
+
+static_assert(is_nothrow_move_assignable<Safe>::value, "WTF!");
+static_assert(!is_nothrow_move_assignable<Unsafe>::value, "WTF!");
+
+static_assert(is_nothrow_move_constructible<VoidNothrowBoth>::value, "WTF!");
+static_assert(is_nothrow_move_assignable<VoidNothrowBoth>::value, "WTF!");
+
+}} // namespace std::experimental
+
+int main() { }
diff --git a/3rdparty/sol2/README.md b/3rdparty/sol2/README.md
new file mode 100644
index 00000000000..3eb58f6d3de
--- /dev/null
+++ b/3rdparty/sol2/README.md
@@ -0,0 +1,75 @@
+## Sol 2.14
+
+[![Build Status](https://travis-ci.org/ThePhD/sol2.svg?branch=develop)](https://travis-ci.org/ThePhD/sol2)
+[![Documentation Status](https://readthedocs.org/projects/sol2/badge/?version=latest)](http://sol2.readthedocs.io/en/latest/?badge=latest)
+
+Sol is a C++ library binding to Lua. It currently supports all Lua versions 5.1+ (LuaJIT 2.x included). Sol aims to be easy to use and easy to add to a project.
+The library is header-only for easy integration with projects.
+
+## Documentation
+
+Find it [here](http://sol2.rtfd.io/). A run-through kind of tutorial is [here](http://sol2.readthedocs.io/en/latest/tutorial/all-the-things.html)! The API documentation goes over most cases (particularly, the "api/usertype" and "api/proxy" and "api/function" sections) that should still get you off your feet and going, and there's an examples directory [here](https://github.com/ThePhD/sol2/tree/develop/examples) as well.
+
+## Sneak Peek
+
+```cpp
+#include <sol.hpp>
+#include <cassert>
+
+int main() {
+ sol::state lua;
+ int x = 0;
+ lua.set_function("beep", [&x]{ ++x; });
+ lua.script("beep()");
+ assert(x == 1);
+}
+```
+
+```cpp
+#include <sol.hpp>
+#include <cassert>
+
+struct vars {
+ int boop = 0;
+};
+
+int main() {
+ sol::state lua;
+ lua.new_usertype<vars>("vars", "boop", &vars::boop);
+ lua.script("beep = vars.new()\n"
+ "beep.boop = 1");
+ assert(lua.get<vars>("beep").boop == 1);
+}
+```
+
+More examples are given in the examples directory.
+
+## Creating a single header
+
+You can grab a single header out of the library [here](https://github.com/ThePhD/sol2/tree/develop/single/sol). For stable version, check the releases tab on github for a provided single header file for maximum ease of use. A script called `single.py` is provided in the repository if there's some bleeding edge change that hasn't been published on the releases page. You can run this script to create a single file version of the library so you can only include that part of it. Check `single.py --help` for more info.
+
+## Features
+
+- [Fastest in the land](http://sol2.readthedocs.io/en/latest/benchmarks.html) (see: sol2 graph and table entries).
+- Supports retrieval and setting of multiple types including `std::string` and `std::map/unordered_map`.
+- Lambda, function, and member function bindings are supported.
+- Intermediate type for checking if a variable exists.
+- Simple API that completely abstracts away the C stack API, including `protected_function` with the ability to use an error-handling function.
+- `operator[]`-style manipulation of tables
+- C++ type representations in lua userdata as `usertype`s with guaranteed cleanup.
+- Customization points to allow your C++ objects to be pushed and retrieved from Lua as multiple consecutive objects, or anything else you desire!
+- Overloaded function calls: `my_function(1); my_function("Hello")` in the same lua script route to different function calls based on parameters
+- Support for tables, nested tables, table iteration with `table.for_each` / `begin()` and `end()` iterators.
+
+## Supported Compilers
+
+Sol makes use of C++11/14 features. GCC 4.9 and Clang 3.4 (with std=c++1z and appropriate standard library) or higher should be able to compile without problems. However, the
+officially supported and CI-tested compilers are:
+
+- GCC 4.9.0+
+- Clang 3.5+
+- Visual Studio 2015 Community (Visual C++ 14.0)+
+
+## License
+
+Sol is distributed with an MIT License. You can see LICENSE.txt for more info.
diff --git a/3rdparty/sol2/bootstrap.py b/3rdparty/sol2/bootstrap.py
new file mode 100644
index 00000000000..d1e6bfdfdcb
--- /dev/null
+++ b/3rdparty/sol2/bootstrap.py
@@ -0,0 +1,206 @@
+#!/usr/bin/env python
+
+import ninja_syntax
+import os, sys, glob, re
+import itertools
+import argparse
+
+# utilities
+def flags(*args):
+ return ' '.join(itertools.chain(*args))
+
+def includes(l):
+ return ['-I"{}"'.format(x) for x in l]
+
+def library_includes(l):
+ return ['-L"{}"'.format(x) for x in l]
+
+def libraries(l):
+ return ['-l{}'.format(x) for x in l]
+
+def dependencies(l):
+ return ['-isystem"{}"'.format(x) for x in l]
+
+def object_file(f):
+ (root, ext) = os.path.splitext(f)
+ return os.path.join(objdir, root + '.o')
+
+def replace_extension(f, e):
+ (root, ext) = os.path.splitext(f)
+ return root + e
+
+# Default install dir
+install_dir = os.path.join('/usr', 'include') if 'linux' in sys.platform else 'include'
+
+# Compiler: Read from environment or defaulted
+cxx = os.environ.get('CXX', "g++")
+
+# command line stuff
+parser = argparse.ArgumentParser()
+parser.add_argument('--debug', action='store_true', help='compile with debug flags')
+parser.add_argument('--cxx', metavar='<compiler>', help='compiler name to use (default: env.CXX=%s)' % cxx, default=cxx)
+parser.add_argument('--cxx-flags', help='additional flags passed to the compiler', default='')
+parser.add_argument('--ci', action='store_true', help=argparse.SUPPRESS)
+parser.add_argument('--testing', action='store_true', help=argparse.SUPPRESS)
+parser.add_argument('--lua-version', help='Lua version, e.g. lua53', default='lua53')
+parser.add_argument('--lua-lib', help='lua library name (without the lib on *nix).', default='lua')
+parser.add_argument('--lua-dir', metavar='<dir>', help='directory lua is in with include and lib subdirectories')
+parser.add_argument('--install-dir', metavar='<dir>', help='directory to install the headers to', default=install_dir);
+parser.epilog = """In order to install sol, administrative privileges might be required.
+Note that installation is done through the 'ninja install' command. To uninstall, the
+command used is 'ninja uninstall'. The default installation directory for this
+system is {}""".format(install_dir)
+
+args = parser.parse_args()
+
+# general variables
+include = [ '.', './include' ]
+depends = [os.path.join('Catch', 'include')]
+cxxflags = [ '-Wall', '-Wextra', '-Wpedantic', '-pedantic', '-pedantic-errors', '-std=c++14', '-ftemplate-depth=1024' ]
+cxxflags.extend([p for p in re.split("( |\\\".*?\\\"|'.*?')", args.cxx_flags) if p.strip()])
+example_cxxflags = [ '-Wall', '-Wextra', '-Wpedantic', '-pedantic', '-pedantic-errors', '-std=c++14', '-ftemplate-depth=1024' ]
+example_cxxflags.extend([p for p in re.split("( |\\\".*?\\\"|'.*?')", args.cxx_flags) if p.strip()])
+ldflags = []
+script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
+sol_dir = os.path.join(script_dir, 'sol')
+sol_file = os.path.join(script_dir, 'sol.hpp')
+
+copy_command = 'cp -rf {} $in && cp -f {} $in'.format(sol_dir, sol_file)
+remove_command = 'rm -rf {} && rm -f {}'.format(os.path.join(args.install_dir, 'sol'), os.path.join(args.install_dir, 'sol.hpp'))
+if sys.platform == 'win32':
+ copy_command = 'robocopy /COPYALL /E {} $in && robocopy /COPYALL {} $in'.format(sol_dir, sol_file)
+ remove_command = 'rmdir /S /Q {} && erase /F /S /Q /A {}'.format(os.path.join(args.install_dir, 'sol'),
+ os.path.join(args.install_dir, 'sol.hpp'))
+
+if not args.lua_lib:
+ args.lua_lib = 'lua'
+
+if args.debug:
+ cxxflags.extend(['-g', '-O0'])
+else:
+ cxxflags.extend(['-DNDEBUG', '-O3'])
+example_cxxflags.extend(['-g', '-O0'])
+
+if args.lua_dir:
+ include.extend([os.path.join(args.lua_dir, 'include')])
+ ldflags.extend(library_includes([os.path.join(args.lua_dir, 'lib')]))
+
+if 'linux' in sys.platform:
+ lua_version = os.environ.get('LUA_VERSION', args.lua_version)
+ if re.match(r'lua5[1-3]', lua_version):
+ # Using normal lua
+ lua_lib = lua_version[:-1] + '.' + lua_version[-1]
+ lua_incl = lua_lib
+ elif re.match(r'luajit5[1-3]', lua_version):
+ # luajit
+ lua_incl = 'luajit-2.0' # I don't get this..
+ lua_lib = lua_version[:-2] + '-' + lua_version[-2] + '.' + lua_version[-1]
+ include.extend(['/usr/include/luajit-2.0/', '/usr/local/include/luajit-2.0/'])
+ else:
+ raise Exception('Unknown lua_version={}' % lua_version)
+
+
+ include.extend(['/usr/include/' + lua_incl, '/usr/local/include/' + lua_incl])
+ ldflags.extend(library_includes(['/usr/local/lib']))
+ ldflags.extend(libraries([lua_lib]))
+elif 'darwin' in sys.platform:
+ # OSX
+ lua_version = os.environ.get('LUA_VERSION', args.lua_version)
+ if re.match(r'lua5[1-3]', lua_version):
+ # Using normal lua
+ lua_incl = lua_version[:-1] + '.' + lua_version[-1]
+ lua_lib = lua_version[:-2] + '.' + lua_version[-2] + '.' + lua_version[-1]
+ elif re.match(r'luajit', lua_version):
+ # luajit
+ lua_incl = 'luajit-2.0'
+ lua_lib = 'luajit'
+ ldflags.extend(['-pagezero_size 10000', '-image_base 100000000'])
+ elif re.match(r'luajit5[1-3]', lua_version):
+ # luajit
+ lua_incl = 'luajit-2.0'
+ lua_lib = lua_version[:-2] + '-' + lua_version[-2] + '.' + lua_version[-1]
+ ldflags.extend(['-pagezero_size 10000', '-image_base 100000000'])
+ else:
+ raise Exception('Unknown lua_version={}' % lua_version)
+
+ depends.extend(['/usr/include/' + lua_incl, '/usr/local/include/' + lua_incl])
+ ldflags.extend(library_includes(['/usr/local/lib']))
+ ldflags.extend(libraries([lua_lib]))
+else:
+ ldflags.extend(libraries([args.lua_lib]))
+
+if args.testing:
+ cxxflags.append('-Wmissing-declarations')
+
+if 'linux' in sys.platform:
+ ldflags.extend(libraries(['dl']))
+
+builddir = 'bin'
+objdir = 'obj'
+if 'win32' in sys.platform:
+ tests = os.path.join(builddir, 'tests.exe')
+else:
+ tests = os.path.join(builddir, 'tests')
+
+tests_inputs = []
+tests_object_files = []
+for f in glob.glob('test*.cpp'):
+ obj = object_file(f)
+ tests_inputs.append(f)
+ tests_object_files.append(obj)
+
+examples = []
+examples_input = []
+for f in glob.glob('examples/*.cpp'):
+ if 'win32' in sys.platform:
+ example = os.path.join(builddir, replace_extension(f, '.exe'))
+ else:
+ example = os.path.join(builddir, replace_extension(f, ''))
+ examples_input.append(f)
+ examples.append(example)
+
+
+# ninja file
+ninja = ninja_syntax.Writer(open('build.ninja', 'w'))
+
+# variables
+ninja.variable('ninja_required_version', '1.3')
+ninja.variable('builddir', 'bin')
+ninja.variable('cxx', args.cxx)
+ninja.variable('cxxflags', flags(cxxflags + includes(include) + dependencies(depends)))
+ninja.variable('example_cxxflags', flags(example_cxxflags + includes(include) + dependencies(depends)))
+ninja.variable('ldflags', flags(ldflags))
+ninja.newline()
+
+# rules
+ninja.rule('bootstrap', command = ' '.join(['python'] + sys.argv), generator = True)
+ninja.rule('compile', command = '$cxx -MMD -MF $out.d -c $cxxflags -Werror $in -o $out',
+ deps = 'gcc', depfile = '$out.d',
+ description = 'compiling $in to $out')
+ninja.rule('link', command = '$cxx $cxxflags $in -o $out $ldflags', description = 'creating $out')
+ninja.rule('tests_runner', command = tests)
+ninja.rule('examples_runner', command = 'cmd /c ' + (' && '.join(examples)) if 'win32' in sys.platform else ' && '.join(examples) )
+ninja.rule('example', command = '$cxx $example_cxxflags -MMD -MF $out.d $in -o $out $ldflags',
+ deps = 'gcc', depfile = '$out.d',
+ description = 'compiling example $in to $out')
+ninja.rule('installer', command = copy_command)
+ninja.rule('uninstaller', command = remove_command)
+ninja.newline()
+
+# builds
+ninja.build('build.ninja', 'bootstrap', implicit = sys.argv[0])
+
+for obj, f in zip(tests_object_files, tests_inputs):
+ ninja.build(obj, 'compile', inputs = f)
+
+for example, f in zip(examples, examples_input):
+ ninja.build(example, 'example', inputs = f)
+
+ninja.build(tests, 'link', inputs = tests_object_files)
+ninja.build('tests', 'phony', inputs = tests)
+ninja.build('examples', 'phony', inputs = examples)
+ninja.build('install', 'installer', inputs = args.install_dir)
+ninja.build('uninstall', 'uninstaller')
+ninja.build('run', 'tests_runner', implicit = 'tests')
+ninja.build('run_examples', 'examples_runner', implicit = 'examples')
+ninja.default('run run_examples')
diff --git a/3rdparty/sol2/docs/Makefile b/3rdparty/sol2/docs/Makefile
new file mode 100644
index 00000000000..ac69fbd7e5d
--- /dev/null
+++ b/3rdparty/sol2/docs/Makefile
@@ -0,0 +1,216 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " applehelp to make an Apple Help Book"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " texinfo to make Texinfo files"
+ @echo " info to make Texinfo files and run them through makeinfo"
+ @echo " gettext to make PO message catalogs"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " xml to make Docutils-native XML files"
+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+ @echo " coverage to run coverage check of the documentation (if enabled)"
+
+.PHONY: clean
+clean:
+ rm -rf $(BUILDDIR)/*
+
+.PHONY: html
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+.PHONY: dirhtml
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+.PHONY: singlehtml
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+.PHONY: pickle
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+.PHONY: json
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+.PHONY: htmlhelp
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+.PHONY: qthelp
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Sol.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Sol.qhc"
+
+.PHONY: applehelp
+applehelp:
+ $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
+ @echo
+ @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
+ @echo "N.B. You won't be able to view it unless you put it in" \
+ "~/Library/Documentation/Help or install it in your application" \
+ "bundle."
+
+.PHONY: devhelp
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/Sol"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Sol"
+ @echo "# devhelp"
+
+.PHONY: epub
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+.PHONY: latex
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+.PHONY: latexpdf
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+.PHONY: latexpdfja
+latexpdfja:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through platex and dvipdfmx..."
+ $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+.PHONY: text
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+.PHONY: man
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+.PHONY: texinfo
+texinfo:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo
+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+ @echo "Run \`make' in that directory to run these through makeinfo" \
+ "(use \`make info' here to do that automatically)."
+
+.PHONY: info
+info:
+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+ @echo "Running Texinfo files through makeinfo..."
+ make -C $(BUILDDIR)/texinfo info
+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+.PHONY: gettext
+gettext:
+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+ @echo
+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+.PHONY: changes
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+.PHONY: linkcheck
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+.PHONY: doctest
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
+
+.PHONY: coverage
+coverage:
+ $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
+ @echo "Testing of coverage in the sources finished, look at the " \
+ "results in $(BUILDDIR)/coverage/python.txt."
+
+.PHONY: xml
+xml:
+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+ @echo
+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+.PHONY: pseudoxml
+pseudoxml:
+ $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+ @echo
+ @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/3rdparty/sol2/docs/make.bat b/3rdparty/sol2/docs/make.bat
new file mode 100644
index 00000000000..ab1cb81297b
--- /dev/null
+++ b/3rdparty/sol2/docs/make.bat
@@ -0,0 +1,263 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
+set I18NSPHINXOPTS=%SPHINXOPTS% source
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. xml to make Docutils-native XML files
+ echo. pseudoxml to make pseudoxml-XML files for display purposes
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ echo. coverage to run coverage check of the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+
+REM Check if sphinx-build is available and fallback to Python version if any
+%SPHINXBUILD% 1>NUL 2>NUL
+if errorlevel 9009 goto sphinx_python
+goto sphinx_ok
+
+:sphinx_python
+
+set SPHINXBUILD=python -m sphinx.__init__
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+:sphinx_ok
+
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Sol.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Sol.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdf" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf
+ cd %~dp0
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdfja" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf-ja
+ cd %~dp0
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+if "%1" == "coverage" (
+ %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of coverage in the sources finished, look at the ^
+results in %BUILDDIR%/coverage/python.txt.
+ goto end
+)
+
+if "%1" == "xml" (
+ %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The XML files are in %BUILDDIR%/xml.
+ goto end
+)
+
+if "%1" == "pseudoxml" (
+ %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
+ goto end
+)
+
+:end
diff --git a/3rdparty/sol2/docs/source/api/api-top.rst b/3rdparty/sol2/docs/source/api/api-top.rst
new file mode 100644
index 00000000000..f9b0378b30e
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/api-top.rst
@@ -0,0 +1,46 @@
+api reference manual
+====================
+
+Browse the various function and classes :doc:`Sol<../index>` utilizes to make your life easier when working with Lua.
+
+
+.. toctree::
+ :caption: Sol API
+ :name: apitoc
+ :maxdepth: 2
+
+ state
+ table
+ proxy
+ as_table
+ usertype
+ simple_usertype
+ usertype_memory
+ unique_usertype_traits
+ tie
+ function
+ protected_function
+ coroutine
+ error
+ object
+ userdata
+ reference
+ thread
+ stack_reference
+ make_reference
+ optional
+ this_state
+ variadic_args
+ overload
+ property
+ var
+ protect
+ readonly
+ as_function
+ c_call
+ resolve
+ stack
+ user
+ compatibility
+ types
+ metatable_key
diff --git a/3rdparty/sol2/docs/source/api/as_function.rst b/3rdparty/sol2/docs/source/api/as_function.rst
new file mode 100644
index 00000000000..bb058ba52c7
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/as_function.rst
@@ -0,0 +1,67 @@
+as_function
+===========
+make sure an object is pushed as a function
+-------------------------------------------
+
+.. code-block:: cpp
+
+ template <typename Sig = sol::function_sig<>, typename... Args>
+ function_argumants<Sig, Args...> as_function ( Args&& ... );
+
+This function serves the purpose of ensuring that a callable struct (like a lambda) can be passed to the ``set( key, value )`` calls on :ref:`sol::table<set-value>` and be treated like a function binding instead of a userdata. It is recommended that one uses the :ref:`sol::table::set_function<set-function>` call instead, but if for some reason one must use ``set``, then ``as_function`` can help ensure a callable struct is handled like a lambda / callable, and not as just a userdata structure.
+
+This class can also make it so usertypes bind variable types as functions to for usertype bindings.
+
+.. code-block:: cpp
+
+ #include <sol.hpp>
+
+ int main () {
+ struct callable {
+ int operator()( int a, bool b ) {
+ return a + b ? 10 : 20;
+ }
+ };
+
+
+ sol::state lua;
+ // Binds struct as userdata
+ lua.set( "not_func", callable() );
+ // Binds struct as function
+ lua.set( "func", sol::as_function( callable() ) );
+ // equivalent: lua.set_function( "func", callable() );
+ // equivalent: lua["func"] = callable();
+ }
+
+Note that if you actually want a userdata, but you want it to be callable, you simply need to create a :ref:`sol::table::new_usertype<new-usertype>` and then bind the ``"__call"`` metamethod (or just use ``sol::meta_function::call`` :ref:`enumeration<meta_function_enum>`).
+
+Here's an example of binding a variable as a function to a usertype:
+
+.. code-block:: cpp
+
+ #include <sol.hpp>
+
+ int main () {
+ class B {
+ public:
+ int bvar = 24;
+ };
+
+ sol::state lua;
+ lua.open_libraries();
+ lua.new_usertype<B>("B",
+ // bind as variable
+ "b", &B::bvar,
+ // bind as function
+ "f", sol::as_function(&B::bvar)
+ );
+
+ B b;
+ lua.set("b", &b);
+ lua.script("x = b:f()");
+ lua.script("y = b.b");
+ int x = lua["x"];
+ int y = lua["y"];
+ assert(x == 24);
+ assert(y == 24);
+ }
diff --git a/3rdparty/sol2/docs/source/api/as_table.rst b/3rdparty/sol2/docs/source/api/as_table.rst
new file mode 100644
index 00000000000..58870fa770f
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/as_table.rst
@@ -0,0 +1,24 @@
+as_table
+===========
+make sure an object is pushed as a table
+----------------------------------------
+
+.. code-block:: cpp
+
+ template <typename T>
+ as_table_t { ... };
+
+ template <typename T>
+ as_table_t<T> as_function ( T&& container );
+
+This function serves the purpose of ensuring that an object is pushed -- if possible -- like a table into Lua. The container passed here can be a pointer, a reference, a ``std::reference_wrapper`` around a container, or just a plain container value. It must have a begin/end function, and if it has a ``std::pair<Key, Value>`` as its ``value_type``, it will be pushed as a dictionary. Otherwise, it's pushed as a sequence.
+
+.. code-block:: cpp
+
+ sol::state lua;
+ lua.open_libraries();
+ lua.set("my_table", sol::as_table(std::vector<int>{ 1, 2, 3, 4, 5 }));
+ lua.script("for k, v in ipairs(my_table) do print(k, v) assert(k == v) end");
+
+
+Note that any caveats with Lua tables apply the moment it is serialized, and the data cannot be gotten out back out in C++ as a vector without explicitly using the ``as_table_t`` marker for your get and conversion operations using Sol. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/c_call.rst b/3rdparty/sol2/docs/source/api/c_call.rst
new file mode 100644
index 00000000000..36395eea549
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/c_call.rst
@@ -0,0 +1,71 @@
+c_call
+======
+Templated type to transport functions through templates
+-------------------------------------------------------
+
+.. code-block:: cpp
+
+ template <typename Function, Function f>
+ int c_call (lua_State* L);
+
+ template <typename... Functions>
+ int c_call (lua_State* L);
+
+The goal of ``sol::c_call<...>`` is to provide a way to wrap a function and transport it through a compile-time context. This enables faster speed at the cost of a much harder to read / poorer interface. ``sol::c_call`` expects a type for its first template argument, and a value of the previously provided type for the second template argument. To make a compile-time transported overloaded function, specify multiple functions in the same ``type, value`` pairing, but put it inside of a ``sol::wrap``. Note that is can also be placed into the argument list for a :doc:`usertype<usertype>` as well.
+
+It is advisable for the user to consider making a macro to do the necessary ``decltype( &function_name, ), function_name``. Sol does not provide one because many codebases already have `one similar to this`_.
+
+Here's an example below of various ways to use ``sol::c_call``:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Compile-time transported function calls
+
+ #include "sol.hpp"
+
+ int f1(int) { return 32; }
+ int f2(int, int) { return 1; }
+ struct fer {
+ double f3(int, int) {
+ return 2.5;
+ }
+ };
+
+
+ int main() {
+
+ sol::state lua;
+ // overloaded function f
+ lua.set("f", sol::c_call<sol::wrap<decltype(&f1), &f1>, sol::wrap<decltype(&f2), &f2>, sol::wrap<decltype(&fer::f3), &fer::f3>>);
+ // singly-wrapped function
+ lua.set("g", sol::c_call<sol::wrap<decltype(&f1), &f1>>);
+ // without the 'sol::wrap' boilerplate
+ lua.set("h", sol::c_call<decltype(&f2), &f2>);
+ // object used for the 'fer' member function call
+ lua.set("obj", fer());
+
+ // call them like any other bound function
+ lua.script("r1 = f(1)");
+ lua.script("r2 = f(1, 2)");
+ lua.script("r3 = f(obj, 1, 2)");
+ lua.script("r4 = g(1)");
+ lua.script("r5 = h(1, 2)");
+
+ // get the results and see
+ // if it worked out
+ int r1 = lua["r1"];
+ // r1 == 32
+ int r2 = lua["r2"];
+ // r2 == 1
+ double r3 = lua["r3"];
+ // r3 == 2.5
+ int r4 = lua["r4"];
+ // r4 == 32
+ int r5 = lua["r5"];
+ // r5 == 1
+
+ return 0;
+ }
+
+
+.. _one similar to this: http://stackoverflow.com/a/5628222/5280922
diff --git a/3rdparty/sol2/docs/source/api/compatibility.rst b/3rdparty/sol2/docs/source/api/compatibility.rst
new file mode 100644
index 00000000000..3299bff931b
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/compatibility.rst
@@ -0,0 +1,16 @@
+compatibility.hpp
+=================
+Lua 5.3/5.2 compatibility for Lua 5.1/LuaJIT
+--------------------------------------------
+
+This is a detail header used to maintain compatability with the 5.2 and 5.3 APIs. It contains code from the MIT-Licensed `Lua code`_ in some places and also from the `lua-compat`_ repository by KeplerProject.
+
+It is not fully documented as this header's only purpose is for internal use to make sure Sol compiles across all platforms / distributions with no errors or missing Lua functionality. If you think there's some compatibility features we are missing or if you are running into redefinition errors, please make an `issue in the issue tracker`_.
+
+If you have this already in your project or you have your own compatibility layer, then please ``#define SOL_NO_COMPAT 1`` before including ``sol.hpp`` or pass this flag on the command line to turn off the compatibility wrapper.
+
+For the licenses, see :doc:`here<../licenses>`
+
+.. _issue in the issue tracker: https://github.com/ThePhD/sol2/issues/
+.. _Lua code: http://www.Lua.org/
+.. _lua-compat: https://github.com/keplerproject/lua-compat-5.3 \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/coroutine.rst b/3rdparty/sol2/docs/source/api/coroutine.rst
new file mode 100644
index 00000000000..3d03da31f5c
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/coroutine.rst
@@ -0,0 +1,109 @@
+coroutine
+=========
+resumable/yielding functions from Lua
+-------------------------------------
+
+A ``coroutine`` is a :doc:`reference<reference>` to a function in Lua that can be called multiple times to yield a specific result. It is run on the :doc:`lua_State<state>` that was used to create it (see :doc:`thread<thread>` for an example on how to get a coroutine that runs on a thread separate from your usual "main" :doc:`lua_State<state>`).
+
+The ``coroutine`` object is entirely similar to the :doc:`protected_function<protected_function>` object, with additional member functions to check if a coroutine has yielded (:doc:`call_status::yielded<types>`) and is thus runnable again, whether it has completed (:ref:`call_status::ok<call-status>`) and thus cannot yield anymore values, or whether it has suffered an error (see :ref:`status()<status>` and :ref:`call_status<call-status>`'s error codes).
+
+For example, you can work with a coroutine like this:
+
+.. code-block:: lua
+ :caption: co.lua
+
+ function loop()
+ while counter ~= 30
+ do
+ coroutine.yield(counter);
+ counter = counter + 1;
+ end
+ return counter
+ end
+
+This is a function that yields:
+
+.. code-block:: cpp
+ :caption: main.cpp
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::coroutine);
+ lua.script_file("co.lua");
+ sol::coroutine cr = lua["loop"];
+
+ for (int counter = 0; // start from 0
+ counter < 10 && cr; // we want 10 values, and we only want to run if the coroutine "cr" is valid
+ // Alternative: counter < 10 && cr.valid()
+ ++counter) {
+ // Call the coroutine, does the computation and then suspends
+ int value = cr();
+ }
+
+Note that this code doesn't check for errors: to do so, you can call the function and assign it as ``auto result = cr();``, then check ``result.valid()`` as is the case with :doc:`protected_function<protected_function>`. Finally, you can run this coroutine on another thread by doing the following:
+
+.. code-block:: cpp
+ :caption: main_with_thread.cpp
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::coroutine);
+ lua.script_file("co.lua");
+ sol::thread runner = sol::thread::create(lua.lua_state());
+ sol::state_view runnerstate = runner.state();
+ sol::coroutine cr = runnerstate["loop"];
+
+ for (int counter = 0; counter < 10 && cr; ++counter) {
+ // Call the coroutine, does the computation and then suspends
+ int value = cr();
+ }
+
+The following are the members of ``sol::coroutine``:
+
+members
+-------
+
+.. code-block:: cpp
+ :caption: function: constructor
+
+ coroutine(lua_State* L, int index = -1);
+
+Grabs the coroutine at the specified index given a ``lua_State*``.
+
+.. code-block:: cpp
+ :caption: returning the coroutine's status
+ :name: status
+
+ call_status status() const noexcept;
+
+Returns the status of a coroutine.
+
+
+.. code-block:: cpp
+ :caption: checks for an error
+
+ bool error() const noexcept;
+
+Checks if an error occured when the coroutine was run.
+
+.. _runnable:
+
+.. code-block:: cpp
+ :caption: runnable and explicit operator bool
+
+ bool runnable () const noexcept;
+ explicit operator bool() const noexcept;
+
+These functions allow you to check if a coroutine can still be called (has more values to yield and has not errored). If you have a coroutine object ``coroutine my_co = /*...*/``, you can either check ``runnable()`` or do ``if ( my_co ) { /* use coroutine */ }``.
+
+.. code-block:: cpp
+ :caption: calling a coroutine
+
+ template<typename... Args>
+ protected_function_result operator()( Args&&... args );
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call( Args&&... args );
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) operator()( types<Ret...>, Args&&... args );
+
+Calls the coroutine. The second ``operator()`` lets you specify the templated return types using the ``my_co(sol::types<int, std::string>, ...)`` syntax. Check ``status()`` afterwards for more information about the success of the run or just check the coroutine object in an ifs tatement, as shown :ref:`above<runnable>`. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/error.rst b/3rdparty/sol2/docs/source/api/error.rst
new file mode 100644
index 00000000000..4bfe21e91a4
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/error.rst
@@ -0,0 +1,15 @@
+error
+=====
+the single error/exception type
+-------------------------------
+
+.. code-block:: cpp
+
+ class error : public std::runtime_error {
+ public:
+ error(const std::string& str): std::runtime_error("Lua: error: " + str) {}
+ };
+
+If an eror is thrown by Sol, it is going to be of this type. We use this in a single place: the default ``at_panic`` function we bind on construction of a :ref:`sol::state<set-panic>`. If you turn :doc:`off exceptions<../exceptions>`, the chances of you seeing this error are nil unless you specifically use it to pull errors out of things such as :doc:`sol::protected_function<protected_function>`.
+
+As it derives from ``std::runtime_error``, which derives from ``std::exception``, you can catch it with a ``catch (const std::exception& )`` clause in your try/catch blocks. You can retrieve a string error from Lua (Lua pushes all its errors as string returns) by using this type with any of the get or lookup functions in Sol. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/function.rst b/3rdparty/sol2/docs/source/api/function.rst
new file mode 100644
index 00000000000..27946117a8c
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/function.rst
@@ -0,0 +1,89 @@
+function
+========
+calling functions bound to Lua
+------------------------------
+
+.. code-block:: cpp
+
+ class function : public reference;
+
+Function is a correct-assuming version of :doc:`protected_function<protected_function>`, omitting the need for typechecks and error handling. It is the default function type of Sol. Grab a function directly off the stack using the constructor:
+
+.. code-block:: cpp
+ :caption: constructor: function
+
+ function(lua_State* L, int index = -1);
+
+
+When called without the return types being specified by either a ``sol::types<...>`` list or a ``call<Ret...>( ... )`` template type list, it generates a :ref:`function_result<function-result>` class that gets implicitly converted to the requested return type. For example:
+
+.. code-block:: lua
+ :caption: func_barks.lua
+ :linenos:
+
+ bark_power = 11;
+
+ function woof ( bark_energy )
+ return (bark_energy * (bark_power / 4))
+ end
+
+The following C++ code will call this function from this file and retrieve the return value:
+
+.. code-block:: cpp
+ :linenos:
+
+ sol::state lua;
+
+ lua.script_file( "func_barks.lua" );
+
+ sol::function woof = lua["woof"];
+ double numwoof = woof(20);
+
+The call ``woof(20)`` generates a :ref:`function_result<function-result>`, which is then implicitly converted to an ``double`` after being called. The intermediate temporary ``function_result`` is then destructed, popping the Lua function call results off the Lua stack.
+
+You can also return multiple values by using ``std::tuple``, or if you need to bind them to pre-existing variables use ``sol::tie``:
+
+.. code-block:: cpp
+ :linenos:
+
+ sol::state lua;
+
+ lua.script( "function f () return 10, 11, 12 end" );
+
+ sol::function f = lua["f"];
+ std::tuple<int, int, int> abc = f(); // 10, 11, 12 from Lua
+ // or
+ int a, b, c;
+ sol::tie(a, b, c) = f(); // a = 10, b = 11, c = 12 from Lua
+
+This makes it much easier to work with multiple return values. Using ``std::tie`` from the C++ standard will result in dangling references or bad behavior because of the very poor way in which C++ tuples/``std::tie`` were specified and implemented: please use ``sol::tie( ... )`` instead to satisfy any multi-return needs.
+
+.. _function-result-warning:
+
+.. warning::
+
+ Do NOT save the return type of a :ref:`function_result<function-result>` with ``auto``, as in ``auto numwoof = woof(20);``, and do NOT store it anywhere. Unlike its counterpart :ref:`protected_function_result<protected-function-result>`, ``function_result`` is NOT safe to store as it assumes that its return types are still at the top of the stack and when its destructor is called will pop the number of results the function was supposed to return off the top of the stack. If you mess with the Lua stack between saving ``function_result`` and it being destructed, you will be subject to an incredible number of surprising and hard-to-track bugs. Don't do it.
+
+.. code-block:: cpp
+ :caption: function: call operator / function call
+
+ template<typename... Args>
+ protected_function_result operator()( Args&&... args );
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call( Args&&... args );
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) operator()( types<Ret...>, Args&&... args );
+
+Calls the function. The second ``operator()`` lets you specify the templated return types using the ``my_func(sol::types<int, std::string>, ...)`` syntax. Function assumes there are no runtime errors, and thusly will call the ``atpanic`` function if an error does occur.
+
+.. note::
+
+ All arguments are forwarded. Unlike :doc:`get/set/operator[] on sol::state<state>` or :doc:`sol::table<table>`, value semantics are not used here. It is forwarding reference semantics, which do not copy/move unless it is specifically done by the receiving functions / specifically done by the user.
+
+
+function call safety
+--------------------
+
+You can have functions here and on usertypes check to definitely make sure that the types passed to C++ functions are what they're supposed to be by adding a ``#define SOL_CHECK_ARGUMENTS`` before including Sol, or passing it on the command line. Otherwise, for speed reasons, these checks are only used where absolutely necessary (like discriminating between :doc:`overloads<overload>`). See :doc:`safety<../safety>` for more information. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/make_reference.rst b/3rdparty/sol2/docs/source/api/make_reference.rst
new file mode 100644
index 00000000000..cd39b5a31d9
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/make_reference.rst
@@ -0,0 +1,26 @@
+make_object/make_reference
+==========================
+Create a value on the Lua stack and return it
+---------------------------------------------
+
+.. code-block:: cpp
+ :caption: function: make_reference
+ :name: make-reference
+
+ template <typename R = reference, bool should_pop = (R is not base of sol::stack_index), typename T>
+ R make_reference(lua_State* L, T&& value);
+ template <typename T, typename R = reference, bool should_pop = (R is base of sol::stack_index), typename... Args>
+ R make_reference(lua_State* L, Args&&... args);
+
+Makes an ``R`` out of the value. The first overload deduces the type from the passed in argument, the second allows you to specify a template parameter and forward any relevant arguments to ``sol::stack::push``. The type figured out for ``R`` is what is referenced from the stack. This allows you to request arbitrary pop-able types from Sol and have it constructed from ``R(lua_State* L, int stack_index)``. If the template boolean ``should_pop`` is ``true``, the value that was pushed will be popped off the stack. It defaults to popping, but if it encounters a type such as :doc:`sol::stack_reference<stack_reference>` (or any of its typically derived types in Sol), it will leave the pushed values on the stack.
+
+.. code-block:: cpp
+ :caption: function: make_object
+ :name: make-object
+
+ template <typename T>
+ object make_object(lua_State* L, T&& value);
+ template <typename T, typename... Args>
+ object make_object(lua_State* L, Args&&... args);
+
+Makes an object out of the value. It pushes it onto the stack, then pops it into the returned ``sol::object``. The first overload deduces the type from the passed in argument, the second allows you to specify a template parameter and forward any relevant arguments to ``sol::stack::push``. The implementation essentially defers to :ref:`sol::make_reference<make-reference>` with the specified arguments, ``R == object`` and ``should_pop == true``. It is preferred that one uses the :ref:`in_place object constructor instead<overloaded-object-constructor>`, since it's probably easier to deal with, but both versions will be supported for forever, since there's really no reason not to and people already have dependencies on ``sol::make_object``.
diff --git a/3rdparty/sol2/docs/source/api/metatable_key.rst b/3rdparty/sol2/docs/source/api/metatable_key.rst
new file mode 100644
index 00000000000..718eb2b2ffc
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/metatable_key.rst
@@ -0,0 +1,154 @@
+metatable_key
+=============
+A key for setting and getting an object's metatable
+---------------------------------------------------
+
+.. code-block:: cpp
+
+ struct metatable_key_t {};
+ const metatable_key_t metatable_key;
+
+You can use this in conjunction with :doc:`sol::table<table>` to set/get a metatable. Lua metatables are powerful ways to override default behavior of objects for various kinds of operators, among other things. Here is an entirely complete example, showing getting and working with a :doc:`usertype<usertype>`'s metatable defined by Sol:
+
+.. code-block:: cpp
+ :caption: messing with metatables
+ :linenos:
+
+ #include <sol.hpp>
+
+ int main () {
+
+ struct bark {
+ int operator()(int x) {
+ return x;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype<bark>("bark",
+ sol::meta_function::call_function, &bark::operator()
+ );
+
+ bark b;
+ lua.set("b", &b);
+
+ sol::table b_as_table = lua["b"];
+ sol::table b_metatable = b_as_table[sol::metatable_key];
+ sol::function b_call = b_metatable["__call"];
+ sol::function b_as_function = lua["b"];
+
+ int result1 = b_as_function(1);
+ int result2 = b_call(b, 1);
+ // result1 == result2 == 1
+ }
+
+It's further possible to have a "Dynamic Getter" (`thanks to billw2012 and Nava2 for this example`_!):
+
+.. code-block:: cpp
+ :caption: One way to make dynamic properties (there are others!)
+ :linenos:
+
+ #include <sol.hpp>
+ #include <unordered_map>
+
+ struct PropertySet {
+ sol::object get_property_lua(const char* name, sol::this_state s)
+ {
+ auto& var = props[name];
+ return sol::make_object(s, var);
+ }
+
+ void set_property_lua(const char* name, sol::stack_object object)
+ {
+ props[name] = object.as<std::string>();
+ }
+
+ std::unordered_map<std::string, std::string> props;
+ };
+
+ struct DynamicObject {
+ PropertySet& get_dynamic_props() {
+ return dynamic_props;
+ }
+
+ PropertySet dynamic_props;
+ };
+
+
+ int main () {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype<PropertySet>("PropertySet",
+ sol::meta_function::new_index, &PropertySet::set_property_lua,
+ sol::meta_function::index, &PropertySet::get_property_lua
+ );
+
+ lua.new_usertype<DynamicObject>("DynamicObject",
+ "props", sol::property(&DynamicObject::get_dynamic_props)
+ );
+
+ lua.script(R"(
+ obj = DynamicObject:new()
+ obj.props.name = 'test name'
+ print('name = ' .. obj.props.name)
+ )");
+
+ std::string name = lua["obj"]["props"]["name"];
+ // name == "test name";
+ }
+
+
+You can even manipulate the ability to set and get items using metatable objects on a usertype or similar:
+
+.. code-block:: cpp
+ :caption: messing with metatables - vector type
+ :linenos:
+
+ #include <sol.hpp>
+
+ class vector {
+ public:
+ double data[3];
+
+ vector() : data{ 0,0,0 } {}
+
+ double& operator[](int i)
+ {
+ return data[i];
+ }
+
+
+ static double my_index(vector& v, int i)
+ {
+ return v[i];
+ }
+
+ static void my_new_index(vector& v, int i, double x)
+ {
+ v[i] = x;
+ }
+ };
+
+ int main () {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.new_usertype<vector>("vector", sol::constructors<sol::types<>>(),
+ sol::meta_function::index, &vector::my_index,
+ sol::meta_function::new_index, &vector::my_new_index);
+ lua.script("v = vector.new()\n"
+ "print(v[1])\n"
+ "v[2] = 3\n"
+ "print(v[2])\n"
+ );
+
+ vector& v = lua["v"];
+ // v[0] == 0.0;
+ // v[1] == 0.0;
+ // v[2] == 3.0;
+ }
+
+
+.. _thanks to billw2012 and Nava2 for this example: https://github.com/ThePhD/sol2/issues/71#issuecomment-225402055 \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/object.rst b/3rdparty/sol2/docs/source/api/object.rst
new file mode 100644
index 00000000000..f38f089cc4d
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/object.rst
@@ -0,0 +1,70 @@
+object
+======
+general-purpose safety reference to an existing object
+------------------------------------------------------
+
+.. code-block:: cpp
+
+ class object : reference;
+
+
+``object``'s goal is to allow someone to pass around the most generic form of a reference to something in Lua (or propogate a ``nil``). It is the logical extension of :doc:`sol::reference<reference>`, and is used in :ref:`sol::table's iterators<table-iterators>`.
+
+
+members
+-------
+
+.. code-block:: cpp
+ :caption: overloaded constructor: object
+ :name: overloaded-object-constructor
+
+ template <typename T>
+ object(T&&);
+ object(lua_State* L, int index = -1);
+ template <typename T, typename... Args>
+ object(lua_State* L, in_place_t, T&& arg, Args&&... args);
+ template <typename T, typename... Args>
+ object(lua_State* L, in_place_type_t<T>, Args&&... args);
+
+There are 4 kinds of constructors here. One allows construction of an object from other reference types such as :doc:`sol::table<table>` and :doc:`sol::stack_reference<stack_reference>`. The second creates an object which references the specific element at the given index in the specified ``lua_State*``. The more advanced ``in_place...`` constructors create a single object by pushing the specified type ``T`` onto the stack and then setting it as the object. It gets popped from the stack afterwards (unless this is an instance of ``sol::stack_object``, in which case it is left on the stack). An example of using this and :doc:`sol::make_object<make_reference>` can be found in the `any_return example`_.
+
+.. code-block:: cpp
+ :caption: function: type conversion
+
+ template<typename T>
+ decltype(auto) as() const;
+
+Performs a cast of the item this reference refers to into the type ``T`` and returns it. It obeys the same rules as :ref:`sol::stack::get\<T><getter>`.
+
+.. code-block:: cpp
+ :caption: function: type check
+
+ template<typename T>
+ bool is() const;
+
+Performs a type check using the :ref:`sol::stack::check<checker>` api, after checking if the reference is valid.
+
+
+non-members
+-----------
+
+.. code-block:: cpp
+ :caption: functions: nil comparators
+
+ bool operator==(const object& lhs, const nil_t&);
+ bool operator==(const nil_t&, const object& rhs);
+ bool operator!=(const object& lhs, const nil_t&);
+ bool operator!=(const nil_t&, const object& rhs);
+
+These allow a person to compare an ``sol::object`` against :ref:`nil<nil>`, which essentially checks if an object references a non-nil value, like so:
+
+.. code-block:: cpp
+
+ if (myobj == sol::nil) {
+ // doesn't have anything...
+ }
+
+Use this to check objects.
+
+
+.. _any_return example: https://github.com/ThePhD/sol2/blob/develop/examples/any_return.cpp \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/optional.rst b/3rdparty/sol2/docs/source/api/optional.rst
new file mode 100644
index 00000000000..f999849bcd9
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/optional.rst
@@ -0,0 +1,6 @@
+optional<T>
+===========
+
+This is an implemention of `optional from the standard library`_. If it detects that a proper optional exists, it will attempt to use it. This is mostly an implementation detail, used in the :ref:`sol::stack::check_get<stack-check-get>` and :ref:`sol::stack::get\<optional\<T>><stack-get>` and ``optional<T> maybe_value = table["arf"];`` implementations for additional safety reasons.
+
+.. _optional from the standard library: http://en.cppreference.com/w/cpp/utility/optional \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/overload.rst b/3rdparty/sol2/docs/source/api/overload.rst
new file mode 100644
index 00000000000..399b409d1af
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/overload.rst
@@ -0,0 +1,89 @@
+overload
+========
+calling different functions based on argument number/type
+---------------------------------------------------------
+
+this function helps users make overloaded functions that can be called from Lua using 1 name but multiple arguments. It is meant to replace the spaghetti of code whre users mock this up by doing strange if statemetns and switches on what version of a function to call based on `luaL_check{number/udata/string}`_. Its use is simple: whereever you can pass a function type to Lua, whether its on a :doc:`usertype<usertype>` or if you are just setting any kind of function with ``set`` or ``set_function`` (for :doc:`table<table>` or :doc:`state(_view)<state>`), simply wrap up the functions you wish to be considered for overload resolution on one function like so:
+
+.. code-block:: cpp
+
+ sol::overload( func1, func2, ... funcN );
+
+
+The functions can be any kind of function / function object (lambda). Given these functions and struct:
+
+.. code-block:: cpp
+ :linenos:
+
+ struct pup {
+ int barks = 0;
+
+ void bark () {
+ ++barks; // bark!
+ }
+
+ bool is_cute () const {
+ return true;
+ }
+ };
+
+ void ultra_bark( pup& p, int barks) {
+ for (; barks --> 0;) p.bark();
+ }
+
+ void picky_bark( pup& p, std::string s) {
+ if ( s == "bark" )
+ p.bark();
+ }
+
+You then use it just like you would for any other part of the api:
+
+.. code-block:: cpp
+ :linenos:
+
+ sol::state lua;
+
+ lua.set_function( "bark", sol::overload(
+ ultra_bark,
+ []() { return "the bark from nowhere"; }
+ ) );
+
+ lua.new_usertype<pup>( "pup",
+ // regular function
+ "is_cute", &pup::is_cute,
+ // overloaded function
+ "bark", sol::overload( &pup::bark, &picky_bark )
+ );
+
+Thusly, doing the following in Lua:
+
+.. code-block:: Lua
+ :caption: pup.lua
+ :linenos:
+
+ local barker = pup.new()
+ pup:bark() -- calls member function pup::bark
+ pup:bark(20) -- calls ultra_bark
+ pup:bark("meow") -- picky_bark, no bark
+ pup:bark("bark") -- picky_bark, bark
+
+ bark(pup, 20) -- calls ultra_bark
+ local nowherebark = bark() -- calls lambda which returns that string
+
+The actual class produced by ``sol::overload`` is essentially a type-wrapper around ``std::tuple`` that signals to the library that an overload is being created:
+
+.. code-block:: cpp
+ :caption: function: create overloaded set
+ :linenos:
+
+ template <typename... Args>
+ struct overloaded_set : std::tuple<Args...> { /* ... */ };
+
+ template <typename... Args>
+ overloaded_set<Args...> overload( Args&&... args );
+
+.. note::
+
+ Please keep in mind that doing this bears a runtime cost to find the proper overload. The cost scales directly not exactly with the number of overloads, but the number of functions that have the same argument count as each other (Sol will early-eliminate any functions that do not match the argument count).
+
+.. _luaL_check{number/udata/string}: http://www.Lua.org/manual/5.3/manual.html#luaL_checkinteger
diff --git a/3rdparty/sol2/docs/source/api/property.rst b/3rdparty/sol2/docs/source/api/property.rst
new file mode 100644
index 00000000000..e3ee02e2353
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/property.rst
@@ -0,0 +1,64 @@
+property
+========
+
+.. code-block:: cpp
+
+ template <typename Read, typename Write>
+ decltype(auto) property ( Read&& read_function, Write&& write_function );
+ template <typename Read>
+ decltype(auto) property ( Read&& read_function );
+ template <typename Write>
+ decltype(auto) property ( Write&& write_function );
+
+These set of functions create a type which allows a setter and getter pair (or a single getter, or a single setter) to be used to create a variable that is either read-write, read-only, or write-only. When used during :doc:`usertype<usertype>` construction, it will create a variable that uses the setter/getter member function specified.
+
+.. code-block:: cpp
+ :caption: player.hpp
+ :linenos:
+
+ class Player {
+ public:
+ int get_hp() const {
+ return hp;
+ }
+
+ void set_hp( int value ) {
+ hp = value;
+ }
+
+ int get_max_hp() const {
+ return hp;
+ }
+
+ void set_max_hp( int value ) {
+ maxhp = value;
+ }
+
+ private:
+ int hp = 50;
+ int maxHp = 50;
+ }
+
+.. code-block:: cpp
+ :caption: game.cpp
+ :linenos:
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.set("theplayer", Player());
+
+ // Yes, you can register after you set a value and it will
+ // connect up the usertype automatically
+ lua.new_usertype<Player>( "Player",
+ "hp", sol::property(&Player::get_hp, &Player::set_hp),
+ "maxHp", sol::property(&Player::get_max_hp, &Player::set_max_hp)
+ );
+
+
+.. code-block:: lua
+ :caption: game-snippet.lua
+
+ -- variable syntax, calls functions
+ theplayer.hp = 20
+ print(theplayer.hp) \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/protect.rst b/3rdparty/sol2/docs/source/api/protect.rst
new file mode 100644
index 00000000000..4f14cb0db2a
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/protect.rst
@@ -0,0 +1,33 @@
+protect
+=======
+Routine to mark a function / variable as requiring safety
+---------------------------------------------------------
+
+.. code-block:: cpp
+
+ template <typename T>
+ auto protect( T&& value );
+
+``sol::protect( my_func )`` allows you to protect a function call or member variable call when it is being set to Lua. It can be used with usertypes or when just setting a function into Sol. Below is an example that demonstrates that a call that would normally not error without :doc:`Safety features turned on<../safety>` that instead errors and makes the Lua safety-call wrapper ``pcall`` fail:
+
+.. code-block:: cpp
+
+ struct protect_me {
+ int gen(int x) {
+ return x;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.new_usertype<protect_me>("protect_me",
+ "gen", sol::protect( &protect_me::gen )
+ );
+
+ lua.script(R"__(
+ pm = protect_me.new()
+ value = pcall(pm.gen,pm)
+ )__");
+ );
+ bool value = lua["value"];
+ // value == false
diff --git a/3rdparty/sol2/docs/source/api/protected_function.rst b/3rdparty/sol2/docs/source/api/protected_function.rst
new file mode 100644
index 00000000000..97d4e09f14f
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/protected_function.rst
@@ -0,0 +1,185 @@
+protected_function
+==================
+Lua function calls that trap errors and provide error handling
+--------------------------------------------------------------
+
+.. code-block:: cpp
+
+ class protected_function : public reference;
+
+Inspired by a request from `starwing<https://github.com/starwing>` in the old repository, this class provides the same interface as :doc:`function<function>` but with heavy protection and a potential error handler for any Lua errors and C++ exceptions. You can grab a function directly off the stack using the constructor, or pass to it 2 valid functions, which we'll demonstrate a little later.
+
+When called without the return types being specified by either a ``sol::types<...>`` list or a ``call<Ret...>( ... )`` template type list, it generates a :doc:`protected_function_result<proxy>` class that gets implicitly converted to the requested return type. For example:
+
+.. code-block:: lua
+ :caption: pfunc_barks.lua
+ :linenos:
+
+ bark_power = 11;
+
+ function got_problems( error_msg )
+ return "got_problems handler: " .. error_msg
+ end
+
+ function woof ( bark_energy )
+ if bark_energy < 20
+ error("*whine*")
+ end
+ return (bark_energy * (bark_power / 4))
+ end
+
+ function woofers ( bark_energy )
+ if bark_energy < 10
+ error("*whine*")
+ end
+ return (bark_energy * (bark_power / 4))
+ end
+
+The following C++ code will call this function from this file and retrieve the return value, unless an error occurs, in which case you can bind an error handling function like so:
+
+.. code-block:: cpp
+ :linenos:
+
+ sol::state lua;
+
+ lua.open_file( "pfunc_barks.lua" );
+
+ sol::protected_function problematicwoof = lua["woof"];
+ problematicwoof.error_handler = lua["got_problems"];
+
+ auto firstwoof = problematic_woof(20);
+ if ( firstwoof.valid() ) {
+ // Can work with contents
+ double numwoof = first_woof;
+ }
+ else{
+ // An error has occured
+ sol::error err = first_woof;
+ }
+
+ // errors, calls handler and then returns a string error from Lua at the top of the stack
+ auto secondwoof = problematic_woof(19);
+ if (secondwoof.valid()) {
+ // Call succeeded
+ double numwoof = secondwoof;
+ }
+ else {
+ // Call failed
+ // Note that if the handler was successfully called, this will include
+ // the additional appended error message information of
+ // "got_problems handler: " ...
+ sol::error err = secondwoof;
+ std::string what = err.what();
+ }
+
+This code is much more long-winded than its :doc:`function<function>` counterpart but allows a person to check for errors. The type here for ``auto`` are ``sol::protected_function_result``. They are implicitly convertible to result types, like all :doc:`proxy-style<proxy>` types are.
+
+Alternatively, with a bad or good function call, you can use ``sol::optional`` to check if the call succeeded or failed:
+
+.. code-block:: cpp
+ :linenos:
+
+ sol::state lua;
+
+ lua.open_file( "pfunc_barks.lua" );
+
+ sol::protected_function problematicwoof = lua["woof"];
+ problematicwoof.error_handler = lua["got_problems"];
+
+ sol::optional<double> maybevalue = problematicwoof(19);
+ if (maybevalue) {
+ // Have a value, use it
+ double numwoof = maybevalue.value();
+ }
+ else {
+ // No value!
+ }
+
+That makes the code a bit more concise and easy to reason about if you don't want to bother with reading the error. Thankfully, unlike ``sol::function_result``, you can save ``sol::protected_function_result`` in a variable and push/pop things above it on the stack where its returned values are. This makes it a bit more flexible than the rigid, performant ``sol::function_result`` type that comes from calling :doc:`sol::function<function>`.
+
+If you're confident the result succeeded, you can also just put the type you want (like ``double`` or ``std::string`` right there and it will get it. But, if it doesn't work out, sol can throw and/or panic if you have the :doc:`safety<../safety>` features turned on:
+
+.. code-block:: cpp
+ :linenos:
+
+ sol::state lua;
+
+ lua.open_file( "pfunc_barks.lua" );
+
+ // construct with function + error handler
+ // shorter than old syntax
+ sol::protected_function problematicwoof(lua["woof"], lua["got_problems"]);
+
+ // dangerous if things go wrong!
+ double value = problematicwoof(19);
+
+
+Finally, it is *important* to note you can set a default handler. The function is described below: please use it to avoid having to constantly set error handlers:
+
+.. code-block:: cpp
+ :linenos:
+
+ sol::state lua;
+
+ lua.open_file( "pfunc_barks.lua" );
+ // sets got_problems as the default
+ // handler for all protected_function errors
+ sol::protected_function::set_default_handler(lua["got_problems"]);
+
+ sol::protected_function problematicwoof = lua["woof"];
+ sol::protected_function problematicwoofers = lua["woofers"];
+
+ double value = problematicwoof(19);
+ double value2 = problematicwoof(9);
+
+
+members
+-------
+
+.. code-block:: cpp
+ :caption: constructor: protected_function
+
+ template <typename T>
+ protected_function( T&& func, reference handler = sol::protected_function::get_default_handler() );
+ protected_function( lua_State* L, int index = -1, reference handler = sol::protected_function::get_default_handler() );
+
+Constructs a ``protected_function``. Use the 2-argument version to pass a custom error handling function more easily. You can also set the :ref:`member variable error_handler<protected-function-error-handler>` after construction later. ``protected_function`` will always use the latest error handler set on the variable, which is either what you passed to it or the default *at the time of construction*.
+
+.. code-block:: cpp
+ :caption: function: call operator / protected function call
+
+ template<typename... Args>
+ protected_function_result operator()( Args&&... args );
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call( Args&&... args );
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) operator()( types<Ret...>, Args&&... args );
+
+Calls the function. The second ``operator()`` lets you specify the templated return types using the ``my_func(sol::types<int, std::string>, ...)`` syntax. If you specify no return type in any way, it produces s ``protected_function_result``.
+
+.. note::
+
+ All arguments are forwarded. Unlike :doc:`get/set/operator[] on sol::state<state>` or :doc:`sol::table<table>`, value semantics are not used here. It is forwarding reference semantics, which do not copy/move unless it is specifically done by the receiving functions / specifically done by the user.
+
+
+.. code-block:: cpp
+ :caption: default handlers
+
+ static const reference& get_default_handler ();
+ static void set_default_handler( reference& ref );
+
+Get and set the Lua entity that is used as the default error handler. The default is a no-ref error handler. You can change that by calling ``protected_function::set_default_handler( lua["my_handler"] );`` or similar: anything that produces a reference should be fine.
+
+.. code-block:: cpp
+ :caption: variable: handler
+ :name: protected-function-error-handler
+
+ reference error_handler;
+
+The error-handler that is called should a runtime error that Lua can detect occurs. The error handler function needs to take a single string argument (use type std::string if you want to use a C++ function bound to lua as the error handler) and return a single string argument (again, return a std::string or string-alike argument from the C++ function if you're using one as the error handler). If :doc:`exceptions<../exceptions>` are enabled, Sol will attempt to convert the ``.what()`` argument of the exception into a string and then call the error handling function. It is a :doc:`reference<reference>`, as it must refer to something that exists in the lua registry or on the Lua stack. This is automatically set to the default error handler when ``protected_function`` is constructed.
+
+.. note::
+
+ ``protected_function_result`` safely pops its values off the stack when its destructor is called, keeping track of the index and number of arguments that were supposed to be returned. If you remove items below it using ``lua_remove``, for example, it will not behave as expected. Please do not perform fundamentally stack-rearranging operations until the destructor is called (pushing/popping above it is just fine).
diff --git a/3rdparty/sol2/docs/source/api/proxy.rst b/3rdparty/sol2/docs/source/api/proxy.rst
new file mode 100644
index 00000000000..897dbbaf7dd
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/proxy.rst
@@ -0,0 +1,201 @@
+proxy, (protected\_)function_result - proxy_base derivatives
+============================================================
+``table[x]`` and ``function(...)`` conversion struct
+----------------------------------------------------
+
+.. code-block:: c++
+
+ template <typename Recurring>
+ struct proxy_base;
+
+ template <typename Table, typename Key>
+ struct proxy : proxy_base<...>;
+
+ struct stack_proxy: proxy_base<...>;
+
+ struct function_result : proxy_base<...>;
+
+ struct protected_function_result: proxy_base<...>;
+
+
+These classes provide implicit assignment operator ``operator=`` (for ``set``) and an implicit conversion operator ``operator T`` (for ``get``) to support items retrieved from the underlying Lua implementation, specifically :doc:`sol::table<table>` and the results of function calls on :doc:`sol::function<function>` and :doc:`sol::protected_function<protected_function>`.
+
+.. _proxy:
+
+proxy
+-----
+
+``proxy`` is returned by lookups into :doc:`sol::table<table>` and table-like entities. Because it is templated on key and table type, it would be hard to spell: you can capture it using the word ``auto`` if you feel like you need to carry it around for some reason before using it. ``proxy`` evaluates its arguments lazily, when you finally call ``get`` or ``set`` on it. Here are some examples given the following lua script.
+
+.. code-block:: lua
+ :linenos:
+ :caption: lua nested table script
+
+ bark = {
+ woof = {
+ [2] = "arf!"
+ }
+ }
+
+
+After loading that file in or putting it in a string and reading the string directly in lua (see :doc:`state`), you can start kicking around with it in C++ like so:
+
+.. code-block:: c++
+ :linenos:
+
+ sol::state lua;
+
+ // produces proxy, implicitly converts to std::string, quietly destroys proxy
+ std::string x = lua["bark"]["woof"][2];
+
+
+``proxy`` lazy evaluation:
+
+.. code-block:: c++
+ :linenos:
+ :caption: multi-get
+
+ auto x = lua["bark"];
+ auto y = x["woof"];
+ auto z = x[2];
+ // retrivies value inside of lua table above
+ std::string value = z; // "arf!"
+ // Can change the value later...
+ z = 20;
+ // Yay, lazy-evaluation!
+ int changed_value = z; // now it's 20!
+
+
+We don't recommend the above to be used across classes or between function: it's more of something you can do to save a reference to a value you like, call a script or run a lua function, and then get it afterwards. You can also set functions (and function objects :ref:`*<note 1>`) this way, and retrieve them as well.
+
+.. code-block:: c++
+ :linenos:
+
+ lua["bark_value"] = 24;
+ lua["chase_tail"] = floof::chase_tail; // chase_tail is a free function
+
+
+members
+-------
+
+.. code-block:: c++
+ :caption: functions: [overloaded] implicit conversion get
+ :name: implicit-get
+
+ requires( sol::is_primitive_type<T>::value == true )
+ template <typename T>
+ operator T() const;
+
+ requires( sol::is_primitive_type<T>::value == false )
+ template <typename T>
+ operator T&() const;
+
+Gets the value associated with the keys the proxy was generated and convers it to the type ``T``. Note that this function will always return ``T&``, a non-const reference, to types which are not based on :doc:`sol::reference<reference>` and not a :doc:`primitive lua type<types>`
+
+.. code-block:: c++
+ :caption: function: get a value
+ :name: regular-get
+
+ template <typename T>
+ decltype(auto) get( ) const;
+
+Gets the value associated with the keys and converts it to the type ``T``.
+
+.. code-block:: c++
+ :caption: function: optionally get a value
+ :name: regular-get-or
+
+ template <typename T, typename Otherwise>
+ optional<T> get_or( Otherwise&& otherise ) const;
+
+Gets the value associated with the keys and converts it to the type ``T``. If it is not of the proper type, it will return a ``sol::nullopt`` instead.
+
+``operator[]`` proxy-only members
+---------------------------------
+
+.. code-block:: c++
+ :caption: function: valid
+ :name: proxy-valid
+
+ bool valid () const;
+
+Returns whether this proxy actually refers to a valid object. It uses :ref:`sol::stack::probe_get_field<stack-probe-get-field>` to determine whether or not its valid.
+
+.. code-block:: c++
+ :caption: functions: [overloaded] implicit set
+ :name: implicit-set
+
+ requires( sol::detail::Function<Fx> == false )
+ template <typename T>
+ proxy& operator=( T&& value );
+
+ requires( sol::detail::Function<Fx> == true )
+ template <typename Fx>
+ proxy& operator=( Fx&& function );
+
+Sets the value associated with the keys the proxy was generated with to ``value``. If this is a function, calls ``set_function``. If it is not, just calls ``set``. Does not exist on :ref:`function_result<function-result>` or :ref:`protected_function_result<protected-function-result>`. See :ref:`note<note 1>` for caveats.
+
+.. code-block:: c++
+ :caption: function: set a callable
+ :name: regular-set-function
+
+ template <typename Fx>
+ proxy& set_function( Fx&& fx );
+
+Sets the value associated with the keys the proxy was generated with to a function ``fx``. Does not exist on :ref:`function_result<function-result>` or :ref:`protected_function_result<protected-function-result>`.
+
+
+.. code-block:: c++
+ :caption: function: set a value
+ :name: regular-set
+
+ template <typename T>
+ proxy& set( T&& value );
+
+Sets the value associated with the keys the proxy was generated with to ``value``. Does not exist on :ref:`function_result<function-result>` or :ref:`protected_function_result<protected-function-result>`.
+
+stack_proxy
+-----------
+
+``sol::stack_proxy`` is what gets returned by :doc:`sol::variadic_args<variadic_args>` and other parts of the framework. It is similar to proxy, but is meant to alias a stack index and not a named variable.
+
+.. _function-result:
+
+function_result
+---------------
+
+``function_result`` is a temporary-only, intermediate-only implicit conversion worker for when :doc:`function<function>` is called. It is *NOT* meant to be stored or captured with ``auto``. It provides fast access to the desired underlying value. It does not implement ``set`` / ``set_function`` / templated ``operator=``, as is present on :ref:`proxy<proxy>`.
+
+
+.. _protected-function-result:
+
+protected_function_result
+-------------------------
+
+``protected_function_result`` is a nicer version of ``function_result`` that can be used to detect errors. Its gives safe access to the desired underlying value. It does not implement ``set`` / ``set_function`` / templated ``operator=`` as is present on :ref:`proxy<proxy>`.
+
+
+.. _note 1:
+
+on function objects and proxies
+-------------------------------
+
+Consider the following:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Note 1 Case
+
+ struct doge {
+ int bark;
+
+ void operator()() {
+ bark += 1;
+ }
+ };
+
+ sol::state lua;
+ lua["object"] = doge{}; // bind constructed doge to "object"
+ // but it binds as a function
+
+When you use the ``lua["object"] = doge{};`` from above, keep in mind that Sol detects if this is a function *callable with any kind of arguments*. Since ``doge`` has overriden ``return_type operator()( argument_types... )`` on itself, it results in satisfying the ``requires`` constraint from above. This means that if you have a user-defined type you want to bind as a :doc:`userdata with usertype semantics<usertype>` with this syntax, it might get bound as a function and not as a user-defined type (d'oh!). use ``lua["object"].set(doge)`` directly to avoid this, or ``lua["object"].set_function(doge{})`` to perform this explicitly. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/readonly.rst b/3rdparty/sol2/docs/source/api/readonly.rst
new file mode 100644
index 00000000000..3a9517f1058
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/readonly.rst
@@ -0,0 +1,11 @@
+readonly
+========
+Routine to mark a member variable as read-only
+----------------------------------------------
+
+.. code-block:: cpp
+
+ template <typename T>
+ auto readonly( T&& value );
+
+The goal of read-only is to protect a variable set on a usertype or a function. Simply wrap it around a member variable, e.g. ``sol::readonly( &my_class::my_member_variable )`` in the appropriate place to use it. If someone tries to set it, it will throw an error.
diff --git a/3rdparty/sol2/docs/source/api/reference.rst b/3rdparty/sol2/docs/source/api/reference.rst
new file mode 100644
index 00000000000..37886dc2300
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/reference.rst
@@ -0,0 +1,75 @@
+reference
+=========
+general purpose reference to Lua object in registry
+---------------------------------------------------
+
+.. code-block:: cpp
+ :caption: reference
+
+ class reference;
+
+This type keeps around a reference to something that was on the stack and places it in the Lua registry. It is the backbone for all things that reference items on the stack and needs to keep them around beyond their appearance and lifetime on said Lua stack. Its progeny include :doc:`sol::coroutine<coroutine>`, :doc:`sol::function<function>`, :doc:`sol::protected_function<protected_function>`, :doc:`sol::object<object>`, :doc:`sol::table<table>`/:doc:`sol::global_table<table>`, :doc:`sol::thread<thread>`, and :doc:`sol::userdata<userdata>`.
+
+For all of these types, there's also a ``stack_{x}`` version of them, such as ``stack_table``
+
+
+members
+-------
+
+.. code-block:: cpp
+ :caption: constructor: reference
+
+ reference(lua_State* L, int index = -1);
+
+Creates a reference from the Lua stack at the specified index, saving it into the metatable registry. This constructor is exposed on all types that derive from ``sol::reference``.
+
+.. code-block:: cpp
+ :caption: function: push referred-to element from the stack
+
+ int push() const noexcept;
+
+This function pushes the referred-to data onto the stack and returns how many things were pushed. Typically, it returns 1.
+
+.. code-block:: cpp
+ :caption: function: reference value
+
+ int registry_index() const noexcept;
+
+The value of the reference in the registry.
+
+.. code-block:: cpp
+ :caption: functions: non-nil, non-null check
+
+ bool valid () const noexcept;
+ explicit operator bool () const noexcept;
+
+These functions check if the reference at ``T`` is valid: that is, if it is not :ref:`nil<nil>` and if it is not non-existing (doesn't refer to anything, including nil) reference. The explicit operator bool allows you to use it in the context of an ``if ( my_obj )`` context.
+
+.. code-block:: cpp
+ :caption: function: retrieves the type
+
+ type get_type() const noexcept;
+
+Gets the :doc:`sol::type<types>` of the reference; that is, the Lua reference.
+
+.. code-block:: cpp
+ :caption: function: lua_State* of the reference
+
+ lua_State* lua_state() const noexcept;
+
+Gets the ``lua_State*`` this reference exists in.
+
+
+non-members
+-----------
+
+.. code-block:: cpp
+ :caption: functions: reference comparators
+
+ bool operator==(const reference&, const reference&);
+ bool operator!=(const reference&, const reference&);
+
+Compares two references using the Lua API's `lua_compare`_ for equality.
+
+
+.. _lua_compare: https://www.lua.org/manual/5.3/manual.html#lua_compare
diff --git a/3rdparty/sol2/docs/source/api/resolve.rst b/3rdparty/sol2/docs/source/api/resolve.rst
new file mode 100644
index 00000000000..d8811d43f5c
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/resolve.rst
@@ -0,0 +1,39 @@
+resolve
+=======
+utility to pick overloaded C++ function calls
+---------------------------------------------
+
+.. code-block:: cpp
+ :caption: function: resolve C++ overload
+
+ template <typename... Args, typename F>
+ auto resolve( F f );
+
+``resolve`` is a function that is meant to help users pick a single function out of a group of overloaded functions in C++. You can use it to pick overloads by specifying the signature as the first template argument. Given a collection of overloaded functions:
+
+.. code-block:: cpp
+ :linenos:
+
+ int overloaded(int x);
+ int overloaded(int x, int y);
+ int overloaded(int x, int y, int z);
+
+You can disambiguate them using ``resolve``:
+
+.. code-block:: cpp
+ :linenos:
+
+ auto one_argument_func = resolve<int(int)>( overloaded );
+ auto two_argument_func = resolve<int(int, int)>( overloaded );
+ auto three_argument_func = resolve<int(int, int, int)>( overloaded );
+
+This resolution becomes useful when setting functions on a :doc:`table<table>` or :doc:`state_view<state>`:
+
+.. code-block:: cpp
+ :linenos:
+
+ sol::state lua;
+
+ lua.set_function("a", resolve<int(int)>( overloaded ) );
+ lua.set_function("b", resolve<int(int, int)>( overloaded ));
+ lua.set_function("c", resolve<int(int, int, int)>( overloaded ));
diff --git a/3rdparty/sol2/docs/source/api/simple_usertype.rst b/3rdparty/sol2/docs/source/api/simple_usertype.rst
new file mode 100644
index 00000000000..e030ed92985
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/simple_usertype.rst
@@ -0,0 +1,16 @@
+simple_usertype
+==================
+structures and classes from C++ made available to Lua code (simpler)
+--------------------------------------------------------------------
+
+
+This type is no different from :doc:`regular usertype<usertype>`, but allows much of its work to be done at runtime instead of compile-time. You can reduce compilation times from a plain `usertype` when you have an exceedingly bulky registration listing.
+
+You can set functions incrementally to reduce compile-time burden with ``simple_usertype`` as well, as shown in `this example`_.
+
+Some developers used ``simple_usertype`` to have variables automatically be functions. To achieve this behavior, wrap the desired variable into :doc:`sol::as_function<as_function>`.
+
+The performance `seems to be good enough`_ to not warn about any implications of having to serialize things at runtime. You do run the risk of using (slightly?) more memory, however, since variables and functions need to be stored differently and separately from the metatable data itself like with a regular ``usertype``. The goal here was to avoid compiler complaints about too-large usertypes (some individuals needed to register 190+ functions, and the compiler choked from the templated implementation of ``usertype``). As of Sol 2.14, this implementation has been heavily refactored to allow for all the same syntax and uses of usertype to apply here, with no caveats/exceptions.
+
+.. _seems to be good enough: https://github.com/ThePhD/sol2/issues/202#issuecomment-246767629
+.. _this example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_simple.cpp \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/stack.rst b/3rdparty/sol2/docs/source/api/stack.rst
new file mode 100644
index 00000000000..0ebb2d2e40b
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/stack.rst
@@ -0,0 +1,199 @@
+stack namespace
+===============
+the nitty-gritty core abstraction layer over Lua
+------------------------------------------------
+
+.. code-block:: cpp
+
+ namespace stack
+
+If you find that the higher level abstractions are not meeting your needs, you may want to delve into the ``stack`` namespace to try and get more out of Sol. ``stack.hpp`` and the ``stack`` namespace define several utilities to work with Lua, including pushing / popping utilities, getters, type checkers, Lua call helpers and more. This namespace is not thoroughly documented as the majority of its interface is mercurial and subject to change between releases to either heavily boost performance or improve the Sol :doc:`api<api-top>`.
+
+There are, however, a few :ref:`template customization points<extension_points>` that you may use for your purposes and a handful of potentially handy functions. These may help if you're trying to slim down the code you have to write, or if you want to make your types behave differently throughout the Sol stack. Note that overriding the defaults **can** throw out many of the safety guarantees Sol provides: therefore, modify the :ref:`extension points<extension_points>` at your own discretion.
+
+structures
+----------
+
+.. code-block:: cpp
+ :caption: struct: record
+ :name: stack-record
+
+ struct record {
+ int last;
+ int used;
+
+ void use(int count);
+ };
+
+This structure is for advanced usage with :ref:`stack::get<stack-get>` and :ref:`stack::check_get<stack-get>`. When overriding the customization points, it is important to call the ``use`` member function on this class with the amount of things you are pulling from the stack. ``used`` contains the total accumulation of items produced. ``last`` is the number of items gotten from the stack with the last operation (not necessarily popped from the stack). In all trivial cases for types, ``last == 1`` and ``used == 1`` after an operation; structures such as ``std::pair`` and ``std::tuple`` may pull more depending on the classes it contains.
+
+When overriding the :doc:`customization points<../tutorial/customization>`, please note that this structure should enable you to push multiple return values and get multiple return values to the stack, and thus be able to seamlessly pack/unpack return values from Lua into a single C++ struct, and vice-versa. This functionality is only recommended for people who need to customize the library further than the basics. It is also a good way to add support for the type and propose it back to the original library so that others may benefit from your work.
+
+Note that customizations can also be put up on a separate page here, if individuals decide to make in-depth custom ones for their framework or other places.
+
+members
+-------
+
+.. code-block:: cpp
+ :caption: function: get
+ :name: stack-get
+
+ template <typename T>
+ auto get( lua_State* L, int index = -1 )
+ template <typename T>
+ auto get( lua_State* L, int index, record& tracking )
+
+Retrieves the value of the object at ``index`` in the stack. The return type varies based on ``T``: with primitive types, it is usually ``T``: for all unrecognized ``T``, it is generally a ``T&`` or whatever the extension point :ref:`stack::getter\<T><getter>` implementation returns. The type ``T`` has top-level ``const`` qualifiers and reference modifiers removed before being forwarded to the extension point :ref:`stack::getter\<T><getter>` struct. ``stack::get`` will default to forwarding all arguments to the :ref:`stack::check_get<stack-check-get>` function with a handler of ``type_panic`` to strongly alert for errors, if you ask for the :doc:`safety<../safety>`.
+
+`record`
+
+You may also retrieve an :doc:`sol::optional\<T><optional>` from this as well, to have it attempt to not throw errors when performing the get and the type is not correct.
+
+.. code-block:: cpp
+ :caption: function: check
+ :name: stack-check
+
+ template <typename T>
+ bool check( lua_State* L, int index = -1 )
+
+ template <typename T, typename Handler>
+ bool check( lua_State* L, int index, Handler&& handler )
+
+Checks if the object at ``index`` is of type ``T``. If it is not, it will call the ``handler`` function with ``lua_State*``, ``int index``, ``type`` expected, and ``type`` actual as arguments.
+
+.. code-block:: cpp
+ :caption: function: check_get
+ :name: stack-check-get
+
+ template <typename T>
+ auto check_get( lua_State* L, int index = -1 )
+ template <typename T, typename Handler>
+ auto check_get( lua_State* L, int index, Handler&& handler, record& tracking )
+
+Retrieves the value of the object at ``index`` in the stack, but does so safely. It returns an ``optional<U>``, where ``U`` in this case is the return type deduced from ``stack::get<T>``. This allows a person to properly check if the type they're getting is what they actually want, and gracefully handle errors when working with the stack if they so choose to. You can define ``SOL_CHECK_ARGUMENTS`` to turn on additional :doc:`safety<../safety>`, in which ``stack::get`` will default to calling this version of the function with a handler of ``type_panic`` to strongly alert for errors and help you track bugs if you suspect something might be going wrong in your system.
+
+.. code-block:: cpp
+ :caption: function: push
+ :name: stack-push
+
+ // push T inferred from call site, pass args... through to extension point
+ template <typename T, typename... Args>
+ int push( lua_State* L, T&& item, Args&&... args )
+
+ // push T that is explicitly specified, pass args... through to extension point
+ template <typename T, typename Arg, typename... Args>
+ int push( lua_State* L, Arg&& arg, Args&&... args )
+
+ // recursively call the the above "push" with T inferred, one for each argument
+ template <typename... Args>
+ int multi_push( lua_State* L, Args&&... args )
+
+Based on how it is called, pushes a variable amount of objects onto the stack. in 99% of cases, returns for 1 object pushed onto the stack. For the case of a ``std::tuple<...>``, it recursively pushes each object contained inside the tuple, from left to right, resulting in a variable number of things pushed onto the stack (this enables multi-valued returns when binding a C++ function to a Lua). Can be called with ``sol::stack::push<T>( L, args... )`` to have arguments different from the type that wants to be pushed, or ``sol::stack::push( L, arg, args... )`` where ``T`` will be inferred from ``arg``. The final form of this function is ``sol::stack::multi_push``, which will call one ``sol::stack::push`` for each argument. The ``T`` that describes what to push is first sanitized by removing top-level ``const`` qualifiers and reference qualifiers before being forwarded to the extension point :ref:`stack::pusher\<T><pusher>` struct.
+
+.. code-block:: cpp
+ :caption: function: set_field
+
+ template <bool global = false, typename Key, typename Value>
+ void set_field( lua_State* L, Key&& k, Value&& v );
+
+ template <bool global = false, typename Key, typename Value>
+ void set_field( lua_State* L, Key&& k, Value&& v, int objectindex);
+
+Sets the field referenced by the key ``k`` to the given value ``v``, by pushing the key onto the stack, pushing the value onto the stack, and then doing the equivalent of ``lua_setfield`` for the object at the given ``objectindex``. Performs optimizations and calls faster verions of the function if the type of ``Key`` is considered a c-style string and/or if its also marked by the templated ``global`` argument to be a global.
+
+.. code-block:: cpp
+ :caption: function: get_field
+
+ template <bool global = false, typename Key>
+ void get_field( lua_State* L, Key&& k [, int objectindex] );
+
+Gets the field referenced by the key ``k``, by pushing the key onto the stack, and then doing the equivalent of ``lua_getfield``. Performs optimizations and calls faster verions of the function if the type of ``Key`` is considered a c-style string and/or if its also marked by the templated ``global`` argument to be a global.
+
+This function leaves the retrieved value on the stack.
+
+.. code-block:: cpp
+ :caption: function: probe_get_field
+ :name: stack-probe-get-field
+
+ template <bool global = false, typename Key>
+ probe probe_get_field( lua_State* L, Key&& k [, int objectindex] );
+
+Gets the field referenced by the key ``k``, by pushing the key onto the stack, and then doing the equivalent of ``lua_getfield``. Performs optimizations and calls faster verions of the function if the type of ``Key`` is considered a c-style string and/or if its also marked by the templated ``global`` argument to be a global. Furthermore, it does this safely by only going in as many levels deep as is possible: if the returned value is not something that can be indexed into, then traversal queries with ``std::tuple``/``std::pair`` will stop early and return probing information with the :ref:`probe struct<stack-probe-struct>`.
+
+This function leaves the retrieved value on the stack.
+
+.. code-block:: cpp
+ :caption: struct: probe
+ :name: stack-probe-struct
+
+ struct probe {
+ bool success;
+ int levels;
+
+ probe(bool s, int l);
+ operator bool() const;
+ };
+
+This struct is used for showing whether or not a :ref:`probing get_field<stack-probe-get-field>` was successful or not.
+
+.. _extension_points:
+
+objects (extension points)
+--------------------------
+
+You can customize the way Sol handles different structures and classes by following the information provided in the :doc:`adding your own types<../tutorial/customization>`.
+
+Below is more extensive information for the curious.
+
+The structs below are already overriden for a handful of types. If you try to mess with them for the types ``sol`` has already overriden them for, you're in for a world of thick template error traces and headaches. Overriding them for your own user defined types should be just fine, however.
+
+.. code-block:: cpp
+ :caption: struct: getter
+ :name: getter
+
+ template <typename T, typename = void>
+ struct getter {
+ static T get (lua_State* L, int index, record& tracking) {
+ // ...
+ return // T, or something related to T.
+ }
+ };
+
+This is an SFINAE-friendly struct that is meant to expose static function ``get`` that returns a ``T``, or something convertible to it. The default implementation assumes ``T`` is a usertype and pulls out a userdata from Lua before attempting to cast it to the desired ``T``. There are implementations for getting numbers (``std::is_floating``, ``std::is_integral``-matching types), getting ``std::string`` and ``const char*``, getting raw userdata with :doc:`userdata_value<types>` and anything as upvalues with :doc:`upvalue_index<types>`, getting raw `lua_CFunction`_ s, and finally pulling out Lua functions into ``std::function<R(Args...)>``. It is also defined for anything that derives from :doc:`sol::reference<reference>`. It also has a special implementation for the 2 standard library smart pointers (see :doc:`usertype memory<usertype_memory>`).
+
+.. code-block:: cpp
+ :caption: struct: pusher
+ :name: pusher
+
+ template <typename X, typename = void>
+ struct pusher {
+ template <typename T>
+ static int push ( lua_State* L, T&&, ... ) {
+ // can optionally take more than just 1 argument
+ // ...
+ return // number of things pushed onto the stack
+ }
+ };
+
+This is an SFINAE-friendly struct that is meant to expose static function ``push`` that returns the number of things pushed onto the stack. The default implementation assumes ``T`` is a usertype and pushes a userdata into Lua with a :ref:`usertype_traits\<T><usertype-traits>` metatable associated with it. There are implementations for pushing numbers (``std::is_floating``, ``std::is_integral``-matching types), getting ``std::string`` and ``const char*``, getting raw userdata with :doc:`userdata<types>` and raw upvalues with :doc:`upvalue<types>`, getting raw `lua_CFunction`_ s, and finally pulling out Lua functions into ``sol::function``. It is also defined for anything that derives from :doc:`sol::reference<reference>`. It also has a special implementation for the 2 standard library smart pointers (see :doc:`usertype memory<usertype_memory>`).
+
+.. code-block:: cpp
+ :caption: struct: checker
+ :name: checker
+
+ template <typename T, type expected = lua_type_of<T>, typename = void>
+ struct checker {
+ template <typename Handler>
+ static bool check ( lua_State* L, int index, Handler&& handler, record& tracking ) {
+ // if the object in the Lua stack at index is a T, return true
+ if ( ... ) return true;
+ // otherwise, call the handler function,
+ // with the required 4 arguments, then return false
+ handler(L, index, expected, indextype);
+ return false;
+ }
+ };
+
+This is an SFINAE-friendly struct that is meant to expose static function ``check`` that returns the number of things pushed onto the stack. The default implementation simply checks whether the expected type passed in through the template is equal to the type of the object at the specified index in the Lua stack. The default implementation for types which are considered ``userdata`` go through a myriad of checks to support checking if a type is *actually* of type ``T`` or if its the base class of what it actually stored as a userdata in that index. Down-casting from a base class to a more derived type is, unfortunately, impossible to do.
+
+.. _lua_CFunction: http://www.Lua.org/manual/5.3/manual.html#lua_CFunction \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/stack_reference.rst b/3rdparty/sol2/docs/source/api/stack_reference.rst
new file mode 100644
index 00000000000..db5359d11aa
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/stack_reference.rst
@@ -0,0 +1,8 @@
+stack_reference
+===============
+zero-overhead object on the stack
+---------------------------------
+
+When you work with a :doc:`sol::reference<reference>`, the object gotten from the stack has a reference to it made in the registry, keeping it alive. If you want to work with the Lua stack directly without having any additional references made, ``sol::stack_reference`` is for you. Its API is identical to ``sol::reference`` in every way, except it contains a ``int stack_index()`` member function that allows you to retrieve the stack index.
+
+All of the base types have ``stack`` versions of themselves, and the APIs are identical to their non-stack forms. This includes :doc:`sol::stack_table<table>`, :doc:`sol::stack_function<function>`, :doc:`sol::stack_protected_function<protected_function>`, :doc:`sol::stack_(light\_)userdata<userdata>` and :doc:`sol::stack_object<object>`. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/state.rst b/3rdparty/sol2/docs/source/api/state.rst
new file mode 100644
index 00000000000..b593d5cc810
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/state.rst
@@ -0,0 +1,121 @@
+state
+=====
+owning and non-owning state holders for registry and globals
+------------------------------------------------------------
+
+.. code-block:: cpp
+
+ class state_view;
+
+ class state : state_view, std::unique_ptr<lua_State*, deleter>;
+
+The most important class here is ``state_view``. This structure takes a ``lua_State*`` that was already created and gives you simple, easy access to Lua's interfaces without taking ownership. ``state`` derives from ``state_view``, inheriting all of this functionality, but has the additional purpose of creating a fresh ``lua_State*`` and managing its lifetime for you in the default constructor.
+
+The majority of the members between ``state_view`` and :doc:`sol::table<table>` are identical, with added for this higher-level type. Therefore, all of the examples and notes in :doc:`sol::table<table>` apply here as well.
+
+enumerations
+------------
+
+.. code-block:: cpp
+ :caption: in-lua libraries
+ :name: lib-enum
+
+ enum class lib : char {
+ base,
+ package,
+ coroutine,
+ string,
+ os,
+ math,
+ table,
+ debug,
+ bit32,
+ io,
+ ffi,
+ jit,
+ count // do not use
+ };
+
+This enumeration details the various base libraries that come with Lua. See the `standard lua libraries`_ for details about the various standard libraries.
+
+
+members
+-------
+
+.. code-block:: cpp
+ :caption: function: open standard libraries/modules
+ :name: open-libraries
+
+ template<typename... Args>
+ void open_libraries(Args&&... args);
+
+This function takes a number of :ref:`sol::lib<lib-enum>` as arguments and opens up the associated Lua core libraries.
+
+.. code-block:: cpp
+ :caption: function: script / script_file
+
+ sol::function_result script(const std::string& code);
+ sol::function_result script_file(const std::string& filename);
+
+These functions run the desired blob of either code that is in a string, or code that comes from a filename, on the ``lua_State*``. It will not run isolated: any scripts or code run will affect code in the ``lua_State*`` the object uses as well (unless ``local`` is applied to a variable declaration, as specified by the Lua language). Code ran in this fashion is not isolated. If you need isolation, consider creating a new state or traditional Lua sandboxing techniques.
+
+If your script returns a value, you can capture it from the returned :ref:`function_result<function-result>`.
+
+.. code-block:: cpp
+ :caption: function: require / require_file
+ :name: state-require-function
+
+ sol::object require(const std::string& key, lua_CFunction open_function, bool create_global = true);
+ sol::object require_script(const std::string& key, const std::string& code, bool create_global = true);
+ sol::object require_file(const std::string& key, const std::string& file, bool create_global = true);
+
+These functions play a role similar to `luaL_requiref`_ except that they make this functionality available for loading a one-time script or a single file. The code here checks if a module has already been loaded, and if it has not, will either load / execute the file or execute the string of code passed in. If ``create_global`` is set to true, it will also link the name ``key`` to the result returned from the open function, the code or the file. Regardless or whether a fresh load happens or not, the returned module is given as a single :doc:`sol::object<object>` for you to use as you see fit.
+
+Thanks to `Eric (EToreo) for the suggestion on this one`_!
+
+.. code-block:: cpp
+ :caption: function: load / load_file
+ :name: state-load-code
+
+ sol::load_result load(const std::string& code);
+ sol::load_result load_file(const std::string& filename);
+
+These functions *load* the desired blob of either code that is in a string, or code that comes from a filename, on the ``lua_State*``. It will not run: it returns a ``load_result`` proxy that can be called to actually run the code, turned into a ``sol::function``, a ``sol::protected_function``, or some other abstraction. If it is called, it will run on the object's current ``lua_State*``: it is not isolated. If you need isolation, consider creating a new state or traditional Lua sandboxing techniques.
+
+.. code-block:: cpp
+ :caption: function: global table / registry table
+
+ sol::global_table globals() const;
+ sol::table registry() const;
+
+Get either the global table or the Lua registry as a :doc:`sol::table<table>`, which allows you to modify either of them directly. Note that getting the global table from a ``state``/``state_view`` is usually unnecessary as it has all the exact same functions as a :doc:`sol::table<table>` anyhow.
+
+
+.. code-block:: cpp
+ :caption: function: Lua set_panic
+ :name: set-panic
+
+ void set_panic(lua_CFunction panic);
+
+Overrides the panic function Lua calls when something unrecoverable or unexpected happens in the Lua VM. Must be a function of the that matches the ``int(*)(lua_State*)`` function signature.
+
+.. code-block:: cpp
+ :caption: function: make a table
+
+ sol::table create_table(int narr = 0, int nrec = 0);
+ template <typename Key, typename Value, typename... Args>
+ sol::table create_table(int narr, int nrec, Key&& key, Value&& value, Args&&... args);
+
+
+ template <typename... Args>
+ sol::table create_table_with(Args&&... args);
+
+ static sol::table create_table(lua_State* L, int narr = 0, int nrec = 0);
+ template <typename Key, typename Value, typename... Args>
+ static sol::table create_table(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args);
+
+Creates a table. Forwards its arguments to :ref:`table::create<table-create>`.
+
+.. _standard lua libraries: http://www.lua.org/manual/5.3/manual.html#6
+.. _luaL_requiref: https://www.lua.org/manual/5.3/manual.html#luaL_requiref
+.. _Eric (EToreo) for the suggestion on this one: https://github.com/ThePhD/sol2/issues/90 \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/table.rst b/3rdparty/sol2/docs/source/api/table.rst
new file mode 100644
index 00000000000..b5a946487de
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/table.rst
@@ -0,0 +1,208 @@
+table
+=====
+a representation of a Lua (meta)table
+-------------------------------------
+
+.. code-block:: cpp
+
+ template <bool global>
+ class table_core;
+
+ typedef table_core<false> table;
+ typedef table_core<true> global_table;
+
+``sol::table`` is an extremely efficient manipulator of state that brings most of the magic of the Sol abstraction. Capable of doing multiple sets at once, multiple gets into a ``std::tuple``, being indexed into using ``[key]`` syntax and setting keys with a similar syntax (see: :doc:`here<proxy>`), ``sol::table`` is the corner of the interaction between Lua and C++.
+
+There are two kinds of tables: the global table and non-global tables: however, both have the exact same interface and all ``sol::global_table`` s are convertible to regular ``sol::table`` s.
+
+Tables are the core of Lua, and they are very much the core of Sol.
+
+
+members
+-------
+
+.. code-block:: cpp
+ :caption: constructor: table
+
+ table(lua_State* L, int index = -1);
+
+Takes a table from the Lua stack at the specified index and allows a person to use all of the abstractions therein.
+
+.. code-block:: cpp
+ :caption: function: get / traversing get
+
+ template<typename... Args, typename... Keys>
+ decltype(auto) get(Keys&&... keys) const;
+
+ template<typename T, typename... Keys>
+ decltype(auto) traverse_get(Keys&&... keys) const;
+
+ template<typename T, typename Key>
+ decltype(auto) get_or(Key&& key, T&& otherwise) const;
+
+ template<typename T, typename Key, typename D>
+ decltype(auto) get_or(Key&& key, D&& otherwise) const;
+
+
+These functions retrieve items from the table. The first one (``get``) can pull out *multiple* values, 1 for each key value passed into the function. In the case of multiple return values, it is returned in a ``std::tuple<Args...>``. It is similar to doing ``return table["a"], table["b"], table["c"]``. Because it returns a ``std::tuple``, you can use ``std::tie``/``std::make_tuple`` on a multi-get to retrieve all of the necessary variables. The second one (``traverse_get``) pulls out a *single* value, using each successive key provided to do another lookup into the last. It is similar to doing ``x = table["a"]["b"]["c"][...]``.
+
+If the keys within nested queries try to traverse into a table that doesn't exist, the second lookup into the nil-returned variable and belong will cause a panic to be fired by the lua C API. If you need to check for keys, check with ``auto x = table.get<sol::optional<int>>( std::tie("a", "b", "c" ) );``, and then use the :doc:`optional<optional>` interface to check for errors. As a short-hand, easy method for returning a default if a value doesn't exist, you can use ``get_or`` instead.
+
+.. code-block:: cpp
+ :caption: function: set / traversing set
+ :name: set-value
+
+ template<typename... Args>
+ table& set(Args&&... args);
+
+ template<typename... Args>
+ table& traverse_set(Args&&... args);
+
+These functions set items into the table. The first one (``set``) can set *multiple* values, in the form ``key_a, value_a, key_b, value_b, ...``. It is similar to ``table[key_a] = value_a; table[key_b] = value_b, ...``. The second one (``traverse_set``) sets a *single* value, using all but the last argument as keys to do another lookup into the value retrieved prior to it. It is equivalent to ``table[key_a][key_b][...] = value;``.
+
+.. note::
+
+ Value semantics are applied to all set operations. If you do not ``std::ref( obj )`` or specifically make a pointer with ``std::addressof( obj )`` or ``&obj``, it will copy / move. This is different from how :doc:`sol::function<function>` behaves with its call operator.
+
+.. code-block:: cpp
+ :caption: function: set a function with the specified key into lua
+ :name: set-function
+
+ template<typename Key, typename Fx>
+ state_view& set_function(Key&& key, Fx&& fx, [...]);
+
+Sets the desired function to the specified key value. Note that it also allows for passing a member function plus a member object or just a single member function: however, using a lambda is almost always better when you want to bind a member function + class instance to a single function call in Lua.
+
+.. code-block:: cpp
+ :caption: function: add
+
+ template<typename... Args>
+ table& add(Args&&... args);
+
+This function appends a value to a table. The definition of appends here is only well-defined for a table which has a perfectly sequential (and integral) ordering of numeric keys with associated non-null values (the same requirement for the :ref:`size<size-function>` function). Otherwise, this falls to the implementation-defined behavior of your Lua VM, whereupon is may add keys into empty 'holes' in the array (e.g., the first empty non-sequential integer key it gets to from ``size``) or perhaps at the very "end" of the "array". Do yourself the favor of making sure your keys are sequential.
+
+Each argument is appended to the list one at a time.
+
+.. code-block:: cpp
+ :caption: function: size
+ :name: size-function
+
+ std::size_t size() const;
+
+This function returns the size of a table. It is only well-defined in the case of a Lua table which has a perfectly sequential (and integral) ordering of numeric keys with associated non-null values.
+
+.. code-block:: cpp
+ :caption: function: setting a usertype
+ :name: new-usertype
+
+ template<typename Class, typename... Args>
+ table& new_usertype(const std::string& name, Args&&... args);
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ table& new_usertype(const std::string& name, Args&&... args);
+ template<typename Class, typename... CArgs, typename... Args>
+ table& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args);
+
+This class of functions creates a new :doc:`usertype<usertype>` with the specified arguments, providing a few extra details for constructors. After creating a usertype with the specified argument, it passes it to :ref:`set_usertype<set_usertype>`.
+
+.. code-block:: cpp
+ :caption: function: setting a simple usertype
+ :name: new-simple-usertype
+
+ template<typename Class, typename... Args>
+ table& new_simple_usertype(const std::string& name, Args&&... args);
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ table& new_simple_usertype(const std::string& name, Args&&... args);
+ template<typename Class, typename... CArgs, typename... Args>
+ table& new_simple_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args);
+
+This class of functions creates a new :doc:`simple usertype<simple_usertype>` with the specified arguments, providing a few extra details for constructors and passing the ``sol::simple`` tag as well. After creating a usertype with the specified argument, it passes it to :ref:`set_usertype<set_usertype>`.
+
+.. code-block:: cpp
+ :caption: function: creating an enum
+ :name: new-enum
+
+ template<bool read_only = true, typename... Args>
+ basic_table_core& new_enum(const std::string& name, Args&&... args);
+
+Use this function to create an enumeration type in Lua. By default, the enum will be made read-only, which creates a tiny performance hit to make the values stored in this table behave exactly like a read-only enumeration in C++. If you plan on changing the enum values in Lua, set the ``read_only`` template parameter in your ``new_enum`` call to false. The arguments are expected to come in ``key, value, key, value, ...`` list.
+
+.. _set_usertype:
+
+.. code-block:: cpp
+ :caption: function: setting a pre-created usertype
+ :name: set-usertype
+
+ template<typename T>
+ table& set_usertype(usertype<T>& user);
+ template<typename Key, typename T>
+ table& set_usertype(Key&& key, usertype<T>& user);
+
+Sets a previously created usertype with the specified ``key`` into the table. Note that if you do not specify a key, the implementation falls back to setting the usertype with a ``key`` of ``usertype_traits<T>::name``, which is an implementation-defined name that tends to be of the form ``{namespace_name 1}_[{namespace_name 2 ...}_{class name}``.
+
+.. code-block:: cpp
+ :caption: function: begin / end for iteration
+ :name: table-iterators
+
+ table_iterator begin () const;
+ table_iterator end() const;
+ table_iterator cbegin() const;
+ table_iterator cend() const;
+
+Provides `input iterators`_ for a table. This allows tables to work with single-pass, input-only algorithms (like ``std::for_each``).
+
+.. code-block:: cpp
+ :caption: function: iteration with a function
+ :name: table-for-each
+
+ template <typename Fx>
+ void for_each(Fx&& fx);
+
+A functional ``for_each`` loop that calls the desired function. The passed in function must take either ``sol::object key, sol::object value`` or take a ``std::pair<sol::object, sol::object> key_value_pair``. This version can be a bit safer as allows the implementation to definitively pop the key/value off the Lua stack after each call of the function.
+
+.. code-block:: cpp
+ :caption: function: operator[] access
+
+ template<typename T>
+ proxy<table&, T> operator[](T&& key);
+ template<typename T>
+ proxy<const table&, T> operator[](T&& key) const;
+
+Generates a :doc:`proxy<proxy>` that is templated on the table type and the key type. Enables lookup of items and their implicit conversion to a desired type.
+
+.. code-block:: cpp
+ :caption: function: create a table with defaults
+ :name: table-create
+
+ table create(int narr = 0, int nrec = 0);
+ template <typename Key, typename Value, typename... Args>
+ table create(int narr, int nrec, Key&& key, Value&& value, Args&&... args);
+
+ static table create(lua_State* L, int narr = 0, int nrec = 0);
+ template <typename Key, typename Value, typename... Args>
+ static table create(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args);
+
+Creates a table, optionally with the specified values pre-set into the table. If ``narr`` or ``nrec`` are 0, then compile-time shenanigans are used to guess the amount of array entries (e.g., integer keys) and the amount of hashable entries (e.g., all other entries).
+
+.. code-block:: cpp
+ :caption: function: create a table with compile-time defaults assumed
+ :name: table-create-with
+
+ template <typename... Args>
+ table create_with(Args&&... args);
+ template <typename... Args>
+ static table create_with(lua_State* L, Args&&... args);
+
+
+Creates a table, optionally with the specified values pre-set into the table. It checks every 2nd argument (the keys) and generates hints for how many array or map-style entries will be placed into the table.
+
+.. code-block:: cpp
+ :caption: function: create a named table with compile-time defaults assumed
+ :name: table-create-named
+
+ template <typename Name, typename... Args>
+ table create_named(Name&& name, Args&&... args);
+
+
+Creates a table, optionally with the specified values pre-set into the table, and sets it as the key ``name`` in the table.
+
+.. _input iterators: http://en.cppreference.com/w/cpp/concept/InputIterator \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/this_state.rst b/3rdparty/sol2/docs/source/api/this_state.rst
new file mode 100644
index 00000000000..c4c6b3b7f75
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/this_state.rst
@@ -0,0 +1,31 @@
+this_state
+==========
+transparent state argument for the current state
+------------------------------------------------
+
+.. code-block:: cpp
+
+ struct this_state;
+
+This class is a transparent type that is meant to be gotten in functions to get the current lua state a bound function or usertype method is being called from. It does not actually retrieve anything from lua nor does it increment the argument count, making it "invisible" to function calls in lua and calls through ``std::function<...>`` and :doc:`sol::function<function>` on this type. It can be put in any position in the argument list of a function:
+
+.. code-block:: cpp
+ :linenos:
+
+ sol::state lua;
+
+ lua.set_function("bark", []( sol::this_state s, int a, int b ){
+ lua_State* L = s; // current state
+ return a + b + lua_gettop(L);
+ });
+
+ lua.script("first = bark(2, 2)"); // only takes 2 arguments, NOT 3
+
+ // Can be at the end, too, or in the middle: doesn't matter
+ lua.set_function("bark", []( int a, int b, sol::this_state s ){
+ lua_State* L = s; // current state
+ return a + b + lua_gettop(L);
+ });
+
+ lua.script("second = bark(2, 2)"); // only takes 2 arguments
+ \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/thread.rst b/3rdparty/sol2/docs/source/api/thread.rst
new file mode 100644
index 00000000000..1a713f973b4
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/thread.rst
@@ -0,0 +1,52 @@
+thread
+======
+a separate state that can contain and run functions
+---------------------------------------------------
+
+.. code-block:: cpp
+
+ class thread : public reference { /* ... */ };
+
+``sol::thread`` is a separate runnable part of the Lua VM that can be used to execute work separately from the main thread, such as with :doc:`coroutines<coroutine>`. To take a table or a coroutine and run it specifically on the ``sol::thread`` you either pulled out of lua or created, just get that function through the :ref:`state of the thread<thread_state>`
+
+members
+-------
+
+.. code-block:: cpp
+ :caption: constructor: thread
+
+ thread(lua_State* L, int index = -1);
+
+Takes a thread from the Lua stack at the specified index and allows a person to use all of the abstractions therein.
+
+.. code-block:: cpp
+ :caption: function: view into thread_state()'s state
+
+ state_view state() const;
+
+This retrieves the current state of the thread, producing a :doc:`state_view<state>` that can be manipulated like any other. :doc:`Coroutines<coroutine>` pulled from Lua using the thread's state will be run on that thread specifically.
+
+.. _thread_state:
+
+.. code-block:: cpp
+ :caption: function: retrieve thread state object
+
+ lua_State* thread_state () const;
+
+This function retrieves the ``lua_State*`` that represents the thread.
+
+.. code-block:: cpp
+ :caption: current thread status
+
+ thread_status status () const;
+
+Retrieves the :doc:`thread status<types>` that describes the current state of the thread.
+
+.. code-block:: cpp
+ :caption: function: thread creation
+ :name: thread-create
+
+ thread create();
+ static thread create (lua_State* L);
+
+Creates a new thread from the given a ``lua_State*``. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/tie.rst b/3rdparty/sol2/docs/source/api/tie.rst
new file mode 100644
index 00000000000..080c8a1cc4f
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/tie.rst
@@ -0,0 +1,26 @@
+tie
+===
+An improved version of ``std::tie``
+-----------------------------------
+
+`std::tie()`_ does not work well with :doc:`sol::function<function>`'s ``sol::function_result`` returns. Use ``sol::tie`` instead. Because they're both named `tie`, you'll need to be explicit when you use Sol's by naming it with the namespace (``sol::tie``), even with a ``using namespace sol;``. Here's an example:
+
+.. code-block:: cpp
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ const auto& code = R"(
+ function test()
+ return 1, 2, 3
+ end
+ )";
+ lua.script(code);
+
+ int a, b, c;
+ //std::tie(a, b, c) = lua["test"]();
+ // will error: use the line below
+ sol::tie(a, b, c) = lua["test"]();
+
+
+.. _std::tie(): http://en.cppreference.com/w/cpp/utility/tuple/tie
diff --git a/3rdparty/sol2/docs/source/api/types.rst b/3rdparty/sol2/docs/source/api/types.rst
new file mode 100644
index 00000000000..9f761ee25b9
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/types.rst
@@ -0,0 +1,207 @@
+types
+=====
+nil, lua_primitive type traits, and other fundamentals
+------------------------------------------------------
+
+The ``types.hpp`` header contains various fundamentals and utilities of Sol.
+
+
+enumerations
+------------
+
+.. code-block:: cpp
+ :caption: syntax of a function called by Lua
+ :name: call-syntax
+
+ enum class call_syntax {
+ dot = 0,
+ colon = 1
+ };
+
+This enumeration indicates the syntax a function was called with in a specific scenario. There are two ways to call a function: with ``obj:func_name( ... )`` or ``obj.func_name( ... );`` The first one passes "obj" as the first argument: the second one does not. In the case of usertypes, this is used to determine whether the call to a :doc:`constructor/initializer<usertype>` was called with a ``:`` or a ``.``, and not misalign the arguments.
+
+.. code-block:: cpp
+ :caption: status of a Lua function call
+ :name: call-status
+
+ enum class call_status : int {
+ ok = LUA_OK,
+ yielded = LUA_YIELD,
+ runtime = LUA_ERRRUN,
+ memory = LUA_ERRMEM,
+ handler = LUA_ERRERR,
+ gc = LUA_ERRGCMM
+ };
+
+This strongly-typed enumeration contains the errors potentially generated by a call to a :doc:`protected function<protected_function>` or a :doc:`coroutine<coroutine>`.
+
+.. code-block:: cpp
+ :caption: status of a Lua thread
+ :name: thread-status
+
+ enum class thread_status : int {
+ ok = LUA_OK,
+ yielded = LUA_YIELD,
+ runtime = LUA_ERRRUN,
+ memory = LUA_ERRMEM,
+ gc = LUA_ERRGCMM,
+ handler = LUA_ERRERR,
+ dead,
+ };
+
+This enumeration contains the status of a thread. The ``thread_status::dead`` state is generated when the thread has nothing on its stack and it is not running anything.
+
+.. code-block:: cpp
+ :caption: status of a Lua load operation
+ :name: load-status
+
+ enum class load_status : int {
+ ok = LUA_OK,
+ runtime = LUA_ERRSYNTAX,
+ memory = LUA_ERRMEM,
+ gc = LUA_ERRGCMM,
+ file = LUA_ERRFILE,
+ };
+
+This enumeration contains the status of a load operation from :ref:`state::load(_file)<state-load-code>`.
+
+.. code-block:: cpp
+ :caption: type enumeration
+ :name: type-enum
+
+ enum class type : int {
+ none = LUA_TNONE,
+ nil = LUA_TNIL,
+ string = LUA_TSTRING,
+ number = LUA_TNUMBER,
+ thread = LUA_TTHREAD,
+ boolean = LUA_TBOOLEAN,
+ function = LUA_TFUNCTION,
+ userdata = LUA_TUSERDATA,
+ lightuserdata = LUA_TLIGHTUSERDATA,
+ table = LUA_TTABLE,
+ poly = none | nil | string | number | thread |
+ table | boolean | function | userdata | lightuserdata
+ };
+
+The base types that Lua natively communicates in and understands. Note that "poly" isn't really a true type, it's just a symbol used in Sol for something whose type hasn't been checked (and you should almost never see it).
+
+
+type traits
+-----------
+
+.. code-block:: cpp
+ :caption: lua_type_of trait
+ :name: lua-type-of
+
+ template <typename T>
+ struct lua_type_of;
+
+This type trait maps a C++ type to a :ref:`type enumeration<type-enum>` value. The default value is ``type::userdata``.
+
+.. code-block:: cpp
+ :caption: primitive checking traits
+ :name: is-primitive
+
+ template <typename T>
+ struct is_lua_primitive;
+
+ template <typename T>
+ struct is_proxy_primitive;
+
+
+This trait is used by :doc:`proxy<proxy>` to know which types should be returned as references to internal Lua memory (e.g., ``userdata`` types) and which ones to return as values (strings, numbers, :doc:`references<reference>`). ``std::reference_wrapper``, ``std::tuple<...>`` are returned as values, but their contents can be references. The default value is false.
+
+special types
+-------------
+
+.. code-block:: cpp
+ :caption: nil
+ :name: nil
+
+ strunil_t {};
+ const nil_t nil {};
+ bool operator==(nil_t, nil_t);
+ bool operator!=(nil_t, nil_t);
+
+``nil`` is a constant used to signify Lua's ``nil``, which is a type and object that something does not exist. It is comparable to itself, :doc:`sol::object<object>` and :doc:`proxy values<proxy>`.
+
+
+.. code-block:: cpp
+ :caption: non_null
+
+ template <typename T>
+ struct non_null {};
+
+A tag type that, when used with :doc:`stack::get\<non_null\<T*>><stack>`, does not perform a ``nil`` check when attempting to retrieve the userdata pointer.
+
+
+.. code-block:: cpp
+ :caption: type list
+ :name: type-list
+
+ template <typename... Args>
+ struct types;
+
+A type list that, unlike ``std::tuple<Args...>``, does not actually contain anything. Used to indicate types and groups of types all over Sol.
+
+
+functions
+---------
+
+.. code-block:: cpp
+ :caption: type_of
+
+ template<typename T>
+ type type_of();
+
+ type type_of(lua_State* L, int index);
+
+
+These functions get the type of a C++ type ``T``; or the type at the specified index on the Lua stack.
+
+.. code-block:: cpp
+ :caption: type checking convenience functions
+
+ int type_panic(lua_State* L, int index, type expected, type actual);
+
+ int no_panic(lua_State*, int, type, type) noexcept;
+
+ void type_error(lua_State* L, int expected, int actual);
+
+ void type_error(lua_State* L, type expected, type actual);
+
+ void type_assert(lua_State* L, int index, type expected, type actual);
+
+ void type_assert(lua_State* L, int index, type expected);
+
+The purpose of these functions is to assert / throw / crash / error (or do nothing, as is the case with ``no_panic``). They're mostly used internally in the framework, but they're provided here if you should need them.
+
+.. code-block:: cpp
+ :caption: type name retrieval
+
+ std::string type_name(lua_State*L, type t);
+
+Gets the Lua-specified name of the :ref:`type<type-enum>`.
+
+structs
+-------
+
+.. code-block:: cpp
+
+ struct userdata_value {
+ void* value;
+ };
+
+ struct light_userdata_value {
+ void* value;
+ };
+
+ struct up_value_index {
+ int index;
+ };
+
+
+Types that differentiate between the two kinds of ``void*`` Lua hands back from its API: full userdata and light userdata, as well as a type that modifies the index passed to ``get`` to refer to `up values`_ These types can be used to trigger different underlying API calls to Lua when working with :doc:`stack<stack>` namespace and the ``push``/``get``/``pop``/``check`` functions.
+
+.. _up values: http://www.Lua.org/manual/5.3/manual.html#4.4 \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/unique_usertype_traits.rst b/3rdparty/sol2/docs/source/api/unique_usertype_traits.rst
new file mode 100644
index 00000000000..4568b11349c
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/unique_usertype_traits.rst
@@ -0,0 +1,44 @@
+unique_usertype_traits<T>
+=========================
+A trait for hooking special handles / pointers
+----------------------------------------------
+
+.. code-block:: cpp
+ :caption: unique_usertype
+ :name: unique-usertype
+
+ template <typename T>
+ struct unique_usertype_traits {
+ typedef T type;
+ typedef T actual_type;
+ static const bool value = false;
+
+ static bool is_null(const actual_type&) {...}
+
+ static type* get (const actual_type&) {...}
+ };
+
+This is a customization point for users who need to *work with special kinds of pointers/handles*. For generic customization, please review the :doc:`customization tutorial<../tutorial/customization>` A traits type for alerting the library that a certain type is to be pushed as a special userdata with special deletion / destruction semantics. It is already defined for ``std::unique_ptr<T, D>`` and ``std::shared_ptr<T>``. You can specialize this to get ``unique_usertype_traits`` semantics with your code, for example with ``boost::shared_ptr<T>`` like so:
+
+.. code-block:: cpp
+
+ namespace sol {
+ template <typename T>
+ struct unique_usertype_traits<boost::shared_ptr<T>> {
+ typedef T type;
+ typedef boost::shared_ptr<T> actual_type;
+ static const bool value = true;
+
+ static bool is_null(const actual_type& value) {
+ return value == nullptr;
+ }
+
+ static type* get (const actual_type& p) {
+ return p.get();
+ }
+ }
+ }
+
+This will allow the framework to properly handle ``boost::shared_ptr<T>``, with ref-counting and all. The `type` is the type that lua and sol will interact with, and will allow you to pull out a non-owning reference / pointer to the data when you just ask for a plain `T*` or `T&` or `T` using the getter functions and properties of Sol.
+
+Note that if ``is_null`` triggers, a ``nil`` value will be pushed into Sol. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/user.rst b/3rdparty/sol2/docs/source/api/user.rst
new file mode 100644
index 00000000000..9a0905d76bd
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/user.rst
@@ -0,0 +1,19 @@
+light<T>/user<T>
+================
+Utility class for the cheapest form of (light) userdata
+-------------------------------------------------------
+
+.. code-block:: cpp
+
+ template <typename T>
+ struct user;
+
+ template <typename T>
+ struct light;
+
+
+``sol::user<T>`` and ``sol::light<T>`` are two utility classes that do not participate in the full :doc:`sol::usertype\<T><usertype>` system. The goal of these classes is to provide the most minimal memory footprint and overhead for putting a single item and getting a single item out of Lua. ``sol::user<T>``, when pushed into Lua, will create a thin, unnamed metatable for that instance specifically which will be for calling its destructor. ``sol::light<T>`` specifically pushes a reference / pointer into Lua as a ``sol::type::lightuserdata``.
+
+If you feel that you do not need to have something participate in the full :doc:`usertype\<T><usertype>` system, use the utility functions ``sol::make_user( ... )`` and ``sol::make_light( ... )`` to create these types and store them into Lua. You can get them off the Lua stack / out of the Lua system by using the same retrieval techniques on ``get`` and ``operator[]`` on tables and with stack operations.
+
+Both have implicit conversion operators to ``T*`` and ``T&``, so you can set them immediately to their respective pointer and reference types if you need them. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/userdata.rst b/3rdparty/sol2/docs/source/api/userdata.rst
new file mode 100644
index 00000000000..6bc64791552
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/userdata.rst
@@ -0,0 +1,13 @@
+userdata
+========
+reference to a userdata
+-----------------------
+
+.. code-block:: cpp
+ :caption: (light\_)userdata reference
+
+ class userdata : public reference;
+
+ class light_userdata : public reference;
+
+These type is meant to hold a reference to a (light) userdata from Lua and make it easy to push an existing userdata onto the stack. It is essentially identical to :doc:`reference<reference>` in every way, just with a definitive C++ type.
diff --git a/3rdparty/sol2/docs/source/api/usertype.rst b/3rdparty/sol2/docs/source/api/usertype.rst
new file mode 100644
index 00000000000..d3282cd5c64
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/usertype.rst
@@ -0,0 +1,329 @@
+usertype<T>
+===========
+structures and classes from C++ made available to Lua code
+----------------------------------------------------------
+
+*Note: ``T`` refers to the type being turned into a usertype.*
+
+While other frameworks extend lua's syntax or create Data Structure Languages (DSLs) to create classes in lua, :doc:`sol<../index>` instead offers the ability to generate easy bindings. These use metatables and userdata in lua for their implementation. Given this C++ class:
+
+.. code-block:: cpp
+ :linenos:
+
+ struct ship {
+ int bullets = 20;
+ int life = 100;
+
+ bool shoot () {
+ if (bullets > 0) {
+ --bullets;
+ // successfully shot
+ return true;
+ }
+ // cannot shoot
+ return false;
+ }
+
+ bool hurt (int by) {
+ life -= by;
+ // have we died?
+ return life < 1;
+ }
+ };
+
+You can bind the it to Lua using the following C++ code:
+
+.. code-block:: cpp
+ :linenos:
+
+ sol::state lua;
+
+ lua.new_usertype<ship>( "ship", // the name of the class, as you want it to be used in lua
+ // List the member functions you wish to bind:
+ // "name_of_item", &class_name::function_or_variable
+ "shoot", &ship::shoot,
+ "hurt", &ship::hurt,
+ // bind variable types, too
+ "life", &ship::bullets
+ // names in lua don't have to be the same as C++,
+ // but it probably helps if they're kept the same,
+ // here we change it just to show its possible
+ "bullet_count", &ship::bullets
+ );
+
+
+Equivalently, you can also write:
+
+.. code-block:: cpp
+ :linenos:
+ :emphasize-lines: 4,12
+
+ sol::state lua;
+
+ // Use constructor directly
+ usertype<ship> shiptype(
+ "shoot", &ship::shoot,
+ "hurt", &ship::hurt,
+ "life", &ship::bullets
+ "bullet_count", &ship::bullets
+ );
+
+ // set usertype explicitly, with the given name
+ lua.set_usertype<ship>( "ship", shiptype );
+
+ // shiptype is now a useless skeleton type, just let it destruct naturally and don't use it again.
+
+
+Note that here, because the C++ class is default-constructible, it will automatically generate a creation function that can be called in lua called "new" that takes no arguments. You can use it like this in lua code:
+
+.. code-block:: lua
+ :linenos:
+
+ fwoosh = ship.new()
+ -- note the ":" that is there: this is mandatory for member function calls
+ -- ":" means "pass self" in Lua
+ local success = fwoosh:shoot()
+ local is_dead = fwoosh:hurt(20)
+ -- check if it works
+ print(is_dead) -- the ship is not dead at this point
+ print(fwoosh.life .. "life left") -- 80 life left
+ print(fwoosh.bullet_count) -- 19
+
+
+There are more advanced use cases for how to create and use a usertype, which are all based on how to use its constructor (see below).
+
+enumerations
+------------
+
+.. _meta_function_enum:
+
+.. code-block:: cpp
+ :caption: meta_function enumeration for names
+ :linenos:
+
+ enum class meta_function {
+ construct,
+ index,
+ new_index,
+ mode,
+ call,
+ metatable,
+ to_string,
+ length,
+ unary_minus,
+ addition,
+ subtraction,
+ multiplication,
+ division,
+ modulus,
+ power_of,
+ involution = power_of,
+ concatenation,
+ equal_to,
+ less_than,
+ less_than_or_equal_to,
+ garbage_collect,
+ call_function,
+ };
+
+
+Use this enumeration to specify names in a manner friendlier than memorizing the special lua metamethod names for each of these. Each binds to a specific operation indicated by the descriptive name of the enum.
+
+members
+-------
+
+.. code-block:: cpp
+ :caption: function: usertype<T> constructor
+ :name: usertype-constructor
+
+ template<typename... Args>
+ usertype<T>(Args&&... args);
+
+
+The constructor of usertype takes a variable number of arguments. It takes an even number of arguments (except in the case where the very first argument is passed as the :ref:`constructor list type<constructor>`). Names can either be strings, :ref:`special meta_function enumerations<meta_function_enum>`, or one of the special indicators for initializers.
+
+
+usertype constructor options
+++++++++++++++++++++++++++++
+
+If you don't specify any constructor options at all and the type is `default_constructible`_, Sol will generate a ``new`` for you. Otherwise, the following are special ways to handle the construction of a usertype:
+
+.. _constructor:
+
+* ``"{name}", constructors<Type-List-0, Type-List-1, ...>``
+ - ``Type-List-N`` must be a ``sol::types<Args...>``, where ``Args...`` is a list of types that a constructor takes. Supports overloading by default
+ - If you pass the ``constructors<...>`` argument first when constructing the usertype, then it will automatically be given a ``"{name}"`` of ``"new"``
+* ``"{name}", sol::initializers( func1, func2, ... )``
+ - Used to handle *initializer functions* that need to initialize the memory itself (but not actually allocate the memory, since that comes as a userdata block from Lua)
+ - Given one or more functions, provides an overloaded Lua function for creating a the specified type
+ + The function must have the argument signature ``func( T*, Arguments... )`` or ``func( T&, Arguments... )``, where the pointer or reference will point to a place of allocated memory that has an uninitialized ``T``. Note that Lua controls the memory, so performing a ``new`` and setting it to the ``T*`` or ``T&`` is a bad idea: instead, use ``placement new`` to invoke a constructor, or deal with the memory exactly as you see fit
+* ``{anything}, sol::factories( func1, func2, ... )``
+ - Used to indicate that a factory function (e.g., something that produces a ``std::unique_ptr<T, ...>``, ``std::shared_ptr<T>``, ``T``, or similar) will be creating the object type
+ - Given one or more functions, provides an overloaded function for invoking
+ + The functions can take any form and return anything, since they're just considered to be some plain function and no placement new or otherwise needs to be done. Results from this function will be pushed into Lua according to the same rules as everything else.
+ + Can be used to stop the generation of a ``.new()`` default constructor since a ``sol::factories`` entry will be recognized as a constructor for the usertype
+ + If this is not sufficient, see next 2 entries on how to specifically block a constructor
+* ``{anything}, sol::no_constructor``
+ - Specifically tells Sol not to create a ``.new()`` if one is not specified and the type is default-constructible
+ - ``{anything}`` should probably be ``"new"``, which will specifically block its creation and give a proper warning if someone calls ``new`` (otherwise it will just give a nil value error)
+ - *Combine with the next one to only allow a factory function for your function type*
+* ``{anything}, {some_factory_function}``
+ - Essentially binds whatever the function is to name ``{anything}``
+ - When used WITH the ``sol::no_constructor`` option above (e.g. ``"new", sol::no_constructor`` and after that having ``"create", &my_creation_func``), one can remove typical constructor avenues and then only provide specific factory functions. Note that this combination is similar to using the ``sol::factories`` method mentioned earlier in this list. To control the destructor as well, see further below
+* ``sol::call_constructor, {valid function / constructor / initializer / factory}``
+ - The purpose of this is to enable the syntax ``local v = my_class( 24 )`` and have that call a constructor; it has no other purpose
+ - This is compatible with luabind, kaguya and other Lua library syntaxes and looks similar to C++ syntax, but the general consensus in Programming with Lua and other places is to use a function named ``new``
+
+usertype destructor options
++++++++++++++++++++++++++++
+
+If you don't specify anything at all and the type is `destructible`_, then a destructor will be bound to the garbage collection metamethod. Otherwise, the following are special ways to handle the destruction of a usertype:
+
+* ``"__gc", sol::destructor( func )`` or ``sol::meta_function::garbage_collect, sol::destructor( func )``
+ - Creates a custom destructor that takes an argument ``T*`` or ``T&`` and expects it to be destructed/destroyed. Note that lua controls the memory and thusly will deallocate the necessary space AFTER this function returns (e.g., do not call ``delete`` as that will attempt to deallocate memory you did not ``new``)
+ - If you just want the default constructor, you can replace the second argument with ``sol::default_destructor``
+ - The usertype will error / throw if you specify a destructor specifically but do not map it to ``sol::meta_function::gc`` or a string equivalent to ``"__gc"``
+
+usertype regular function options
++++++++++++++++++++++++++++++++++
+
+If you don't specify anything at all and the type ``T`` supports ``operator <``, ``operator <=``, or ``operator==`` (``const`` or non-``const`` qualified):
+
+* for ``operator <`` and ``operator <=``
+ - These two ``sol::meta_function::less_than(_or_equal_to)`` are generated for you and overriden in Lua.
+* for ``operator==``
+ - An equality operator will always be generated, doing pointer comparison if ``operator==`` on the two value types is not supported or doing a reference comparison and a value comparison if ``operator==`` is supported
+* heterogenous operators cannot be supported for equality, as Lua specifically checks if they use the same function to do the comparison: if they do not, then the equality method is not invoked; one way around this would be to write one ``int super_equality_function(lua_State* L) { ... }``, pull out arguments 1 and 2 from the stack for your type, and check all the types and then invoke ``operator==`` yourself after getting the types out of Lua (possibly using :ref:`sol::stack::get<stack-get>` and :ref:`sol::stack::check_get<stack-check-get>`)
+
+Otherwise, the following is used to specify functions to bind on the specific usertype for ``T``.
+
+* ``"{name}", &free_function``
+ - Binds a free function / static class function / function object (lambda) to ``"{name}"``. If the first argument is ``T*`` or ``T&``, then it will bind it as a member function. If it is not, it will be bound as a "static" function on the lua table
+* ``"{name}", &type::function_name`` or ``"{name}", &type::member_variable``
+ - Binds a typical member function or variable to ``"{name}"``. In the case of a member variable or member function, ``type`` must be ``T`` or a base of ``T``
+* ``"{name}", sol::readonly( &type::member_variable )``
+ - Binds a typical variable to ``"{name}"``. Similar to the above, but the variable will be read-only, meaning an error will be generated if anything attemps to write to this variable
+* ``"{name}", sol::as_function( &type::member_variable )``
+ - Binds a typical variable to ``"{name}"`` *but forces the syntax to be callable like a function*. This produces a getter and a setter accessible by ``obj:name()`` to get and ``obj::name(value)`` to set.
+* ``"{name}", sol::property( getter_func, setter_func )``
+ - Binds a typical variable to ``"{name}"``, but gets and sets using the specified setter and getter functions. Not that if you do not pass a setter function, the variable will be read-only. Also not that if you do not pass a getter function, it will be write-only
+* ``"{name}", sol::var( some_value )`` or ``"{name}", sol::var( std::ref( some_value ) )``
+ - Binds a typical variable to ``"{name}"``, optionally by reference (e.g., refers to the same memory in C++). This is useful for global variables / static class variables and the like
+* ``"{name}", sol::overloaded( Func1, Func2, ... )``
+ - Creates an oveloaded member function that discriminates on number of arguments and types.
+* ``sol::base_classes, sol::bases<Bases...>``
+ - Tells a usertype what its base classes are. You need this to have derived-to-base conversions work properly. See :ref:`inheritance<usertype-inheritance>`
+
+
+usertype arguments - simple usertype
+++++++++++++++++++++++++++++++++++++
+
+* ``sol::simple``
+ - Only allowed as the first argument to the usertype constructor, must be accompanied by a ``lua_State*``
+ - This tag triggers the :doc:`simple usertype<simple_usertype>` changes / optimizations
+ - Only supported when directly invoking the constructor (e.g. not when calling ``sol::table::new_usertype`` or ``sol::table::new_simple_usertype``)
+ - Should probably not be used directly. Use ``sol::table::new_usertype`` or ``sol::table::new_simple_usertype`` instead
+
+
+
+overloading
+-----------
+
+Functions set on a usertype support overloading. See :doc:`here<overload>` for an example.
+
+
+.. _usertype-inheritance:
+
+inheritance
+-----------
+
+Sol can adjust pointers from derived classes to base classes at runtime, but it has some caveats based on what you compile with:
+
+If your class has no complicatedâ„¢ virtual inheritance or multiple inheritance, than you can try to sneak away with a performance boost from not specifying any base classes and doing any casting checks. (What does "complicatedâ„¢" mean? Ask your compiler's documentation, if you're in that deep.)
+
+For the rest of us safe individuals out there: You must specify the ``sol::base_classes`` tag with the ``sol::bases<Types...>()`` argument, where ``Types...`` are all the base classes of the single type ``T`` that you are making a usertype out of.
+
+.. note::
+
+ Always specify your bases if you plan to retrieve a base class using the Sol abstraction directly and not casting yourself.
+
+.. code-block:: cpp
+ :linenos:
+
+ struct A {
+ int a = 10;
+ virtual int call() { return 0; }
+ };
+ struct B : A {
+ int b = 11;
+ virtual int call() override { return 20; }
+ };
+
+Then, to register the base classes explicitly:
+
+.. code-block:: cpp
+ :linenos:
+ :emphasize-lines: 5
+
+ sol::state lua;
+
+ lua.new_usertype<B>( "B",
+ "call", &B::call,
+ sol::base_classes, sol::bases<A>()
+ );
+
+.. note::
+
+ You must list ALL base classes, including (if there were any) the base classes of A, and the base classes of those base classes, etc. if you want Sol/Lua to handle them automagically.
+
+.. note::
+
+ Sol does not support down-casting from a base class to a derived class at runtime.
+
+.. warning::
+
+ Specify all base class member variables and member functions to avoid current implementation caveats regarding automatic base member lookup. Sol currently attempts to link base class methods and variables with their derived classes with an undocumented, unsupported feature, provided you specify ``sol::base_classes<...>``. Unfortunately, this can come at the cost of performance, depending on how "far" the base is from the derived class in the bases lookup list. If you do not want to suffer the performance degradation while we iron out the kinks in the implementation (and want it to stay performant forever), please specify all the base methods on the derived class in the method listing you write. In the future, we hope that with reflection we will not have to worry about this.
+
+
+inheritance + overloading
+-------------------------
+
+While overloading is supported regardless of inheritance caveats or not, the current version of Sol has a first-match, first-call style of overloading when it comes to inheritance. Put the functions with the most derived arguments first to get the kind of matching you expect or cast inside of an intermediary C++ function and call the function you desire.
+
+traits
+------
+
+.. code-block:: cpp
+ :caption: usertype_traits<T>
+ :name: usertype-traits
+
+ template<typename T>
+ struct usertype_traits {
+ static const std::string name;
+ static const std::string metatable;
+ static const std::string variable_metatable;
+ static const std::string gc_table;
+ };
+
+
+This trait is used to provide names for the various metatables and global tables used to perform cleanup and lookup. They are automagically generated at runtime. Sol attempts to parse the output of ``__PRETTY_FUCNTION__`` (``g++``/``clang++``) or ``_FUNCDSIG`` (``vc++``) to get the proper type name. If you have a special need you can override the names for your specific type. If you notice a bug in a class name when you don't manually specify it during setting a usertype, feel free to open an issue request or send an e-mail!
+
+
+compilation speed
+-----------------
+
+.. note::
+
+ If you find that compilation times are too long and you're only binding member functions, consider perhaps using :doc:`simple usertypes<simple_usertype>`. This can reduce compile times (but may cost memory size and speed). See the simple usertypes documentation for more details.
+
+
+performance note
+----------------
+
+.. note::
+
+ Note that performance for member function calls goes down by a fixed overhead if you also bind variables as well as member functions. This is purely a limitation of the Lua implementation and there is, unfortunately, nothing that can be done about it. If you bind only functions and no variables, however, Sol will automatically optimize the Lua runtime and give you the maximum performance possible. *Please consider ease of use and maintenance of code before you make everything into functions.*
+
+
+.. _destructible: http://en.cppreference.com/w/cpp/types/is_destructible
+.. _default_constructible: http://en.cppreference.com/w/cpp/types/is_constructible \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/usertype_memory.rst b/3rdparty/sol2/docs/source/api/usertype_memory.rst
new file mode 100644
index 00000000000..55734f7e543
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/usertype_memory.rst
@@ -0,0 +1,47 @@
+usertype memory
+===============
+
+.. note::
+
+ Sol does not take ownership of raw pointers, returned from functions or set through the ``set`` functions. Return a value, a ``std::unique_ptr``, a ``std::shared_ptr`` of some kind, or hook up the :doc:`unique usertypes traits<unique_usertype_traits>` to work for some specific handle structure you use (AKA, for ``boost::shared_ptr``).
+
+The userdata generated by Sol has a specific layout, depending on how Sol recognizes userdata passed into it. All of the referred to metatable names are generated from :ref:`usertype_traits\<T><usertype-traits>`
+
+In general, we always insert a T* in the first `sizeof(T*)` bytes, so the any framework that pulls out those first bytes expecting a pointer will work. The rest of the data has some different alignments and contents based on what it's used for and how it's used.
+
+For ``T``
+---------
+
+These are classified with the metatable name from :ref:`usertype_traits\<T><usertype-traits>`.
+
+The data layout for references is as follows::
+
+ | T* | T |
+ ^-sizeof(T*) bytes-^-sizeof(T) bytes, actual data-^
+
+Lua will clean up the memory itself but does not know about any destruction semantics T may have imposed, so when we destroy this data we simply call the destructor to destroy the object and leave the memory changes to for lua to handle after the "__gc" method exits.
+
+
+For ``T*``
+----------
+
+These are classified as a separate ``T*`` metatable, essentially the "reference" table. Things passed to Sol as a pointer or as a ``std::reference<T>`` are considered to be references, and thusly do not have a ``__gc`` (garbage collection) method by default. All raw pointers are non-owning pointers in C++. If you're working with a C API, provide a wrapper around pointers that are supposed to own data and use the constructor/destructor idioms (e.g., with an internal ``std::unique_ptr``) to keep things clean.
+
+The data layout for data that only refers is as follows::
+
+ | T* |
+ ^-sizeof(T*) bytes-^
+
+That is it. No destruction semantics need to be called.
+
+For ``std::unique_ptr<T, D>`` and ``std::shared_ptr<T>``
+--------------------------------------------------------
+
+These are classified as :ref:`"unique usertypes"<unique-usertype>`, and have a special metatable for them as well. The special metatable is either generated when you add the usertype to Lua using :ref:`set_usertype<set-usertype>` or when you first push one of these special types. In addition to the data, a deleter function that understands the following layout is injected into the usertype.
+
+The data layout for these kinds of types is as follows::
+
+ | T* | void(*)(void*) function_pointer | T |
+ ^-sizeof(T*) bytes-^-sizeof(void(*)(void*)) bytes, deleter-^- sizeof(T) bytes, actal data -^
+
+Note that we put a special deleter function before the actual data. This is because the custom deleter must know where the offset to the data is, not the rest of the library. Sol just needs to know about ``T*`` and the userdata (and userdata metatable) to work, everything else is for preserving construction / destruction semantics. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/api/var.rst b/3rdparty/sol2/docs/source/api/var.rst
new file mode 100644
index 00000000000..9e9bcec57d9
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/var.rst
@@ -0,0 +1,49 @@
+var
+===
+For hooking up static / global variables to Lua usertypes
+---------------------------------------------------------
+
+The sole purpose of this tagging type is to work with :doc:`usertypes<usertype>` to provide ``my_class.my_static_var`` access, and to also provide reference-based access as well.
+
+.. code-block:: cpp
+
+ #include <sol.hpp>
+
+ struct test {
+ static int muh_variable;
+ };
+ int test::muh_variable = 25;
+
+
+ int main () {
+ sol::state lua;
+ lua.open_libraries();
+ lua.new_usertype<test>("test",
+ "direct", sol::var(2),
+ "global", sol::var(test::muh_variable),
+ "ref_global", sol::var(std::ref(test::muh_variable))
+ );
+
+ int direct_value = lua["test"]["direct"];
+ // direct_value == 2
+
+ int global = lua["test"]["global"];
+ // global == 25
+ int global2 = lua["test"]["ref_global"];
+ // global2 == 25
+
+ test::muh_variable = 542;
+
+ global = lua["test"]["global"];
+ // global == 25
+ // global is its own memory: was passed by value
+
+ global2 = lua["test"]["ref_global"];
+ // global2 == 542
+ // global2 was passed through std::ref
+ // global2 holds a reference to muh_variable
+ // if muh_variable goes out of scope or is deleted
+ // problems could arise, so be careful!
+
+ return 0;
+ }
diff --git a/3rdparty/sol2/docs/source/api/variadic_args.rst b/3rdparty/sol2/docs/source/api/variadic_args.rst
new file mode 100644
index 00000000000..5d3e0c10282
--- /dev/null
+++ b/3rdparty/sol2/docs/source/api/variadic_args.rst
@@ -0,0 +1,49 @@
+variadic_args
+=============
+transparent argument to deal with multiple parameters to a function
+-------------------------------------------------------------------
+
+
+.. code-block:: cpp
+
+ struct variadic_args;
+
+This class is meant to represent every single argument at its current index and beyond in a function list. It does not increment the argument count and is thus transparent. You can place it anywhere in the argument list, and it will represent all of the objects in a function call that come after it, whether they are listed explicitly or not.
+
+``variadic_args`` also has ``begin()`` and ``end()`` functions that return (almost) random-acess iterators. These return a proxy type that can be implicitly converted, much like the :doc:`table proxy type<proxy>`.
+
+.. code-block:: cpp
+ :linenos:
+
+ #include <sol.hpp>
+
+ int main () {
+
+ sol::state lua;
+
+ // Function requires 2 arguments
+ // rest can be variadic, but:
+ // va will include everything after "a" argument,
+ // which means "b" will be part of the varaidic_args list too
+ // at position 0
+ lua.set_function("v", [](int a, sol::variadic_args va, int b) {
+ int r = 0;
+ for (auto v : va) {
+ int value = v; // get argument out (implicit conversion)
+ // can also do int v = va.get<int>(i); with index i
+ r += value;
+ }
+ // Only have to add a, b was included
+ return r + a;
+ });
+
+ lua.script("x = v(25, 25)");
+ lua.script("x2 = v(25, 25, 100, 50, 250, 150)");
+ lua.script("x3 = v(1, 2, 3, 4, 5, 6)");
+ // will error: not enough arguments
+ //lua.script("x4 = v(1)");
+
+ lua.script("print(x)"); // 50
+ lua.script("print(x2)"); // 600
+ lua.script("print(x3)"); // 21
+ }
diff --git a/3rdparty/sol2/docs/source/benchmarks.rst b/3rdparty/sol2/docs/source/benchmarks.rst
new file mode 100644
index 00000000000..f85277b6df1
--- /dev/null
+++ b/3rdparty/sol2/docs/source/benchmarks.rst
@@ -0,0 +1,94 @@
+benchmarks
+==========
+because somebody is going to ask eventually...
+----------------------------------------------
+
+
+Here are measurements of the *overhead that libraries impose around the Lua C API*: that is, the cost of abstracting / wrapping the plain Lua C API. Measurements are (at the time of writing) done with all libraries compiled against a DLL version of Lua 5.3.3 to make sure each Lua call has the same overhead between libraries (no Link Time Optimizations or other static library optimizations).
+
+These are some informal and formal benchmarks done by both the developers of sol and other library developers / users. We leave you to interpret the data as you see fit.
+
+* `lua_binding_benchmarks`_ by satoren (developer of `kaguya`_) (`Sol`_ is the "sol2" entry)
+* `lua-bench`_ by ThePhD (developer of `Sol`_)
+
+As of the writing of this documentation (August 12th, 2016), :doc:`Sol<index>` (Sol2) seems to take the cake in most categories for speed! Below are some graphs from `lua-bench`_. You can read the benchmarking code there if you think something was done wrong, and submit a pull requests or comment on something to make sure that ThePhD is being honest about his work. All categories are the performance of things described at the top of the :doc:`feature table<features>`.
+
+Note that Sol here makes use of its more performant variants (see :doc:`c_call<api/c_call>`), and ThePhD also does his best to make use of the most performant variants for other frameworks by disabling type checks where possible as well (Thanks to Liam Devine of OOLua for explaining how to turn off type checks in OOLua).
+
+Bars go up to the average execution time. Lower is better. Reported times are for the desired operation run through `nonius`_. Results are sorted from top to bottom by best to worst. Note that there are error bars to show potential variance in performance: generally, same-sized errors bars plus very close average execution time implies no significant difference in speed, despite the vastly different abstraction techniques used.
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20function%20calls.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20function%20calls.png
+ :alt: bind several member functions to an object and call them in Lua code
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20variable.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20variable.png
+ :alt: bind a variable to an object and call it in Lua code
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20member%20variable.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20many%20member%20variables.png
+ :alt: bind MANY variables to an object and call it in Lua code
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20c%20function%20through%20lua.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20c%20function%20through%20lua.png
+ :alt: retrieve a C function bound in Lua and call it from C++
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20stateful%20c%20function.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20stateful%20c%20function.png
+ :alt: bind a stateful C function (e.g., a mutable lambda), retrieve it, and call it from C++
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20c%20function.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20c%20function.png
+ :alt: call a C function through Lua code
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20lua%20function.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20lua%20function.png
+ :alt: retrieve a plain Lua function and call it from C++
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20multi%20return.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20multi%20return.png
+ :alt: return mutliple objects from C++ using std::tuple or through a library-defined mechanism
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20global%20get.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20global%20get.png
+ :alt: retrieve a value from the global table
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20global%20set.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20global%20set.png
+ :alt: set a value into the global table
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20table%20chained%20get.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20table%20chained%20get.png
+ :alt: measures the cost of doing consecutive lookups into a table that exists from C++; some libraries fail here because they do not do lazy evaluation or chaining properly
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20table%20get.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20table%20get.png
+ :alt: measures the cost of retrieving a value from a table in C++; this nests 1 level so as to not be equivalent to any measured global table get optimzations
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20table%20chained%20set.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20table%20chained%20set.png
+ :alt: measures the cost of doing consecutive lookups into a table that exists from C++ and setting the final value; some libraries fail here because they do not do lazy evaluation or chaining properly
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20table%20set.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20table%20set.png
+ :alt: measures the cost of setting a value into a table in C++; this nests 1 level so as to not be equivalent to any measured global table set optimzations
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20return%20userdata.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20return%20userdata.png
+ :alt: bind a C function which returns a custom class by-value and call it through Lua code
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20get%20optional.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20get%20optional.png
+ :alt: retrieve an item from a table that does not exist in Lua and check for its existence (testing the cost of the failure case)
+
+.. image:: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20base%20from%20derived.png
+ :target: https://raw.githubusercontent.com/ThePhD/lua-bench/master/lua%20-%20results/lua%20bench%20graph%20-%20base%20from%20derived.png
+ :alt: retrieve base class pointer out of Lua without knowing exact derived at compile-time, and have it be correct for multiple-inheritance
+
+
+
+.. _lua-bench: https://github.com/ThePhD/lua-bench
+.. _lua_binding_benchmarks: http://satoren.github.io/lua_binding_benchmark/
+.. _kaguya: https://github.com/satoren/kaguya
+.. _Sol: https://github.com/ThePhD/sol2
+.. _nonius: https://github.com/rmartinho/nonius/
diff --git a/3rdparty/sol2/docs/source/cmake.rst b/3rdparty/sol2/docs/source/cmake.rst
new file mode 100644
index 00000000000..2d9e378d7e6
--- /dev/null
+++ b/3rdparty/sol2/docs/source/cmake.rst
@@ -0,0 +1,54 @@
+CMake Script
+============
+
+Thanks to `Kevin Brightwell`_, you can drop this CMake Script into your CMake Projects to have Sol part of one of its builds:
+
+.. code-block:: cmake
+ :caption: CMake Build Script
+ :name: cmake-build-script
+
+ # Needed for ExternalProject_Add()
+ include(ExternalProject)
+
+ # Needed for building single header for sol2
+ find_package(PythonInterp 3 REQUIRED)
+
+ # Configuration data for What sol2 version to use and where to put it
+ set(SOL2_TAG v2.5.6)
+ set(SOL2_HPP "${CMAKE_BINARY_DIR}/include/sol.hpp")
+
+ # Download and "install" sol2
+ ExternalProject_add(
+ sol2
+ PREFIX ${VENDOR_PATH} # Set this value yourself
+
+ GIT_REPOSITORY "https://github.com/ThePhD/sol2.git"
+ GIT_TAG ${SOL2_TAG}
+
+ # No CMake commands to run, so tell CMake not to configure
+ CONFIGURE_COMMAND ""
+
+ # Generate the single header and put it in ${SOL2_HPP}
+ BINARY_DIR ${VENDOR_PREFIX}/src/sol2
+ BUILD_COMMAND
+ ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/include
+ COMMAND
+ ${PYTHON_EXECUTABLE} ./single.py -o "${SOL2_HPP}"
+
+ # No install or test command for the library
+ INSTALL_COMMAND ""
+ TEST_COMMAND "")
+
+ # Conditionally turn on SOL_CHECK_ARGUMENTS if using Debug mode
+ if (CMAKE_BUILD_TYPE MATCHES "[Dd]ebug")
+ if (VERBOSE)
+ message(STATUS "Turning on SOL_CHECK_ARGUMENTS in Debug mode.")
+ endif()
+ add_definitions(-DSOL_CHECK_ARGUMENTS)
+ endif()
+
+ # Make sure sol2 is found as a system directory
+ include_directories(SYSTEM ${CMAKE_BINARY_DIR}/include)
+
+
+.. _Kevin Brightwell: https://github.com/ThePhD/sol2/issues/89
diff --git a/3rdparty/sol2/docs/source/codecvt.rst b/3rdparty/sol2/docs/source/codecvt.rst
new file mode 100644
index 00000000000..ff901edea1e
--- /dev/null
+++ b/3rdparty/sol2/docs/source/codecvt.rst
@@ -0,0 +1,8 @@
+std::(w/u16/u32)string support
+==============================
+because this is surprisingly hard using standard C++
+----------------------------------------------------
+
+Individuals using Visual Studio 2015, or on Windows with the VC++ and MinGW compilers (possibly Clang++ on Windows as well) have ``<codecvt>`` headers, and thusly Sol will attempt to include it. Individuals on GC 4.9.x, Clang 3.5.x, Clang 3.6.x do not seem to have ``<codecvt>`` shipped with the standard library that comes with installation of these compilers. If you want ``std::wstring``, ``std::u16string``, ``std::u32string`` automatic handling then you need to make sure you have those headers and then define ``SOL_CODECVT_SUPPORT``.
+
+ThePhD did not want this to have to be a thing, but slow implementations and such force their hand. When GCC 7.x comes out, ThePhD will consider removing the effect of defining this macro and leaving <codecvt> support in at all times.
diff --git a/3rdparty/sol2/docs/source/conf.py b/3rdparty/sol2/docs/source/conf.py
new file mode 100644
index 00000000000..63733022b90
--- /dev/null
+++ b/3rdparty/sol2/docs/source/conf.py
@@ -0,0 +1,291 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Sol documentation build configuration file, created by
+# sphinx-quickstart on Mon Feb 29 21:49:51 2016.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+ 'sphinx.ext.doctest',
+ 'sphinx.ext.todo'
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'Sol'
+copyright = '2016, ThePhD'
+author = 'ThePhD'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '2.14'
+# The full version, including alpha/beta/rc tags.
+release = '2.14.8'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# The default highlighting language: default is python
+highlight_language = 'c++'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = True
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = "haiku"
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+html_theme_path = ["_themes", ]
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (relative to this directory) to use as a favicon of
+# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Language to be used for generating the HTML full-text search index.
+# Sphinx supports the following languages:
+# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
+# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr'
+#html_search_language = 'en'
+
+# A dictionary with options for the search language support, empty by default.
+# Now only 'ja' uses this config value
+#html_search_options = {'type': 'default'}
+
+# The name of a javascript file (relative to the configuration directory) that
+# implements a search results scorer. If empty, the default will be used.
+#html_search_scorer = 'scorer.js'
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Soldoc'
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+
+# Latex figure (float) alignment
+#'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (master_doc, 'Sol.tex', 'Sol Documentation',
+ 'ThePhD', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ (master_doc, 'sol', 'Sol Documentation',
+ [author], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ (master_doc, 'Sol', 'Sol Documentation',
+ author, 'Sol', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
diff --git a/3rdparty/sol2/docs/source/eevee_code_after.jpg b/3rdparty/sol2/docs/source/eevee_code_after.jpg
new file mode 100644
index 00000000000..33594ce5e0b
--- /dev/null
+++ b/3rdparty/sol2/docs/source/eevee_code_after.jpg
Binary files differ
diff --git a/3rdparty/sol2/docs/source/eevee_code_before.jpg b/3rdparty/sol2/docs/source/eevee_code_before.jpg
new file mode 100644
index 00000000000..ea9650ff1ac
--- /dev/null
+++ b/3rdparty/sol2/docs/source/eevee_code_before.jpg
Binary files differ
diff --git a/3rdparty/sol2/docs/source/exceptions.rst b/3rdparty/sol2/docs/source/exceptions.rst
new file mode 100644
index 00000000000..13be8b9a667
--- /dev/null
+++ b/3rdparty/sol2/docs/source/exceptions.rst
@@ -0,0 +1,51 @@
+exceptions
+==========
+since somebody is going to ask about it...
+------------------------------------------
+
+Yes, you can turn off exceptions in Sol with ``#define SOL_NO_EXCEPTIONS`` before including or by passing the command line argument that defines ``SOL_NO_EXCEPTIONS``. We don't recommend it unless you're playing with a Lua distro that also doesn't play nice with exceptions (like non-x64 versions of :ref:`LuaJIT<LuaJIT and exceptions>` ).
+
+If you turn this off, the default `at_panic`_ function :doc:`state<api/state>` set for you will not throw. Instead, the default Lua behavior of aborting will take place (and give you no chance of escape unless you implement your own at_panic function and decide to try ``longjmp`` out).
+
+To make this not be the case, you can set a panic function directly with ``lua_atpanic( lua, my_panic_function );`` or when you create the ``sol::state`` with ``sol::state lua(my_panic_function);``. Here's an example ``my_panic_function`` you can have that prints out its errors:
+
+.. code-block:: cpp
+ :caption: regular panic function
+
+ #include <sol.hpp>
+ #include <iostream>
+
+ int my_panic_function( lua_State* L ) {
+ // error message is at the top of the stack
+ const char* message = lua_tostring(L, -1);
+ // message can be null, so don't crash
+ // us with nullptr-constructed-string if it is
+ std::string err = message ? message : "An unexpected error occurred and forced the lua state to call atpanic";
+ // Weee
+ std::cerr << err << std::endl;
+ // When this function exits, Lua will exhibit default behavior and abort()
+ }
+
+ int main () {
+ sol::state lua(my_panic_function);
+ }
+
+
+Note that ``SOL_NO_EXCEPTIONS`` will also disable :doc:`protected_function<api/protected_function>`'s ability to catch C++ errors you throw from C++ functions bound to Lua that you are calling through that API. So, only turn off exceptions in Sol if you're sure you're never going to use exceptions ever. Of course, if you are ALREADY not using Exceptions, you don't have to particularly worry about this and now you can use Sol!
+
+If there is a place where a throw statement is called or a try/catch is used and it is not hidden behind a ``#ifndef SOL_NO_EXCEPTIONS`` block, please file an issue at `issue`_ or submit your very own pull request so everyone can benefit!
+
+
+.. _LuaJIT and exceptions:
+
+LuaJIT and exceptions
+---------------------
+
+It is important to note that a popular 5.1 distribution of Lua, LuaJIT, has some serious `caveats regarding exceptions`_. LuaJIT's exception promises are flaky at best on x64 (64-bit) platforms, and entirely terrible on non-x64 (32-bit, ARM, etc.) platorms. The trampolines we have in place for all functions bound through conventional means in Sol will catch exceptions and turn them into Lua errors so that LuaJIT remainds unperturbed, but if you link up a C function directly yourself and throw, chances are you might have screwed the pooch.
+
+Testing in `this closed issue`_ that it doesn't play nice on 64-bit Linux in many cases either, especially when it hits an error internal to the interpreter (and does not go through Sol). We do have tests, however, that compile for our continuous integration check-ins that check this functionality across several compilers and platforms to keep you protected and given hard, strong guarantees for what happens if you throw in a function bound by Sol. If you stray outside the realm of Sol's protection, however... Good luck.
+
+.. _issue: https://github.com/ThePhD/sol2/issues/
+.. _at_panic: http://www.Lua.org/manual/5.3/manual.html#4.6
+.. _caveats regarding exceptions: http://luajit.org/extensions.html#exceptions
+.. _this closed issue: https://github.com/ThePhD/sol2/issues/28 \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/features.rst b/3rdparty/sol2/docs/source/features.rst
new file mode 100644
index 00000000000..527398af374
--- /dev/null
+++ b/3rdparty/sol2/docs/source/features.rst
@@ -0,0 +1,258 @@
+features
+========
+what does Sol (and other libraries) support?
+--------------------------------------------
+
+The goal of Sol is to provide an incredibly clean API that provides high performance (comparable or better than the C it was written on) and extreme ease of use. That is, users should be able to say: "this works pretty much how I expected it to."
+
+For the hard technical components of Lua and its ecosystem we support, here is the full rundown:
+
+what Sol supports
+-----------------
+
+* Support for Lua 5.1, 5.2, and 5.3. We achieve this through our "doc:`compatibility<compatibility>` header.
+
+* :doc:`Table<api/table>` support: setting values, getting values of multiple (different) types
+ - :doc:`Lazy evaluation<api/proxy>` for nested/chained queries
+ ``table["a"]["b"]["c"] = 24;``
+ - Implicit conversion to the types you want
+ ``double b = table["computed_value"];``
+
+* :doc:`Optional<api/optional>` support: setting values, getting values of multiple (different) types
+ - :doc:`Lazy evaluation<api/proxy>` for nested/chained queries
+ ``optional<int> maybe_number = table["a"]["b"]["invalid_key"];``
+ - Turns on safety when you want it: speed when you don't
+
+* Support for callables (functions, lambdas, member functions)
+ - Pull out any Lua function with :doc:`sol::function<api/function>`
+ ``sol::function fx = table["socket_send"];``
+ - Can also set callables into :doc:`operator[] proxies<api/proxy>`
+ ``table["move_dude"] = engine::move_dude;``
+ - Safety: use :doc:`sol::protected_function<api/protected_function>` to catch any kind of error
+ + ANY kind: C++ exception or Lua erors are trapped and run through the optional ``error_handler`` variable
+ - *Advanced:* Overloading of a single function so you don't need to do boring typechecks
+
+* User-Defined Type (:doc:`sol::usertype<api/usertype>` in the API) support:
+ - Set member functions to be called
+ - Set member variables
+ - Set variables on a class that are based on setter/getter functions
+ - Use free-functions that take the Type as a first argument (pointer or reference)
+ - Support for "Factory" classes that do not expose constructor or destructor
+ - Modifying memory of userdata in C++ directly affects Lua without copying, and
+ - Modifying userdata in Lua directly affects C++ references/pointers
+ ``my_class& a = table["a"];``
+ ``my_class* a_ptr = table["a"];``
+ - If you want a copy, just use value semantics and get copies:
+ ``my_class a = table["a"];``
+
+* Thread/Coroutine support
+ - Use, resume, and play with :doc:`coroutines<api/coroutine>` like regular functions
+ - Get and use them even on a separate Lua :doc:`thread<api/thread>`
+ - Monitor status and get check errors
+
+* *Advanced:* Customizable and extensible to your own types if you override :doc:`getter/pusher/checker<api/stack>` template struct definitions.
+
+
+The Feature Matrixâ„¢
+-------------------
+
+The below feature table checks for the presence of something. It, however, does not actually account for any kind of laborious syntax.
+
+✔ full support: works as you'd expect (operator[] on tables, etc...)
+
+~ partial support / wonky support: this means its either supported through some other fashion (not with the desired syntax, serious caveats, etc.). Sometimes means dropping down to use the plain C API (at which point, what was the point of the abstraction?).
+
+✗ no support: feature doesn't work or, if it's there, it REALLY sucks to use
+
+Implementation notes from using the libraries are below the tables.
+
+
+category explanations
+---------------------
+
+Explanations for a few categories are below (rest are self-explanatory).
+
+* optional: Support for getting an element, or potentially not (and not forcing the default construction of what amounts to a bogus/dead object). Usually comes with ``std(::experimental)::optional``. It's a fairly new class, so a hand-rolled class internal to the library with similar semantics is also acceptable
+* tables: Some sort of abstraction for dealing with tables. Ideal support is ``mytable["some_key"] = value``, and everything that the syntax implies.
+* table chaining: In conjunction with tables, having the ability to query deeply into tables ``mytable["key1"]["key2"]["key3"]``. Note that this becomes a tripping point for some libraries: crashing if ``"key1"`` doesn't exist while trying to access ``"key2"`` (Sol avoids this specifically when you use ``sol::optional``), and sometimes it's also a heavy performance bottleneck as expressions are not lazy-evaluated by a library.
+* arbitrary keys: Letting C++ code use userdata, other tables, integers, etc. as keys for into a table.
+* user-defined types (udts): C++ types given form and function in Lua code.
+* udts - member functions: C++ member functions on a type, usually callable with ``my_object:foo(1)`` or similar in Lua.
+* udts - variables: C++ member variables, manipulated by ``my_object.var = 24`` and friends
+* function binding: Support for binding all types of functions. Lambdas, member functions, free functions, in different contexts, etc...
+* protected function: Use of ``lua_pcall`` to call a function, which offers error-handling and trampolining (as well as the ability to opt-in / opt-out of this behavior)
+* multi-return: returning multiple values from and to Lua (generally through ``std::tuple<...>`` or in some other way)
+* variadic/variant argument: being able to accept "anything" from Lua, and even return "anything" to Lua (``object`` abstraction, variadic arguments, etc...)
+* inheritance: allowing some degree of subtyping or inheritance on classes / userdata from Lua - this generally means that you can retrieve a base pointer from Lua even if you hand the library a derived pointer
+* overloading: the ability to call overloaded functions, matched based on arity or type (``foo( 1 )`` from lua calls a different function then ``foo( "bark" )``).
+* Lua thread: basic wrapping of the lua thread API; ties in with coroutine.
+* coroutines: allowing a function to be called multiple times, resuming the execution of a Lua coroutine each time
+
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| | plain C | luawrapper | lua-intf | luabind | Selene | Sol2 | oolua | lua-api-pp | kaguya | SLB3 | SWIG | luacppinterface | luwra |
+| | | | | | | | | | | | | | |
++===========================+=============+============+==========+=========+==========+===========+===========+================+==========+==========+===========+=================+========+
+| optional | ~ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✗ | ✗ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| tables | ~ | ~ | ~ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✗ | ✗ | ~ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| table chaining | ~ | ~ | ~ | ✔ | ✔ | ✔ | ✗ | ✔ | ✔ | ✗ | ✗ | ~ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| arbitrary keys | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ | ~ | ✔ | ✗ | ✗ | ✗ | ✗ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| user-defined types (udts) | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| udts: member functions | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| udts: variables | ~ | ~ | ~ | ~ | ~ | ✔ | ~ | ~ | ~ | ✗ | ✔ | ✗ | ~ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| stack abstractions | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✗ | ~ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| lua callables from C(++) | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| function binding | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ~ | ✔ | ~ | ~ | ~ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| protected call | ~ | ✗ | ~ | ~ | ~ | ✔ | ~ | ✔ | ~ | ~ | ~ | ~ | ~ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| multi-return | ~ | ✗ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ~ | ✔ | ~ | ✗ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| variadic/variant argument | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ~ | ~ | ~ | ✗ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| inheritance | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ~ | ✔ | ~ | ✔ | ~ | ✗ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| overloading | ~ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✔ | ✗ | ✗ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| Lua thread | ~ | ✗ | ~ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| coroutines | ~ | ✗ | ~ | ✔ | ✔ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| no-rtti support | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| no-exception support | ✔ | ✗ | ✔ | ~ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| Lua 5.1 | ✔ | ✔ | ✔ | ✔ | ✗ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| Lua 5.2 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| Lua 5.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| luajit | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ | ✔ |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+| distribution | compile | header | both | compile | header | header | compile | compile | header | compile | generated | compile | header |
++---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
+
+
+notes on implementations
+------------------------
+
+Plain C -
+
+* Obviously you can do anything you want with Plain C, but the effort involved is astronomical in comparison to what frameworks offer
+* Does not scale very well (in terms of developer ease of use)
+* Compilation (or package manager use) is obviously required for your platform and required to use ANY of these libraries, but that's okay because all libraries need some version of Lua anyways, so you always have this!
+
+kaguya -
+
+* member variables are automatically turned into ``obj:x( value )`` to set and ``obj:x()`` to get
+* Has optional support
+* Inspired coroutine support for Sol
+* Library author (satoren) is a nice guy!
+* C++11/14, or boostified (which makes it C++03 compatible)
+* Class registration is a bit verbose, but not as offensive as OOLua or lua-intf or others
+
+Sol -
+
+* One of the few libraries with optional support!
+* Basically the fastest in almomst all respects: http://sol2.readthedocs.io/en/latest/benchmarks.html
+* Overloading support can get messy with inheritance, see :doc:`here<api/overload>`
+* C++14/"C++1y" (-std=c++14, -std=c++1y, =std=c++1z) flags are used (available since GCC 4.9 and Clang 3.5)
+* Active issues, active individuals
+* Deserves lots of love!
+
+lua-intf -
+
+* Can be both header-only or compiled
+* Has optional support
+* C++11
+* Macro-based registration (strange pseudo-language)
+* Fairly fast in most regards
+* Registering classes/"modules" in using C++ code is extremely verbose
+* In order to chain lookups, one has to do ``mykey.mykey2`` on the ``operator[]`` lookup (e.g., you can't nest them arbitrarily, you have to pre-compose the proper lookup string) (fails miserably for non-string lookups!).
+* Not too shabby!
+
+Selene -
+
+* member variables are automatically turned into ``obj:set_x( value )`` to set and ``obj:x()`` to get
+* Registering classes/"modules" using C++ code is extremely verbose, similar to lua-intf's style
+* Eats crap when it comes to performance, most of the time (see :doc:`benchmarks<benchmarks>`)
+* Lots of users (blogpost etc. made it popular), but the Repository is kinda stagnant...
+
+luawrapper -
+
+* Takes the approach of writing and reading tables using ``readVariable`` and ``writeVariable`` functions
+* C++11, no macros!
+* The interface can be clunky (no table-like data structures: most things go though ``readVariable`` / ``writeVariable``)
+* Internal Compiler errors in Visual Studio 2015 - submitted a PR to fix it, hopefully it'll get picked up
+
+SWIG (3.0) -
+
+* Very comprehensive for binding concepts of C++ (classes, variables, etc.) to Lua
+* Helps with literally nothing else (tables, threads, stack abstractions, etc.)
+* Not really a good, full-featured Library...
+* Requires preprocessing step (but it's not a... TERRIBLY complicated preprocessing step); some boilerplate in writing additional classes that you've already declared
+
+luacppinterface -
+
+* The branch that fixes VC++ warnings and introduces some new work has type checker issues, so use the stable branch only
+* No member variable support
+* Actually has tables (but no operator[])
+* Does not support arbitrary keys
+
+luabind -
+
+* One of the older frameworks, but has many people updating it and providing "deboostified" versions
+* Strange in-lua keywords and parsing to allow for classes to be written in lua
+ - not sure if good feature; vendor lock-in to that library to depend on this specific class syntax?
+* Comprehensive lua bindings (can even bind "properties")
+* There's some code that produces an ICE in Visual C++: I submitted a fix to the library in the hopes that it'll get accepted
+* Wonky table support: no basic conversion functions on ``luabind::object``; have to push object then use lua API to get what you want
+
+lua-api-pp -
+
+* Compiled, but the recommendation is to add the source files directly to your project
+* Userdata registration with thick setup-macros: LUAPP_USERDATA( ... ) plus a bunch of free functions that take a ``T& self`` argument
+ - You can bind member functions directly but only if you override metatable entries
+ - Otherwise, COMPLICATED self-registration that makes you wonder why you're using the framework
+* You have to create a context and then call it to start accessing the lua state (adding more boilerplate... thanks)
+ - Thankfully, unlike many libraries, it actually has a Table type that can be used semi-easily. FINALLY
+* C++11-ish in some regards
+* Sad face, thanks to the way userdata registration is handled
+
+SLB3 -
+
+* Old code exported to github from dying google code
+* ".NET Style" - to override functionality, derive from class -- boilerplate (isn't that what we're trying to get rid of?)
+* Pointers everywhere: ownership semantics unclear
+* Piss-poor documentation, ugh!
+* Least favorite to work with, for sure!
+
+oolua -
+
+* The syntax for this library is thicker than a brick. No, seriously. `Go read the docs`_
+* The worst in terms of how to use it: may have docs, but the DSL is extraordinarily crappy with thick, hard-to-debug/hard-to-error-check macros
+ - Same problem as lua-api-pp: cannot have the declaration macros anywhere but the toplevel namespace because of template declaration macro
+* Supports not having exceptions or rtti turned on (shiny!)
+* Poor RAII support: default-construct-and-get style (requires some form of initalization to perform a ``get`` of an object, and it's hard to extend)
+ - The library author has informed me that he does personally advises individuals do not use the ``Table`` abstraction in OOLua... Do I likewise tell people to consider its table abstractions defunct?
+* Member variables are turned into function calls (``get_x`` and ``set_x`` by default)
+
+luwra -
+
+* How do you store stateful functors / lambas? So far, no support for such.
+* Cannot pull functions without first leaving them on the stack: manual cleanup becomes a thing
+* Doesn't understand ``std::function`` conversions and the like (but with some extra code can get it to work)
+* Recently improved by a lot: can chain tables and such, even if performance is a bit sad for that use case
+* When you do manage to set function calls with the macros they are fast (can a template solution do just as good? Sol is going to find out!)
+* No member variable support - get turned into getter/setter functions, similar to kaguya
+
+.. _Go read the docs: https://oolua.org/docs/index.html
diff --git a/3rdparty/sol2/docs/source/index.rst b/3rdparty/sol2/docs/source/index.rst
new file mode 100644
index 00000000000..b1ec3a4f276
--- /dev/null
+++ b/3rdparty/sol2/docs/source/index.rst
@@ -0,0 +1,123 @@
+.. Sol documentation master file, created by
+ sphinx-quickstart on Mon Feb 29 21:49:51 2016.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+.. image:: sol.png
+ :target: https://github.com/ThePhD/sol2
+ :alt: sol2 repository
+
+Sol 2.14
+========
+a fast, simple C++ and Lua Binding
+----------------------------------
+
+When you need to hit the ground running with Lua and C++, `Sol`_ is the go-to framework for high-performance binding with an easy to use API.
+
+.. image:: https://travis-ci.org/ThePhD/sol2.svg?branch=develop
+ :target: https://travis-ci.org/ThePhD/sol2
+ :alt: build status
+
+get going:
+----------
+
+.. toctree::
+ :maxdepth: 1
+ :name: mastertoc
+
+ tutorial/all-the-things
+ tutorial/tutorial-top
+ features
+ api/api-top
+ mentions
+ benchmarks
+ performance
+ safety
+ exceptions
+ rtti
+ codecvt
+ cmake
+ licenses
+ origin
+
+
+"I need feature X, maybe you have it?"
+--------------------------------------
+Take a look at the :doc:`Features<features>` page: it links to much of the API. You can also just straight up browse the :doc:`api<api/api-top>` or ease in with the :doc:`tutorials<tutorial/tutorial-top>`. Don't see a feature you want? Send inquiries for support for a particular abstraction to the `issues`_ tracker.
+
+
+the basics:
+-----------
+
+.. note::
+ More examples can be found in the `examples directory`_
+
+
+.. code-block:: c++
+ :caption: functions
+ :linenos:
+
+ #include <sol.hpp>
+ #include <cassert>
+
+ int main() {
+ sol::state lua;
+ int x = 0;
+ lua.set_function("beep", [&x]{ ++x; });
+ lua.script("beep()");
+ assert(x == 1);
+
+ sol::function beep = lua["beep"];
+ beep();
+ assert(x == 2);
+
+ return 0;
+ }
+
+
+.. code-block:: c++
+ :caption: linking C++ structures to Lua
+ :linenos:
+
+ #include <sol.hpp>
+ #include <cassert>
+
+ struct vars {
+ int boop = 0;
+
+ int bop () const {
+ return boop + 1;
+ }
+ };
+
+ int main() {
+ sol::state lua;
+ lua.new_usertype<vars>("vars",
+ "boop", &vars::boop
+ "bop", &vars::bop);
+ lua.script("beep = vars.new()\n"
+ "beep.boop = 1\n"
+ "bopvalue = beep:bop()");
+
+ vars& beep = lua["beep"];
+ int bopvalue = lua["bopvalue"];
+
+ assert(beep.boop == 1);
+ assert(lua.get<vars>("beep").boop == 1);
+ assert(beep.bop() == 2);
+ assert(bopvalue == 2);
+
+ return 0;
+ }
+
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+
+.. _Sol: https://github.com/ThePhD/sol2
+.. _issues: https://github.com/ThePhD/sol2/issues
+.. _examples directory: https://github.com/ThePhD/sol2/tree/develop/examples \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/licenses.rst b/3rdparty/sol2/docs/source/licenses.rst
new file mode 100644
index 00000000000..f43d97b5e3a
--- /dev/null
+++ b/3rdparty/sol2/docs/source/licenses.rst
@@ -0,0 +1,47 @@
+licenses
+========
+
+The following licenses cover all of the code in Sol. Spoiler: they're all `MIT`_ and it's safe to use in commercial code: feel free to copy/paste the below right into your own attributions / licenses file.
+
+Sol - ThePhD/sol2:
+------------------
+
+ The MIT License (MIT)
+
+ Copyright (c) 2013-2016 Rapptz, ThePhD, and contributors
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Lua-compat-5.3 - keplerproject/Lua-compat-5.3:
+----------------------------------------------
+
+ The MIT License (MIT)
+
+ Copyright (c) 2015 Kepler Project.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Lua - Lua.org:
+--------------
+
+ The MIT License (MIT)
+
+ Copyright © 1994–2015 Lua.org, PUC-Rio.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+ .. _MIT: http://opensource.org/licenses/MIT \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/mentions.rst b/3rdparty/sol2/docs/source/mentions.rst
new file mode 100644
index 00000000000..7b920150181
--- /dev/null
+++ b/3rdparty/sol2/docs/source/mentions.rst
@@ -0,0 +1,50 @@
+mentions
+========
+so does anyone cool use this thing...?
+--------------------------------------
+
+Okay, so the features don't convince you, the documentation doesn't convince you, you want to see what *other* people think about Sol? Well, aside from the well-wishes that come through in the issue tracker, here's a few things floating around about sol2 that I occasionally get pinged about:
+
+`eevee`_ demonstrating the sheer code reduction by using sol2:
+
+
+.. |before| image:: eevee_code_before.jpg
+ :target: https://twitter.com/eevee/status/762039984085798913
+ :alt: Plain C API
+ :align: middle
+
+.. |after| image:: eevee_code_after.jpg
+ :target: https://twitter.com/eevee/status/762039984085798913
+ :alt: Now with sol2!
+ :align: middle
+
++----------+---------+
+| |before| | |after| |
++----------+---------+
+
+
+* (CppNow) sol2 was mentioned in a comparison to other scripting languages by ChaiScript developer, Jason Turner (@lefticus), at a conference!
+ - https://github.com/lefticus/presentations/blob/master/HowAndWhyToAddScripting.md
+* (CppCast) Showed up in CppCast with Elias Daler!
+ - https://eliasdaler.github.io/cppcast#read-more
+ - http://cppcast.com/2016/07/elias-daler/
+* (Eevee) A really nice and neat developer/artist/howaretheysotalented person is attempting to use it for zdoom!
+ - https://eev.ee/dev/2016/08/07/weekly-roundup-three-big-things/
+* (Twitter) Twitter has some people that link it:
+ - https://twitter.com/eevee/status/762039984085798913
+ - https://twitter.com/thephantomderp/status/762043162835709952
+ - https://twitter.com/EliasDaler/status/739082026679173120
+ - https://twitter.com/racodslair/status/754031870640267264
+* (Reddit) Posts on reddit about it!
+ - https://www.reddit.com/r/cpp/comments/4a8gy7/sol2_lua_c_binding_framework/
+ - https://www.reddit.com/r/cpp/comments/4x82hd/plain_c_versus_lua_libraries_benchmarking_speed/
+* Somehow landed on a Torque3D thread...
+ - http://forums.torque3d.org/viewtopic.php?f=32&t=629&p=5246&sid=8e759990ab1ce38a48e896fc9fd62653#p5241
+
+
+`Tell me about your uses!`_
+
+Are you using sol2 for something neat? Want it to be featured here or think it's unfair that ThePhD hasn't found it yet? Well, drop an issue in the repo or send an e-mail!
+
+.. _Tell me about your uses!: https://github.com/ThePhD/sol2/issues/189
+.. _eevee: https://twitter.com/eevee \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/origin.rst b/3rdparty/sol2/docs/source/origin.rst
new file mode 100644
index 00000000000..cc2e3d72467
--- /dev/null
+++ b/3rdparty/sol2/docs/source/origin.rst
@@ -0,0 +1,28 @@
+origin
+======
+
+In the beginning, there was Sir Dennis Ritchie. And Ritchie saw the void, and outstretched his hand, and commanded "Let there be water." And lo, it was so, and there was the C. And with the C, other entities dared to venture on the void given form. Lord Bjarne Stroustrup too did outstretch his hands and say "Let there be an abundance." And lo, into the sea was cast a double portion of surplus of all the things that swam. And for a while, it was good. But other entities were still curious about what yet lay undefined, and one such pantheon, PUC-RIO, saw that it fitting to create the moon. And with the waters and sea made and the moon cast in a starry night sky, PUC-RIO and Dennis and Stroustrup saw that they did good. They oversaw the moon and the sea and gave sound council and it grew. But as the time grew, humanity grew... discontent. No longer were the simple fishing rods and the flowing tides and the dark sky enough lit by a pale moon, no matter how miraculously they were made, enough. They sought out more.
+
+They sought out the light.
+
+And lo, `Danny Y., Rapptz`_ did stand firm in the sea and cast his hands to the sky and said "Let there be Light!". And in the sky was cast a sun. It was an early sun, a growing sun, and many gathered to its warmth, marveling at a life they never knew. And he saw that it was good...
+
+
+seriously
+---------
+
+Sol was originally started by many moon cycles ago to interop with Lua and C++. `Rapptz`_ It was very successful and many rejoiced at having an easy to use abstraction on top of the Lua API. Rapptz continued to make a number of great projects and has been busy with other things, so upon seeing the repository grow stagnant and tired in the last very long while (over a year), `ThePhD`_ forked it into Sol2 and rebooted the code with the hopes of reaching the Milestone and the documentation you have today.
+
+To get to the old repo, head over `here`_.
+
+
+the name
+--------
+
+Sol means sun. The moon (Lua) needs a sun, because without it only the bleak night of copy-paste programming and off-by-one errors would prevail.
+
+
+.. _here: https://github.com/Rapptz/sol
+.. _ThePhD: https://github.com/ThePhD
+.. _Danny Y., Rapptz: https://github.com/Rapptz
+.. _Rapptz: https://github.com/Rapptz \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/performance.rst b/3rdparty/sol2/docs/source/performance.rst
new file mode 100644
index 00000000000..cdfaa9614e6
--- /dev/null
+++ b/3rdparty/sol2/docs/source/performance.rst
@@ -0,0 +1,15 @@
+getting performance
+===================
+things to make Sol as fast as possible
+--------------------------------------
+
+
+As shown by the :doc:`benchmarks<benchmarks>`, Sol is very performant with its abstractions. However, in the case where you need every last drop of performance from Sol, a number of tips and API usage tricks will be documented here. PLEASE benchmark / profile your code before you start invoking these, as some of them trade in readability / clarity for performance.
+
+* If you have a bound function call / bound member function that you are going to call in a very tight, performance-heavy loop, considering using :doc:`sol::c_call<api/c_call>`
+* It is currently undocumented that usertypes will "inherit" member function / member variables from bound classes, mostly because the semantics are unclear and it is not the most performant (although it is flexible: you can register base classes after / whenever you want in relation to the derived class, provided that derived class has its bases listed). Specifying all member functions / member variables for the usertype constructor / ``new_usertype`` function call and not relying on base lookup will boost performance of member lookup
+* Specifying base classes can make getting the usertype out of Sol a bit slower since we have to check and cast; if you know the exact type wherever you're retrieving it, considering not specifying the bases, retrieving the exact type from Sol, and then casting to a base type yourself
+* Member variables can sometimes cost an extra lookup to occur within the Lua system (as mentioned :doc:`bottom of the usertype page<api/usertype>`); until we find out a safe way around this, member variables will always incur that extra lookup cost
+
+
+That's it as far as different performance options are avilable to make Sol run faster. Again, please make sure to invoke these only when you know Sol is the bottleneck. If you find some form of the performance unacceptable to you, also feel free to open an issue at the github. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/rtti.rst b/3rdparty/sol2/docs/source/rtti.rst
new file mode 100644
index 00000000000..91aad3e939b
--- /dev/null
+++ b/3rdparty/sol2/docs/source/rtti.rst
@@ -0,0 +1,14 @@
+run-time type information (rtti)
+================================
+because somebody's going to want to shut this off, too...
+---------------------------------------------------------
+
+Sol does not use RTTI anymore.
+
+*THE BELOW IS NO LONGER NEEDED.*
+
+Not compiling with C++'s run-time type information? Do a ``#define SOL_NO_RTII`` before you include ``sol.hpp`` or define ``SOL_NO_RTTI`` on your command line. Be sure to understand the :ref:`implications<usertype-inheritance>` of doing so if you also turn off exceptions.
+
+If you come across bugs or can't compile because there's a stray `typeid` or `typeinfo` that wasn't hidden behind a ``#ifndef SOL_NO_RTTI``, please file `an issue`_ or even make a pull request so it can be fixed for everyone.
+
+.. _an issue: https://github.com/ThePhD/sol2/issues \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/safety.rst b/3rdparty/sol2/docs/source/safety.rst
new file mode 100644
index 00000000000..8e01113f2a1
--- /dev/null
+++ b/3rdparty/sol2/docs/source/safety.rst
@@ -0,0 +1,22 @@
+safety
+======
+
+Sol was designed to be correct and fast, and in the pursuit of both uses the regular ``lua_to{x}`` functions of Lua rather than the checking versions (``lua_check{X}``) functions. The API defaults to paranoidly-safe alternatives if you have a ``#define SOL_CHECK_ARGUMENTS`` before you include Sol, or if you pass the ``SOL_CHECK_ARGUMENTS`` define on the build command for your build system. By default, it is off and remains off unless you define this, even in debug mode. The same goes for ``#define SOL_SAFE_USERTYPE``.
+
+Note that you can obtain safety with regards to functions you bind by using the :doc:`protect<api/protect>` wrapper around function/variable bindings you set into Lua.
+
+``SOL_SAFE_USERTYPE`` triggers the following change:
+ * If the userdata to a usertype function is nil, will trigger an error instead of letting things go through and letting the system segfault.
+
+``SOL_CHECK_ARGUMENTS`` triggers the following changes:
+ * ``sol::stack::get`` (used everywhere) defaults to using ``sol::stack::check_get`` and dereferencing the argument. It uses ``sol::type_panic`` as the handler if something goes wrong.
+ * ``sol::stack::call`` and its variants will, if no templated boolean is specified, check all of the arguments for a function call.
+ * If ``SOL_SAFE_USERTYPE`` is not defined, it gets defined to turn being on.
+
+Remember that if you want these features, you must explicitly turn them on. Additionally, you can have basic boolean checks when using the API by just converting to a :doc:`sol::optional\<T><api/optional>` when necessary. Tests are compiled with this on to ensure everythign is going as expected.
+
+Finally, some warnings that may help with errors when working with Sol:
+
+.. warning::
+
+ Do NOT save the return type of a :ref:`function_result<function-result>` with ``auto``, as in ``auto numwoof = woof(20);``, and do NOT store it anywhere. See :ref:`here<function-result-warning>`. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/sol.png b/3rdparty/sol2/docs/source/sol.png
new file mode 100644
index 00000000000..eedee2ed3d0
--- /dev/null
+++ b/3rdparty/sol2/docs/source/sol.png
Binary files differ
diff --git a/3rdparty/sol2/docs/source/sol.psd b/3rdparty/sol2/docs/source/sol.psd
new file mode 100644
index 00000000000..84865d5198b
--- /dev/null
+++ b/3rdparty/sol2/docs/source/sol.psd
Binary files differ
diff --git a/3rdparty/sol2/docs/source/tutorial/all-the-things.rst b/3rdparty/sol2/docs/source/tutorial/all-the-things.rst
new file mode 100644
index 00000000000..fa9e73ac6c0
--- /dev/null
+++ b/3rdparty/sol2/docs/source/tutorial/all-the-things.rst
@@ -0,0 +1,606 @@
+tutorial: quick 'n' dirty
+=========================
+
+These are all the things. Use your browser's search to find things you want.
+
+You'll need to ``#include <sol.hpp>``/``#include "sol.hpp"`` somewhere in your code. Sol is header-only, so you don't need to compile anything.
+
+opening a state
+---------------
+
+.. code-block:: cpp
+
+ int main (int argc, char* argv[]) {
+ sol::state lua;
+ // open some common libraries
+ lua.open_libraries(sol::lib::base, sol::lib::package);
+ lua.script( "print('bark bark bark!')" );
+ }
+
+
+sol::state on lua_State*
+------------------------
+
+For your system/game that already has lua, but you'd like something nice:
+
+.. code-block:: cpp
+
+ int pre_existing_system( lua_State* L ) {
+ sol::state_view lua(L);
+ lua.script( "print('bark bark bark!')" );
+ return 0;
+ }
+
+
+running lua code
+----------------
+
+.. code-block:: cpp
+
+ sol::state lua;
+ // load and execute from string
+ lua.script("a = 'test'");
+ // load and execute from file
+ lua.script_file("path/to/luascript.lua");
+
+ // run a script, get the result
+ int value = lua.script("return 54");
+ // value == 54
+
+ // load file without execute
+ sol::load_result script1 = lua.load_file("path/to/luascript.lua");
+ script1(); //execute
+ // load string without execute
+ sol::load_result script2 = lua.load("a = 'test'");
+ script2(); //execute
+
+ sol::load_result script3 = lua.load("return 24");
+ int value2 = script3(); // execute, get return value
+ // value2 == 24
+
+
+set and get variables
+---------------------
+
+You can set/get everything.
+
+.. code-block:: cpp
+
+ sol::lua_state lua;
+
+ lua.open_libraries(sol::lib::base);
+
+ // integer types
+ lua.set("number", 24);
+
+ // floating point numbers
+ lua["number2"] = 24.5;
+
+ // string types
+ lua["important_string"] = "woof woof";
+
+ // non-recognized types is stored as userdata
+ // is callable, therefore gets stored as a function
+ lua["a_function"] = [](){ return 100; };
+
+ // make a table
+ lua["some_table"] = lua.create_table_wth("value", 24);
+
+
+Equivalent to loading a lua file with:
+
+.. code-block:: lua
+
+ number = 24
+ number2 = 24.5
+ important_string = "woof woof"
+ a_function = function () return 100 end
+ some_table = { value = 24 }
+
+Retrieve these variables using this syntax:
+
+.. code-block:: cpp
+
+ // implicit conversion
+ int number = lua["number"];
+
+ // explicit get
+ auto number2 = lua.get<double>("number2");
+
+ // strings too
+ std::string important_string = lua["important_string"];
+
+ // dig into a table
+ int value = lua["value"]["value"];
+
+ // get a function
+ sol::function a_function = lua["a_function"];
+ int value_is_100 = a_function();
+
+ // get a std::function
+ std::function<int()> a_std_function = lua["a_function"];
+ int value_is_still_100 = a_std_function();
+
+Retrieve Lua types using ``object`` and other ``sol::`` types.
+
+.. code-block:: cpp
+
+ sol::state lua;
+
+ // ... everything from before
+
+ sol::object number_obj = lua.get<sol::object>( "number" );
+ // sol::type::number
+ sol::type t1 = number_obj.get_type();
+
+ sol::object function_obj = lua[ "a_function" ];
+ // sol::type::function
+ sol::type t2 = function_obj.get_type();
+ bool is_it_really = function_obj.is<std::function<int()>(); // true
+
+ // will not contain data
+ sol::optional<int> check_for_me = lua["a_function"];
+
+
+You can erase things by setting it to ``nullptr`` or ``sol::nil``.
+
+.. code-block:: cpp
+
+ sol::state lua;
+
+ lua.script("exists = 250");
+
+ int first_try = lua.get_or<int>( 322 );
+ // first_try == 250
+
+ lua.set("exists", sol::nil);
+
+ int second_try = lua.get_or<int>( 322 );
+ // second_try == 322
+
+
+Note that if its a :doc:`userdata/usertype<../api/usertype>` for a C++ type, the destructor will run only when the garbage collector deems it appropriate to destroy the memory. If you are relying on the destructor being run when its set to ``sol::nil``, you're probably committing a mistake.
+
+tables
+------
+
+:doc:`sol::state<../api/state>` is a table too.
+
+.. code-block:: cpp
+
+ sol::state lua;
+
+ // Raw string literal for easy multiline
+ lua.script( R"(
+ abc = { [0] = 24 }
+ def = {
+ ghi = {
+ bark = 50,
+ woof = abc
+ }
+ }
+ )"
+ );
+
+ sol::table abc = lua["abc"];
+ sol::table def = lua["def"];
+ sol::table ghi = lua["def"]["ghi"];
+
+ int bark1 = def["ghi"]["bark"];
+ int bark2 = lua["def"]["ghi"]["bark"];
+ // bark1 == bark2 == 50
+
+ int abcval1 = abc[0];
+ int abcval2 = ghi["woof"][0];
+ // abcval1 == abcval2 == 24
+
+If you're going deep, be safe:
+
+.. code-block:: cpp
+
+ sol::state lua;
+
+ sol::optional<int> will_not_error = lua["abc"]["DOESNOTEXIST"]["ghi"];
+ // will_not_error == sol::nullopt
+ int will_not_error2 = lua["abc"]["def"]["ghi"]["jklm"].get_or<int>(25);
+ // is 25
+
+ // if you don't go safe,
+ // will throw (or do at_panic if no exceptions)
+ int aaaahhh = lua["abc"]["hope_u_liek_crash"];
+
+
+make tables
+-----------
+
+Make some:
+
+.. code-block:: cpp
+
+ sol::state lua;
+
+ lua["abc"] = lua.create_table_with(
+ 0, 24
+ );
+
+ lua.create_named_table("def",
+ "ghi", lua.create_table_with(
+ "bark", 50,
+ // can reference other existing stuff too
+ "woof", lua["abc"]
+ )
+ );
+
+Equivalent Lua code:
+
+.. code-block:: lua
+
+ abc = { [0] = 24 }
+ def = {
+ ghi = {
+ bark = 50,
+ woof = abc
+ }
+ }
+
+
+You can put anything you want in tables as values or keys, including strings, numbers, functions, other tables.
+
+Note that this idea that things can be nested is important and will help later when you get into :ref:`namespacing<namespacing>`.
+
+
+functions
+---------
+
+They're great. Use them:
+
+.. code-block:: cpp
+
+ sol::state lua;
+
+ lua.script("function f (a, b, c, d) return 1 end");
+ lua.script("function g (a, b) return a + b end");
+
+ // fixed signature std::function<...>
+ std::function<int(int, double, int, std::string)> stdfx = lua["f"];
+ // sol::function is often easier:
+ // takes a variable number/types of arguments...
+ sol::function fx = lua["f"];
+
+ int is_one = stdfx(1, 34.5, 3, "bark");
+ int is_also_one = fx(1, "boop", 3, "bark");
+
+ // call through operator[]
+ int is_three = lua["g"](1, 2);
+ // is_three == 3
+ double is_4_8 = lua["g"](2.4, 2.4);
+ // is_4_8 == 4.8
+
+If you need to protect against errors and parser problems and you're not ready to deal with Lua's `longjmp` problems (if you compiled with C), use :doc:`sol::protected_function<../api/protected_function>`.
+
+You can bind member variables as functions too, as well as all KINDS of function-like things:
+
+.. code-block:: cpp
+
+ void some_function () {
+ std::cout << "some function!" << std::endl;
+ }
+
+ void some_other_function () {
+ std::cout << "some other function!" << std::endl;
+ }
+
+ struct some_class {
+ int variable = 30;
+
+ double member_function () {
+ return 24.5;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ // put an instance of "some_class" into lua
+ // (we'll go into more detail about this later
+ // just know here that it works and is
+ // put into lua as a userdata
+ lua.set("sc", some_class());
+
+ // binds a plain function
+ lua["f1"] = some_function;
+ lua.set_function("f2", &some_other_function);
+
+ // binds just the member function
+ lua["m1"] = &some_class::member_function;
+
+ // binds the class to the type
+ lua.set_function("m2", &some_class::member_function, some_class{});
+
+ // binds just the member variable as a function
+ lua["v1"] = &some_class::variable;
+
+ // binds class with member variable as function
+ lua.set_function("v2", &some_class::variable, some_class{});
+
+The lua code to call these things is:
+
+.. code-block:: lua
+
+ f1() -- some function!
+ f2() -- some other function!
+
+ -- need class instance if you don't bind it with the function
+ print(m1(sc)) -- 24.5
+ -- does not need class instance: was bound to lua with one
+ print(m2()) -- 24.5
+
+ -- need class instance if you
+ -- don't bind it with the function
+ print(v1(sc)) -- 30
+ -- does not need class instance:
+ -- it was bound with one
+ print(v2()) -- 30
+
+ -- can set, still
+ -- requires instance
+ v1(sc, 212)
+ -- can set, does not need
+ -- class instance: was bound with one
+ v2(254)
+
+ print(v1(sc)) -- 212
+ print(v2()) -- 254
+
+Can use ``sol::readonly( &some_class::variable )`` to make a variable readonly and error if someone tries to write to it.
+
+
+self call
+---------
+
+You can pass the 'self' argument through C++ to emulate 'member function' calls in Lua.
+
+.. code-block:: cpp
+
+ sol::state lua;
+
+ lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::table);
+
+ // a small script using 'self' syntax
+ lua.script(R"(
+ some_table = { some_val = 100 }
+
+ function some_table:add_to_some_val(value)
+ self.some_val = self.some_val + value
+ end
+
+ function print_some_val()
+ print("some_table.some_val = " .. some_table.some_val)
+ end
+ )");
+
+ // do some printing
+ lua["print_some_val"]();
+ // 100
+
+ sol::table self = lua["some_table"];
+ self["add_to_some_val"](self, 10);
+ lua["print_some_val"]();
+
+
+
+multiple returns from lua
+-------------------------
+
+.. code-block:: cpp
+
+ sol::state lua;
+
+ lua.script("function f (a, b, c) return a, b, c end");
+
+ std::tuple<int, int, int> result;
+ result = lua["f"](100, 200, 300);
+ // result == { 100, 200, 300 }
+ int a, int b;
+ std::string c;
+ sol::tie( a, b, c ) = lua["f"](100, 200, "bark");
+ // a == 100
+ // b == 200
+ // c == "bark"
+
+
+multiple returns to lua
+-----------------------
+
+.. code-block:: cpp
+
+ sol::state lua;
+
+ lua["f"] = [](int a, int b, sol::object c) {
+ // sol::object can be anything here: just pass it through
+ return std::make_tuple( a, b, c );
+ };
+
+ std::tuple<int, int, int> result = lua["f"](100, 200, 300);
+ // result == { 100, 200, 300 }
+
+ std::tuple<int, int, std::string> result2;
+ result2 = lua["f"](100, 200, "BARK BARK BARK!")
+ // result2 == { 100, 200, "BARK BARK BARK!" }
+
+ int a, int b;
+ std::string c;
+ sol::tie( a, b, c ) = lua["f"](100, 200, "bark");
+ // a == 100
+ // b == 200
+ // c == "bark"
+
+
+C++ classes from C++
+--------------------
+
+Everything that is not a:
+
+ * primitive type: ``bool``, ``char/short/int/long/long long``, ``float/double``
+ * string type: ``std::string``, ``const char*``
+ * function type: function pointers, ``lua_CFunction``, ``std::function``, :doc:`sol::function/sol::protected_function<../api/function>`, :doc:`sol::coroutine<../api/coroutine>`, member variable, member function
+ * designated sol type: :doc:`sol::table<../api/table>`, :doc:`sol::thread<../api/thread>`, :doc:`sol::error<../api/error>`, :doc:`sol::object<../api/object>`
+ * transparent argument type: :doc:`sol::variadic_arg<../api/variadic_args>`, :doc:`sol::this_state<../api/this_state>`
+ * usertype<T> class: :doc:`sol::usertype<../api/usertype>`
+
+Is set as a :doc:`userdata + usertype<../api/usertype>`.
+
+.. code-block:: cpp
+
+ struct Doge {
+ int tailwag = 50;
+ }
+
+ Doge dog{};
+
+ // Copy into lua: destroyed by Lua VM during garbage collection
+ lua["dog"] = dog;
+ // OR: move semantics - will call move constructor if present instead
+ // Again, owned by Lua
+ lua["dog"] = std::move( dog );
+ lua["dog"] = Doge{};
+ lua["dog"] = std::make_unique<Doge>();
+ lua["dog"] = std::make_shared<Doge>();
+ // Identical to above
+
+ Doge dog2{};
+
+ lua.set("dog", dog2);
+ lua.set("dog", std::move(dog2));
+ lua.set("dog", Doge{});
+ lua.set("dog", std::unique_ptr<Doge>(new Doge()));
+ lua.set("dog", std::shared_ptr<Doge>(new Doge()));
+
+``std::unique_ptr``/``std::shared_ptr``'s reference counts / deleters will :doc:`be respected<../api/unique_usertype_traits>`. If you want it to refer to something, whose memory you know won't die in C++, do the following:
+
+.. code-block:: cpp
+
+ struct Doge {
+ int tailwag = 50;
+ }
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ Doge dog{}; // Kept alive somehow
+
+ // Later...
+ // The following stores a reference, and does not copy/move
+ // lifetime is same as dog in C++
+ // (access after it is destroyed is bad)
+ lua["dog"] = &dog;
+ // Same as above: respects std::reference_wrapper
+ lua["dog"] = std::ref(dog);
+ // These two are identical to above
+ lua.set( "dog", &dog );
+ lua.set( "dog", std::ref( dog ) );
+
+Get userdata in the same way as everything else:
+
+.. code-block:: cpp
+
+ struct Doge {
+ int tailwag = 50;
+ }
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ Doge& dog = lua["dog"]; // References Lua memory
+ Doge* dog_pointer = lua["dog"]; // References Lua memory
+ Doge dog_copy = lua["dog"]; // Copies, will not affect lua
+
+Note that you can change the data of usertype variables and it will affect things in lua if you get a pointer or a reference from Sol:
+
+.. code-block:: cpp
+
+ struct Doge {
+ int tailwag = 50;
+ }
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ Doge& dog = lua["dog"]; // References Lua memory
+ Doge* dog_pointer = lua["dog"]; // References Lua memory
+ Doge dog_copy = lua["dog"]; // Copies, will not affect lua
+
+ dog_copy.tailwag = 525;
+ // Still 50
+ lua.script("assert(dog.tailwag == 50)");
+
+ dog.tailwag = 100;
+ // Now 100
+ lua.script("assert(dog.tailwag == 100)");
+
+
+C++ classes put into Lua
+------------------------
+
+See this :doc:`section here<cxx-in-lua>` and after perhaps see if :doc:`simple usertypes suit your needs<../api/simple_usertype>`. Also check out some `a basic example`_, `special functions`_ and `initializers`_,
+
+
+.. _namespacing:
+
+namespacing
+-----------
+
+You can emulate namespacing by having a table and giving it the namespace names you want before registering enums or usertypes:
+
+.. code-block:: cpp
+
+ struct my_class {
+ int b = 24;
+
+ int f () const {
+ return 24;
+ }
+
+ void g () {
+ ++b;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries();
+
+ // set up table
+ sol::table bark = lua.create_named_table("bark");
+
+ bark.new_usertype<my_class>( "my_class",
+ "f", &my_class::f,
+ "g", &my_class::g
+ ); // the usual
+
+ // 'bark' namespace
+ lua.script("obj = bark.my_class.new()" );
+ lua.script("obj:g()");
+ my_class& obj = lua["obj"];
+ // obj.b == 25
+
+
+This technique can be used to register namespace-like functions and classes. It can be as deep as you want. Just make a table and name it appropriately, in either Lua script or using the equivalent Sol code. As long as the table FIRST exists (e.g., make it using a script or with one of Sol's methods or whatever you like), you can put anything you want specifically into that table using :doc:`sol::table's<../api/table>` abstractions.
+
+advanced
+--------
+
+Some more advanced things you can do/read about:
+ * :doc:`metatable manipulations<../api/metatable_key>` allow a user to change how indexing, function calls, and other things work on a single type.
+ * :doc:`ownership semantics<ownership>` are described for how lua deals with (raw) pointers.
+ * :doc:`stack manipulation<../api/stack>` to safely play with the stack. You can also define customization points for ``stack::get``/``stack::check``/``stack::push`` for your type.
+ * :doc:`make_reference/make_object convenience function<../api/make_reference>` to get the same benefits and conveniences as the low-level stack API but put into objects you can specify.
+ * :doc:`stack references<../api/stack_reference>` to have zero-overhead Sol abstractions while not copying to the Lua registry.
+ * :doc:`unique usertype traits<../api/unique_usertype_traits>` allows you to specialize handle/RAII types from other frameworks, like boost, and Unreal, to work with Sol.
+ * :doc:`variadic arguments<../api/variadic_args>` in functions with ``sol::variadic_args``.
+ * :doc:`this_state<../api/this_state>` to get the current ``lua_State*``.
+ * :doc:`resolve<../api/resolve>` overloads in case you have overloaded functions; a cleaner casting utility.
+
+.. _a basic example: https://github.com/ThePhD/sol2/blob/develop/examples/usertype.cpp
+.. _special functions: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_special_functions.cpp
+.. _initializers: https://github.com/ThePhD/sol2/blob/develop/examples/usertype_initializers.cpp
+
diff --git a/3rdparty/sol2/docs/source/tutorial/customization.rst b/3rdparty/sol2/docs/source/tutorial/customization.rst
new file mode 100644
index 00000000000..31fcad46568
--- /dev/null
+++ b/3rdparty/sol2/docs/source/tutorial/customization.rst
@@ -0,0 +1,114 @@
+adding your own types
+=====================
+
+Sometimes, overriding Sol to make it handle certain ``struct``'s and ``class``'es as something other than just userdata is desirable. The way to do this is to take advantage of the 4 customization points for Sol. These are ``sol::lua_size<T>``, ``sol::stack::pusher<T, C>``, ``sol::stack::getter<T, C>``, ``sol::stack::checker<T, sol::type t, C>``.
+
+These are template class/structs, so you'll override them using a technique C++ calls *class/struct specialization*. Below is an example of a struct that gets broken apart into 2 pieces when going in the C++ --> Lua direction, and then pulled back into a struct when going in the Lua --> C++:
+
+.. code-block:: cpp
+ :caption: two_things.hpp
+ :name: customization-overriding
+
+ #include <sol.hpp>
+
+ struct two_things {
+ int a;
+ bool b;
+ };
+
+ namespace sol {
+
+ // First, the expected size
+ // Specialization of a struct
+ // We expect 2, so use 2
+ template <>
+ struct lua_size<two_things> : std::integral_constant<int, 2> {};
+
+ // Now, specialize various stack structures
+ namespace stack {
+
+ template <>
+ struct checker<two_things> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ // indices can be negative to count backwards from the top of the stack,
+ // rather than the bottom up
+ // to deal with this, we adjust the index to
+ // its absolute position using the lua_absindex function
+ int absolute_index = lua_absindex(L, index);
+ // Check first and second second index for being the proper types
+ bool success = stack::check<int>(L, absolute_index - 1, handler)
+ && stack::check<bool>(L, absolute_index, handler);
+ tracking.use(2);
+ return success;
+ }
+ };
+
+ template <>
+ struct getter<two_things> {
+ static two_things get(lua_State* L, int index, record& tracking) {
+ int absolute_index = lua_absindex(L, index);
+ // Get the first element
+ int a = stack::get<int>(L, absolute_index - 1);
+ // Get the second element,
+ // in the +1 position from the first
+ bool b = stack::get<bool>(L, absolute_index);
+ // we use 2 slots, each of the previous takes 1
+ tracking.use(2);
+ return two_things{ a, b };
+ }
+ };
+
+ template <>
+ struct pusher<two_things> {
+ static int push(lua_State* L, const two_things& things) {
+ int amount = stack::push(L, things.a);
+ // amount will be 1: int pushes 1 item
+ amount += stack::push(L, things.b);
+ // amount 2 now, since bool pushes a single item
+ // Return 2 things
+ return amount;
+ }
+ };
+
+ }
+ }
+
+
+This is the base formula that you can follow to extend to your own classes. Using it in the rest of the library should then be seamless:
+
+.. code-block:: cpp
+ :caption: customization: using it
+ :name: customization-using
+
+ #include <sol.hpp>
+ #include <two_things.hpp>
+
+ int main () {
+
+ sol::state lua;
+
+ // Create a pass-through style of function
+ lua.script("function f ( a, b ) return a, b end");
+
+ // get the function out of Lua
+ sol::function f = lua["f"];
+
+ two_things things = f(two_things{24, true});
+ // things.a == 24
+ // things.b == true
+
+ return 0;
+ }
+
+
+And that's it!
+
+A few things of note about the implementation: First, there's an auxiliary parameter of type :doc:`sol::stack::record<../api/stack>` for the getters and checkers. This keeps track of what the last complete operation performed. Since we retrieved 2 members, we use ``tracking.use(2);`` to indicate that we used 2 stack positions (one for ``bool``, one for ``int``). The second thing to note here is that we made sure to use the ``index`` parameter, and then proceeded to add 1 to it for the next one.
+
+You can make something pushable into Lua, but not get-able in the same way if you only specialize one part of the system. If you need to retrieve it (as a return using one or multiple values from Lua), you should specialize the ``sol::stack::getter`` template class and the ``sol::stack::checker`` template class. If you need to push it into Lua at some point, then you'll want to specialize the ``sol::stack::pusher`` template class. The ``sol::lua_size`` template class trait needs to be specialized for both cases, unless it only pushes 1 item, in which case the default implementation will assume 1.
+
+
+In general, this is fine since most getters/checkers only use 1 stack point. But, if you're doing more complex nested classes, it would be useful to use ``tracking.last`` to understand how many stack indices the last getter/checker operation did and increment it by ``index + tracking.last`` after using a ``stack::check<..>( L, index, tracking)`` call.
+
+You can read more about the structs themselves :ref:`over on the API page for stack<extension_points>`, and if there's something that goes wrong or you have anymore questions, please feel free to drop a line on the Github Issues page or send an e-mail! \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/tutorial/cxx-in-lua.rst b/3rdparty/sol2/docs/source/tutorial/cxx-in-lua.rst
new file mode 100644
index 00000000000..dac47dfb228
--- /dev/null
+++ b/3rdparty/sol2/docs/source/tutorial/cxx-in-lua.rst
@@ -0,0 +1,138 @@
+C++ in Lua
+==========
+
+Using user defined types ("usertype"s, or just "udt"s) is simple with Sol. If you don't call any member variables or functions, then you don't even have to 'register' the usertype at all: just pass it through. But if you want variables and functions on your usertype inside of Lua, you need to register it. We're going to give a short example here that includes a bunch of information on how to work with things.
+
+Take this ``player`` struct in C++ in a header file:
+
+.. code-block:: cpp
+ :caption: test_player.hpp
+
+ struct player {
+ public:
+ int bullets;
+ int speed;
+
+ player()
+ : player(3, 100) {
+
+ }
+
+ player(int ammo)
+ : player(ammo, 100) {
+
+ }
+
+ player(int ammo, int hitpoints)
+ : bullets(ammo), hp(hitpoints) {
+
+ }
+
+ void boost () {
+ speed += 10;
+ }
+
+ bool shoot () {
+ if (bullets < 1)
+ return false;
+ --bullets;
+ return true;
+ }
+
+ void set_hp(int value) {
+ hp = value;
+ }
+
+ int get_hp() const {
+ return hp;
+ }
+
+ private:
+ int hp;
+ };
+
+
+It's a fairly minimal class, but we don't want to have to rewrite this with metatables in Lua. We want this to be part of Lua easily. The following is the Lua code that we'd like to have work properly:
+
+.. code-block:: lua
+ :caption: player_script.lua
+
+ -- call single argument integer constructor
+ p1 = player.new(2)
+
+ -- p2 is still here from being
+ -- set with lua["p2"] = player(0);
+ -- in cpp file
+ local p2shoots = p2:shoot()
+ assert(not p2shoots)
+ -- had 0 ammo
+
+ -- set variable property setter
+ p1.hp = 545;
+ -- get variable through property getter
+ print(p1.hp);
+
+ local did_shoot_1 = p1:shoot()
+ print(did_shoot_1)
+ print(p1.bullets)
+ local did_shoot_2 = p1:shoot()
+ print(did_shoot_2)
+ print(p1.bullets)
+ local did_shoot_3 = p1:shoot()
+ print(did_shoot_3)
+
+ -- can read
+ print(p1.bullets)
+ -- would error: is a readonly variable, cannot write
+ -- p1.bullets = 20
+
+ p1:boost()
+
+To do this, you bind things using the ``new_usertype`` and ``set_usertype`` methods as shown below. These methods are on both :doc:`table<../api/table>` and :doc:`state(_view)<../api/state>`, but we're going to just use it on ``state``:
+
+.. code-block:: cpp
+ :caption: player_script.cpp
+
+ #include <sol.hpp>
+
+ int main () {
+ sol::state lua;
+
+ // note that you can set a
+ // userdata before you register a usertype,
+ // and it will still carry
+ // the right metatable if you register it later
+
+ // set a variable "p2" of type "player" with 0 ammo
+ lua["p2"] = player(0);
+
+ // make usertype metatable
+ lua.new_usertype<player>( "player",
+
+ // 3 constructors
+ sol::constructors<sol::types<>, sol::types<int>, sol::types<int, int>>(),
+
+ // typical member function that returns a variable
+ "shoot", &player::shoot,
+ // typical member function
+ "boost", &player::boost,
+
+ // gets or set the value using member variable syntax
+ "hp", sol::property(&player::get_hp, &player::set_hp),
+
+ // read and write variable
+ "speed", &player::speed,
+ // can only read from, not write to
+ "bullets", sol::readonly( &player::bullets )
+ );
+
+ lua.script_file("player_script.lua");
+ }
+
+That script should run fine now, and you can observe and play around with the values. Even more stuff :doc:`you can do<../api/usertype>` is described elsewhere, like initializer functions (private constructors / destructors support), "static" functions callable with ``name.my_function( ... )``, and overloaded member functions. You can even bind global variables (even by reference with ``std::ref``) with ``sol::var``. There's a lot to try out!
+
+This is a powerful way to allow reuse of C++ code from Lua beyond just registering functions, and should get you on your way to having more complex classes and data structures! In the case that you need more customization than just usertypes, however, you can customize Sol to behave more fit to your desires by using the desired :doc:`customization and extension structures<customization>`.
+
+You can check out this code and more complicated code at the `examples directory`_ by looking at the ``usertype_``-prefixed examples.
+
+.. _examples directory: https://github.com/ThePhD/sol2/tree/develop/examples \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/tutorial/existing.rst b/3rdparty/sol2/docs/source/tutorial/existing.rst
new file mode 100644
index 00000000000..89a83f8078d
--- /dev/null
+++ b/3rdparty/sol2/docs/source/tutorial/existing.rst
@@ -0,0 +1,27 @@
+integrating into existing code
+==============================
+
+If you're already using lua and you just want to use ``sol`` in some places, you can use ``state_view``:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: using state_view
+ :name: state-view-snippet
+
+ void something_in_my_system (lua_State* L) {
+ // start using Sol with a pre-existing system
+ sol::state_view lua(L); // non-owning
+
+ lua.script("print('bark bark bark!')");
+
+ sol::table expected_table(L); // get the table off the top of the stack
+ // start using it...
+ }
+
+:doc:`sol::state_view<../api/state>` is exactly like ``sol::state``, but it doesn't manage the lifetime of a ``lua_State*``. Therefore, you get all the goodies that come with a ``sol::state`` without any of the ownership implications. Sol has no initialization components that need to deliberately remain alive for the duration of the program. It's entirely self-containing and uses lua's garbage collectors and various implementation techniques to require no state C++-side. After you do that, all of the power of `Sol` is available to you, and then some!
+
+You may also want to call ``require`` and supply a string of a script file or something that returns an object that you set equal to something in C++. For that, you can use the :ref:`require functionality<state-require-function>`.
+
+Remember that Sol can be as lightweight as you want it: almost all of Sol's types take the ``lua_State*`` argument and then a second ``int index`` stack index argument, meaning you can use :doc:`tables<../api/table>`, :doc:`lua functions<../api/function>`, :doc:`coroutines<../api/coroutine>`, and other reference-derived objects that expose the proper constructor for your use. You can also set :doc:`usertypes<../api/usertype>` and other things you need without changing your entire architecture.
+
+Note that you can also make non-standard pointer and reference types with custom reference counting and such also play nice with the system. See :doc:`unique_usertype_traits\<T><../api/unique_usertype_traits>` to see how! Custom types is also mentioned in the :doc:`customization tutorial<customization>`. \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/tutorial/functions.rst b/3rdparty/sol2/docs/source/tutorial/functions.rst
new file mode 100644
index 00000000000..2b2f0e3ba61
--- /dev/null
+++ b/3rdparty/sol2/docs/source/tutorial/functions.rst
@@ -0,0 +1,341 @@
+functions and You
+=================
+
+Sol can register all kinds of functions. Many are shown in the :doc:`quick 'n' dirty<all-the-things>`, but here we will discuss many of the additional ways you can register functions into a sol-wrapped Lua system.
+
+Setting a new function
+----------------------
+
+Given a C++ function, you can drop it into Sol in several equivalent ways, working similar to how :ref:`setting variables<writing-main-cpp>` works:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Registering C++ functions
+ :name: writing-functions
+
+ #include <sol.hpp>
+
+ std::string my_function( int a, std::string b ) {
+ // Create a string with the letter 'D' "a" times,
+ // append it to 'b'
+ return b + std::string( 'D', a );
+ }
+
+ int main () {
+
+ sol::state lua;
+
+ lua["my_func"] = my_function; // way 1
+ lua.set("my_func", my_function); // way 2
+ lua.set_function("my_func", my_function); // way 3
+
+ // This function is now accessible as 'my_func' in
+ // lua scripts / code run on this state:
+ lua.script("some_str = my_func(1, "Da");
+
+ // Read out the global variable we stored in 'some_str' in the
+ // quick lua code we just executed
+ std::string some_str = lua["some_str"];
+ // some_str == "DaD"
+ }
+
+The same code works with all sorts of functions, from member function/variable pointers you have on a class as well as lambdas:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Registering C++ member functions
+ :name: writing-member-functions
+
+ struct my_class {
+ int a = 0;
+
+ my_class(int x) : a(x) {
+
+ }
+
+ int func() {
+ ++a; // increment a by 1
+ return a;
+ }
+ };
+
+ int main () {
+
+ sol::state lua;
+
+ // Here, we are binding the member function and a class instance: it will call the function on
+ // the given class instance
+ lua.set_function("my_class_func", &my_class::func, my_class());
+
+ // We do not pass a class instance here:
+ // the function will need you to pass an instance of "my_class" to it
+ // in lua to work, as shown below
+ lua.set_function("my_class_func_2", &my_class::func);
+
+ // With a pre-bound instance:
+ lua.script(R"(
+ first_value = my_class_func()
+ second_value = my_class_func()
+ )");
+ // first_value == 1
+ // second_value == 2
+
+ // With no bound instance:
+ lua.set("obj", my_class(24));
+ // Calls "func" on the class instance
+ // referenced by "obj" in Lua
+ lua.script(R"(
+ third_value = my_class_func_2(obj)
+ fourth_value = my_class_func_2(obj)
+ )");
+ // first_value == 25
+ // second_value == 26
+ }
+
+Member class functions and member class variables will both be turned into functions when set in this manner. You can get intuitive variable with the ``obj.a = value`` access after this section when you learn about :doc:`usertypes to have C++ in Lua<cxx-in-lua>`, but for now we're just dealing with functions!
+
+
+Another question a lot of people have is about function templates. Function templates -- member functions or free functions -- cannot be registered because they do not exist until you instantiate them in C++. Therefore, given a templated function such as:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: A C++ templated function
+ :name: writing-templated-functions-the-func
+
+ template <typename A, typename B>
+ auto my_add( A a, B b ) {
+ return a + b;
+ }
+
+
+You must specify all the template arguments in order to bind and use it, like so:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Registering function template instantiations
+ :name: writing-templated-functions
+
+
+ int main () {
+
+ sol::state lua;
+
+ // adds 2 integers
+ lua["my_int_add"] = my_add<int, int>;
+
+ // concatenates 2 strings
+ lua["my_string_combine"] = my_add<std::string, std::string>;
+
+ lua.script("my_num = my_int_add(1, 2)");
+ int my_num = lua["my_num"];
+ // my_num == 3
+
+ lua.script("my_str = my_string_combine('bark bark', ' woof woof')");
+ std::string my_str = lua["my_str"];
+ // my_str == "bark bark woof woof"
+ }
+
+Notice here that we bind two separate functions. What if we wanted to bind only one function, but have it behave differently based on what arguments it is called with? This is called Overloading, and it can be done with :doc:`sol::overload<../api/overload>` like so:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Registering C++ function template instantiations
+ :name: writing-templated-functions-overloaded
+
+
+ int main () {
+
+ sol::state lua;
+
+ // adds 2 integers
+ lua["my_combine"] = sol::overload( my_add<int, int>, my_add<std::string, std::string> );
+
+ lua.script("my_num = my_combine(1, 2)");
+ lua.script("my_str = my_combine('bark bark', ' woof woof')");
+ int my_num = lua["my_num"];
+ std::string my_str = lua["my_str"];
+ // my_num == 3
+ // my_str == "bark bark woof woof"
+ }
+
+This is useful for functions which can take multiple types and need to behave differently based on those types. You can set as many overloads as you want, and they can be of many different types.
+
+.. note::
+
+ Function object ``obj`` -- a struct with a ``return_type operator()( ... )`` member defined on them, like all C++ lambdas -- are not interpreted as functions when you use ``set`` for ``mytable.set( key, value )``. This only happens automagically with ``mytable[key] = obj``. To be explicit about wanting a struct to be interpreted as a function, use ``mytable.set_function( key, func_value );``. You can be explicit about wanting a function as well by using the :doc:`sol::as_function<../api/as_function>` call.
+
+
+Getting a function from Lua
+---------------------------
+
+There are 2 ways to get a function from Lua. One is with :doc:`sol::function<../api/function>` and the other is a more advanced wrapper with :doc:`sol::protected_function<../api/protected_function>`. Use them to retrieve callables from Lua and call the underlying function, in two ways:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Retrieving a sol::function
+ :name: reading-functions
+
+ int main () {
+
+ sol::state lua;
+
+ lua.script(R"(
+ function f (a)
+ return a + 5
+ end
+ )");
+
+ // Get and immediately call
+ int x = lua["f"](30);
+ // x == 35
+
+ // Store it into a variable first, then call
+ sol::function f = lua["f"];
+ int y = f(20);
+ // y == 25
+ }
+
+You can get anything that's a callable in Lua, including C++ functions you bind using ``set_function`` or similar. ``sol::protected_function`` behaves similarly to ``sol::function``, but has a :ref:`error_handler<protected-function-error-handler>` variable you can set to a Lua function. This catches all errors and runs them through the error-handling function:
+
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Retrieving a sol::protected_function
+ :name: reading-protected-functions
+
+ int main () {
+ sol::state lua;
+
+ lua.script(R"(
+ function handler (message)
+ return "Handled this message: " .. message
+ end
+
+ function f (a)
+ if a < 0 then
+ error("negative number detected")
+ end
+ return a + 5
+ end
+ )");
+
+ sol::protected_function f = lua["f"];
+ f.error_handler = lua["handler"];
+
+ sol::protected_function_result result = f(-500);
+ if (result.valid()) {
+ // Call succeeded
+ int x = result;
+ }
+ else {
+ // Call failed
+ sol::error err = result;
+ std::string what = err.what();
+ // 'what' Should read
+ // "Handled this message: negative number detected"
+ }
+ }
+
+
+Multiple returns to and from Lua
+--------------------------------
+
+You can return multiple items to and from Lua using ``std::tuple``/``std::pair`` classes provided by C++. These enable you to also use :doc:`sol::tie<../api/tie>` to set return values into pre-declared items. To recieve multiple returns, just ask for a ``std::tuple`` type from the result of a function's computation, or ``sol::tie`` a bunch of pre-declared variables together and set the result equal to that:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Multiple returns from Lua
+ :name: multi-return-lua-functions
+
+ int main () {
+ sol::state lua;
+
+ lua.script("function f (a, b, c) return a, b, c end");
+
+ std::tuple<int, int, int> result;
+ result = lua["f"](1, 2, 3);
+ // result == { 1, 2, 3 }
+ int a, int b;
+ std::string c;
+ sol::tie( a, b, c ) = lua["f"](1, 2, "bark");
+ // a == 1
+ // b == 2
+ // c == "bark"
+ }
+
+You can also return mutiple items yourself from a C++-bound function. Here, we're going to bind a C++ lambda into Lua, and then call it through Lua and get a ``std::tuple`` out on the other side:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Multiple returns into Lua
+ :name: multi-return-cxx-functions
+
+ int main () {
+ sol::state lua;
+
+ lua["f"] = [](int a, int b, sol::object c) {
+ // sol::object can be anything here: just pass it through
+ return std::make_tuple( a, b, c );
+ };
+
+ std::tuple<int, int, int> result = lua["f"](1, 2, 3);
+ // result == { 1, 2, 3 }
+
+ std::tuple<int, int, std::string> result2;
+ result2 = lua["f"](1, 2, "Arf?")
+ // result2 == { 1, 2, "Arf?" }
+
+ int a, int b;
+ std::string c;
+ sol::tie( a, b, c ) = lua["f"](1, 2, "meow");
+ // a == 1
+ // b == 2
+ // c == "meow"
+ }
+
+
+Note here that we use :doc:`sol::object<../api/object>` to transport through "any value" that can come from Lua. You can also use ``sol::make_object`` to create an object from some value, so that it can be returned into Lua as well.
+
+
+Any return to and from Lua
+--------------------------
+
+It was hinted at in the previous code example, but ``sol::object`` is a good way to pass "any type" back into Lua (while we all wait for ``std::variant<...>`` to get implemented and shipped by C++ compiler/library implementers).
+
+It can be used like so, inconjunction with ``sol::this_state``:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: Return anything into Lua
+ :name: object-return-cxx-functions
+
+ sol::object fancy_func (sol::object a, sol::object b, sol::this_state s) {
+ sol::state_view lua(s);
+ if (a.is<int>() && b.is<int>()) {
+ return sol::make_object(lua, a.as<int>() + b.as<int>());
+ }
+ else if (a.is<bool>()) {
+ bool do_triple = a.as<bool>();
+ return sol::make_object(lua, b.as<double>() * ( do_triple ? 3 : 1 ) );
+ }
+ return sol::make_object(lua, sol::nil);
+ }
+
+ int main () {
+ sol::state lua;
+
+ lua["f"] = fancy_func;
+
+ int result = lua["f"](1, 2);
+ // result == 3
+ double result2 = lua["f"](false, 2.5);
+ // result2 == 2.5
+
+ // call in Lua, get result
+ lua.script("result3 = f(true, 5.5)");
+ double result3 = lua["result3"];
+ // result3 == 16.5
+ }
+
+
+This covers almost everything you need to know about Functions and how they interact with Sol. For some advanced tricks and neat things, check out :doc:`sol::this_state<../api/this_state>` and :doc:`sol::variadic_args<../api/variadic_args>`. The next stop in this tutorial is about :doc:`C++ types (usertypes) in Lua<cxx-in-lua>`! \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/tutorial/getting-started.rst b/3rdparty/sol2/docs/source/tutorial/getting-started.rst
new file mode 100644
index 00000000000..fd83e4fcb93
--- /dev/null
+++ b/3rdparty/sol2/docs/source/tutorial/getting-started.rst
@@ -0,0 +1,84 @@
+getting started
+===============
+
+Let's get you going with Sol! To start, you'll need to use a lua distribution of some sort. Sol doesn't provide that: it only wraps the API that comes with it, so you can pick whatever distribution you like for your application. There are lots, but the two popular ones are `vanilla Lua`_ and speedy `LuaJIT`_ . We recommend vanilla Lua if you're getting started, LuaJIT if you need speed and can handle some caveats: the interface for Sol doesn't change no matter what Lua version you're using.
+
+If you need help getting or building Lua, check out the `Lua page on getting started`_. Note that for Visual Studio, one can simply download the sources, include all the Lua library files in that project, and then build for debug/release, x86/x64/ARM rather easily and with minimal interference. Just make sure to adjust the Project Property page to build as a static library (or a DLL with the proper define set in the ``Preprocessor`` step).
+
+After that, make sure you grab either the `single header file release`_, or just perform a clone of the `github repository here`_ and set your include paths up so that you can get at ``sol.hpp`` somehow. Note that we also have the latest version of the single header file with all dependencies included kept in the `repository as well`_. We recommend the single-header-file release, since it's easier to move around, manage and update if you commit it with some form of version control. If you use the github clone method and do not point to the `single/sol/sol.hpp`_ on your include files, you *must* update submodules in order to make sure Optional is present in the repository. Clone with:
+
+>>> git clone https://github.com/ThePhD/sol2.git
+>>> git submodule update --init
+
+or, just run
+
+>>> git clone --recursive https://github.com/ThePhD/sol2.git
+
+When you're ready, try compiling this short snippet:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: test.cpp: the first snippet
+ :name: the-first-snippet
+
+ #include <sol.hpp> // or #include "sol.hpp", whichever suits your needs
+
+ int main (int argc, char* argv[]) {
+
+ sol::state lua;
+ lua.open_libraries( sol::lib::base );
+
+ lua.script( "print('bark bark bark!')" );
+
+ return 0;
+ }
+
+Using this simple command line:
+
+>>> g++ -std=c++14 test.cpp -I"path/to/lua/include" -L"path/to/lua/lib" -llua
+
+Or using your favorite IDE / tool after setting up your include paths and library paths to Lua according to the documentation of the Lua distribution you got. Remember your linked lua library (``-llua``) and include / library paths will depend on your OS, file system, Lua distribution and your installation / compilation method of your Lua distribution.
+
+.. note::
+
+ If you get an avalanche of errors (particularly referring to ``auto``), you may not have enabled C++14 / C++17 mode for your compiler. Add one of ``std=c++14``, ``std=c++1z`` OR ``std=c++1y`` to your compiler options. By default, this is always-on for VC++ compilers in Visual Studio and friends, but g++ and clang++ require a flag (unless you're on `GCC 6.0`_).
+
+If this works, you're ready to start! The first line creates the ``lua_State`` and will hold onto it for the duration of the scope its declared in (e.g., from the opening ``{`` to the closing ``}``). It will automatically close / cleanup that lua state when it gets destructed. The second line opens a single lua-provided library, "base". There are several other libraries that come with lua that you can open by default, and those are included in the :ref:`sol::lib<lib-enum>` enumeration. You can open multiple base libraries by specifying multiple ``sol::lib`` arguments:
+
+.. code-block:: cpp
+ :linenos:
+ :caption: test.cpp: the first snippet
+ :name: the-second-snippet
+
+ #include <sol.hpp>
+
+ int main (int argc, char* argv[]) {
+
+ sol::state lua;
+ lua.open_libraries( sol::lib::base, sol::lib::coroutine, sol::lib::string, sol::lib::io );
+
+ lua.script( "print('bark bark bark!')" );
+
+ return 0;
+ }
+
+If you're interested in integrating Sol with a project that already uses some other library or Lua in the codebase, check out the :doc:`existing example<existing>` to see how to work with Sol when you add it to a project (the existing example covers ``require`` as well)!
+
+Next, let's start :doc:`reading/writing some variables<variables>` from Lua into C++, and vice-versa!
+
+
+.. _vanilla Lua: https://www.lua.org/
+
+.. _LuaJIT: http://luajit.org/
+
+.. _GCC 6.0: https://gcc.gnu.org/gcc-6/changes.html
+
+.. _single header file release: https://github.com/ThePhD/sol2/releases
+
+.. _repository as well: https://github.com/ThePhD/sol2/blob/develop/single/sol/sol.hpp
+
+.. _single/sol/sol.hpp: https://github.com/ThePhD/sol2/blob/develop/single/sol/sol.hpp
+
+.. _github repository here: https://github.com/ThePhD/sol2
+
+.. _Lua page on getting started: https://www.lua.org/start.html \ No newline at end of file
diff --git a/3rdparty/sol2/docs/source/tutorial/ownership.rst b/3rdparty/sol2/docs/source/tutorial/ownership.rst
new file mode 100644
index 00000000000..96eb350da78
--- /dev/null
+++ b/3rdparty/sol2/docs/source/tutorial/ownership.rst
@@ -0,0 +1,94 @@
+ownership
+=========
+
+Sol will not take ownership of raw pointers: raw pointers do not own anything.
+
+.. code-block:: cpp
+
+ struct my_type {
+ void stuff () {}
+ };
+
+ sol::state lua;
+
+ // AAAHHH BAD
+ // dangling pointer!
+ lua["my_func"] = []() -> my_type* {
+ return new my_type();
+ };
+
+ // AAAHHH!
+ lua.set("something", new my_type());
+
+ // AAAAAAHHH!!!
+ lua["something_else"] = new my_type();
+
+Use/return a ``unique_ptr`` or ``shared_ptr`` instead or just return a value:
+
+.. code-block:: cpp
+
+ // :ok:
+ lua["my_func"] = []() -> std::unique_ptr<my_type> {
+ return std::make_unique<my_type>();
+ };
+
+ // :ok:
+ lua["my_func"] = []() -> std::shared_ptr<my_type> {
+ return std::make_shared<my_type>();
+ };
+
+ // :ok:
+ lua["my_func"] = []() -> my_type {
+ return my_type();
+ };
+
+ // :ok:
+ lua.set("something", std::unique_ptr<my_type>(new my_type()));
+
+ std::shared_ptr<my_type> my_shared = std::make_shared<my_type>();
+ // :ok:
+ lua.set("something_else", my_shared);
+
+ auto my_unique = std::make_unique<my_type>();
+ lua["other_thing"] = std::move(my_unique);
+
+If you have something you know is going to last and you just want to give it to Lua as a reference, then it's fine too:
+
+.. code-block:: cpp
+
+ // :ok:
+ lua["my_func"] = []() -> my_type* {
+ static my_type mt;
+ return &mt;
+ };
+
+
+Sol can detect ``nullptr``, so if you happen to return it there won't be any dangling because a ``sol::nil`` will be pushed.
+
+.. code-block:: cpp
+
+ struct my_type {
+ void stuff () {}
+ };
+
+ sol::state lua;
+
+ // BUT THIS IS STILL BAD DON'T DO IT AAAHHH BAD
+ // return a unique_ptr still or something!
+ lua["my_func"] = []() -> my_type* {
+ return nullptr;
+ };
+
+ lua["my_func_2"] = [] () -> std::unique_ptr<my_type> {
+ // default-constructs as a nullptr,
+ // gets pushed as nil to Lua
+ return std::unique_ptr<my_type>();
+ // same happens for std::shared_ptr
+ }
+
+ // Acceptable, it will set 'something' to nil
+ // (and delete it on next GC if there's no more references)
+ lua.set("something", nullptr);
+
+ // Also fine
+ lua["something_else"] = nullptr;
diff --git a/3rdparty/sol2/docs/source/tutorial/tutorial-top.rst b/3rdparty/sol2/docs/source/tutorial/tutorial-top.rst
new file mode 100644
index 00000000000..730423fdb5a
--- /dev/null
+++ b/3rdparty/sol2/docs/source/tutorial/tutorial-top.rst
@@ -0,0 +1,21 @@
+tutorial
+========
+
+Take some time to learn the framework with thse tutorials. But, if you need to get going FAST, try using the :doc:`quick 'n' dirty<all-the-things>` approach and your browser's / editors search function. It will also serve you well to look at all the `examples`_, which have recently gotten a bit of an overhaul to contain more relevant working examples.
+
+
+.. toctree::
+ :caption: Sol Tutorial
+ :name: tutorialtoc
+ :maxdepth: 2
+
+ all-the-things
+ getting-started
+ existing
+ variables
+ functions
+ cxx-in-lua
+ ownership
+ customization
+
+.. _examples: https://github.com/ThePhD/sol2/tree/develop/examples
diff --git a/3rdparty/sol2/docs/source/tutorial/variables.rst b/3rdparty/sol2/docs/source/tutorial/variables.rst
new file mode 100644
index 00000000000..20105bf8003
--- /dev/null
+++ b/3rdparty/sol2/docs/source/tutorial/variables.rst
@@ -0,0 +1,202 @@
+variables
+=========
+
+Working with variables is easy with Sol, and behaves pretty much like any associative array / map structure you've dealt with previously. Given this lua file that gets loaded into Sol:
+
+reading
+-------
+
+.. code-block:: lua
+ :caption: variables.lua
+
+ config = {
+ fullscreen = false,
+ resolution = { x = 1024, y = 768 }
+ }
+
+.. code-block:: cpp
+ :caption: main.cpp
+ :name: variables-main-cpp
+
+ #include <sol.hpp>
+
+ int main () {
+
+ sol::state lua;
+ lua.script_file( variables.lua );
+
+ return 0;
+ }
+
+You can interact with the variables like this:
+
+.. code-block:: cpp
+ :caption: main.cpp extended
+ :name: extended-variables-main-cpp
+
+ #include <sol.hpp>
+ #include <tuple>
+ #include <utility> // for std::pair
+
+ int main () {
+
+ sol::state lua;
+ lua.script_file( variables.lua );
+
+ // the type "state" behaves exactly like a table!
+ bool isfullscreen = lua["config"]["fullscreen"]; // can get nested variables
+ sol::table config = lua["config"];
+
+ // can also get it using the "get" member function
+ // auto replaces the unqualified type name
+ auto resolution = config.get<sol::table>( "config" );
+
+ // table and state can have multiple things pulled out of it too
+ std::pair<int, int> xyresolution = resolution.get<int, int>( "x", "y" );
+ // As an example, you can also pull out a tuple as well
+ std::tuple<int, int> xyresolutiontuple = resolution.get<int, int>( "x", "y" );
+
+
+ return 0;
+ }
+
+From this example, you can see that there's many ways to pull out the varaibles you want. You can get For example, to determine if a nested variable exists or not, you can use ``auto`` to capture the value of a ``table[key]`` lookup, and then use the ``.valid()`` method:
+
+.. code-block:: cpp
+ :caption: safe lookup
+
+ auto bark = lua["config"]["bark"];
+ if (bark.valid()) {
+ // branch not taken: config / bark is not a variable
+ }
+ else {
+ // Branch taken: config is a not a variable
+ }
+
+This comes in handy when you want to check if a nested variable exists. You can also check if a toplevel variable is present or not by using ``sol::optional``, which also checks if A) the keys you're going into exist and B) the type you're trying to get is of a specific type:
+
+.. code-block:: cpp
+ :caption: optional lookup
+
+ sol::optional<int> not_an_integer = lua["config"]["fullscreen"];
+ if (not_an_integer) {
+ // Branch not taken: value is not an integer
+ }
+
+ sol::optoinal<bool> is_a_boolean = lua["config"]["fullscreen"];
+ if (is_a_boolean) {
+ // Branch taken: the value is a boolean
+ }
+
+ sol::optional<double> does_not_exist = lua["not_a_variable"];
+ if (does_not_exist) {
+ // Branch not taken: that variable is not present
+ }
+
+This can come in handy when, even in optimized or release modes, you still want the safety of checking. You can also use the `get_or` methods to, if a certain value may be present but you just want to default the value to something else:
+
+.. code-block:: cpp
+ :caption: get_or lookup
+
+ // this will result in a value of '24'
+ int is_defaulted = lua["config"]["fullscreen"].get_or( 24 );
+
+ // This will result in the value of the config, which is 'false'
+ bool is_not_defaulted = lua["config"]["fullscreen"];
+
+That's all it takes to read variables!
+
+
+writing
+-------
+
+Writing gets a lot simpler. Even without scripting a file or a string, you can read and write variables into lua as you please:
+
+.. code-block:: cpp
+ :caption: main.cpp
+ :name: writing-main-cpp
+
+ #include <sol.hpp>
+ #include <iostream>
+
+ int main () {
+
+ sol::state lua;
+
+ // open those basic lua libraries again, like print() etc.
+ lua.open_libraries( sol::lib::base );
+
+ // value in the global table
+ lua["bark"] = 50;
+
+ // a table being created in the global table
+ lua["some_table"] = lua.create_table_with(
+ "key0", 24,
+ "key1", 25,
+ lua["bark"], "the key is 50 and this string is its value!"
+ );
+
+ // Run a plain ol' string of lua code
+ // Note you can interact with things set through Sol in C++ with lua!
+ // Using a "Raw String Literal" to have multi-line goodness: http://en.cppreference.com/w/cpp/language/string_literal
+ lua.script(R"(
+
+ print(some_table[50])
+ print(some_table["key0"])
+ print(some_table["key1"])
+
+ -- a lua comment: access a global in a lua script with the _G table
+ print(_G["bark"])
+
+ )");
+
+ return 0;
+ }
+
+This example pretty much sums up what can be done. Note that the syntax ``lua["non_existing_key_1"] = 1`` will make that variable, but if you tunnel too deep without first creating a table, the Lua API will panic (e.g., ``lua["does_not_exist"]["b"] = 20`` will trigger a panic). You can also be lazy with reading / writing values:
+
+.. code-block:: cpp
+ :caption: main.cpp
+ :name: lazy-main-cpp
+
+ #include <sol.hpp>
+ #include <iostream>
+
+ int main () {
+
+ sol::state lua;
+
+ auto barkkey = lua["bark"];
+ if (barkkey.valid()) {
+ // Branch not taken: doesn't exist yet
+ std::cout << "How did you get in here, arf?!" << std::endl;
+ }
+
+ barkkey = 50;
+ if (barkkey.valid()) {
+ // Branch taken: value exists!
+ std::cout << "Bark Bjork Wan Wan Wan" << std::endl;
+ }
+ }
+
+Finally, it's possible to erase a reference/variable by setting it to ``nil``, using the constant ``sol::nil`` in C++:
+
+.. code-block:: cpp
+ :caption: main.cpp
+ :name: erase-main-cpp
+
+ #include <sol.hpp>
+
+ int main () {
+
+ sol::state lua;
+ lua["bark"] = 50;
+ sol::optional<int> x = lua["bark"];
+ // x will have a value
+
+ lua["bark"] = sol::nil;
+ sol::optional<int> y = lua["bark"];
+ // y will not have a value
+ }
+
+It's easy to see that there's a lot of options to do what you want here. But, these are just traditional numbers and strings. What if we want more power, more capabilities than what these limited types can offer us? Let's throw some :doc:`functions in there<functions>` :doc:`C++ classes into the mix<cxx-in-lua>`! \ No newline at end of file
diff --git a/3rdparty/sol2/examples/any_return.cpp b/3rdparty/sol2/examples/any_return.cpp
new file mode 100644
index 00000000000..f286071b8d8
--- /dev/null
+++ b/3rdparty/sol2/examples/any_return.cpp
@@ -0,0 +1,46 @@
+#include <sol.hpp>
+
+#include <iostream>
+#include <cassert>
+
+// Uses some of the fancier bits of sol2, including the "transparent argument",
+// sol::this_state, which gets the current state and does not increment
+// function arguments
+sol::object fancy_func(sol::object a, sol::object b, sol::this_state s) {
+ sol::state_view lua(s);
+ if (a.is<int>() && b.is<int>()) {
+ return sol::object(lua, sol::in_place, a.as<int>() + b.as<int>());
+ }
+ else if (a.is<bool>()) {
+ bool do_triple = a.as<bool>();
+ return sol::object(lua, sol::in_place<double>, b.as<double>() * (do_triple ? 3 : 1));
+ }
+ // Can also use make_object
+ return sol::make_object(lua, sol::nil);
+}
+
+int main() {
+ sol::state lua;
+
+ lua["f"] = fancy_func;
+
+ int result = lua["f"](1, 2);
+ // result == 3
+ assert(result == 3);
+ double result2 = lua["f"](false, 2.5);
+ // result2 == 2.5
+ assert(result2 == 2.5);
+
+ // call in Lua, get result
+ // notice we only need 2 arguments here, not 3 (sol::this_state is transparent)
+ lua.script("result3 = f(true, 5.5)");
+ double result3 = lua["result3"];
+ // result3 == 16.5
+ assert(result3 == 16.5);
+
+ std::cout << "=== any_return example ===" << std::endl;
+ std::cout << "result : " << result << std::endl;
+ std::cout << "result2: " << result2 << std::endl;
+ std::cout << "result3: " << result3 << std::endl;
+ std::cout << std::endl;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/examples/basic.cpp b/3rdparty/sol2/examples/basic.cpp
new file mode 100644
index 00000000000..cf00ee70ab2
--- /dev/null
+++ b/3rdparty/sol2/examples/basic.cpp
@@ -0,0 +1,19 @@
+#include <sol.hpp>
+
+#include <iostream>
+
+int main() {
+ // create an empty lua state
+ sol::state lua;
+
+ // by default, libraries are not opened
+ // you can open libraries by using open_libraries
+ // the libraries reside in the sol::lib enum class
+ lua.open_libraries(sol::lib::base);
+
+ // call lua code directly
+ std::cout << "=== basic example ===" << std::endl;
+ lua.script("print('hello world')");
+
+ std::cout << std::endl;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/examples/config.cpp b/3rdparty/sol2/examples/config.cpp
new file mode 100644
index 00000000000..d899de385ca
--- /dev/null
+++ b/3rdparty/sol2/examples/config.cpp
@@ -0,0 +1,39 @@
+#include <sol.hpp>
+#include <string>
+#include <iostream>
+
+// shows how to load basic data to a struct
+
+struct config {
+ std::string name;
+ int width;
+ int height;
+
+ void print() {
+ std::cout << "Name: " << name << '\n'
+ << "Width: " << width << '\n'
+ << "Height: " << height << '\n';
+ }
+};
+
+int main() {
+ sol::state lua;
+ config screen;
+ // To use the file, uncomment here and make sure it is in local dir
+ //lua.script_file("config.lua");
+ lua.script(R"(
+name = "Asus"
+width = 1920
+height = 1080
+)");
+ screen.name = lua.get<std::string>("name");
+ screen.width = lua.get<int>("width");
+ screen.height = lua.get<int>("height");
+ assert(screen.name == "Asus");
+ assert(screen.width == 1920);
+ assert(screen.height == 1080);
+
+ std::cout << "=== config example ===" << std::endl;
+ screen.print();
+ std::cout << std::endl;
+}
diff --git a/3rdparty/sol2/examples/config.lua b/3rdparty/sol2/examples/config.lua
new file mode 100644
index 00000000000..0144f989a84
--- /dev/null
+++ b/3rdparty/sol2/examples/config.lua
@@ -0,0 +1,3 @@
+name = "Asus"
+width = 1920
+height = 1080
diff --git a/3rdparty/sol2/examples/customization.cpp b/3rdparty/sol2/examples/customization.cpp
new file mode 100644
index 00000000000..45280e5989b
--- /dev/null
+++ b/3rdparty/sol2/examples/customization.cpp
@@ -0,0 +1,91 @@
+#include <sol.hpp>
+
+#include <iostream>
+#include <iomanip>
+#include <cassert>
+
+struct two_things {
+ int a;
+ bool b;
+};
+
+namespace sol {
+
+ // First, the expected size
+ // Specialization of a struct
+ template <>
+ struct lua_size<two_things> : std::integral_constant<int, 2> {};
+
+ // Now, specialize various stack structures
+ namespace stack {
+
+ template <>
+ struct checker<two_things> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ // indices can be negative to count backwards from the top of the stack,
+ // rather than the bottom up
+ // to deal with this, we adjust the index to
+ // its absolute position using the lua_absindex function
+ int absolute_index = lua_absindex(L, index);
+ // Check first and second second index for being the proper types
+ bool success = stack::check<int>(L, absolute_index + 1, handler)
+ && stack::check<bool>(L, absolute_index, handler);
+ tracking.use(2);
+ return success;
+ }
+ };
+
+ template <>
+ struct getter<two_things> {
+ static two_things get(lua_State* L, int index, record& tracking) {
+ int absolute_index = lua_absindex(L, index);
+ // Get the first element
+ int a = stack::get<int>(L, absolute_index);
+ // Get the second element,
+ // in the +1 position from the first
+ bool b = stack::get<bool>(L, absolute_index + 1);
+ // we use 2 slots, each of the previous takes 1
+ tracking.use(2);
+ return two_things{ a, b };
+ }
+ };
+
+ template <>
+ struct pusher<two_things> {
+ static int push(lua_State* L, const two_things& things) {
+ int amount = stack::push(L, things.a);
+ // amount will be 1: int pushes 1 item
+ amount += stack::push(L, things.b);
+ // amount 2 now, since bool pushes a single item
+ // Return 2 things
+ return amount;
+ }
+ };
+
+ }
+}
+
+int main() {
+ sol::state lua;
+
+ // Create a pass-through style of function
+ lua.script("function f ( a, b ) return a, b end");
+
+ // get the function out of Lua
+ sol::function f = lua["f"];
+
+ two_things things = f(two_things{ 24, true });
+ assert(things.a == 24);
+ assert(things.b == true);
+ // things.a == 24
+ // things.b == true
+
+ std::cout << "=== customization example ===" << std::endl;
+ std::cout << std::boolalpha;
+ std::cout << "things.a: " << things.a << std::endl;
+ std::cout << "things.b: " << things.b << std::endl;
+ std::cout << std::endl;
+
+ return 0;
+}
diff --git a/3rdparty/sol2/examples/functions.cpp b/3rdparty/sol2/examples/functions.cpp
new file mode 100644
index 00000000000..b4f9a1da140
--- /dev/null
+++ b/3rdparty/sol2/examples/functions.cpp
@@ -0,0 +1,110 @@
+#include <sol.hpp>
+#include <cassert>
+#include <iostream>
+
+inline int my_add(int x, int y) {
+ return x + y;
+}
+
+struct multiplier {
+ int operator()(int x) {
+ return x * 10;
+ }
+
+ static int by_five(int x) {
+ return x * 5;
+ }
+};
+
+inline std::string make_string( std::string input ) {
+ return "string: " + input;
+}
+
+int main() {
+ std::cout << "=== functions example ===" << std::endl;
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ // setting a function is simple
+ lua.set_function("my_add", my_add);
+
+ // you could even use a lambda
+ lua.set_function("my_mul", [](double x, double y) { return x * y; });
+
+ // member function pointers and functors as well
+ lua.set_function("mult_by_ten", multiplier{});
+ lua.set_function("mult_by_five", &multiplier::by_five);
+
+ // assert that the functions work
+ lua.script("assert(my_add(10, 11) == 21)");
+ lua.script("assert(my_mul(4.5, 10) == 45)");
+ lua.script("assert(mult_by_ten(50) == 500)");
+ lua.script("assert(mult_by_five(10) == 50)");
+
+ // using lambdas, functions can have state.
+ int x = 0;
+ lua.set_function("inc", [&x]() { x += 10; });
+
+ // calling a stateful lambda modifies the value
+ lua.script("inc()");
+ assert(x == 10);
+ if (x == 10) {
+ // Do something based on this information
+ std::cout << "Yahoo! x is " << x << std::endl;
+ }
+
+ // this can be done as many times as you want
+ lua.script(R"(
+inc()
+inc()
+inc()
+)");
+ assert(x == 40);
+ if (x == 40) {
+ // Do something based on this information
+ std::cout << "Yahoo! x is " << x << std::endl;
+ }
+ // retrieval of a function is done similarly
+ // to other variables, using sol::function
+ sol::function add = lua["my_add"];
+ int value = add(10, 11);
+ // second way to call the function
+ int value2 = add.call<int>(10, 11);
+ assert(value == 21);
+ assert(value2 == 21);
+ if (value == 21 && value2 == 21) {
+ std::cout << "Woo, value is 21!" << std::endl;
+ }
+
+ // multi-return functions are supported using
+ // std::tuple as the interface.
+ lua.set_function("multi", [] { return std::make_tuple(10, "goodbye"); });
+ lua.script("x, y = multi()");
+ lua.script("assert(x == 10 and y == 'goodbye')");
+
+ auto multi = lua.get<sol::function>("multi");
+ int first;
+ std::string second;
+ sol::tie(first, second) = multi();
+
+ // use the values
+ assert(first == 10);
+ assert(second == "goodbye");
+
+ // you can even overload functions
+ // just pass in the different functions
+ // you want to pack into a single name:
+ // make SURE they take different types!
+
+ lua.set_function("func", sol::overload([](int x) { return x; }, make_string, my_add));
+
+ // All these functions are now overloaded through "func"
+ lua.script(R"(
+print(func(1))
+print(func("bark"))
+print(func(1,2))
+)");
+
+ std::cout << std::endl;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/examples/namespacing.cpp b/3rdparty/sol2/examples/namespacing.cpp
new file mode 100644
index 00000000000..8d32744eb64
--- /dev/null
+++ b/3rdparty/sol2/examples/namespacing.cpp
@@ -0,0 +1,33 @@
+#define SOL_CHECK_ARGUMENTS
+#include <sol.hpp>
+#include <cassert>
+
+int main() {
+ struct my_class {
+ int b = 24;
+
+ int f() const {
+ return 24;
+ }
+
+ void g() {
+ ++b;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries();
+
+ sol::table bark = lua.create_named_table("bark");
+ bark.new_usertype<my_class>("my_class",
+ "f", &my_class::f,
+ "g", &my_class::g
+ ); // the usual
+
+ lua.script("obj = bark.my_class.new()"); // this works
+ lua.script("obj:g()");
+ my_class& obj = lua["obj"];
+ assert(obj.b == 25);
+
+ return 0;
+}
diff --git a/3rdparty/sol2/examples/player_script.lua b/3rdparty/sol2/examples/player_script.lua
new file mode 100644
index 00000000000..432983e02a7
--- /dev/null
+++ b/3rdparty/sol2/examples/player_script.lua
@@ -0,0 +1,29 @@
+-- call single argument integer constructor
+p1 = player.new(2)
+
+-- p2 is still here from being
+-- set with lua["p2"] = player(0); below
+local p2shoots = p2:shoot()
+assert(not p2shoots)
+-- had 0 ammo
+
+-- set variable property setter
+p1.hp = 545;
+-- get variable through property getter
+print(p1.hp);
+
+local did_shoot_1 = p1:shoot()
+print(did_shoot_1)
+print(p1.bullets)
+local did_shoot_2 = p1:shoot()
+print(did_shoot_2)
+print(p1.bullets)
+local did_shoot_3 = p1:shoot()
+print(did_shoot_3)
+
+-- can read
+print(p1.bullets)
+-- would error: is a readonly variable, cannot write
+-- p1.bullets = 20
+
+p1:boost() \ No newline at end of file
diff --git a/3rdparty/sol2/examples/protected_functions.cpp b/3rdparty/sol2/examples/protected_functions.cpp
new file mode 100644
index 00000000000..340f0134d63
--- /dev/null
+++ b/3rdparty/sol2/examples/protected_functions.cpp
@@ -0,0 +1,47 @@
+#include <sol.hpp>
+
+#include <iostream>
+
+int main() {
+ std::cout << "=== protected_functions example ===" << std::endl;
+
+ sol::state lua;
+
+ // A complicated function which can error out
+ // We define both in terms of Lua code
+
+ lua.script(R"(
+ function handler (message)
+ return "Handled this message: " .. message
+ end
+
+ function f (a)
+ if a < 0 then
+ error("negative number detected")
+ end
+ return a + 5
+ end
+ )");
+
+ // Get a protected function out of Lua
+ sol::protected_function f = lua["f"];
+ // Set a non-default error handler
+ f.error_handler = lua["handler"];
+
+ sol::protected_function_result result = f(-500);
+ if (result.valid()) {
+ // Call succeeded
+ int x = result;
+ std::cout << "call succeeded, result is " << x << std::endl;
+ }
+ else {
+ // Call failed
+ sol::error err = result;
+ std::string what = err.what();
+ std::cout << "call failed, sol::error::what() is " << what << std::endl;
+ // 'what' Should read
+ // "Handled this message: negative number detected"
+ }
+
+ std::cout << std::endl;
+}
diff --git a/3rdparty/sol2/examples/require.cpp b/3rdparty/sol2/examples/require.cpp
new file mode 100644
index 00000000000..a94765b9453
--- /dev/null
+++ b/3rdparty/sol2/examples/require.cpp
@@ -0,0 +1,47 @@
+#define SOL_CHECK_ARGUMENTS
+#include <sol.hpp>
+#include <cassert>
+
+#include <iostream>
+
+struct some_class {
+ int bark = 2012;
+};
+
+sol::table open_mylib(sol::this_state s) {
+ sol::state_view lua(s);
+
+ sol::table module = lua.create_table();
+ module["func"] = []() { /* super cool function here */ };
+ // register a class too
+ module.new_usertype<some_class>("some_class",
+ "bark", &some_class::bark
+ );
+
+ return module;
+}
+
+int main() {
+ std::cout << "=== require example ===" << std::endl;
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::package);
+ // sol::c_call takes functions at the template level
+ // and turns it into a lua_CFunction
+ // alternatively, one can use sol::c_call<sol::wrap<callable_struct, callable_struct{}>> to make the call
+ // if it's a constexpr struct
+ lua.require("my_lib", sol::c_call<decltype(&open_mylib), &open_mylib>);
+
+ // do ALL THE THINGS YOU LIKE
+ lua.script(R"(
+s = my_lib.some_class.new()
+s.bark = 20;
+)");
+ some_class& s = lua["s"];
+ assert(s.bark == 20);
+ std::cout << "s.bark = " << s.bark << std::endl;
+
+ std::cout << std::endl;
+
+ return 0;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/examples/self_call.cpp b/3rdparty/sol2/examples/self_call.cpp
new file mode 100644
index 00000000000..c64ded34133
--- /dev/null
+++ b/3rdparty/sol2/examples/self_call.cpp
@@ -0,0 +1,35 @@
+#define SOL_CHECK_ARGUMENTS
+#include <sol.hpp>
+#include <cassert>
+#include <iostream>
+
+int main() {
+ std::cout << "=== self_call example ===" << std::endl;
+
+ sol::state lua;
+
+ lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::table);
+
+ // a small script using 'self' syntax
+ lua.script(R"(
+ some_table = { some_val = 100 }
+
+ function some_table:add_to_some_val(value)
+ self.some_val = self.some_val + value
+ end
+
+ function print_some_val()
+ print("some_table.some_val = " .. some_table.some_val)
+ end
+ )");
+
+ // do some printing
+ lua["print_some_val"]();
+ // 100
+
+ sol::table self = lua["some_table"];
+ self["add_to_some_val"](self, 10);
+ lua["print_some_val"]();
+
+ std::cout << std::endl;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/examples/static_variables.cpp b/3rdparty/sol2/examples/static_variables.cpp
new file mode 100644
index 00000000000..c101e824484
--- /dev/null
+++ b/3rdparty/sol2/examples/static_variables.cpp
@@ -0,0 +1,61 @@
+#include <sol.hpp>
+
+#include <iostream>
+#include <cassert>
+
+struct test {
+ static int muh_variable;
+};
+int test::muh_variable = 25;
+
+
+int main() {
+ std::cout << "=== static_variables example ===" << std::endl;
+
+ sol::state lua;
+ lua.open_libraries();
+ lua.new_usertype<test>("test",
+ "direct", sol::var(2),
+ "global", sol::var(test::muh_variable),
+ "ref_global", sol::var(std::ref(test::muh_variable))
+ );
+
+ int direct_value = lua["test"]["direct"];
+ // direct_value == 2
+ assert(direct_value == 2);
+ std::cout << "direct_value: " << direct_value << std::endl;
+
+ int global = lua["test"]["global"];
+ int global2 = lua["test"]["ref_global"];
+ // global == 25
+ // global2 == 25
+ assert(global == 25);
+ assert(global2 == 25);
+
+ std::cout << "First round of values --" << std::endl;
+ std::cout << global << std::endl;
+ std::cout << global2 << std::endl;
+
+ test::muh_variable = 542;
+
+ global = lua["test"]["global"];
+ // global == 25
+ // global is its own memory: was passed by value
+
+ global2 = lua["test"]["ref_global"];
+ // global2 == 542
+ // global2 was passed through std::ref
+ // global2 holds a reference to muh_variable
+ // if muh_variable goes out of scope or is deleted
+ // problems could arise, so be careful!
+
+ assert(global == 25);
+ assert(global2 == 542);
+
+ std::cout << "Second round of values --" << std::endl;
+ std::cout << "global : " << global << std::endl;
+ std::cout << "global2: " << global2 << std::endl;
+ std::cout << std::endl;
+
+ return 0;
+}
diff --git a/3rdparty/sol2/examples/tables.cpp b/3rdparty/sol2/examples/tables.cpp
new file mode 100644
index 00000000000..41798d3b0b4
--- /dev/null
+++ b/3rdparty/sol2/examples/tables.cpp
@@ -0,0 +1,59 @@
+#include <sol.hpp>
+#include <string>
+#include <iostream>
+
+// this example shows how to read data in from a lua table
+
+int main() {
+ std::cout << "=== tables example ===" << std::endl;
+
+ sol::state lua;
+ // table used as an array
+ lua.script("table1 = {\"hello\", \"table\"}");
+ // table with a nested table and the key value syntax
+ lua.script("table2 = {"
+ "[\"nestedTable\"] = {"
+ "[\"key1\"] = \"value1\","
+ "[\"key2\"]= \"value2\""
+ "},"
+ "[\"name\"]= \"table2\""
+ "}");
+
+
+ /* Shorter Syntax: */
+ // using the values stored in table1
+ /*std::cout << (std::string)lua["table1"][1] << " "
+ << (std::string)lua["table1"][2] << '\n';
+ */
+ // some retrieval of values from the nested table
+ // the cleaner way of doing things
+ // chain off the the get<>() / [] results
+ auto t2 = lua.get<sol::table>("table2");
+ auto nestedTable = t2.get<sol::table>("nestedTable");
+ // Alternatively:
+ //sol::table t2 = lua["table2"];
+ //sol::table nestedTable = t2["nestedTable"];
+
+ std::string x = lua["table2"]["nestedTable"]["key2"];
+ std::cout << "nested table: key1 : " << nestedTable.get<std::string>("key1") << ", key2: "
+ << x
+ << '\n';
+ std::cout << "name of t2: " << t2.get<std::string>("name") << '\n';
+ std::string t2name = t2["name"];
+ std::cout << "name of t2: " << t2name << '\n';
+
+ /* Longer Syntax: */
+ // using the values stored in table1
+ std::cout << lua.get<sol::table>("table1").get<std::string>(1) << " "
+ << lua.get<sol::table>("table1").get<std::string>(2) << '\n';
+
+ // some retrieval of values from the nested table
+ // the cleaner way of doing things
+ std::cout << "nested table: key1 : " << nestedTable.get<std::string>("key1") << ", key2: "
+ // yes you can chain the get<>() results
+ << lua.get<sol::table>("table2").get<sol::table>("nestedTable").get<std::string>("key2")
+ << '\n';
+ std::cout << "name of t2: " << t2.get<std::string>("name") << '\n';
+
+ std::cout << std::endl;
+}
diff --git a/3rdparty/sol2/examples/usertype.cpp b/3rdparty/sol2/examples/usertype.cpp
new file mode 100644
index 00000000000..496a0b763d3
--- /dev/null
+++ b/3rdparty/sol2/examples/usertype.cpp
@@ -0,0 +1,109 @@
+#include <sol.hpp>
+#include <iostream>
+#include <cassert>
+#include <cmath>
+
+struct foo {
+private:
+ std::string name;
+public:
+ foo(std::string name): name(std::string(name)) {}
+
+ void print() {
+ std::cout << name << '\n';
+ }
+
+ int test(int x) {
+ return name.length() + x;
+ }
+};
+
+struct vector {
+private:
+ float x = 0;
+ float y = 0;
+public:
+ vector() = default;
+ vector(float x): x(x) {}
+ vector(float x, float y): x(x), y(y) {}
+
+ bool is_unit() const {
+ return (x * x + y * y) == 1.f;
+ }
+};
+
+struct variables {
+ bool low_gravity = false;
+ int boost_level = 0;
+
+};
+
+int main() {
+ std::cout << "=== usertype example ===" << std::endl;
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::math);
+
+ // the simplest way to create a class is through
+ // sol::state::new_userdata
+ // the first template is the class type
+ // the rest are the constructor parameters
+ // using new_userdata you can only have one constructor
+
+
+ // you must make sure that the name of the function
+ // goes before the member function pointer
+ lua.new_usertype<foo, std::string>("foo", "print", &foo::print, "test", &foo::test);
+
+ // making the class from lua is simple
+ // same with calling member functions
+ lua.script("x = foo.new('test')\n"
+ "x:print()\n"
+ "y = x:test(10)");
+
+ auto y = lua.get<int>("y");
+ std::cout << y << std::endl; // show 14
+
+ // if you want a class to have more than one constructor
+ // the way to do so is through set_userdata and creating
+ // a userdata yourself with constructor types
+
+ {
+ // Notice the brace: this means we're in a new scope
+ // first, define the different types of constructors
+ sol::constructors<sol::types<>, sol::types<float>, sol::types<float, float>> ctor;
+
+ // the only template parameter is the class type
+ // the first argument of construction is the name
+ // second is the constructor types
+ // then the rest are function name and member function pointer pairs
+ sol::usertype<vector> utype(ctor, "is_unit", &vector::is_unit);
+
+ // then you must register it
+ lua.set_usertype("vector", utype);
+ // You can throw away the usertype after you set it: you do NOT
+ // have to keep it around
+ // cleanup happens automagically
+ }
+ // calling it is the same as new_userdata
+
+ lua.script("v = vector.new()\n"
+ "v = vector.new(12)\n"
+ "v = vector.new(10, 10)\n"
+ "assert(not v:is_unit())\n");
+
+ // You can even have C++-like member-variable-access
+ // just pass is public member variables in the same style as functions
+ lua.new_usertype<variables>("variables", "low_gravity", &variables::low_gravity, "boost_level", &variables::boost_level);
+
+ // making the class from lua is simple
+ // same with calling member functions/variables
+ lua.script("local vars = variables.new()\n"
+ "assert(not vars.low_gravity)\n"
+ "vars.low_gravity = true\n"
+ "local x = vars.low_gravity\n"
+ "assert(x)");
+
+ std::cout << std::endl;
+
+}
diff --git a/3rdparty/sol2/examples/usertype_advanced.cpp b/3rdparty/sol2/examples/usertype_advanced.cpp
new file mode 100644
index 00000000000..32679089844
--- /dev/null
+++ b/3rdparty/sol2/examples/usertype_advanced.cpp
@@ -0,0 +1,121 @@
+#include <sol.hpp>
+
+#include <iostream>
+
+struct player {
+public:
+ int bullets;
+ int speed;
+
+ player()
+ : player(3, 100) {
+
+ }
+
+ player(int ammo)
+ : player(ammo, 100) {
+
+ }
+
+ player(int ammo, int hitpoints)
+ : bullets(ammo), hp(hitpoints) {
+
+ }
+
+ void boost() {
+ speed += 10;
+ }
+
+ bool shoot() {
+ if (bullets < 1)
+ return false;
+ --bullets;
+ return true;
+ }
+
+ void set_hp(int value) {
+ hp = value;
+ }
+
+ int get_hp() const {
+ return hp;
+ }
+
+private:
+ int hp;
+};
+
+int main() {
+ std::cout << "=== usertype_advanced example ===" << std::endl;
+ sol::state lua;
+
+ lua.open_libraries(sol::lib::base);
+
+ // note that you can set a
+ // userdata before you register a usertype,
+ // and it will still carry
+ // the right metatable if you register it later
+
+ // set a variable "p2" of type "player" with 0 ammo
+ lua["p2"] = player(0);
+
+ // make usertype metatable
+ lua.new_usertype<player>("player",
+
+ // 3 constructors
+ sol::constructors<sol::types<>, sol::types<int>, sol::types<int, int>>(),
+
+ // typical member function that returns a variable
+ "shoot", &player::shoot,
+ // typical member function
+ "boost", &player::boost,
+
+ // gets or set the value using member variable syntax
+ "hp", sol::property(&player::get_hp, &player::set_hp),
+
+ // read and write variable
+ "speed", &player::speed,
+ // can only read from, not write to
+ "bullets", sol::readonly(&player::bullets)
+ );
+
+ std::string player_script = R"(
+-- call single argument integer constructor
+p1 = player.new(2)
+
+-- p2 is still here from being
+-- set with lua["p2"] = player(0); below
+local p2shoots = p2:shoot()
+assert(not p2shoots)
+-- had 0 ammo
+
+-- set variable property setter
+p1.hp = 545
+-- get variable through property getter
+print(p1.hp)
+assert(p1.hp == 545)
+
+local did_shoot_1 = p1:shoot()
+print(did_shoot_1)
+print(p1.bullets)
+local did_shoot_2 = p1:shoot()
+print(did_shoot_2)
+print(p1.bullets)
+local did_shoot_3 = p1:shoot()
+print(did_shoot_3)
+
+-- can read
+print(p1.bullets)
+-- would error: is a readonly variable, cannot write
+-- p1.bullets = 20
+
+p1:boost()
+)";
+
+ // Uncomment and use the file to try that out, too!
+ // Make sure it's in the local directory of the executable after you build, or adjust the filename path
+ // Or whatever else you like!
+ //lua.script_file("player_script.lua");
+ lua.script(player_script);
+ std::cout << std::endl;
+}
diff --git a/3rdparty/sol2/examples/usertype_initializers.cpp b/3rdparty/sol2/examples/usertype_initializers.cpp
new file mode 100644
index 00000000000..10f1f68cb94
--- /dev/null
+++ b/3rdparty/sol2/examples/usertype_initializers.cpp
@@ -0,0 +1,67 @@
+#define SOL_CHECK_ARGUMENTS
+#include <sol.hpp>
+#include <memory>
+#include <iostream>
+#include <cassert>
+
+struct holy {
+private:
+ holy() : data() {}
+ holy(int value) : data(value) {}
+ ~holy() {}
+
+public:
+ struct deleter {
+ void operator()(holy* p) const {
+ destroy(*p);
+ }
+ };
+
+ const int data;
+
+ static std::unique_ptr<holy, deleter> create() {
+ std::cout << "creating 'holy' unique_ptr directly and letting sol/Lua handle it" << std::endl;
+ return std::unique_ptr<holy, deleter>(new holy(50));
+ }
+
+ static void initialize(holy& uninitialized_memory) {
+ std::cout << "initializing 'holy' userdata at " << static_cast<void*>(&uninitialized_memory) << std::endl;
+ // receive uninitialized memory from Lua:
+ // properly set it by calling a constructor
+ // on it
+ // "placement new"
+ new (&uninitialized_memory) holy();
+ }
+
+ static void destroy(holy& memory_from_lua) {
+ std::cout << "destroying 'holy' userdata at " << static_cast<void*>(&memory_from_lua) << std::endl;
+ memory_from_lua.~holy();
+ }
+};
+
+int main() {
+ std::cout << "=== usertype_initializers example ===" << std::endl;
+ { // additional scope to make usertype destroy earlier
+ sol::state lua;
+ lua.open_libraries();
+
+ lua.new_usertype<holy>("holy",
+ "new", sol::initializers(&holy::initialize),
+ "create", sol::factories(&holy::create),
+ sol::meta_function::garbage_collect, sol::destructor(&holy::destroy),
+ "data", &holy::data
+ );
+
+ lua.script(R"(
+h1 = holy.create()
+h2 = holy.new()
+print('h1.data is ' .. h1.data)
+print('h2.data is ' .. h2.data)
+)");
+ holy& h1 = lua["h1"];
+ holy& h2 = lua["h2"];
+ assert(h1.data == 50);
+ assert(h2.data == 0);
+ }
+ std::cout << std::endl;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/examples/usertype_simple.cpp b/3rdparty/sol2/examples/usertype_simple.cpp
new file mode 100644
index 00000000000..1b64e3b403f
--- /dev/null
+++ b/3rdparty/sol2/examples/usertype_simple.cpp
@@ -0,0 +1,95 @@
+#define SOL_CHECK_ARGUMENTS
+#include <sol.hpp>
+#include <memory>
+#include <iostream>
+#include <cassert>
+
+class generator {
+private:
+ int data = 2;
+
+public:
+ int get_data() const { return data; }
+ void set_data(int value) { data = value % 10; }
+
+ std::vector<int> generate_list() {
+ return { data, data * 2, data * 3, data * 4, data * 5 };
+ }
+};
+
+struct my_data {
+ int first = 4;
+ int second = 8;
+ int third = 12;
+};
+
+int main() {
+ std::cout << "=== usertype_simple example ===" << std::endl;
+
+ sol::state lua;
+ lua.open_libraries();
+
+ // simple_usertype acts and behaves like
+ // a regular usertype
+ lua.new_simple_usertype<my_data>("my_data",
+ "first", &my_data::first,
+ "second", &my_data::second,
+ "third", &my_data::third
+ );
+
+ {
+ // But, simple_usertype also has a `set` function
+ // where you can append things to the
+ // method listing after doing `create_simple_usertype`.
+ auto generator_registration = lua.create_simple_usertype<generator>();
+ generator_registration.set("data", sol::property(&generator::get_data, &generator::set_data));
+ // you MUST set the usertype after
+ // creating it
+ lua.set_usertype("generator", generator_registration);
+ }
+
+ // Can update a simple_usertype at runtime, after registration
+ lua["generator"]["generate_list"] = [](generator& self) { return self.generate_list(); };
+ // can set 'static methods' (no self) as well
+ lua["generator"]["get_num"] = []() { return 100; };
+
+ // Mix it all together!
+ lua.script(R"(
+mdata = my_data.new()
+
+local g = generator.new()
+g.data = mdata.first
+list1 = g:generate_list()
+g.data = mdata.second
+list2 = g:generate_list()
+g.data = mdata.third
+list3 = g:generate_list()
+
+print("From lua: ")
+for i = 1, #list1 do
+ print("\tlist1[" .. i .. "] = " .. list1[i])
+end
+for i = 1, #list2 do
+ print("\tlist2[" .. i .. "] = " .. list2[i])
+end
+for i = 1, #list3 do
+ print("\tlist3[" .. i .. "] = " .. list3[i])
+end
+
+)");
+ my_data& mdata = lua["mdata"];
+ std::vector<int>& list1 = lua["list1"];
+ std::vector<int>& list2 = lua["list2"];
+ std::vector<int>& list3 = lua["list3"];
+ assert(list1.size() == 5);
+ assert(list2.size() == 5);
+ assert(list3.size() == 5);
+ for (int i = 1; i <= 5; ++i) {
+ assert(list1[i - 1] == (mdata.first % 10) * i);
+ assert(list2[i - 1] == (mdata.second % 10) * i);
+ assert(list3[i - 1] == (mdata.third % 10) * i);
+ }
+
+ std::cout << std::endl;
+ return 0;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/examples/usertype_special_functions.cpp b/3rdparty/sol2/examples/usertype_special_functions.cpp
new file mode 100644
index 00000000000..ef1492dfc76
--- /dev/null
+++ b/3rdparty/sol2/examples/usertype_special_functions.cpp
@@ -0,0 +1,70 @@
+#define SOL_CHECK_ARGUMENTS
+#include <sol.hpp>
+#include <iostream>
+#include <cassert>
+#include <cmath>
+
+struct vec {
+ double x;
+ double y;
+
+ vec() : x(0), y(0) {}
+ vec(double x, double y) : x(x), y(y) {}
+
+ vec operator-(const vec& right) const {
+ return vec(x - right.x, y - right.y);
+ }
+};
+
+double dot(const vec& left, const vec& right) {
+ return left.x * right.x + left.x * right.x;
+}
+
+vec operator+(const vec& left, const vec& right) {
+ return vec(left.x + right.x, left.y + right.y);
+}
+
+int main() {
+ sol::state lua;
+ lua.open_libraries();
+
+ lua.new_usertype<vec>("vec",
+ sol::constructors<sol::types<>, sol::types<double, double>>(),
+ "dot", &dot,
+ "norm", [](const vec& self) { double len = std::sqrt(dot(self, self)); return vec(self.x / len, self.y / len); },
+ // we use `sol::resolve` because other operator+ can exist
+ // in the (global) namespace
+ sol::meta_function::addition, sol::resolve<const vec&, const vec&>(::operator+),
+ sol::meta_function::subtraction, &vec::operator-
+ );
+
+ lua.script(R"(
+ v1 = vec.new(1, 0)
+ v2 = vec.new(0, 1)
+ -- as "member function"
+ d1 = v1:dot(v2)
+ -- as "static" / "free function"
+ d2 = vec.dot(v1, v2)
+ assert(d1 == d2)
+
+ -- doesn't matter if
+ -- bound as free function
+ -- or member function:
+ a1 = v1 + v2
+ s1 = v1 - v2
+)");
+
+ vec& a1 = lua["a1"];
+ vec& s1 = lua["s1"];
+
+ assert(a1.x == 1 && a1.y == 1);
+ assert(s1.x == 1 && s1.y == -1);
+
+ lua["a2"] = lua["a1"];
+
+ lua.script(R"(
+ assert(a1 == a2)
+ )");
+
+ std::cout << std::endl;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/examples/usertype_var.cpp b/3rdparty/sol2/examples/usertype_var.cpp
new file mode 100644
index 00000000000..9f56490aa29
--- /dev/null
+++ b/3rdparty/sol2/examples/usertype_var.cpp
@@ -0,0 +1,45 @@
+#define SOL_CHECK_ARGUMENTS
+#include <sol.hpp>
+#include <iostream>
+
+struct test {
+ static int number;
+};
+int test::number = 25;
+
+
+int main() {
+ sol::state lua;
+ lua.open_libraries();
+ lua.new_usertype<test>("test",
+ "direct", sol::var(2),
+ "number", sol::var(test::number),
+ "ref_number", sol::var(std::ref(test::number))
+ );
+
+ int direct_value = lua["test"]["direct"];
+ assert(direct_value == 2);
+ // direct_value == 2
+
+ int number = lua["test"]["number"];
+ assert(number == 25);
+ int ref_number = lua["test"]["ref_number"];
+ assert(ref_number == 25);
+
+ test::number = 542;
+
+ assert(lua["test"]["number"] == 25);
+ // number is its own memory: was passed by value
+ // So does not change
+
+ assert(lua["test"]["ref_number"] == 542);
+ // ref_number is just test::number
+ // passed through std::ref
+ // so, it holds a reference
+ // which can be updated
+ // be careful about referencing local variables,
+ // if they go out of scope but are still reference
+ // you'll suffer dangling reference bugs!
+
+ return 0;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/examples/variables.cpp b/3rdparty/sol2/examples/variables.cpp
new file mode 100644
index 00000000000..ece88915703
--- /dev/null
+++ b/3rdparty/sol2/examples/variables.cpp
@@ -0,0 +1,37 @@
+#include <sol.hpp>
+#include <iostream>
+
+int main() {
+ std::cout << "=== variables example ===" << std::endl;
+
+ sol::state lua;
+
+ // need the base library for assertions
+ lua.open_libraries(sol::lib::base);
+
+ // basic setting of a variable
+ // through multiple ways
+ lua["x"] = 10;
+ lua.set("y", "hello");
+
+ // assert values are as given
+ lua.script("assert(x == 10)");
+ lua.script("assert(y == 'hello')");
+
+
+ // basic retrieval of a variable
+ // through multiple ways
+ int x = lua["x"];
+ auto y = lua.get<std::string>("y");
+
+ int x2;
+ std::string y2;
+ std::tie(x2, y2) = lua.get<int, std::string>("x", "y");
+
+ // show the values
+ std::cout << x << std::endl;
+ std::cout << y << std::endl;
+ std::cout << x2 << std::endl;
+ std::cout << y2 << std::endl;
+ std::cout << std::endl;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/examples/variadic_args.cpp b/3rdparty/sol2/examples/variadic_args.cpp
new file mode 100644
index 00000000000..918e33ec790
--- /dev/null
+++ b/3rdparty/sol2/examples/variadic_args.cpp
@@ -0,0 +1,40 @@
+#include <sol.hpp>
+
+#include <iostream>
+
+int main() {
+ std::cout << "=== variadic_args example ===" << std::endl;
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ // Function requires 2 arguments
+ // rest can be variadic, but:
+ // va will include everything after "a" argument,
+ // which means "b" will be part of the varaidic_args list too
+ // at position 0
+ lua.set_function("v", [](int a, sol::variadic_args va, int /*b*/) {
+ int r = 0;
+ for (auto v : va) {
+ int value = v; // get argument out (implicit conversion)
+ // can also do int v = va.get<int>(i); with index i
+ r += value;
+ }
+ // Only have to add a, b was included from variadic_args and beyond
+ return r + a;
+ });
+
+ lua.script("x = v(25, 25)");
+ lua.script("x2 = v(25, 25, 100, 50, 250, 150)");
+ lua.script("x3 = v(1, 2, 3, 4, 5, 6)");
+ // will error: not enough arguments
+ //lua.script("x4 = v(1)");
+
+ lua.script("assert(x == 50)");
+ lua.script("assert(x2 == 600)");
+ lua.script("assert(x3 == 21)");
+ lua.script("print(x)"); // 50
+ lua.script("print(x2)"); // 600
+ lua.script("print(x3)"); // 21
+ std::cout << std::endl;
+} \ No newline at end of file
diff --git a/3rdparty/sol2/install.deps.sh b/3rdparty/sol2/install.deps.sh
new file mode 100644
index 00000000000..b3571190663
--- /dev/null
+++ b/3rdparty/sol2/install.deps.sh
@@ -0,0 +1,96 @@
+#!/usr/bin/env bash
+
+# This script installs and configures the dependencies for the project
+
+case `uname` in
+ Darwin) export OS_NAME="osx" ;;
+ Linux) export OS_NAME="linux" ;;
+esac
+
+echo "Building on: ${OS_NAME}"
+
+if env | grep -qE '^(?:TRAVIS|CI)='; then
+# We're on Travis, intialize variables:
+ echo "Detected CI Build -> CI=${CI}"
+else
+# We're building locally
+ export CI=false
+ echo "Detected Local Build -> CI=${CI}"
+fi
+
+export_compiler_vars() {
+ case ${COMPILER} in
+ appleclang*)
+ export CC=clang
+ export CXX=clang++
+ ;;
+
+ clang*)
+ export CC=$(echo ${COMPILER} | sed 's/\+//g')
+ export CXX=${COMPILER}
+ ;;
+
+ g++-*)
+ export CC=$(echo ${COMPILER} | sed 's/\+/c/g')
+ export CXX=${COMPILER}
+ ;;
+
+ *) echo "Invalid compiler version" ; exit 2 ;;
+ esac
+
+ echo "CC=${CC}"
+ $CC --version
+
+ echo "CXX=${CXX}"
+ $CXX --version
+}
+
+install_os_deps() {
+ # Install all of the OS specific OS dependencies
+ echo "Install: os-based dependencies"
+
+ local wd=`pwd`
+
+ case ${OS_NAME} in
+ osx)
+ export HOMEBREW_NO_EMOJI=1
+
+ echo "brew update ..."; brew update > /dev/null
+
+ case ${COMPILER} in
+ appleclang*) ;;
+
+ g++-5)
+ brew install gcc5
+ brew link gcc5 --overwrite --force
+ ;;
+
+ g++-4.9) ;;
+
+ *) echo "Invalid compiler version" ; exit 2 ;;
+ esac
+
+ brew install ninja
+
+ local lua_pkg
+ case ${LUA_VERSION} in
+ lua53) lua_pkg=lua53 ;;
+ lua52) lua_pkg=lua ;;
+ lua51) lua_pkg=lua51 ;;
+ luajit52) lua_pkg=luajit ;;
+ luajit) lua_pkg=luajit ;;
+ *) echo "Invalid Lua Version for OSX"
+ exit 2
+ ;;
+ esac
+
+ brew install ${lua_pkg}
+ ;;
+
+ linux)
+ # no extras currently
+ ;;
+ esac
+
+ cd ${wd}
+}
diff --git a/3rdparty/sol2/ninja_syntax.py b/3rdparty/sol2/ninja_syntax.py
new file mode 100644
index 00000000000..14b932ff4c8
--- /dev/null
+++ b/3rdparty/sol2/ninja_syntax.py
@@ -0,0 +1,156 @@
+#!/usr/bin/python
+
+"""Python module for generating .ninja files.
+
+Note that this is emphatically not a required piece of Ninja; it's
+just a helpful utility for build-file-generation systems that already
+use Python.
+"""
+
+import textwrap
+
+def escape_path(word):
+ return word.replace('$ ', '$$ ').replace(' ', '$ ').replace(':', '$:')
+
+class Writer(object):
+ def __init__(self, output, width=78):
+ self.output = output
+ self.width = width
+
+ def newline(self):
+ self.output.write('\n')
+
+ def comment(self, text):
+ for line in textwrap.wrap(text, self.width - 2):
+ self.output.write('# ' + line + '\n')
+
+ def variable(self, key, value, indent=0):
+ if value is None:
+ return
+ if isinstance(value, list):
+ value = ' '.join(filter(None, value)) # Filter out empty strings.
+ self._line('%s = %s' % (key, value), indent)
+
+ def pool(self, name, depth):
+ self._line('pool %s' % name)
+ self.variable('depth', depth, indent=1)
+
+ def rule(self, name, command, description=None, depfile=None,
+ generator=False, pool=None, restat=False, rspfile=None,
+ rspfile_content=None, deps=None):
+ self._line('rule %s' % name)
+ self.variable('command', command, indent=1)
+ if description:
+ self.variable('description', description, indent=1)
+ if depfile:
+ self.variable('depfile', depfile, indent=1)
+ if generator:
+ self.variable('generator', '1', indent=1)
+ if pool:
+ self.variable('pool', pool, indent=1)
+ if restat:
+ self.variable('restat', '1', indent=1)
+ if rspfile:
+ self.variable('rspfile', rspfile, indent=1)
+ if rspfile_content:
+ self.variable('rspfile_content', rspfile_content, indent=1)
+ if deps:
+ self.variable('deps', deps, indent=1)
+
+ def build(self, outputs, rule, inputs=None, implicit=None, order_only=None,
+ variables=None):
+ outputs = self._as_list(outputs)
+ out_outputs = [escape_path(x) for x in outputs]
+ all_inputs = [escape_path(x) for x in self._as_list(inputs)]
+
+ if implicit:
+ implicit = [escape_path(x) for x in self._as_list(implicit)]
+ all_inputs.append('|')
+ all_inputs.extend(implicit)
+ if order_only:
+ order_only = [escape_path(x) for x in self._as_list(order_only)]
+ all_inputs.append('||')
+ all_inputs.extend(order_only)
+
+ self._line('build %s: %s' % (' '.join(out_outputs),
+ ' '.join([rule] + all_inputs)))
+
+ if variables:
+ if isinstance(variables, dict):
+ iterator = iter(variables.items())
+ else:
+ iterator = iter(variables)
+
+ for key, val in iterator:
+ self.variable(key, val, indent=1)
+
+ return outputs
+
+ def include(self, path):
+ self._line('include %s' % path)
+
+ def subninja(self, path):
+ self._line('subninja %s' % path)
+
+ def default(self, paths):
+ self._line('default %s' % ' '.join(self._as_list(paths)))
+
+ def _count_dollars_before_index(self, s, i):
+ """Returns the number of '$' characters right in front of s[i]."""
+ dollar_count = 0
+ dollar_index = i - 1
+ while dollar_index > 0 and s[dollar_index] == '$':
+ dollar_count += 1
+ dollar_index -= 1
+ return dollar_count
+
+ def _line(self, text, indent=0):
+ """Write 'text' word-wrapped at self.width characters."""
+ leading_space = ' ' * indent
+ while len(leading_space) + len(text) > self.width:
+ # The text is too wide; wrap if possible.
+
+ # Find the rightmost space that would obey our width constraint and
+ # that's not an escaped space.
+ available_space = self.width - len(leading_space) - len(' $')
+ space = available_space
+ while True:
+ space = text.rfind(' ', 0, space)
+ if (space < 0 or
+ self._count_dollars_before_index(text, space) % 2 == 0):
+ break
+
+ if space < 0:
+ # No such space; just use the first unescaped space we can find.
+ space = available_space - 1
+ while True:
+ space = text.find(' ', space + 1)
+ if (space < 0 or
+ self._count_dollars_before_index(text, space) % 2 == 0):
+ break
+ if space < 0:
+ # Give up on breaking.
+ break
+
+ self.output.write(leading_space + text[0:space] + ' $\n')
+ text = text[space+1:]
+
+ # Subsequent lines are continuations, so indent them.
+ leading_space = ' ' * (indent+2)
+
+ self.output.write(leading_space + text + '\n')
+
+ def _as_list(self, input):
+ if input is None:
+ return []
+ if isinstance(input, list):
+ return input
+ return [input]
+
+
+def escape(string):
+ """Escape a string such that it can be embedded into a Ninja file without
+ further interpretation."""
+ assert '\n' not in string, 'Ninja syntax does not allow newlines'
+ # We only have one special metacharacter: '$'.
+ return string.replace('$', '$$')
diff --git a/3rdparty/sol2/single.py b/3rdparty/sol2/single.py
new file mode 100644
index 00000000000..f53a9410320
--- /dev/null
+++ b/3rdparty/sol2/single.py
@@ -0,0 +1,165 @@
+#!/usr/bin/env python
+
+import argparse
+import os, sys
+import re
+import datetime as dt
+
+# python 3 compatibility
+try:
+ import cStringIO as sstream
+except ImportError:
+ from io import StringIO
+
+description = "Converts sol to a single file for convenience."
+
+# command line parser
+parser = argparse.ArgumentParser(usage='%(prog)s [options...]', description=description)
+parser.add_argument('--output', '-o', help='name and location of where to place file', metavar='file', default='sol.hpp')
+parser.add_argument('--quiet', help='suppress all output', action='store_true')
+args = parser.parse_args()
+
+script_path = os.path.normpath(os.path.dirname(os.path.realpath(__file__)))
+working_dir = os.getcwd()
+os.chdir(script_path)
+
+intro = """// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// This file was generated with a script.
+// Generated {time} UTC
+// This header was generated with sol {version} (revision {revision})
+// https://github.com/ThePhD/sol2
+
+#ifndef {guard}
+#define {guard}
+
+"""
+
+module_path = os.path.join(script_path)
+
+includes = set([])
+standard_include = re.compile(r'#include <(.*?)>')
+local_include = re.compile(r'#include "(.*?)"')
+ifndef_cpp = re.compile(r'#ifndef SOL_.*?_HPP')
+define_cpp = re.compile(r'#define SOL_.*?_HPP')
+endif_cpp = re.compile(r'#endif // SOL_.*?_HPP')
+
+def get_include(line, base_path):
+ local_match = local_include.match(line)
+ if local_match:
+ # local include found
+ full_path = os.path.normpath(os.path.join(base_path, local_match.group(1))).replace('\\', '/')
+ return full_path
+
+ return None
+
+
+def is_include_guard(line):
+ return ifndef_cpp.match(line) or define_cpp.match(line) or endif_cpp.match(line)
+
+def get_revision():
+ return os.popen('git rev-parse --short HEAD').read().strip()
+
+def get_version():
+ return os.popen('git describe --tags --abbrev=0').read().strip()
+
+def process_file(filename, out):
+ global includes
+ filename = os.path.normpath(filename)
+ relativefilename = filename.replace(script_path + os.sep, "").replace("\\", "/")
+
+ if filename in includes:
+ return
+
+ includes.add(filename)
+
+ if not args.quiet:
+ print('processing {}'.format(filename))
+
+ out.write('// beginning of {}\n\n'.format(relativefilename))
+ empty_line_state = True
+
+ with open(filename, 'r', encoding='utf-8') as f:
+ for line in f:
+ # skip comments
+ if line.startswith('//'):
+ continue
+
+ # skip include guard non-sense
+ if is_include_guard(line):
+ continue
+
+ # get relative directory
+ base_path = os.path.dirname(filename)
+
+ # check if it's a standard file
+ std = standard_include.search(line)
+ if std:
+ std_file = os.path.join('std', std.group(0))
+ if std_file in includes:
+ continue
+ includes.add(std_file)
+
+ # see if it's an include file
+ name = get_include(line, base_path)
+
+ if name:
+ process_file(name, out)
+ continue
+
+ empty_line = len(line.strip()) == 0
+
+ if empty_line and empty_line_state:
+ continue
+
+ empty_line_state = empty_line
+
+ # line is fine
+ out.write(line)
+
+ out.write('// end of {}\n\n'.format(relativefilename))
+
+
+version = get_version()
+revision = get_revision()
+include_guard = 'SOL_SINGLE_INCLUDE_HPP'
+
+if not args.quiet:
+ print('Creating single header for sol')
+ print('Current version: {version} (revision {revision})\n'.format(version = version, revision = revision))
+
+
+processed_files = [os.path.join(script_path, 'sol', x) for x in ('state.hpp', 'object.hpp', 'function.hpp', 'coroutine.hpp')]
+result = ''
+
+ss = StringIO()
+ss.write(intro.format(time=dt.datetime.utcnow(), revision=revision, version=version, guard=include_guard))
+for processed_file in processed_files:
+ process_file(processed_file, ss)
+
+ss.write('#endif // {}\n'.format(include_guard))
+result = ss.getvalue()
+ss.close()
+
+with open(args.output, 'w', encoding='utf-8') as f:
+ f.write(result)
+
diff --git a/3rdparty/sol2/single/sol/sol.hpp b/3rdparty/sol2/single/sol/sol.hpp
new file mode 100644
index 00000000000..c2c8a328bc3
--- /dev/null
+++ b/3rdparty/sol2/single/sol/sol.hpp
@@ -0,0 +1,12323 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// This file was generated with a script.
+// Generated 2016-10-06 00:53:22.017715 UTC
+// This header was generated with sol v2.14.9 (revision 0ba4650)
+// https://github.com/ThePhD/sol2
+
+#ifndef SOL_SINGLE_INCLUDE_HPP
+#define SOL_SINGLE_INCLUDE_HPP
+
+// beginning of sol/state.hpp
+
+// beginning of sol/state_view.hpp
+
+// beginning of sol/error.hpp
+
+#include <stdexcept>
+#include <string>
+
+namespace sol {
+ namespace detail {
+ struct direct_error_tag {};
+ const auto direct_error = direct_error_tag{};
+ } // detail
+
+ class error : public std::runtime_error {
+ private:
+ // Because VC++ is a fuccboi
+ std::string w;
+ public:
+ error(const std::string& str) : error(detail::direct_error, "lua: error: " + str) {}
+ error(detail::direct_error_tag, const std::string& str) : std::runtime_error(""), w(str) {}
+ error(detail::direct_error_tag, std::string&& str) : std::runtime_error(""), w(std::move(str)) {}
+
+ error(const error& e) = default;
+ error(error&& e) = default;
+ error& operator=(const error& e) = default;
+ error& operator=(error&& e) = default;
+
+ virtual const char* what() const noexcept override {
+ return w.c_str();
+ }
+ };
+
+} // sol
+
+// end of sol/error.hpp
+
+// beginning of sol/table.hpp
+
+// beginning of sol/table_core.hpp
+
+// beginning of sol/proxy.hpp
+
+// beginning of sol/traits.hpp
+
+// beginning of sol/tuple.hpp
+
+#include <tuple>
+#include <cstddef>
+
+namespace sol {
+ namespace detail {
+ using swallow = std::initializer_list<int>;
+ } // detail
+
+ template<typename... Args>
+ struct types { typedef std::make_index_sequence<sizeof...(Args)> indices; static constexpr std::size_t size() { return sizeof...(Args); } };
+ namespace meta {
+ namespace detail {
+ template<typename... Args>
+ struct tuple_types_ { typedef types<Args...> type; };
+
+ template<typename... Args>
+ struct tuple_types_<std::tuple<Args...>> { typedef types<Args...> type; };
+ } // detail
+
+ template<typename T>
+ using unqualified = std::remove_cv<std::remove_reference_t<T>>;
+
+ template<typename T>
+ using unqualified_t = typename unqualified<T>::type;
+
+ template<typename... Args>
+ using tuple_types = typename detail::tuple_types_<Args...>::type;
+
+ template<typename Arg>
+ struct pop_front_type;
+
+ template<typename Arg>
+ using pop_front_type_t = typename pop_front_type<Arg>::type;
+
+ template<typename... Args>
+ struct pop_front_type<types<Args...>> { typedef void front_type; typedef types<Args...> type; };
+
+ template<typename Arg, typename... Args>
+ struct pop_front_type<types<Arg, Args...>> { typedef Arg front_type; typedef types<Args...> type; };
+
+ template <std::size_t N, typename Tuple>
+ using tuple_element = std::tuple_element<N, unqualified_t<Tuple>>;
+
+ template <std::size_t N, typename Tuple>
+ using tuple_element_t = std::tuple_element_t<N, unqualified_t<Tuple>>;
+
+ template <std::size_t N, typename Tuple>
+ using unqualified_tuple_element = unqualified<tuple_element_t<N, Tuple>>;
+
+ template <std::size_t N, typename Tuple>
+ using unqualified_tuple_element_t = unqualified_t<tuple_element_t<N, Tuple>>;
+
+ } // meta
+} // sol
+
+// end of sol/tuple.hpp
+
+// beginning of sol/bind_traits.hpp
+
+namespace sol {
+ namespace meta {
+ namespace meta_detail {
+
+ template<class F>
+ struct check_deducible_signature {
+ struct nat {};
+ template<class G>
+ static auto test(int) -> decltype(&G::operator(), void());
+ template<class>
+ static auto test(...)->nat;
+
+ using type = std::is_void<decltype(test<F>(0))>;
+ };
+ } // meta_detail
+
+ template<class F>
+ struct has_deducible_signature : meta_detail::check_deducible_signature<F>::type { };
+
+ namespace meta_detail {
+
+ template <std::size_t I, typename T>
+ struct void_tuple_element : meta::tuple_element<I, T> {};
+
+ template <std::size_t I>
+ struct void_tuple_element<I, std::tuple<>> { typedef void type; };
+
+ template <std::size_t I, typename T>
+ using void_tuple_element_t = typename void_tuple_element<I, T>::type;
+
+ template <bool has_c_variadic, typename T, typename R, typename... Args>
+ struct basic_traits {
+ private:
+ typedef std::conditional_t<std::is_void<T>::value, int, T>& first_type;
+
+ public:
+ static const bool is_member_function = std::is_void<T>::value;
+ static const bool has_c_var_arg = has_c_variadic;
+ static const std::size_t arity = sizeof...(Args);
+ static const std::size_t free_arity = sizeof...(Args)+static_cast<std::size_t>(!std::is_void<T>::value);
+ typedef types<Args...> args_list;
+ typedef std::tuple<Args...> args_tuple;
+ typedef T object_type;
+ typedef R return_type;
+ typedef tuple_types<R> returns_list;
+ typedef R(function_type)(Args...);
+ typedef std::conditional_t<std::is_void<T>::value, args_list, types<first_type, Args...>> free_args_list;
+ typedef std::conditional_t<std::is_void<T>::value, R(Args...), R(first_type, Args...)> free_function_type;
+ typedef std::conditional_t<std::is_void<T>::value, R(*)(Args...), R(*)(first_type, Args...)> free_function_pointer_type;
+ typedef std::remove_pointer_t<free_function_pointer_type> signature_type;
+ template<std::size_t i>
+ using arg_at = void_tuple_element_t<i, args_tuple>;
+ };
+
+ template<typename Signature, bool b = has_deducible_signature<Signature>::value>
+ struct fx_traits : basic_traits<false, void, void> {};
+
+ // Free Functions
+ template<typename R, typename... Args>
+ struct fx_traits<R(Args...), false> : basic_traits<false, void, R, Args...> {
+ typedef R(*function_pointer_type)(Args...);
+ };
+
+ template<typename R, typename... Args>
+ struct fx_traits<R(*)(Args...), false> : basic_traits<false, void, R, Args...> {
+ typedef R(*function_pointer_type)(Args...);
+ };
+
+ template<typename R, typename... Args>
+ struct fx_traits<R(Args..., ...), false> : basic_traits<true, void, R, Args...> {
+ typedef R(*function_pointer_type)(Args..., ...);
+ };
+
+ template<typename R, typename... Args>
+ struct fx_traits<R(*)(Args..., ...), false> : basic_traits<true, void, R, Args...> {
+ typedef R(*function_pointer_type)(Args..., ...);
+ };
+
+ // Member Functions
+ /* C-Style Variadics */
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...), false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...);
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...), false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...);
+ };
+
+ /* Const Volatile */
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const volatile, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const volatile;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const volatile, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const volatile;
+ };
+
+ /* Member Function Qualifiers */
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) &, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) &, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const &, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const &, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const volatile &, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const volatile &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const volatile &, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const volatile &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) && , false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) && ;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) && , false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) && ;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const &&, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const &&;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const &&, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const &&;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const volatile &&, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const volatile &&;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const volatile &&, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const volatile &&;
+ };
+
+ template<typename Signature>
+ struct fx_traits<Signature, true> : fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> {};
+
+ template<typename Signature, bool b = std::is_member_object_pointer<Signature>::value>
+ struct callable_traits : fx_traits<std::decay_t<Signature>> {
+
+ };
+
+ template<typename R, typename T>
+ struct callable_traits<R(T::*), true> {
+ typedef R Arg;
+ typedef T object_type;
+ using signature_type = R(T::*);
+ static const bool is_member_function = false;
+ static const std::size_t arity = 1;
+ static const std::size_t free_arity = 2;
+ typedef std::tuple<Arg> args_tuple;
+ typedef R return_type;
+ typedef types<Arg> args_list;
+ typedef types<T, Arg> free_args_list;
+ typedef meta::tuple_types<R> returns_list;
+ typedef R(function_type)(T&, R);
+ typedef R(*function_pointer_type)(T&, R);
+ typedef R(*free_function_pointer_type)(T&, R);
+ template<std::size_t i>
+ using arg_at = void_tuple_element_t<i, args_tuple>;
+ };
+ } // meta_detail
+
+ template<typename Signature>
+ struct bind_traits : meta_detail::callable_traits<Signature> {};
+
+ template<typename Signature>
+ using function_args_t = typename bind_traits<Signature>::args_list;
+
+ template<typename Signature>
+ using function_signature_t = typename bind_traits<Signature>::signature_type;
+
+ template<typename Signature>
+ using function_return_t = typename bind_traits<Signature>::return_type;
+
+ } // meta
+} // sol
+
+// end of sol/bind_traits.hpp
+
+#include <type_traits>
+#include <memory>
+#include <functional>
+
+namespace sol {
+ template<std::size_t I>
+ using index_value = std::integral_constant<std::size_t, I>;
+
+ namespace meta {
+ template<typename T>
+ struct identity { typedef T type; };
+
+ template<typename T>
+ using identity_t = typename identity<T>::type;
+
+ template<typename... Args>
+ struct is_tuple : std::false_type { };
+
+ template<typename... Args>
+ struct is_tuple<std::tuple<Args...>> : std::true_type { };
+
+ template<typename T>
+ struct unwrapped {
+ typedef T type;
+ };
+
+ template<typename T>
+ struct unwrapped<std::reference_wrapper<T>> {
+ typedef T type;
+ };
+
+ template<typename T>
+ using unwrapped_t = typename unwrapped<T>::type;
+
+ template <typename T>
+ struct unwrap_unqualified : unwrapped<unqualified_t<T>> {};
+
+ template <typename T>
+ using unwrap_unqualified_t = typename unwrap_unqualified<T>::type;
+
+ template<typename T>
+ struct remove_member_pointer;
+
+ template<typename R, typename T>
+ struct remove_member_pointer<R T::*> {
+ typedef R type;
+ };
+
+ template<typename R, typename T>
+ struct remove_member_pointer<R T::* const> {
+ typedef R type;
+ };
+
+ template<typename T>
+ using remove_member_pointer_t = remove_member_pointer<T>;
+
+ template<template<typename...> class Templ, typename T>
+ struct is_specialization_of : std::false_type { };
+ template<typename... T, template<typename...> class Templ>
+ struct is_specialization_of<Templ, Templ<T...>> : std::true_type { };
+
+ template<class T, class...>
+ struct all_same : std::true_type { };
+
+ template<class T, class U, class... Args>
+ struct all_same<T, U, Args...> : std::integral_constant <bool, std::is_same<T, U>::value && all_same<T, Args...>::value> { };
+
+ template<class T, class...>
+ struct any_same : std::false_type { };
+
+ template<class T, class U, class... Args>
+ struct any_same<T, U, Args...> : std::integral_constant <bool, std::is_same<T, U>::value || any_same<T, Args...>::value> { };
+
+ template<typename T>
+ using invoke_t = typename T::type;
+
+ template<bool B>
+ using boolean = std::integral_constant<bool, B>;
+
+ template<typename T>
+ using neg = boolean<!T::value>;
+
+ template<typename Condition, typename Then, typename Else>
+ using condition = std::conditional_t<Condition::value, Then, Else>;
+
+ template<typename... Args>
+ struct all : boolean<true> {};
+
+ template<typename T, typename... Args>
+ struct all<T, Args...> : condition<T, all<Args...>, boolean<false>> {};
+
+ template<typename... Args>
+ struct any : boolean<false> {};
+
+ template<typename T, typename... Args>
+ struct any<T, Args...> : condition<T, boolean<true>, any<Args...>> {};
+
+ enum class enable_t {
+ _
+ };
+
+ constexpr const auto enabler = enable_t::_;
+
+ template<bool value, typename T = void>
+ using disable_if_t = std::enable_if_t<!value, T>;
+
+ template<typename... Args>
+ using enable = std::enable_if_t<all<Args...>::value, enable_t>;
+
+ template<typename... Args>
+ using disable = std::enable_if_t<neg<all<Args...>>::value, enable_t>;
+
+ template<typename... Args>
+ using disable_any = std::enable_if_t<neg<any<Args...>>::value, enable_t>;
+
+ template<typename V, typename... Vs>
+ struct find_in_pack_v : boolean<false> { };
+
+ template<typename V, typename Vs1, typename... Vs>
+ struct find_in_pack_v<V, Vs1, Vs...> : any<boolean<(V::value == Vs1::value)>, find_in_pack_v<V, Vs...>> { };
+
+ namespace meta_detail {
+ template<std::size_t I, typename T, typename... Args>
+ struct index_in_pack : std::integral_constant<std::size_t, SIZE_MAX> { };
+
+ template<std::size_t I, typename T, typename T1, typename... Args>
+ struct index_in_pack<I, T, T1, Args...> : std::conditional_t<std::is_same<T, T1>::value, std::integral_constant<std::ptrdiff_t, I>, index_in_pack<I + 1, T, Args...>> { };
+ }
+
+ template<typename T, typename... Args>
+ struct index_in_pack : meta_detail::index_in_pack<0, T, Args...> { };
+
+ template<typename T, typename List>
+ struct index_in : meta_detail::index_in_pack<0, T, List> { };
+
+ template<typename T, typename... Args>
+ struct index_in<T, types<Args...>> : meta_detail::index_in_pack<0, T, Args...> { };
+
+ template<std::size_t I, typename... Args>
+ struct at_in_pack {};
+
+ template<std::size_t I, typename... Args>
+ using at_in_pack_t = typename at_in_pack<I, Args...>::type;
+
+ template<std::size_t I, typename Arg, typename... Args>
+ struct at_in_pack<I, Arg, Args...> : std::conditional<I == 0, Arg, at_in_pack_t<I - 1, Args...>> {};
+
+ template<typename Arg, typename... Args>
+ struct at_in_pack<0, Arg, Args...> { typedef Arg type; };
+
+ namespace meta_detail {
+ template<std::size_t Limit, std::size_t I, template<typename...> class Pred, typename... Ts>
+ struct count_for_pack : std::integral_constant<std::size_t, 0> {};
+ template<std::size_t Limit, std::size_t I, template<typename...> class Pred, typename T, typename... Ts>
+ struct count_for_pack<Limit, I, Pred, T, Ts...> : std::conditional_t < sizeof...(Ts) == 0 || Limit < 2,
+ std::integral_constant<std::size_t, I + static_cast<std::size_t>(Limit != 0 && Pred<T>::value)>,
+ count_for_pack<Limit - 1, I + static_cast<std::size_t>(Pred<T>::value), Pred, Ts...>
+ > { };
+ template<std::size_t I, template<typename...> class Pred, typename... Ts>
+ struct count_2_for_pack : std::integral_constant<std::size_t, 0> {};
+ template<std::size_t I, template<typename...> class Pred, typename T, typename U, typename... Ts>
+ struct count_2_for_pack<I, Pred, T, U, Ts...> : std::conditional_t<sizeof...(Ts) == 0,
+ std::integral_constant<std::size_t, I + static_cast<std::size_t>(Pred<T>::value)>,
+ count_2_for_pack<I + static_cast<std::size_t>(Pred<T>::value), Pred, Ts...>
+ > { };
+ } // meta_detail
+
+ template<template<typename...> class Pred, typename... Ts>
+ struct count_for_pack : meta_detail::count_for_pack<sizeof...(Ts), 0, Pred, Ts...> { };
+
+ template<template<typename...> class Pred, typename List>
+ struct count_for;
+
+ template<template<typename...> class Pred, typename... Args>
+ struct count_for<Pred, types<Args...>> : count_for_pack<Pred, Args...> {};
+
+ template<std::size_t Limit, template<typename...> class Pred, typename... Ts>
+ struct count_for_to_pack : meta_detail::count_for_pack<Limit, 0, Pred, Ts...> { };
+
+ template<template<typename...> class Pred, typename... Ts>
+ struct count_2_for_pack : meta_detail::count_2_for_pack<0, Pred, Ts...> { };
+
+ template<typename... Args>
+ struct return_type {
+ typedef std::tuple<Args...> type;
+ };
+
+ template<typename T>
+ struct return_type<T> {
+ typedef T type;
+ };
+
+ template<>
+ struct return_type<> {
+ typedef void type;
+ };
+
+ template <typename... Args>
+ using return_type_t = typename return_type<Args...>::type;
+
+ namespace meta_detail {
+ template <typename> struct always_true : std::true_type {};
+ struct is_invokable_tester {
+ template <typename Fun, typename... Args>
+ always_true<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
+ template <typename...>
+ std::false_type static test(...);
+ };
+ } // meta_detail
+
+ template <typename T>
+ struct is_invokable;
+ template <typename Fun, typename... Args>
+ struct is_invokable<Fun(Args...)> : decltype(meta_detail::is_invokable_tester::test<Fun, Args...>(0)) {};
+
+ namespace meta_detail {
+
+ template<typename T, bool isclass = std::is_class<unqualified_t<T>>::value>
+ struct is_callable : std::is_function<std::remove_pointer_t<T>> {};
+
+ template<typename T>
+ struct is_callable<T, true> {
+ using yes = char;
+ using no = struct { char s[2]; };
+
+ struct F { void operator()(); };
+ struct Derived : T, F {};
+ template<typename U, U> struct Check;
+
+ template<typename V>
+ static no test(Check<void (F::*)(), &V::operator()>*);
+
+ template<typename>
+ static yes test(...);
+
+ static const bool value = sizeof(test<Derived>(0)) == sizeof(yes);
+ };
+
+ struct has_begin_end_impl {
+ template<typename T, typename U = unqualified_t<T>,
+ typename B = decltype(std::declval<U&>().begin()),
+ typename E = decltype(std::declval<U&>().end())>
+ static std::true_type test(int);
+
+ template<typename...>
+ static std::false_type test(...);
+ };
+
+ struct has_key_value_pair_impl {
+ template<typename T, typename U = unqualified_t<T>,
+ typename V = typename U::value_type,
+ typename F = decltype(std::declval<V&>().first),
+ typename S = decltype(std::declval<V&>().second)>
+ static std::true_type test(int);
+
+ template<typename...>
+ static std::false_type test(...);
+ };
+
+ template <typename T, typename U = T, typename = decltype(std::declval<T&>() < std::declval<U&>())>
+ std::true_type supports_op_less_test(const T&);
+ std::false_type supports_op_less_test(...);
+ template <typename T, typename U = T, typename = decltype(std::declval<T&>() == std::declval<U&>())>
+ std::true_type supports_op_equal_test(const T&);
+ std::false_type supports_op_equal_test(...);
+ template <typename T, typename U = T, typename = decltype(std::declval<T&>() <= std::declval<U&>())>
+ std::true_type supports_op_less_equal_test(const T&);
+ std::false_type supports_op_less_equal_test(...);
+
+ } // meta_detail
+
+ template <typename T>
+ using supports_op_less = decltype(meta_detail::supports_op_less_test(std::declval<T&>()));
+ template <typename T>
+ using supports_op_equal = decltype(meta_detail::supports_op_equal_test(std::declval<T&>()));
+ template <typename T>
+ using supports_op_less_equal = decltype(meta_detail::supports_op_less_equal_test(std::declval<T&>()));
+
+ template<typename T>
+ struct is_callable : boolean<meta_detail::is_callable<T>::value> {};
+
+ template<typename T>
+ struct has_begin_end : decltype(meta_detail::has_begin_end_impl::test<T>(0)) {};
+
+ template<typename T>
+ struct has_key_value_pair : decltype(meta_detail::has_key_value_pair_impl::test<T>(0)) {};
+
+ template <typename T>
+ using is_string_constructible = any<std::is_same<unqualified_t<T>, const char*>, std::is_same<unqualified_t<T>, char>, std::is_same<unqualified_t<T>, std::string>, std::is_same<unqualified_t<T>, std::initializer_list<char>>>;
+
+ template <typename T>
+ using is_c_str = any<
+ std::is_same<std::decay_t<unqualified_t<T>>, const char*>,
+ std::is_same<std::decay_t<unqualified_t<T>>, char*>,
+ std::is_same<unqualified_t<T>, std::string>
+ >;
+
+ template <typename T>
+ struct is_move_only : all<
+ neg<std::is_reference<T>>,
+ neg<std::is_copy_constructible<unqualified_t<T>>>,
+ std::is_move_constructible<unqualified_t<T>>
+ > {};
+
+ template <typename T>
+ using is_not_move_only = neg<is_move_only<T>>;
+
+ namespace meta_detail {
+ template <typename T, meta::disable<meta::is_specialization_of<std::tuple, meta::unqualified_t<T>>> = meta::enabler>
+ decltype(auto) force_tuple(T&& x) {
+ return std::forward_as_tuple(std::forward<T>(x));
+ }
+
+ template <typename T, meta::enable<meta::is_specialization_of<std::tuple, meta::unqualified_t<T>>> = meta::enabler>
+ decltype(auto) force_tuple(T&& x) {
+ return std::forward<T>(x);
+ }
+ } // meta_detail
+
+ template <typename... X>
+ decltype(auto) tuplefy(X&&... x) {
+ return std::tuple_cat(meta_detail::force_tuple(std::forward<X>(x))...);
+ }
+ } // meta
+ namespace detail {
+ template <std::size_t I, typename Tuple>
+ decltype(auto) forward_get(Tuple&& tuple) {
+ return std::forward<meta::tuple_element_t<I, Tuple>>(std::get<I>(tuple));
+ }
+
+ template <std::size_t... I, typename Tuple>
+ auto forward_tuple_impl(std::index_sequence<I...>, Tuple&& tuple) -> decltype(std::tuple<decltype(forward_get<I>(tuple))...>(forward_get<I>(tuple)...)) {
+ return std::tuple<decltype(forward_get<I>(tuple))...>(std::move(std::get<I>(tuple))...);
+ }
+
+ template <typename Tuple>
+ auto forward_tuple(Tuple&& tuple) {
+ auto x = forward_tuple_impl(std::make_index_sequence<std::tuple_size<meta::unqualified_t<Tuple>>::value>(), std::forward<Tuple>(tuple));
+ return x;
+ }
+
+ template<typename T>
+ auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
+ return std::forward<T>(item);
+ }
+
+ template<typename T>
+ T& unwrap(std::reference_wrapper<T> arg) {
+ return arg.get();
+ }
+
+ template<typename T>
+ auto deref(T&& item) -> decltype(std::forward<T>(item)) {
+ return std::forward<T>(item);
+ }
+
+ template<typename T>
+ inline T& deref(T* item) {
+ return *item;
+ }
+
+ template<typename T, typename Dx>
+ inline std::add_lvalue_reference_t<T> deref(std::unique_ptr<T, Dx>& item) {
+ return *item;
+ }
+
+ template<typename T>
+ inline std::add_lvalue_reference_t<T> deref(std::shared_ptr<T>& item) {
+ return *item;
+ }
+
+ template<typename T, typename Dx>
+ inline std::add_lvalue_reference_t<T> deref(const std::unique_ptr<T, Dx>& item) {
+ return *item;
+ }
+
+ template<typename T>
+ inline std::add_lvalue_reference_t<T> deref(const std::shared_ptr<T>& item) {
+ return *item;
+ }
+
+ template<typename T>
+ inline T* ptr(T& val) {
+ return std::addressof(val);
+ }
+
+ template<typename T>
+ inline T* ptr(std::reference_wrapper<T> val) {
+ return std::addressof(val.get());
+ }
+
+ template<typename T>
+ inline T* ptr(T* val) {
+ return val;
+ }
+ } // detail
+} // sol
+
+// end of sol/traits.hpp
+
+// beginning of sol/object.hpp
+
+// beginning of sol/optional.hpp
+
+// beginning of sol/in_place.hpp
+
+namespace sol {
+
+ namespace detail {
+ struct in_place_of {};
+ template <std::size_t I>
+ struct in_place_of_i {};
+ template <typename T>
+ struct in_place_of_t {};
+ } // detail
+
+ struct in_place_tag { struct init {}; constexpr in_place_tag(init) {} in_place_tag() = delete; };
+ constexpr inline in_place_tag in_place(detail::in_place_of) { return in_place_tag(in_place_tag::init()); }
+ template <typename T>
+ constexpr inline in_place_tag in_place(detail::in_place_of_t<T>) { return in_place_tag(in_place_tag::init()); }
+ template <std::size_t I>
+ constexpr inline in_place_tag in_place(detail::in_place_of_i<I>) { return in_place_tag(in_place_tag::init()); }
+
+ using in_place_t = in_place_tag(&)(detail::in_place_of);
+ template <typename T>
+ using in_place_type_t = in_place_tag(&)(detail::in_place_of_t<T>);
+ template <std::size_t I>
+ using in_place_index_t = in_place_tag(&)(detail::in_place_of_i<I>);
+
+} // sol
+
+// end of sol/in_place.hpp
+
+#if defined(SOL_USE_BOOST)
+#include <boost/optional.hpp>
+#else
+// beginning of Optional/optional.hpp
+
+# ifndef ___SOL_OPTIONAL_HPP___
+# define ___SOL_OPTIONAL_HPP___
+
+# include <utility>
+# include <type_traits>
+# include <initializer_list>
+# include <cassert>
+# include <functional>
+# include <string>
+# include <stdexcept>
+
+# define TR2_OPTIONAL_REQUIRES(...) typename ::std::enable_if<__VA_ARGS__::value, bool>::type = false
+
+# if defined __GNUC__ // NOTE: GNUC is also defined for Clang
+# if (__GNUC__ >= 5)
+# define TR2_OPTIONAL_GCC_5_0_AND_HIGHER___
+# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)
+# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+# elif (__GNUC__ > 4)
+# define TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+# endif
+#
+# if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)
+# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
+# elif (__GNUC__ > 4)
+# define TR2_OPTIONAL_GCC_4_7_AND_HIGHER___
+# endif
+#
+# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 8) && (__GNUC_PATCHLEVEL__ >= 1)
+# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# elif (__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)
+# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# elif (__GNUC__ > 4)
+# define TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# endif
+# endif
+#
+# if defined __clang_major__
+# if (__clang_major__ == 3 && __clang_minor__ >= 5)
+# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
+# elif (__clang_major__ > 3)
+# define TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
+# endif
+# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_
+# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+# elif (__clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ >= 2)
+# define TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+# endif
+# endif
+#
+# if defined _MSC_VER
+# if (_MSC_VER >= 1900)
+# define TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+# endif
+# endif
+
+# if defined __clang__
+# if (__clang_major__ > 2) || (__clang_major__ == 2) && (__clang_minor__ >= 9)
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
+# else
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
+# endif
+# elif defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
+# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 1
+# else
+# define OPTIONAL_HAS_THIS_RVALUE_REFS 0
+# endif
+
+# if defined TR2_OPTIONAL_GCC_4_8_1_AND_HIGHER___
+# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 1
+# define OPTIONAL_CONSTEXPR_INIT_LIST constexpr
+# else
+# define OPTIONAL_HAS_CONSTEXPR_INIT_LIST 0
+# define OPTIONAL_CONSTEXPR_INIT_LIST
+# endif
+
+# if defined TR2_OPTIONAL_CLANG_3_5_AND_HIGHTER_ && (defined __cplusplus) && (__cplusplus != 201103L)
+# define OPTIONAL_HAS_MOVE_ACCESSORS 1
+# else
+# define OPTIONAL_HAS_MOVE_ACCESSORS 0
+# endif
+
+# // In C++11 constexpr implies const, so we need to make non-const members also non-constexpr
+# if (defined __cplusplus) && (__cplusplus == 201103L)
+# define OPTIONAL_MUTABLE_CONSTEXPR
+# else
+# define OPTIONAL_MUTABLE_CONSTEXPR constexpr
+# endif
+
+namespace sol{
+
+# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
+ // leave it: the user doesn't want it
+# else
+ template <typename T>
+ using is_trivially_destructible = ::std::has_trivial_destructor<T>;
+# endif
+
+# if (defined TR2_OPTIONAL_GCC_4_7_AND_HIGHER___)
+ // leave it; our metafunctions are already defined.
+# elif defined TR2_OPTIONAL_CLANG_3_4_2_AND_HIGHER_
+ // leave it; our metafunctions are already defined.
+# elif defined TR2_OPTIONAL_MSVC_2015_AND_HIGHER___
+ // leave it: it is already there
+# elif defined TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
+ // leave it: the user doesn't want it
+# else
+
+template <class T>
+struct is_nothrow_move_constructible
+{
+ constexpr static bool value = ::std::is_nothrow_constructible<T, T&&>::value;
+};
+
+template <class T, class U>
+struct is_assignable
+{
+ template <class X, class Y>
+ constexpr static bool has_assign(...) { return false; }
+
+ template <class X, class Y, size_t S = sizeof((::std::declval<X>() = ::std::declval<Y>(), true)) >
+ // the comma operator is necessary for the cases where operator= returns void
+ constexpr static bool has_assign(bool) { return true; }
+
+ constexpr static bool value = has_assign<T, U>(true);
+};
+
+template <class T>
+struct is_nothrow_move_assignable
+{
+ template <class X, bool has_any_move_assign>
+ struct has_nothrow_move_assign {
+ constexpr static bool value = false;
+ };
+
+ template <class X>
+ struct has_nothrow_move_assign<X, true> {
+ constexpr static bool value = noexcept( ::std::declval<X&>() = ::std::declval<X&&>() );
+ };
+
+ constexpr static bool value = has_nothrow_move_assign<T, is_assignable<T&, T&&>::value>::value;
+};
+
+# endif
+
+template <class T> class optional;
+
+template <class T> class optional<T&>;
+
+template <class T> inline constexpr T&& constexpr_forward(typename ::std::remove_reference<T>::type& t) noexcept
+{
+ return static_cast<T&&>(t);
+}
+
+template <class T> inline constexpr T&& constexpr_forward(typename ::std::remove_reference<T>::type&& t) noexcept
+{
+ static_assert(!::std::is_lvalue_reference<T>::value, "!!");
+ return static_cast<T&&>(t);
+}
+
+template <class T> inline constexpr typename ::std::remove_reference<T>::type&& constexpr_move(T&& t) noexcept
+{
+ return static_cast<typename ::std::remove_reference<T>::type&&>(t);
+}
+
+#if defined NDEBUG
+# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) (EXPR)
+#else
+# define TR2_OPTIONAL_ASSERTED_EXPRESSION(CHECK, EXPR) ((CHECK) ? (EXPR) : ([]{assert(!#CHECK);}(), (EXPR)))
+#endif
+
+namespace detail_
+{
+
+template <typename T>
+struct has_overloaded_addressof
+{
+ template <class X>
+ constexpr static bool has_overload(...) { return false; }
+
+ template <class X, size_t S = sizeof(::std::declval<X&>().operator&()) >
+ constexpr static bool has_overload(bool) { return true; }
+
+ constexpr static bool value = has_overload<T>(true);
+};
+
+template <typename T, TR2_OPTIONAL_REQUIRES(!has_overloaded_addressof<T>)>
+constexpr T* static_addressof(T& ref)
+{
+ return &ref;
+}
+
+template <typename T, TR2_OPTIONAL_REQUIRES(has_overloaded_addressof<T>)>
+T* static_addressof(T& ref)
+{
+ return ::std::addressof(ref);
+}
+
+template <class U>
+constexpr U convert(U v) { return v; }
+
+} // namespace detail_
+
+constexpr struct trivial_init_t {} trivial_init{};
+
+struct nullopt_t
+{
+ struct init{};
+ constexpr explicit nullopt_t(init){}
+};
+constexpr nullopt_t nullopt{nullopt_t::init()};
+
+class bad_optional_access : public ::std::logic_error {
+public:
+ explicit bad_optional_access(const ::std::string& what_arg) : ::std::logic_error{what_arg} {}
+ explicit bad_optional_access(const char* what_arg) : ::std::logic_error{what_arg} {}
+};
+
+template <class T>
+struct optional_base
+{
+ bool init_;
+ char storage_[sizeof(T)];
+
+ constexpr optional_base() noexcept : init_(false), storage_() {};
+
+ explicit optional_base(const T& v) : init_(true), storage_() {
+ new (&storage())T(v);
+ }
+
+ explicit optional_base(T&& v) : init_(true), storage_() {
+ new (&storage())T(constexpr_move(v));
+ }
+
+ template <class... Args> explicit optional_base(in_place_t, Args&&... args)
+ : init_(true), storage_() {
+ new (&storage())T(constexpr_forward<Args>(args)...);
+ }
+
+ template <class U, class... Args, TR2_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
+ explicit optional_base(in_place_t, ::std::initializer_list<U> il, Args&&... args)
+ : init_(true), storage_() {
+ new (&storage())T(il, constexpr_forward<Args>(args)...);
+ }
+#if defined __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif
+ T& storage() {
+ return *reinterpret_cast<T*>(&storage_[0]);
+ }
+
+ constexpr const T& storage() const {
+ return *reinterpret_cast<T const*>(&storage_[0]);
+ }
+#if defined __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+ ~optional_base() { if (init_) { storage().T::~T(); } }
+};
+
+#if defined __GNUC__ && !defined TR2_OPTIONAL_GCC_5_0_AND_HIGHER___
+template <typename T>
+using constexpr_optional_base = optional_base<T>;
+#else
+template <class T>
+struct constexpr_optional_base
+{
+ bool init_;
+ char storage_[sizeof(T)];
+ constexpr constexpr_optional_base() noexcept : init_(false), storage_() {}
+
+ explicit constexpr constexpr_optional_base(const T& v) : init_(true), storage_() {
+ new (&storage())T(v);
+ }
+
+ explicit constexpr constexpr_optional_base(T&& v) : init_(true), storage_() {
+ new (&storage())T(constexpr_move(v));
+ }
+
+ template <class... Args> explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
+ : init_(true), storage_() {
+ new (&storage())T(constexpr_forward<Args>(args)...);
+ }
+
+ template <class U, class... Args, TR2_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
+ OPTIONAL_CONSTEXPR_INIT_LIST explicit constexpr_optional_base(in_place_t, ::std::initializer_list<U> il, Args&&... args)
+ : init_(true), storage_() {
+ new (&storage())T(il, constexpr_forward<Args>(args)...);
+ }
+
+#if defined __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif
+ T& storage() {
+ return (*reinterpret_cast<T*>(&storage_[0]));
+ }
+
+ constexpr const T& storage() const {
+ return (*reinterpret_cast<T const*>(&storage_[0]));
+ }
+#if defined __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+ ~constexpr_optional_base() = default;
+};
+#endif
+
+template <class T>
+using OptionalBase = typename ::std::conditional<
+ ::std::is_trivially_destructible<T>::value,
+ constexpr_optional_base<typename ::std::remove_const<T>::type>,
+ optional_base<typename ::std::remove_const<T>::type>
+>::type;
+
+template <class T>
+class optional : private OptionalBase<T>
+{
+ static_assert( !::std::is_same<typename ::std::decay<T>::type, nullopt_t>::value, "bad T" );
+ static_assert( !::std::is_same<typename ::std::decay<T>::type, in_place_t>::value, "bad T" );
+
+ constexpr bool initialized() const noexcept { return OptionalBase<T>::init_; }
+ typename ::std::remove_const<T>::type* dataptr() { return ::std::addressof(OptionalBase<T>::storage()); }
+ constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage()); }
+
+# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
+ constexpr const T& contained_val() const& { return OptionalBase<T>::storage(); }
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+ OPTIONAL_MUTABLE_CONSTEXPR T&& contained_val() && { return ::std::move(OptionalBase<T>::storage()); }
+ OPTIONAL_MUTABLE_CONSTEXPR T& contained_val() & { return OptionalBase<T>::storage(); }
+# else
+ T& contained_val() & { return OptionalBase<T>::storage(); }
+ T&& contained_val() && { return ::std::move(OptionalBase<T>::storage()); }
+# endif
+# else
+ constexpr const T& contained_val() const { return OptionalBase<T>::storage(); }
+ T& contained_val() { return OptionalBase<T>::storage(); }
+# endif
+
+ void clear() noexcept {
+ if (initialized()) dataptr()->T::~T();
+ OptionalBase<T>::init_ = false;
+ }
+
+ template <class... Args>
+ void initialize(Args&&... args) noexcept(noexcept(T(::std::forward<Args>(args)...)))
+ {
+ assert(!OptionalBase<T>::init_);
+ ::new (static_cast<void*>(dataptr())) T(::std::forward<Args>(args)...);
+ OptionalBase<T>::init_ = true;
+ }
+
+ template <class U, class... Args>
+ void initialize(::std::initializer_list<U> il, Args&&... args) noexcept(noexcept(T(il, ::std::forward<Args>(args)...)))
+ {
+ assert(!OptionalBase<T>::init_);
+ ::new (static_cast<void*>(dataptr())) T(il, ::std::forward<Args>(args)...);
+ OptionalBase<T>::init_ = true;
+ }
+
+public:
+ typedef T value_type;
+
+ // 20.5.5.1, constructors
+ constexpr optional() noexcept : OptionalBase<T>() {};
+ constexpr optional(nullopt_t) noexcept : OptionalBase<T>() {};
+
+ optional(const optional& rhs)
+ : OptionalBase<T>()
+ {
+ if (rhs.initialized()) {
+ ::new (static_cast<void*>(dataptr())) T(*rhs);
+ OptionalBase<T>::init_ = true;
+ }
+ }
+
+ optional(const optional<T&>& rhs) : optional()
+ {
+ if (rhs) {
+ ::new (static_cast<void*>(dataptr())) T(*rhs);
+ OptionalBase<T>::init_ = true;
+ }
+ }
+
+ optional(optional&& rhs) noexcept(::std::is_nothrow_move_constructible<T>::value)
+ : OptionalBase<T>()
+ {
+ if (rhs.initialized()) {
+ ::new (static_cast<void*>(dataptr())) T(::std::move(*rhs));
+ OptionalBase<T>::init_ = true;
+ }
+ }
+
+ constexpr optional(const T& v) : OptionalBase<T>(v) {}
+
+ constexpr optional(T&& v) : OptionalBase<T>(constexpr_move(v)) {}
+
+ template <class... Args>
+ explicit constexpr optional(in_place_t, Args&&... args)
+ : OptionalBase<T>(in_place, constexpr_forward<Args>(args)...) {}
+
+ template <class U, class... Args, TR2_OPTIONAL_REQUIRES(::std::is_constructible<T, ::std::initializer_list<U>>)>
+ OPTIONAL_CONSTEXPR_INIT_LIST explicit optional(in_place_t, ::std::initializer_list<U> il, Args&&... args)
+ : OptionalBase<T>(in_place, il, constexpr_forward<Args>(args)...) {}
+
+ // 20.5.4.2, Destructor
+ ~optional() = default;
+
+ // 20.5.4.3, assignment
+ optional& operator=(nullopt_t) noexcept
+ {
+ clear();
+ return *this;
+ }
+
+ optional& operator=(const optional& rhs)
+ {
+ if (initialized() == true && rhs.initialized() == false) clear();
+ else if (initialized() == false && rhs.initialized() == true) initialize(*rhs);
+ else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs;
+ return *this;
+ }
+
+ optional& operator=(optional&& rhs)
+ noexcept(::std::is_nothrow_move_assignable<T>::value && ::std::is_nothrow_move_constructible<T>::value)
+ {
+ if (initialized() == true && rhs.initialized() == false) clear();
+ else if (initialized() == false && rhs.initialized() == true) initialize(::std::move(*rhs));
+ else if (initialized() == true && rhs.initialized() == true) contained_val() = ::std::move(*rhs);
+ return *this;
+ }
+
+ template <class U>
+ auto operator=(U&& v)
+ -> typename ::std::enable_if
+ <
+ ::std::is_same<typename ::std::decay<U>::type, T>::value,
+ optional&
+ >::type
+ {
+ if (initialized()) { contained_val() = ::std::forward<U>(v); }
+ else { initialize(::std::forward<U>(v)); }
+ return *this;
+ }
+
+ template <class... Args>
+ void emplace(Args&&... args)
+ {
+ clear();
+ initialize(::std::forward<Args>(args)...);
+ }
+
+ template <class U, class... Args>
+ void emplace(::std::initializer_list<U> il, Args&&... args)
+ {
+ clear();
+ initialize<U, Args...>(il, ::std::forward<Args>(args)...);
+ }
+
+ // 20.5.4.4, Swap
+ void swap(optional<T>& rhs) noexcept(::std::is_nothrow_move_constructible<T>::value && noexcept(swap(::std::declval<T&>(), ::std::declval<T&>())))
+ {
+ if (initialized() == true && rhs.initialized() == false) { rhs.initialize(::std::move(**this)); clear(); }
+ else if (initialized() == false && rhs.initialized() == true) { initialize(::std::move(*rhs)); rhs.clear(); }
+ else if (initialized() == true && rhs.initialized() == true) { using ::std::swap; swap(**this, *rhs); }
+ }
+
+ // 20.5.4.5, Observers
+
+ explicit constexpr operator bool() const noexcept { return initialized(); }
+
+ constexpr T const* operator ->() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr());
+ }
+
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+
+ OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
+ assert (initialized());
+ return dataptr();
+ }
+
+ constexpr T const& operator *() const& {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
+ assert (initialized());
+ return contained_val();
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
+ assert (initialized());
+ return constexpr_move(contained_val());
+ }
+
+ constexpr T const& value() const& {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+ OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
+ if (!initialized()) throw bad_optional_access("bad optional access");
+ return ::std::move(contained_val());
+ }
+
+# else
+
+ T* operator ->() {
+ assert (initialized());
+ return dataptr();
+ }
+
+ constexpr T const& operator *() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
+ }
+
+ T& operator *() {
+ assert (initialized());
+ return contained_val();
+ }
+
+ constexpr T const& value() const {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+ T& value() {
+ return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
+ }
+
+# endif
+
+# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
+
+ template <class V>
+ constexpr T value_or(V&& v) const&
+ {
+ return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
+
+ template <class V>
+ OPTIONAL_MUTABLE_CONSTEXPR T value_or(V&& v) &&
+ {
+ return *this ? constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# else
+
+ template <class V>
+ T value_or(V&& v) &&
+ {
+ return *this ? constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# endif
+
+# else
+
+ template <class V>
+ constexpr T value_or(V&& v) const
+ {
+ return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
+ }
+
+# endif
+
+};
+
+template <class T>
+class optional<T&>
+{
+ static_assert( !::std::is_same<T, nullopt_t>::value, "bad T" );
+ static_assert( !::std::is_same<T, in_place_t>::value, "bad T" );
+ T* ref;
+
+public:
+
+ // 20.5.5.1, construction/destruction
+ constexpr optional() noexcept : ref(nullptr) {}
+
+ constexpr optional(nullopt_t) noexcept : ref(nullptr) {}
+
+ constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {}
+
+ optional(T&&) = delete;
+
+ constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {}
+
+ explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {}
+
+ explicit optional(in_place_t, T&&) = delete;
+
+ ~optional() = default;
+
+ // 20.5.5.2, mutation
+ optional& operator=(nullopt_t) noexcept {
+ ref = nullptr;
+ return *this;
+ }
+
+ // optional& operator=(const optional& rhs) noexcept {
+ // ref = rhs.ref;
+ // return *this;
+ // }
+
+ // optional& operator=(optional&& rhs) noexcept {
+ // ref = rhs.ref;
+ // return *this;
+ // }
+
+ template <typename U>
+ auto operator=(U&& rhs) noexcept
+ -> typename ::std::enable_if
+ <
+ ::std::is_same<typename ::std::decay<U>::type, optional<T&>>::value,
+ optional&
+ >::type
+ {
+ ref = rhs.ref;
+ return *this;
+ }
+
+ template <typename U>
+ auto operator=(U&& rhs) noexcept
+ -> typename ::std::enable_if
+ <
+ !::std::is_same<typename ::std::decay<U>::type, optional<T&>>::value,
+ optional&
+ >::type
+ = delete;
+
+ void emplace(T& v) noexcept {
+ ref = detail_::static_addressof(v);
+ }
+
+ void emplace(T&&) = delete;
+
+ void swap(optional<T&>& rhs) noexcept
+ {
+ ::std::swap(ref, rhs.ref);
+ }
+
+ // 20.5.5.3, observers
+ constexpr T* operator->() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
+ }
+
+ constexpr T& operator*() const {
+ return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
+ }
+
+ constexpr T& value() const {
+ return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
+ }
+
+ explicit constexpr operator bool() const noexcept {
+ return ref != nullptr;
+ }
+
+ template <typename V>
+ constexpr T& value_or(V&& v) const
+ {
+ return *this ? **this : detail_::convert<T&>(constexpr_forward<V>(v));
+ }
+};
+
+template <class T>
+class optional<T&&>
+{
+ static_assert( sizeof(T) == 0, "optional rvalue references disallowed" );
+};
+
+template <class T> constexpr bool operator==(const optional<T>& x, const optional<T>& y)
+{
+ return bool(x) != bool(y) ? false : bool(x) == false ? true : *x == *y;
+}
+
+template <class T> constexpr bool operator!=(const optional<T>& x, const optional<T>& y)
+{
+ return !(x == y);
+}
+
+template <class T> constexpr bool operator<(const optional<T>& x, const optional<T>& y)
+{
+ return (!y) ? false : (!x) ? true : *x < *y;
+}
+
+template <class T> constexpr bool operator>(const optional<T>& x, const optional<T>& y)
+{
+ return (y < x);
+}
+
+template <class T> constexpr bool operator<=(const optional<T>& x, const optional<T>& y)
+{
+ return !(y < x);
+}
+
+template <class T> constexpr bool operator>=(const optional<T>& x, const optional<T>& y)
+{
+ return !(x < y);
+}
+
+template <class T> constexpr bool operator==(const optional<T>& x, nullopt_t) noexcept
+{
+ return (!x);
+}
+
+template <class T> constexpr bool operator==(nullopt_t, const optional<T>& x) noexcept
+{
+ return (!x);
+}
+
+template <class T> constexpr bool operator!=(const optional<T>& x, nullopt_t) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator!=(nullopt_t, const optional<T>& x) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept
+{
+ return false;
+}
+
+template <class T> constexpr bool operator<(nullopt_t, const optional<T>& x) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator<=(const optional<T>& x, nullopt_t) noexcept
+{
+ return (!x);
+}
+
+template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept
+{
+ return true;
+}
+
+template <class T> constexpr bool operator>(const optional<T>& x, nullopt_t) noexcept
+{
+ return bool(x);
+}
+
+template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept
+{
+ return false;
+}
+
+template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept
+{
+ return true;
+}
+
+template <class T> constexpr bool operator>=(nullopt_t, const optional<T>& x) noexcept
+{
+ return (!x);
+}
+
+template <class T> constexpr bool operator==(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x == v : false;
+}
+
+template <class T> constexpr bool operator==(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v == *x : false;
+}
+
+template <class T> constexpr bool operator!=(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x != v : true;
+}
+
+template <class T> constexpr bool operator!=(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v != *x : true;
+}
+
+template <class T> constexpr bool operator<(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x < v : true;
+}
+
+template <class T> constexpr bool operator>(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v > *x : true;
+}
+
+template <class T> constexpr bool operator>(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x > v : false;
+}
+
+template <class T> constexpr bool operator<(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v < *x : false;
+}
+
+template <class T> constexpr bool operator>=(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x >= v : false;
+}
+
+template <class T> constexpr bool operator<=(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v <= *x : false;
+}
+
+template <class T> constexpr bool operator<=(const optional<T>& x, const T& v)
+{
+ return bool(x) ? *x <= v : true;
+}
+
+template <class T> constexpr bool operator>=(const T& v, const optional<T>& x)
+{
+ return bool(x) ? v >= *x : true;
+}
+
+template <class T> constexpr bool operator==(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x == v : false;
+}
+
+template <class T> constexpr bool operator==(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v == *x : false;
+}
+
+template <class T> constexpr bool operator!=(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x != v : true;
+}
+
+template <class T> constexpr bool operator!=(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v != *x : true;
+}
+
+template <class T> constexpr bool operator<(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x < v : true;
+}
+
+template <class T> constexpr bool operator>(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v > *x : true;
+}
+
+template <class T> constexpr bool operator>(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x > v : false;
+}
+
+template <class T> constexpr bool operator<(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v < *x : false;
+}
+
+template <class T> constexpr bool operator>=(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x >= v : false;
+}
+
+template <class T> constexpr bool operator<=(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v <= *x : false;
+}
+
+template <class T> constexpr bool operator<=(const optional<T&>& x, const T& v)
+{
+ return bool(x) ? *x <= v : true;
+}
+
+template <class T> constexpr bool operator>=(const T& v, const optional<T&>& x)
+{
+ return bool(x) ? v >= *x : true;
+}
+
+template <class T> constexpr bool operator==(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x == v : false;
+}
+
+template <class T> constexpr bool operator==(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v == *x : false;
+}
+
+template <class T> constexpr bool operator!=(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x != v : true;
+}
+
+template <class T> constexpr bool operator!=(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v != *x : true;
+}
+
+template <class T> constexpr bool operator<(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x < v : true;
+}
+
+template <class T> constexpr bool operator>(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v > *x : true;
+}
+
+template <class T> constexpr bool operator>(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x > v : false;
+}
+
+template <class T> constexpr bool operator<(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v < *x : false;
+}
+
+template <class T> constexpr bool operator>=(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x >= v : false;
+}
+
+template <class T> constexpr bool operator<=(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v <= *x : false;
+}
+
+template <class T> constexpr bool operator<=(const optional<const T&>& x, const T& v)
+{
+ return bool(x) ? *x <= v : true;
+}
+
+template <class T> constexpr bool operator>=(const T& v, const optional<const T&>& x)
+{
+ return bool(x) ? v >= *x : true;
+}
+
+template <class T>
+void swap(optional<T>& x, optional<T>& y) noexcept(noexcept(x.swap(y)))
+{
+ x.swap(y);
+}
+
+template <class T>
+constexpr optional<typename ::std::decay<T>::type> make_optional(T&& v)
+{
+ return optional<typename ::std::decay<T>::type>(constexpr_forward<T>(v));
+}
+
+template <class X>
+constexpr optional<X&> make_optional(::std::reference_wrapper<X> v)
+{
+ return optional<X&>(v.get());
+}
+
+} // namespace
+
+namespace std
+{
+ template <typename T>
+ struct hash<sol::optional<T>>
+ {
+ typedef typename hash<T>::result_type result_type;
+ typedef sol::optional<T> argument_type;
+
+ constexpr result_type operator()(argument_type const& arg) const {
+ return arg ? ::std::hash<T>{}(*arg) : result_type{};
+ }
+ };
+
+ template <typename T>
+ struct hash<sol::optional<T&>>
+ {
+ typedef typename hash<T>::result_type result_type;
+ typedef sol::optional<T&> argument_type;
+
+ constexpr result_type operator()(argument_type const& arg) const {
+ return arg ? ::std::hash<T>{}(*arg) : result_type{};
+ }
+ };
+}
+
+# undef TR2_OPTIONAL_REQUIRES
+# undef TR2_OPTIONAL_ASSERTED_EXPRESSION
+
+# endif //___SOL_OPTIONAL_HPP___
+// end of Optional/optional.hpp
+
+#endif // Boost vs. Better optional
+
+namespace sol {
+
+#if defined(SOL_USE_BOOST)
+ template <typename T>
+ using optional = boost::optional<T>;
+ using nullopt_t = boost::none_t;
+ const nullopt_t nullopt = boost::none;
+#endif // Boost vs. Better optional
+
+} // sol
+
+// end of sol/optional.hpp
+
+// beginning of sol/reference.hpp
+
+// beginning of sol/types.hpp
+
+// beginning of sol/compatibility.hpp
+
+// beginning of sol/compatibility/version.hpp
+
+#include <lua.hpp>
+
+#if defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
+#ifndef SOL_CODECVT_SUPPORT
+#define SOL_CODECVT_SUPPORT 1
+#endif // sol codecvt support
+#elif defined(__GNUC__)
+#if __GNUC__ >= 5
+#ifndef SOL_CODECVT_SUPPORT
+#define SOL_CODECVT_SUPPORT 1
+#endif // codecvt support
+#endif // g++ 5.x.x
+#else
+#endif // Windows/VC++ vs. g++ vs Others
+
+#ifdef LUAJIT_VERSION
+#ifndef SOL_LUAJIT
+#define SOL_LUAJIT
+#define SOL_LUAJIT_VERSION LUAJIT_VERSION_NUM
+#endif // sol luajit
+#endif // luajit
+
+#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
+#define SOL_LUA_VERSION LUA_VERSION_NUM
+#elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
+#define SOL_LUA_VERSION LUA_VERSION_NUM
+#elif !defined(LUA_VERSION_NUM)
+#define SOL_LUA_VERSION 500
+#else
+#define SOL_LUA_VERSION 502
+#endif // Lua Version 502, 501 || luajit, 500
+
+#ifdef _MSC_VER
+#ifdef _DEBUG
+#ifndef NDEBUG
+#ifndef SOL_CHECK_ARGUMENTS
+#endif // Check Arguments
+#ifndef SOL_SAFE_USERTYPE
+#define SOL_SAFE_USERTYPE
+#endif // Safe Usertypes
+#endif // NDEBUG
+#endif // Debug
+
+#ifndef _CPPUNWIND
+#ifndef SOL_NO_EXCEPTIONS
+#define SOL_NO_EXCEPTIONS 1
+#endif
+#endif // Automatic Exceptions
+
+#ifndef _CPPRTTI
+#ifndef SOL_NO_RTTI
+#define SOL_NO_RTTI 1
+#endif
+#endif // Automatic RTTI
+
+#elif defined(__GNUC__) || defined(__clang__)
+
+#ifndef NDEBUG
+#ifndef __OPTIMIZE__
+#ifndef SOL_CHECK_ARGUMENTS
+#endif // Check Arguments
+#ifndef SOL_SAFE_USERTYPE
+#define SOL_SAFE_USERTYPE
+#endif // Safe Usertypes
+#endif // g++ optimizer flag
+#endif // Not Debug
+
+#ifndef __EXCEPTIONS
+#ifndef SOL_NO_EXCEPTIONS
+#define SOL_NO_EXCEPTIONS 1
+#endif
+#endif // No Exceptions
+
+#ifndef __GXX_RTTI
+#ifndef SOL_NO_RTII
+#define SOL_NO_RTTI 1
+#endif
+#endif // No RTTI
+
+#endif // vc++ || clang++/g++
+
+#ifndef SOL_SAFE_USERTYPE
+#ifdef SOL_CHECK_ARGUMENTS
+#define SOL_SAFE_USERTYPE
+#endif // Turn on Safety for all
+#endif // Safe Usertypes
+
+// end of sol/compatibility/version.hpp
+
+#ifndef SOL_NO_COMPAT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+// beginning of sol/compatibility/5.1.0.h
+
+#ifndef SOL_5_1_0_H
+#define SOL_5_1_0_H
+
+#if SOL_LUA_VERSION == 501
+/* Lua 5.1 */
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+/* LuaJIT doesn't define these unofficial macros ... */
+#if !defined(LUAI_INT32)
+#include <limits.h>
+#if INT_MAX-20 < 32760
+#define LUAI_INT32 long
+#define LUAI_UINT32 unsigned long
+#elif INT_MAX > 2147483640L
+#define LUAI_INT32 int
+#define LUAI_UINT32 unsigned int
+#else
+#error "could not detect suitable lua_Unsigned datatype"
+#endif
+#endif
+
+/* LuaJIT does not have the updated error codes for thread status/function returns */
+#ifndef LUA_ERRGCMM
+#define LUA_ERRGCMM (LUA_ERRERR + 1)
+#endif // LUA_ERRGCMM
+
+/* LuaJIT does not support continuation contexts / return error codes? */
+#ifndef LUA_KCONTEXT
+#define LUA_KCONTEXT std::ptrdiff_t
+typedef LUA_KCONTEXT lua_KContext;
+typedef int(*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
+#endif // LUA_KCONTEXT
+
+#define LUA_OPADD 0
+#define LUA_OPSUB 1
+#define LUA_OPMUL 2
+#define LUA_OPDIV 3
+#define LUA_OPMOD 4
+#define LUA_OPPOW 5
+#define LUA_OPUNM 6
+#define LUA_OPEQ 0
+#define LUA_OPLT 1
+#define LUA_OPLE 2
+
+typedef LUAI_UINT32 lua_Unsigned;
+
+typedef struct luaL_Buffer_52 {
+ luaL_Buffer b; /* make incorrect code crash! */
+ char *ptr;
+ size_t nelems;
+ size_t capacity;
+ lua_State *L2;
+} luaL_Buffer_52;
+#define luaL_Buffer luaL_Buffer_52
+
+#define lua_tounsigned(L, i) lua_tounsignedx(L, i, NULL)
+
+#define lua_rawlen(L, i) lua_objlen(L, i)
+
+inline void lua_callk(lua_State *L, int nargs, int nresults, lua_KContext, lua_KFunction) {
+ // should probably warn the user of Lua 5.1 that continuation isn't supported...
+ lua_call(L, nargs, nresults);
+}
+inline int lua_pcallk(lua_State *L, int nargs, int nresults, int errfunc, lua_KContext, lua_KFunction) {
+ // should probably warn the user of Lua 5.1 that continuation isn't supported...
+ return lua_pcall(L, nargs, nresults, errfunc);
+}
+void lua_arith(lua_State *L, int op);
+int lua_compare(lua_State *L, int idx1, int idx2, int op);
+void lua_pushunsigned(lua_State *L, lua_Unsigned n);
+lua_Unsigned luaL_checkunsigned(lua_State *L, int i);
+lua_Unsigned lua_tounsignedx(lua_State *L, int i, int *isnum);
+lua_Unsigned luaL_optunsigned(lua_State *L, int i, lua_Unsigned def);
+lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum);
+void lua_len(lua_State *L, int i);
+int luaL_len(lua_State *L, int i);
+const char *luaL_tolstring(lua_State *L, int idx, size_t *len);
+void luaL_requiref(lua_State *L, char const* modname, lua_CFunction openf, int glb);
+
+#define luaL_buffinit luaL_buffinit_52
+void luaL_buffinit(lua_State *L, luaL_Buffer_52 *B);
+
+#define luaL_prepbuffsize luaL_prepbuffsize_52
+char *luaL_prepbuffsize(luaL_Buffer_52 *B, size_t s);
+
+#define luaL_addlstring luaL_addlstring_52
+void luaL_addlstring(luaL_Buffer_52 *B, const char *s, size_t l);
+
+#define luaL_addvalue luaL_addvalue_52
+void luaL_addvalue(luaL_Buffer_52 *B);
+
+#define luaL_pushresult luaL_pushresult_52
+void luaL_pushresult(luaL_Buffer_52 *B);
+
+#undef luaL_buffinitsize
+#define luaL_buffinitsize(L, B, s) \
+ (luaL_buffinit(L, B), luaL_prepbuffsize(B, s))
+
+#undef luaL_prepbuffer
+#define luaL_prepbuffer(B) \
+ luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
+
+#undef luaL_addchar
+#define luaL_addchar(B, c) \
+ ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize(B, 1)), \
+ ((B)->ptr[(B)->nelems++] = (c)))
+
+#undef luaL_addsize
+#define luaL_addsize(B, s) \
+ ((B)->nelems += (s))
+
+#undef luaL_addstring
+#define luaL_addstring(B, s) \
+ luaL_addlstring(B, s, strlen(s))
+
+#undef luaL_pushresultsize
+#define luaL_pushresultsize(B, s) \
+ (luaL_addsize(B, s), luaL_pushresult(B))
+
+typedef struct kepler_lua_compat_get_string_view {
+ const char *s;
+ size_t size;
+} kepler_lua_compat_get_string_view;
+
+inline const char* kepler_lua_compat_get_string(lua_State* L, void* ud, size_t* size) {
+ kepler_lua_compat_get_string_view* ls = (kepler_lua_compat_get_string_view*) ud;
+ (void)L;
+ if (ls->size == 0) return NULL;
+ *size = ls->size;
+ ls->size = 0;
+ return ls->s;
+}
+
+#if !defined(SOL_LUAJIT) || ((SOL_LUAJIT_VERSION - 020100) <= 0)
+
+inline int luaL_loadbufferx(lua_State* L, const char* buff, size_t size, const char* name, const char*) {
+ kepler_lua_compat_get_string_view ls;
+ ls.s = buff;
+ ls.size = size;
+ return lua_load(L, kepler_lua_compat_get_string, &ls, name/*, mode*/);
+}
+
+#endif // LuaJIT 2.1.x beta and beyond
+
+#endif /* Lua 5.1 */
+
+#endif // SOL_5_1_0_H// end of sol/compatibility/5.1.0.h
+
+// beginning of sol/compatibility/5.0.0.h
+
+#ifndef SOL_5_0_0_H
+#define SOL_5_0_0_H
+
+#if SOL_LUA_VERSION < 501
+/* Lua 5.0 */
+
+#define LUA_QL(x) "'" x "'"
+#define LUA_QS LUA_QL("%s")
+
+#define luaL_Reg luaL_reg
+
+#define luaL_opt(L, f, n, d) \
+ (lua_isnoneornil(L, n) ? (d) : f(L, n))
+
+#define luaL_addchar(B,c) \
+ ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
+ (*(B)->p++ = (char)(c)))
+
+#endif // Lua 5.0
+
+#endif // SOL_5_0_0_H
+// end of sol/compatibility/5.0.0.h
+
+// beginning of sol/compatibility/5.x.x.h
+
+#ifndef SOL_5_X_X_H
+#define SOL_5_X_X_H
+
+#if SOL_LUA_VERSION < 502
+
+#define LUA_RIDX_GLOBALS LUA_GLOBALSINDEX
+
+#define LUA_OK 0
+
+#define lua_pushglobaltable(L) \
+ lua_pushvalue(L, LUA_GLOBALSINDEX)
+
+#define luaL_newlib(L, l) \
+ (lua_newtable((L)),luaL_setfuncs((L), (l), 0))
+
+void luaL_checkversion(lua_State *L);
+
+int lua_absindex(lua_State *L, int i);
+void lua_copy(lua_State *L, int from, int to);
+void lua_rawgetp(lua_State *L, int i, const void *p);
+void lua_rawsetp(lua_State *L, int i, const void *p);
+void *luaL_testudata(lua_State *L, int i, const char *tname);
+lua_Number lua_tonumberx(lua_State *L, int i, int *isnum);
+void lua_getuservalue(lua_State *L, int i);
+void lua_setuservalue(lua_State *L, int i);
+void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
+void luaL_setmetatable(lua_State *L, const char *tname);
+int luaL_getsubtable(lua_State *L, int i, const char *name);
+void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level);
+int luaL_fileresult(lua_State *L, int stat, const char *fname);
+
+#endif // Lua 5.1 and below
+
+#endif // SOL_5_X_X_H
+// end of sol/compatibility/5.x.x.h
+
+// beginning of sol/compatibility/5.x.x.inl
+
+#ifndef SOL_5_X_X_INL
+#define SOL_5_X_X_INL
+
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM == 501
+
+#include <errno.h>
+
+#define PACKAGE_KEY "_sol.package"
+
+inline int lua_absindex(lua_State *L, int i) {
+ if (i < 0 && i > LUA_REGISTRYINDEX)
+ i += lua_gettop(L) + 1;
+ return i;
+}
+
+inline void lua_copy(lua_State *L, int from, int to) {
+ int abs_to = lua_absindex(L, to);
+ luaL_checkstack(L, 1, "not enough stack slots");
+ lua_pushvalue(L, from);
+ lua_replace(L, abs_to);
+}
+
+inline void lua_rawgetp(lua_State *L, int i, const void *p) {
+ int abs_i = lua_absindex(L, i);
+ lua_pushlightuserdata(L, (void*)p);
+ lua_rawget(L, abs_i);
+}
+
+inline void lua_rawsetp(lua_State *L, int i, const void *p) {
+ int abs_i = lua_absindex(L, i);
+ luaL_checkstack(L, 1, "not enough stack slots");
+ lua_pushlightuserdata(L, (void*)p);
+ lua_insert(L, -2);
+ lua_rawset(L, abs_i);
+}
+
+inline void *luaL_testudata(lua_State *L, int i, const char *tname) {
+ void *p = lua_touserdata(L, i);
+ luaL_checkstack(L, 2, "not enough stack slots");
+ if (p == NULL || !lua_getmetatable(L, i))
+ return NULL;
+ else {
+ int res = 0;
+ luaL_getmetatable(L, tname);
+ res = lua_rawequal(L, -1, -2);
+ lua_pop(L, 2);
+ if (!res)
+ p = NULL;
+ }
+ return p;
+}
+
+inline lua_Number lua_tonumberx(lua_State *L, int i, int *isnum) {
+ lua_Number n = lua_tonumber(L, i);
+ if (isnum != NULL) {
+ *isnum = (n != 0 || lua_isnumber(L, i));
+ }
+ return n;
+}
+
+inline static void push_package_table(lua_State *L) {
+ lua_pushliteral(L, PACKAGE_KEY);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ if (!lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ /* try to get package table from globals */
+ lua_pushliteral(L, "package");
+ lua_rawget(L, LUA_GLOBALSINDEX);
+ if (lua_istable(L, -1)) {
+ lua_pushliteral(L, PACKAGE_KEY);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ }
+ }
+}
+
+inline void lua_getuservalue(lua_State *L, int i) {
+ luaL_checktype(L, i, LUA_TUSERDATA);
+ luaL_checkstack(L, 2, "not enough stack slots");
+ lua_getfenv(L, i);
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ if (lua_rawequal(L, -1, -2)) {
+ lua_pop(L, 1);
+ lua_pushnil(L);
+ lua_replace(L, -2);
+ }
+ else {
+ lua_pop(L, 1);
+ push_package_table(L);
+ if (lua_rawequal(L, -1, -2)) {
+ lua_pop(L, 1);
+ lua_pushnil(L);
+ lua_replace(L, -2);
+ }
+ else
+ lua_pop(L, 1);
+ }
+}
+
+inline void lua_setuservalue(lua_State *L, int i) {
+ luaL_checktype(L, i, LUA_TUSERDATA);
+ if (lua_isnil(L, -1)) {
+ luaL_checkstack(L, 1, "not enough stack slots");
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ lua_replace(L, -2);
+ }
+ lua_setfenv(L, i);
+}
+
+/*
+** Adapted from Lua 5.2.0
+*/
+inline void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) {
+ luaL_checkstack(L, nup + 1, "too many upvalues");
+ for (; l->name != NULL; l++) { /* fill the table with given functions */
+ int i;
+ lua_pushstring(L, l->name);
+ for (i = 0; i < nup; i++) /* copy upvalues to the top */
+ lua_pushvalue(L, -(nup + 1));
+ lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
+ lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */
+ }
+ lua_pop(L, nup); /* remove upvalues */
+}
+
+inline void luaL_setmetatable(lua_State *L, const char *tname) {
+ luaL_checkstack(L, 1, "not enough stack slots");
+ luaL_getmetatable(L, tname);
+ lua_setmetatable(L, -2);
+}
+
+inline int luaL_getsubtable(lua_State *L, int i, const char *name) {
+ int abs_i = lua_absindex(L, i);
+ luaL_checkstack(L, 3, "not enough stack slots");
+ lua_pushstring(L, name);
+ lua_gettable(L, abs_i);
+ if (lua_istable(L, -1))
+ return 1;
+ lua_pop(L, 1);
+ lua_newtable(L);
+ lua_pushstring(L, name);
+ lua_pushvalue(L, -2);
+ lua_settable(L, abs_i);
+ return 0;
+}
+
+#ifndef SOL_LUAJIT
+inline static int countlevels(lua_State *L) {
+ lua_Debug ar;
+ int li = 1, le = 1;
+ /* find an upper bound */
+ while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
+ /* do a binary search */
+ while (li < le) {
+ int m = (li + le) / 2;
+ if (lua_getstack(L, m, &ar)) li = m + 1;
+ else le = m;
+ }
+ return le - 1;
+}
+
+inline static int findfield(lua_State *L, int objidx, int level) {
+ if (level == 0 || !lua_istable(L, -1))
+ return 0; /* not found */
+ lua_pushnil(L); /* start 'next' loop */
+ while (lua_next(L, -2)) { /* for each pair in table */
+ if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
+ if (lua_rawequal(L, objidx, -1)) { /* found object? */
+ lua_pop(L, 1); /* remove value (but keep name) */
+ return 1;
+ }
+ else if (findfield(L, objidx, level - 1)) { /* try recursively */
+ lua_remove(L, -2); /* remove table (but keep name) */
+ lua_pushliteral(L, ".");
+ lua_insert(L, -2); /* place '.' between the two names */
+ lua_concat(L, 3);
+ return 1;
+ }
+ }
+ lua_pop(L, 1); /* remove value */
+ }
+ return 0; /* not found */
+}
+
+inline static int pushglobalfuncname(lua_State *L, lua_Debug *ar) {
+ int top = lua_gettop(L);
+ lua_getinfo(L, "f", ar); /* push function */
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ if (findfield(L, top + 1, 2)) {
+ lua_copy(L, -1, top + 1); /* move name to proper place */
+ lua_pop(L, 2); /* remove pushed values */
+ return 1;
+ }
+ else {
+ lua_settop(L, top); /* remove function and global table */
+ return 0;
+ }
+}
+
+inline static void pushfuncname(lua_State *L, lua_Debug *ar) {
+ if (*ar->namewhat != '\0') /* is there a name? */
+ lua_pushfstring(L, "function " LUA_QS, ar->name);
+ else if (*ar->what == 'm') /* main? */
+ lua_pushliteral(L, "main chunk");
+ else if (*ar->what == 'C') {
+ if (pushglobalfuncname(L, ar)) {
+ lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
+ lua_remove(L, -2); /* remove name */
+ }
+ else
+ lua_pushliteral(L, "?");
+ }
+ else
+ lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
+}
+
+#define LEVELS1 12 /* size of the first part of the stack */
+#define LEVELS2 10 /* size of the second part of the stack */
+
+inline void luaL_traceback(lua_State *L, lua_State *L1,
+ const char *msg, int level) {
+ lua_Debug ar;
+ int top = lua_gettop(L);
+ int numlevels = countlevels(L1);
+ int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;
+ if (msg) lua_pushfstring(L, "%s\n", msg);
+ lua_pushliteral(L, "stack traceback:");
+ while (lua_getstack(L1, level++, &ar)) {
+ if (level == mark) { /* too many levels? */
+ lua_pushliteral(L, "\n\t..."); /* add a '...' */
+ level = numlevels - LEVELS2; /* and skip to last ones */
+ }
+ else {
+ lua_getinfo(L1, "Slnt", &ar);
+ lua_pushfstring(L, "\n\t%s:", ar.short_src);
+ if (ar.currentline > 0)
+ lua_pushfstring(L, "%d:", ar.currentline);
+ lua_pushliteral(L, " in ");
+ pushfuncname(L, &ar);
+ lua_concat(L, lua_gettop(L) - top);
+ }
+ }
+ lua_concat(L, lua_gettop(L) - top);
+}
+#endif
+
+inline const lua_Number *lua_version(lua_State *L) {
+ static const lua_Number version = LUA_VERSION_NUM;
+ if (L == NULL) return &version;
+ // TODO: wonky hacks to get at the inside of the incomplete type lua_State?
+ //else return L->l_G->version;
+ else return &version;
+}
+
+inline static void luaL_checkversion_(lua_State *L, lua_Number ver) {
+ const lua_Number* v = lua_version(L);
+ if (v != lua_version(NULL))
+ luaL_error(L, "multiple Lua VMs detected");
+ else if (*v != ver)
+ luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
+ ver, *v);
+ /* check conversions number -> integer types */
+ lua_pushnumber(L, -(lua_Number)0x1234);
+ if (lua_tointeger(L, -1) != -0x1234 ||
+ lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
+ luaL_error(L, "bad conversion number->int;"
+ " must recompile Lua with proper settings");
+ lua_pop(L, 1);
+}
+
+inline void luaL_checkversion(lua_State* L) {
+ luaL_checkversion_(L, LUA_VERSION_NUM);
+}
+
+#ifndef SOL_LUAJIT
+inline int luaL_fileresult(lua_State *L, int stat, const char *fname) {
+ int en = errno; /* calls to Lua API may change this value */
+ if (stat) {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+ else {
+ char buf[1024];
+#ifdef __GLIBC__
+ strerror_r(en, buf, 1024);
+#else
+ strerror_s(buf, 1024, en);
+#endif
+ lua_pushnil(L);
+ if (fname)
+ lua_pushfstring(L, "%s: %s", fname, buf);
+ else
+ lua_pushstring(L, buf);
+ lua_pushnumber(L, (lua_Number)en);
+ return 3;
+ }
+}
+#endif // luajit
+#endif // Lua 5.0 or Lua 5.1
+
+#if SOL_LUA_VERSION == 501
+
+typedef LUAI_INT32 LUA_INT32;
+
+/********************************************************************/
+/* extract of 5.2's luaconf.h */
+/* detects proper defines for faster unsigned<->number conversion */
+/* see copyright notice at the end of this file */
+/********************************************************************/
+
+#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE)
+#define LUA_WIN /* enable goodies for regular Windows platforms */
+#endif
+
+#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
+
+/* Microsoft compiler on a Pentium (32 bit) ? */
+#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */
+
+#define LUA_MSASMTRICK
+#define LUA_IEEEENDIAN 0
+#define LUA_NANTRICK
+
+/* pentium 32 bits? */
+#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */
+
+#define LUA_IEEE754TRICK
+#define LUA_IEEELL
+#define LUA_IEEEENDIAN 0
+#define LUA_NANTRICK
+
+/* pentium 64 bits? */
+#elif defined(__x86_64) /* }{ */
+
+#define LUA_IEEE754TRICK
+#define LUA_IEEEENDIAN 0
+
+#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */
+
+#define LUA_IEEE754TRICK
+#define LUA_IEEEENDIAN 1
+
+#else /* }{ */
+
+/* assume IEEE754 and a 32-bit integer type */
+#define LUA_IEEE754TRICK
+
+#endif /* } */
+
+#endif /* } */
+
+/********************************************************************/
+/* extract of 5.2's llimits.h */
+/* gives us lua_number2unsigned and lua_unsigned2number */
+/* see copyright notice just below this one here */
+/********************************************************************/
+
+/*********************************************************************
+* This file contains parts of Lua 5.2's source code:
+*
+* Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*********************************************************************/
+
+#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */
+/* trick with Microsoft assembler for X86 */
+
+#define lua_number2unsigned(i,n) \
+ {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;}
+
+#elif defined(LUA_IEEE754TRICK) /* }{ */
+/* the next trick should work on any machine using IEEE754 with
+a 32-bit int type */
+
+union compat52_luai_Cast { double l_d; LUA_INT32 l_p[2]; };
+
+#if !defined(LUA_IEEEENDIAN) /* { */
+#define LUAI_EXTRAIEEE \
+ static const union compat52_luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)};
+#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33)
+#else
+#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN
+#define LUAI_EXTRAIEEE /* empty */
+#endif /* } */
+
+#define lua_number2int32(i,n,t) \
+ { LUAI_EXTRAIEEE \
+ volatile union compat52_luai_Cast u; u.l_d = (n) + 6755399441055744.0; \
+ (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; }
+
+#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned)
+
+#endif /* } */
+
+/* the following definitions always work, but may be slow */
+
+#if !defined(lua_number2unsigned) /* { */
+/* the following definition assures proper modulo behavior */
+#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT)
+#include <math.h>
+#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1)
+#define lua_number2unsigned(i,n) \
+ ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED))
+#else
+#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n))
+#endif
+#endif /* } */
+
+#if !defined(lua_unsigned2number)
+/* on several machines, coercion from unsigned to double is slow,
+so it may be worth to avoid */
+#define lua_unsigned2number(u) \
+ (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u))
+#endif
+
+/********************************************************************/
+
+inline static void compat52_call_lua(lua_State *L, char const code[], size_t len,
+ int nargs, int nret) {
+ lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code);
+ if (lua_type(L, -1) != LUA_TFUNCTION) {
+ lua_pop(L, 1);
+ if (luaL_loadbuffer(L, code, len, "=none"))
+ lua_error(L);
+ lua_pushvalue(L, -1);
+ lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code);
+ }
+ lua_insert(L, -nargs - 1);
+ lua_call(L, nargs, nret);
+}
+
+static const char compat52_arith_code[] = {
+ "local op,a,b=...\n"
+ "if op==0 then return a+b\n"
+ "elseif op==1 then return a-b\n"
+ "elseif op==2 then return a*b\n"
+ "elseif op==3 then return a/b\n"
+ "elseif op==4 then return a%b\n"
+ "elseif op==5 then return a^b\n"
+ "elseif op==6 then return -a\n"
+ "end\n"
+};
+
+inline void lua_arith(lua_State *L, int op) {
+ if (op < LUA_OPADD || op > LUA_OPUNM)
+ luaL_error(L, "invalid 'op' argument for lua_arith");
+ luaL_checkstack(L, 5, "not enough stack slots");
+ if (op == LUA_OPUNM)
+ lua_pushvalue(L, -1);
+ lua_pushnumber(L, op);
+ lua_insert(L, -3);
+ compat52_call_lua(L, compat52_arith_code,
+ sizeof(compat52_arith_code) - 1, 3, 1);
+}
+
+static const char compat52_compare_code[] = {
+ "local a,b=...\n"
+ "return a<=b\n"
+};
+
+inline int lua_compare(lua_State *L, int idx1, int idx2, int op) {
+ int result = 0;
+ switch (op) {
+ case LUA_OPEQ:
+ return lua_equal(L, idx1, idx2);
+ case LUA_OPLT:
+ return lua_lessthan(L, idx1, idx2);
+ case LUA_OPLE:
+ luaL_checkstack(L, 5, "not enough stack slots");
+ idx1 = lua_absindex(L, idx1);
+ idx2 = lua_absindex(L, idx2);
+ lua_pushvalue(L, idx1);
+ lua_pushvalue(L, idx2);
+ compat52_call_lua(L, compat52_compare_code,
+ sizeof(compat52_compare_code) - 1, 2, 1);
+ result = lua_toboolean(L, -1);
+ lua_pop(L, 1);
+ return result;
+ default:
+ luaL_error(L, "invalid 'op' argument for lua_compare");
+ }
+ return 0;
+}
+
+inline void lua_pushunsigned(lua_State *L, lua_Unsigned n) {
+ lua_pushnumber(L, lua_unsigned2number(n));
+}
+
+inline lua_Unsigned luaL_checkunsigned(lua_State *L, int i) {
+ lua_Unsigned result;
+ lua_Number n = lua_tonumber(L, i);
+ if (n == 0 && !lua_isnumber(L, i))
+ luaL_checktype(L, i, LUA_TNUMBER);
+ lua_number2unsigned(result, n);
+ return result;
+}
+
+inline lua_Unsigned lua_tounsignedx(lua_State *L, int i, int *isnum) {
+ lua_Unsigned result;
+ lua_Number n = lua_tonumberx(L, i, isnum);
+ lua_number2unsigned(result, n);
+ return result;
+}
+
+inline lua_Unsigned luaL_optunsigned(lua_State *L, int i, lua_Unsigned def) {
+ return luaL_opt(L, luaL_checkunsigned, i, def);
+}
+
+inline lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum) {
+ lua_Integer n = lua_tointeger(L, i);
+ if (isnum != NULL) {
+ *isnum = (n != 0 || lua_isnumber(L, i));
+ }
+ return n;
+}
+
+inline void lua_len(lua_State *L, int i) {
+ switch (lua_type(L, i)) {
+ case LUA_TSTRING: /* fall through */
+ case LUA_TTABLE:
+ if (!luaL_callmeta(L, i, "__len"))
+ lua_pushnumber(L, (int)lua_objlen(L, i));
+ break;
+ case LUA_TUSERDATA:
+ if (luaL_callmeta(L, i, "__len"))
+ break;
+ /* maybe fall through */
+ default:
+ luaL_error(L, "attempt to get length of a %s value",
+ lua_typename(L, lua_type(L, i)));
+ }
+}
+
+inline int luaL_len(lua_State *L, int i) {
+ int res = 0, isnum = 0;
+ luaL_checkstack(L, 1, "not enough stack slots");
+ lua_len(L, i);
+ res = (int)lua_tointegerx(L, -1, &isnum);
+ lua_pop(L, 1);
+ if (!isnum)
+ luaL_error(L, "object length is not a number");
+ return res;
+}
+
+inline const char *luaL_tolstring(lua_State *L, int idx, size_t *len) {
+ if (!luaL_callmeta(L, idx, "__tostring")) {
+ int t = lua_type(L, idx);
+ switch (t) {
+ case LUA_TNIL:
+ lua_pushliteral(L, "nil");
+ break;
+ case LUA_TSTRING:
+ case LUA_TNUMBER:
+ lua_pushvalue(L, idx);
+ break;
+ case LUA_TBOOLEAN:
+ if (lua_toboolean(L, idx))
+ lua_pushliteral(L, "true");
+ else
+ lua_pushliteral(L, "false");
+ break;
+ default:
+ lua_pushfstring(L, "%s: %p", lua_typename(L, t),
+ lua_topointer(L, idx));
+ break;
+ }
+ }
+ return lua_tolstring(L, -1, len);
+}
+
+inline void luaL_requiref(lua_State *L, char const* modname,
+ lua_CFunction openf, int glb) {
+ luaL_checkstack(L, 3, "not enough stack slots");
+ lua_pushcfunction(L, openf);
+ lua_pushstring(L, modname);
+ lua_call(L, 1, 1);
+ lua_getglobal(L, "package");
+ if (lua_istable(L, -1) == 0) {
+ lua_pop(L, 1);
+ lua_createtable(L, 0, 16);
+ lua_setglobal(L, "package");
+ lua_getglobal(L, "package");
+ }
+ lua_getfield(L, -1, "loaded");
+ if (lua_istable(L, -1) == 0) {
+ lua_pop(L, 1);
+ lua_createtable(L, 0, 1);
+ lua_setfield(L, -2, "loaded");
+ lua_getfield(L, -1, "loaded");
+ }
+ lua_replace(L, -2);
+ lua_pushvalue(L, -2);
+ lua_setfield(L, -2, modname);
+ lua_pop(L, 1);
+ if (glb) {
+ lua_pushvalue(L, -1);
+ lua_setglobal(L, modname);
+ }
+}
+
+inline void luaL_buffinit(lua_State *L, luaL_Buffer_52 *B) {
+ /* make it crash if used via pointer to a 5.1-style luaL_Buffer */
+ B->b.p = NULL;
+ B->b.L = NULL;
+ B->b.lvl = 0;
+ /* reuse the buffer from the 5.1-style luaL_Buffer though! */
+ B->ptr = B->b.buffer;
+ B->capacity = LUAL_BUFFERSIZE;
+ B->nelems = 0;
+ B->L2 = L;
+}
+
+inline char *luaL_prepbuffsize(luaL_Buffer_52 *B, size_t s) {
+ if (B->capacity - B->nelems < s) { /* needs to grow */
+ char* newptr = NULL;
+ size_t newcap = B->capacity * 2;
+ if (newcap - B->nelems < s)
+ newcap = B->nelems + s;
+ if (newcap < B->capacity) /* overflow */
+ luaL_error(B->L2, "buffer too large");
+ newptr = (char*)lua_newuserdata(B->L2, newcap);
+ memcpy(newptr, B->ptr, B->nelems);
+ if (B->ptr != B->b.buffer)
+ lua_replace(B->L2, -2); /* remove old buffer */
+ B->ptr = newptr;
+ B->capacity = newcap;
+ }
+ return B->ptr + B->nelems;
+}
+
+inline void luaL_addlstring(luaL_Buffer_52 *B, const char *s, size_t l) {
+ memcpy(luaL_prepbuffsize(B, l), s, l);
+ luaL_addsize(B, l);
+}
+
+inline void luaL_addvalue(luaL_Buffer_52 *B) {
+ size_t len = 0;
+ const char *s = lua_tolstring(B->L2, -1, &len);
+ if (!s)
+ luaL_error(B->L2, "cannot convert value to string");
+ if (B->ptr != B->b.buffer)
+ lua_insert(B->L2, -2); /* userdata buffer must be at stack top */
+ luaL_addlstring(B, s, len);
+ lua_remove(B->L2, B->ptr != B->b.buffer ? -2 : -1);
+}
+
+inline void luaL_pushresult(luaL_Buffer_52 *B) {
+ lua_pushlstring(B->L2, B->ptr, B->nelems);
+ if (B->ptr != B->b.buffer)
+ lua_replace(B->L2, -2); /* remove userdata buffer */
+}
+
+#endif /* SOL_LUA_VERSION == 501 */
+
+#endif // SOL_5_X_X_INL
+// end of sol/compatibility/5.x.x.inl
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SOL_NO_COMPAT
+
+// end of sol/compatibility.hpp
+
+// beginning of sol/string_shim.hpp
+
+#pragma once
+
+namespace sol {
+ namespace string_detail {
+ struct string_shim {
+ std::size_t s;
+ const char* p;
+
+ string_shim(const std::string& r) : string_shim(r.data(), r.size()) {}
+ string_shim(const char* p) : string_shim(p, std::char_traits<char>::length(p)) {}
+ string_shim(const char* p, std::size_t s) : s(s), p(p) {}
+
+ static int compare(const char* lhs_p, std::size_t lhs_sz, const char* rhs_p, std::size_t rhs_sz) {
+ int result = std::char_traits<char>::compare(lhs_p, rhs_p, lhs_sz < rhs_sz ? lhs_sz : rhs_sz);
+ if (result != 0)
+ return result;
+ if (lhs_sz < rhs_sz)
+ return -1;
+ if (lhs_sz > rhs_sz)
+ return 1;
+ return 0;
+ }
+
+ const char* c_str() const {
+ return p;
+ }
+
+ const char* data() const {
+ return p;
+ }
+
+ std::size_t size() const {
+ return s;
+ }
+
+ bool operator==(const string_shim& r) const {
+ return compare(p, s, r.data(), r.size()) == 0;
+ }
+
+ bool operator==(const char* r) const {
+ return compare(r, std::char_traits<char>::length(r), p, s) == 0;
+ }
+
+ bool operator==(const std::string& r) const {
+ return compare(r.data(), r.size(), p, s) == 0;
+ }
+
+ bool operator!=(const string_shim& r) const {
+ return !(*this == r);
+ }
+
+ bool operator!=(const char* r) const {
+ return !(*this == r);
+ }
+
+ bool operator!=(const std::string& r) const {
+ return !(*this == r);
+ }
+ };
+ }
+}// end of sol/string_shim.hpp
+
+#include <array>
+
+namespace sol {
+ namespace detail {
+#ifdef SOL_NO_EXCEPTIONS
+ template <lua_CFunction f>
+ int static_trampoline(lua_State* L) {
+ return f(L);
+ }
+
+ template <typename Fx, typename... Args>
+ int trampoline(lua_State* L, Fx&& f, Args&&... args) {
+ return f(L, std::forward<Args>(args)...);
+ }
+
+ inline int c_trampoline(lua_State* L, lua_CFunction f) {
+ return trampoline(L, f);
+ }
+#else
+ template <lua_CFunction f>
+ int static_trampoline(lua_State* L) {
+ try {
+ return f(L);
+ }
+ catch (const char *s) {
+ lua_pushstring(L, s);
+ }
+ catch (const std::exception& e) {
+ lua_pushstring(L, e.what());
+ }
+ catch (...) {
+ lua_pushstring(L, "caught (...) exception");
+ }
+ return lua_error(L);
+ }
+
+ template <typename Fx, typename... Args>
+ int trampoline(lua_State* L, Fx&& f, Args&&... args) {
+ try {
+ return f(L, std::forward<Args>(args)...);
+ }
+ catch (const char *s) {
+ lua_pushstring(L, s);
+ }
+ catch (const std::exception& e) {
+ lua_pushstring(L, e.what());
+ }
+ catch (...) {
+ lua_pushstring(L, "caught (...) exception");
+ }
+ return lua_error(L);
+ }
+
+ inline int c_trampoline(lua_State* L, lua_CFunction f) {
+ return trampoline(L, f);
+ }
+#endif // Exceptions vs. No Exceptions
+
+ template <typename T>
+ struct unique_usertype {};
+
+ template <typename T>
+ struct implicit_wrapper {
+ T& item;
+ implicit_wrapper(T* item) : item(*item) {}
+ implicit_wrapper(T& item) : item(item) {}
+ operator T& () {
+ return item;
+ }
+ operator T* () {
+ return std::addressof(item);
+ }
+ };
+ } // detail
+
+ struct nil_t {};
+ const nil_t nil{};
+ inline bool operator==(nil_t, nil_t) { return true; }
+ inline bool operator!=(nil_t, nil_t) { return false; }
+
+ struct metatable_key_t {};
+ const metatable_key_t metatable_key = {};
+
+ struct no_metatable_t {};
+ const no_metatable_t no_metatable = {};
+
+ typedef std::remove_pointer_t<lua_CFunction> lua_r_CFunction;
+
+ template <typename T>
+ struct unique_usertype_traits {
+ typedef T type;
+ typedef T actual_type;
+ static const bool value = false;
+
+ template <typename U>
+ static bool is_null(U&&) {
+ return false;
+ }
+
+ template <typename U>
+ static auto get(U&& value) {
+ return std::addressof(detail::deref(value));
+ }
+ };
+
+ template <typename T>
+ struct unique_usertype_traits<std::shared_ptr<T>> {
+ typedef T type;
+ typedef std::shared_ptr<T> actual_type;
+ static const bool value = true;
+
+ static bool is_null(const actual_type& p) {
+ return p == nullptr;
+ }
+
+ static type* get(const actual_type& p) {
+ return p.get();
+ }
+ };
+
+ template <typename T, typename D>
+ struct unique_usertype_traits<std::unique_ptr<T, D>> {
+ typedef T type;
+ typedef std::unique_ptr<T, D> actual_type;
+ static const bool value = true;
+
+ static bool is_null(const actual_type& p) {
+ return p == nullptr;
+ }
+
+ static type* get(const actual_type& p) {
+ return p.get();
+ }
+ };
+
+ template <typename T>
+ struct non_null {};
+
+ template <typename... Args>
+ struct function_sig {};
+
+ struct upvalue_index {
+ int index;
+ upvalue_index(int idx) : index(lua_upvalueindex(idx)) {}
+ operator int() const { return index; }
+ };
+
+ struct raw_index {
+ int index;
+ raw_index(int i) : index(i) {}
+ operator int() const { return index; }
+ };
+
+ struct absolute_index {
+ int index;
+ absolute_index(lua_State* L, int idx) : index(lua_absindex(L, idx)) {}
+ operator int() const { return index; }
+ };
+
+ struct lightuserdata_value {
+ void* value;
+ lightuserdata_value(void* data) : value(data) {}
+ operator void*() const { return value; }
+ };
+
+ struct userdata_value {
+ void* value;
+ userdata_value(void* data) : value(data) {}
+ operator void*() const { return value; }
+ };
+
+ template <typename L>
+ struct light {
+ L* value;
+
+ light(L& x) : value(std::addressof(x)) {}
+ light(L* x) : value(x) {}
+ light(void* x) : value(static_cast<L*>(x)) {}
+ operator L* () const { return value; }
+ operator L& () const { return *value; }
+ };
+
+ template <typename T>
+ auto make_light(T& l) {
+ typedef meta::unwrapped_t<std::remove_pointer_t<std::remove_pointer_t<T>>> L;
+ return light<L>(l);
+ }
+
+ template <typename U>
+ struct user {
+ U value;
+
+ user(U x) : value(std::move(x)) {}
+ operator U* () { return std::addressof(value); }
+ operator U& () { return value; }
+ operator const U& () const { return value; }
+ };
+
+ template <typename T>
+ auto make_user(T&& u) {
+ typedef meta::unwrapped_t<meta::unqualified_t<T>> U;
+ return user<U>(std::forward<T>(u));
+ }
+
+ template <typename T>
+ struct metatable_registry_key {
+ T key;
+
+ metatable_registry_key(T key) : key(std::forward<T>(key)) {}
+ };
+
+ template <typename T>
+ auto meta_registry_key(T&& key) {
+ typedef meta::unqualified_t<T> K;
+ return metatable_registry_key<K>(std::forward<T>(key));
+ }
+
+ template <typename... Upvalues>
+ struct closure {
+ lua_CFunction c_function;
+ std::tuple<Upvalues...> upvalues;
+ closure(lua_CFunction f, Upvalues... upvalues) : c_function(f), upvalues(std::forward<Upvalues>(upvalues)...) {}
+ };
+
+ template <>
+ struct closure<> {
+ lua_CFunction c_function;
+ int upvalues;
+ closure(lua_CFunction f, int upvalues = 0) : c_function(f), upvalues(upvalues) {}
+ };
+
+ typedef closure<> c_closure;
+
+ template <typename... Args>
+ closure<Args...> make_closure(lua_CFunction f, Args&&... args) {
+ return closure<Args...>(f, std::forward<Args>(args)...);
+ }
+
+ template <typename Sig, typename... Ps>
+ struct function_arguments {
+ std::tuple<Ps...> arguments;
+ template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, function_arguments>> = meta::enabler>
+ function_arguments(Arg&& arg, Args&&... args) : arguments(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+ };
+
+ template <typename Sig = function_sig<>, typename... Args>
+ auto as_function(Args&&... args) {
+ return function_arguments<Sig, std::decay_t<Args>...>(std::forward<Args>(args)...);
+ }
+
+ template <typename Sig = function_sig<>, typename... Args>
+ auto as_function_reference(Args&&... args) {
+ return function_arguments<Sig, Args...>(std::forward<Args>(args)...);
+ }
+
+ template <typename T>
+ struct as_table_t {
+ T source;
+ template <typename... Args>
+ as_table_t(Args&&... args) : source(std::forward<Args>(args)...) {}
+
+ operator std::add_lvalue_reference_t<T> () {
+ return source;
+ }
+ };
+
+ template <typename T>
+ as_table_t<T> as_table(T&& container) {
+ return as_table_t<T>(std::forward<T>(container));
+ }
+
+ struct this_state {
+ lua_State* L;
+ operator lua_State* () const {
+ return L;
+ }
+ lua_State* operator-> () const {
+ return L;
+ }
+ };
+
+ enum class call_syntax {
+ dot = 0,
+ colon = 1
+ };
+
+ enum class call_status : int {
+ ok = LUA_OK,
+ yielded = LUA_YIELD,
+ runtime = LUA_ERRRUN,
+ memory = LUA_ERRMEM,
+ handler = LUA_ERRERR,
+ gc = LUA_ERRGCMM
+ };
+
+ enum class thread_status : int {
+ ok = LUA_OK,
+ yielded = LUA_YIELD,
+ runtime = LUA_ERRRUN,
+ memory = LUA_ERRMEM,
+ gc = LUA_ERRGCMM,
+ handler = LUA_ERRERR,
+ dead,
+ };
+
+ enum class load_status : int {
+ ok = LUA_OK,
+ syntax = LUA_ERRSYNTAX,
+ memory = LUA_ERRMEM,
+ gc = LUA_ERRGCMM,
+ file = LUA_ERRFILE,
+ };
+
+ enum class type : int {
+ none = LUA_TNONE,
+ nil = LUA_TNIL,
+ string = LUA_TSTRING,
+ number = LUA_TNUMBER,
+ thread = LUA_TTHREAD,
+ boolean = LUA_TBOOLEAN,
+ function = LUA_TFUNCTION,
+ userdata = LUA_TUSERDATA,
+ lightuserdata = LUA_TLIGHTUSERDATA,
+ table = LUA_TTABLE,
+ poly = none | nil | string | number | thread |
+ table | boolean | function | userdata | lightuserdata
+ };
+
+ enum class meta_function {
+ construct,
+ index,
+ new_index,
+ mode,
+ call,
+ metatable,
+ to_string,
+ length,
+ unary_minus,
+ addition,
+ subtraction,
+ multiplication,
+ division,
+ modulus,
+ power_of,
+ involution = power_of,
+ concatenation,
+ equal_to,
+ less_than,
+ less_than_or_equal_to,
+ garbage_collect,
+ call_function = call,
+ };
+
+ typedef meta_function meta_method;
+
+ const std::array<std::string, 2> meta_variable_names = { {
+ "__index",
+ "__newindex",
+ } };
+
+ const std::array<std::string, 21> meta_function_names = { {
+ "new",
+ "__index",
+ "__newindex",
+ "__mode",
+ "__call",
+ "__metatable",
+ "__tostring",
+ "__len",
+ "__unm",
+ "__add",
+ "__sub",
+ "__mul",
+ "__div",
+ "__mod",
+ "__pow",
+ "__concat",
+ "__eq",
+ "__lt",
+ "__le",
+ "__gc",
+ } };
+
+ inline const std::string& name_of(meta_function mf) {
+ return meta_function_names[static_cast<int>(mf)];
+ }
+
+ inline type type_of(lua_State* L, int index) {
+ return static_cast<type>(lua_type(L, index));
+ }
+
+ inline int type_panic(lua_State* L, int index, type expected, type actual) {
+ return luaL_error(L, "stack index %d, expected %s, received %s", index,
+ expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)),
+ expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(actual))
+ );
+ }
+
+ // Specify this function as the handler for lua::check if you know there's nothing wrong
+ inline int no_panic(lua_State*, int, type, type) noexcept {
+ return 0;
+ }
+
+ inline void type_error(lua_State* L, int expected, int actual) {
+ luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
+ }
+
+ inline void type_error(lua_State* L, type expected, type actual) {
+ type_error(L, static_cast<int>(expected), static_cast<int>(actual));
+ }
+
+ inline void type_assert(lua_State* L, int index, type expected, type actual) {
+ if (expected != type::poly && expected != actual) {
+ type_panic(L, index, expected, actual);
+ }
+ }
+
+ inline void type_assert(lua_State* L, int index, type expected) {
+ type actual = type_of(L, index);
+ type_assert(L, index, expected, actual);
+ }
+
+ inline std::string type_name(lua_State* L, type t) {
+ return lua_typename(L, static_cast<int>(t));
+ }
+
+ class reference;
+ class stack_reference;
+ template <typename Table, typename Key>
+ struct proxy;
+ template<typename T>
+ class usertype;
+ template <bool, typename T>
+ class basic_table_core;
+ template <bool b>
+ using table_core = basic_table_core<b, reference>;
+ template <bool b>
+ using stack_table_core = basic_table_core<b, stack_reference>;
+ typedef table_core<false> table;
+ typedef table_core<true> global_table;
+ typedef stack_table_core<false> stack_table;
+ typedef stack_table_core<true> stack_global_table;
+ template <typename T>
+ class basic_function;
+ template <typename T>
+ class basic_protected_function;
+ using function = basic_function<reference>;
+ using protected_function = basic_protected_function<reference>;
+ using stack_function = basic_function<stack_reference>;
+ using stack_protected_function = basic_protected_function<stack_reference>;
+ template <typename base_t>
+ class basic_object;
+ template <typename base_t>
+ class basic_userdata;
+ template <typename base_t>
+ class basic_lightuserdata;
+ struct variadic_args;
+ using object = basic_object<reference>;
+ using stack_object = basic_object<stack_reference>;
+ using userdata = basic_userdata<reference>;
+ using stack_userdata = basic_userdata<stack_reference>;
+ using lightuserdata = basic_lightuserdata<reference>;
+ using stack_lightuserdata = basic_lightuserdata<stack_reference>;
+ class coroutine;
+ class thread;
+ struct variadic_args;
+ struct this_state;
+
+ namespace detail {
+ template <typename T, typename = void>
+ struct lua_type_of : std::integral_constant<type, type::userdata> {};
+
+ template <>
+ struct lua_type_of<std::string> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<std::wstring> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<std::u16string> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<std::u32string> : std::integral_constant<type, type::string> {};
+
+ template <std::size_t N>
+ struct lua_type_of<char[N]> : std::integral_constant<type, type::string> {};
+
+ template <std::size_t N>
+ struct lua_type_of<wchar_t[N]> : std::integral_constant<type, type::string> {};
+
+ template <std::size_t N>
+ struct lua_type_of<char16_t[N]> : std::integral_constant<type, type::string> {};
+
+ template <std::size_t N>
+ struct lua_type_of<char32_t[N]> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<char> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<wchar_t> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<char16_t> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<char32_t> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<const char*> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<const char16_t*> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<const char32_t*> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<string_detail::string_shim> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<bool> : std::integral_constant<type, type::boolean> {};
+
+ template <>
+ struct lua_type_of<nil_t> : std::integral_constant<type, type::nil> { };
+
+ template <>
+ struct lua_type_of<nullopt_t> : std::integral_constant<type, type::nil> { };
+
+ template <>
+ struct lua_type_of<std::nullptr_t> : std::integral_constant<type, type::nil> { };
+
+ template <>
+ struct lua_type_of<sol::error> : std::integral_constant<type, type::string> { };
+
+ template <bool b, typename Base>
+ struct lua_type_of<basic_table_core<b, Base>> : std::integral_constant<type, type::table> { };
+
+ template <>
+ struct lua_type_of<reference> : std::integral_constant<type, type::poly> {};
+
+ template <>
+ struct lua_type_of<stack_reference> : std::integral_constant<type, type::poly> {};
+
+ template <typename Base>
+ struct lua_type_of<basic_object<Base>> : std::integral_constant<type, type::poly> {};
+
+ template <typename... Args>
+ struct lua_type_of<std::tuple<Args...>> : std::integral_constant<type, type::poly> {};
+
+ template <typename A, typename B>
+ struct lua_type_of<std::pair<A, B>> : std::integral_constant<type, type::poly> {};
+
+ template <>
+ struct lua_type_of<void*> : std::integral_constant<type, type::lightuserdata> {};
+
+ template <>
+ struct lua_type_of<lightuserdata_value> : std::integral_constant<type, type::lightuserdata> {};
+
+ template <>
+ struct lua_type_of<userdata_value> : std::integral_constant<type, type::userdata> {};
+
+ template <typename T>
+ struct lua_type_of<light<T>> : std::integral_constant<type, type::lightuserdata> {};
+
+ template <typename T>
+ struct lua_type_of<user<T>> : std::integral_constant<type, type::userdata> {};
+
+ template <typename Base>
+ struct lua_type_of<basic_lightuserdata<Base>> : std::integral_constant<type, type::lightuserdata> {};
+
+ template <typename Base>
+ struct lua_type_of<basic_userdata<Base>> : std::integral_constant<type, type::userdata> {};
+
+ template <>
+ struct lua_type_of<lua_CFunction> : std::integral_constant<type, type::function> {};
+
+ template <>
+ struct lua_type_of<std::remove_pointer_t<lua_CFunction>> : std::integral_constant<type, type::function> {};
+
+ template <typename Base>
+ struct lua_type_of<basic_function<Base>> : std::integral_constant<type, type::function> {};
+
+ template <typename Base>
+ struct lua_type_of<basic_protected_function<Base>> : std::integral_constant<type, type::function> {};
+
+ template <>
+ struct lua_type_of<coroutine> : std::integral_constant<type, type::function> {};
+
+ template <>
+ struct lua_type_of<thread> : std::integral_constant<type, type::thread> {};
+
+ template <typename Signature>
+ struct lua_type_of<std::function<Signature>> : std::integral_constant<type, type::function> {};
+
+ template <typename T>
+ struct lua_type_of<optional<T>> : std::integral_constant<type, type::poly> {};
+
+ template <>
+ struct lua_type_of<variadic_args> : std::integral_constant<type, type::poly> {};
+
+ template <>
+ struct lua_type_of<this_state> : std::integral_constant<type, type::poly> {};
+
+ template <>
+ struct lua_type_of<type> : std::integral_constant<type, type::poly> {};
+
+ template <typename T>
+ struct lua_type_of<T*> : std::integral_constant<type, type::userdata> {};
+
+ template <typename T>
+ struct lua_type_of<T, std::enable_if_t<std::is_arithmetic<T>::value>> : std::integral_constant<type, type::number> {};
+
+ template <typename T>
+ struct lua_type_of<T, std::enable_if_t<std::is_enum<T>::value>> : std::integral_constant<type, type::number> {};
+
+ template <>
+ struct lua_type_of<meta_function> : std::integral_constant<type, type::string> {};
+
+ template <typename C, C v, template <typename...> class V, typename... Args>
+ struct accumulate : std::integral_constant<C, v> {};
+
+ template <typename C, C v, template <typename...> class V, typename T, typename... Args>
+ struct accumulate<C, v, V, T, Args...> : accumulate<C, v + V<T>::value, V, Args...> {};
+ } // detail
+
+ template <typename T>
+ struct is_unique_usertype : std::integral_constant<bool, unique_usertype_traits<T>::value> {};
+
+ template <typename T>
+ struct lua_type_of : detail::lua_type_of<T> {};
+
+ template <typename T>
+ struct lua_size : std::integral_constant<int, 1> { };
+
+ template <typename A, typename B>
+ struct lua_size<std::pair<A, B>> : std::integral_constant<int, lua_size<A>::value + lua_size<B>::value> { };
+
+ template <typename... Args>
+ struct lua_size<std::tuple<Args...>> : std::integral_constant<int, detail::accumulate<int, 0, lua_size, Args...>::value> { };
+
+ template <typename T>
+ struct is_lua_primitive : std::integral_constant<bool,
+ type::userdata != lua_type_of<meta::unqualified_t<T>>::value
+ || (lua_size<T>::value > 1)
+ || std::is_base_of<reference, meta::unqualified_t<T>>::value
+ || std::is_base_of<stack_reference, meta::unqualified_t<T>>::value
+ || meta::is_specialization_of<std::tuple, meta::unqualified_t<T>>::value
+ || meta::is_specialization_of<std::pair, meta::unqualified_t<T>>::value
+ > { };
+
+ template <typename T>
+ struct is_lua_reference : std::integral_constant<bool,
+ std::is_base_of<reference, meta::unqualified_t<T>>::value
+ || std::is_base_of<stack_reference, meta::unqualified_t<T>>::value
+ || meta::is_specialization_of<proxy, meta::unqualified_t<T>>::value
+ > { };
+
+ template <typename T>
+ struct is_lua_primitive<T*> : std::true_type {};
+ template <typename T>
+ struct is_lua_primitive<std::reference_wrapper<T>> : std::true_type { };
+ template <typename T>
+ struct is_lua_primitive<user<T>> : std::true_type { };
+ template <typename T>
+ struct is_lua_primitive<light<T>> : is_lua_primitive<T*> { };
+ template <typename T>
+ struct is_lua_primitive<optional<T>> : std::true_type {};
+ template <>
+ struct is_lua_primitive<userdata_value> : std::true_type {};
+ template <>
+ struct is_lua_primitive<lightuserdata_value> : std::true_type {};
+ template <typename T>
+ struct is_lua_primitive<non_null<T>> : is_lua_primitive<T*> {};
+
+ template <typename T>
+ struct is_proxy_primitive : is_lua_primitive<T> { };
+
+ template <typename T>
+ struct is_transparent_argument : std::false_type {};
+
+ template <>
+ struct is_transparent_argument<this_state> : std::true_type {};
+
+ template <>
+ struct is_transparent_argument<variadic_args> : std::true_type {};
+
+ template <typename Signature>
+ struct lua_bind_traits : meta::bind_traits<Signature> {
+ private:
+ typedef meta::bind_traits<Signature> base_t;
+ public:
+ static const std::size_t true_arity = base_t::arity;
+ static const std::size_t arity = base_t::arity - meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
+ static const std::size_t true_free_arity = base_t::free_arity;
+ static const std::size_t free_arity = base_t::free_arity - meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
+ };
+
+ template <typename T>
+ struct is_table : std::false_type {};
+ template <bool x, typename T>
+ struct is_table<basic_table_core<x, T>> : std::true_type {};
+
+ template <typename T>
+ struct is_function : std::false_type {};
+ template <typename T>
+ struct is_function<basic_function<T>> : std::true_type {};
+ template <typename T>
+ struct is_function<basic_protected_function<T>> : std::true_type {};
+
+ template <typename T>
+ struct is_lightuserdata : std::false_type {};
+ template <typename T>
+ struct is_lightuserdata<basic_lightuserdata<T>> : std::true_type {};
+
+ template <typename T>
+ struct is_userdata : std::false_type {};
+ template <typename T>
+ struct is_userdata<basic_userdata<T>> : std::true_type {};
+
+ template<typename T>
+ inline type type_of() {
+ return lua_type_of<meta::unqualified_t<T>>::value;
+ }
+} // sol
+
+// end of sol/types.hpp
+
+// beginning of sol/stack_reference.hpp
+
+namespace sol {
+ class stack_reference {
+ private:
+ lua_State* L = nullptr;
+ int index = 0;
+
+ protected:
+ int registry_index() const noexcept {
+ return LUA_NOREF;
+ }
+
+ public:
+ stack_reference() noexcept = default;
+ stack_reference(nil_t) noexcept : stack_reference() {};
+ stack_reference(lua_State* L, int i) noexcept : L(L), index(lua_absindex(L, i)) {}
+ stack_reference(lua_State* L, absolute_index i) noexcept : L(L), index(i) {}
+ stack_reference(lua_State* L, raw_index i) noexcept : L(L), index(i) {}
+ stack_reference(stack_reference&& o) noexcept = default;
+ stack_reference& operator=(stack_reference&&) noexcept = default;
+ stack_reference(const stack_reference&) noexcept = default;
+ stack_reference& operator=(const stack_reference&) noexcept = default;
+
+ int push() const noexcept {
+ lua_pushvalue(L, index);
+ return 1;
+ }
+
+ void pop(int n = 1) const noexcept {
+ lua_pop(lua_state(), n);
+ }
+
+ int stack_index() const noexcept {
+ return index;
+ }
+
+ type get_type() const noexcept {
+ int result = lua_type(L, index);
+ return static_cast<type>(result);
+ }
+
+ lua_State* lua_state() const noexcept {
+ return L;
+ }
+
+ bool valid() const noexcept {
+ type t = get_type();
+ return t != type::nil && t != type::none;
+ }
+ };
+
+ inline bool operator== (const stack_reference& l, const stack_reference& r) {
+ return lua_compare(l.lua_state(), l.stack_index(), r.stack_index(), LUA_OPEQ) == 0;
+ }
+
+ inline bool operator!= (const stack_reference& l, const stack_reference& r) {
+ return !operator==(l, r);
+ }
+} // sol
+
+// end of sol/stack_reference.hpp
+
+namespace sol {
+ namespace stack {
+ template <bool top_level>
+ struct push_popper_n {
+ lua_State* L;
+ int t;
+ push_popper_n(lua_State* L, int x) : L(L), t(x) { }
+ ~push_popper_n() { lua_pop(L, t); }
+ };
+ template <>
+ struct push_popper_n<true> {
+ push_popper_n(lua_State*, int) { }
+ };
+ template <bool top_level, typename T>
+ struct push_popper {
+ T t;
+ push_popper(T x) : t(x) { t.push(); }
+ ~push_popper() { t.pop(); }
+ };
+ template <typename T>
+ struct push_popper<true, T> {
+ push_popper(T) {}
+ ~push_popper() {}
+ };
+ template <bool top_level = false, typename T>
+ push_popper<top_level, T> push_pop(T&& x) {
+ return push_popper<top_level, T>(std::forward<T>(x));
+ }
+ template <bool top_level = false>
+ push_popper_n<top_level> pop_n(lua_State* L, int x) {
+ return push_popper_n<top_level>(L, x);
+ }
+ } // stack
+
+ namespace detail {
+ struct global_tag { } const global_{};
+ } // detail
+
+ class reference {
+ private:
+ lua_State* L = nullptr; // non-owning
+ int ref = LUA_NOREF;
+
+ int copy() const noexcept {
+ if (ref == LUA_NOREF)
+ return LUA_NOREF;
+ push();
+ return luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+
+ protected:
+ reference(lua_State* L, detail::global_tag) noexcept : L(L) {
+ lua_pushglobaltable(L);
+ ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+
+ int stack_index() const noexcept {
+ return -1;
+ }
+
+ public:
+ reference() noexcept = default;
+ reference(nil_t) noexcept : reference() {}
+ reference(const stack_reference& r) noexcept : reference(r.lua_state(), r.stack_index()) {}
+ reference(stack_reference&& r) noexcept : reference(r.lua_state(), r.stack_index()) {}
+ reference(lua_State* L, int index = -1) noexcept : L(L) {
+ lua_pushvalue(L, index);
+ ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+
+ virtual ~reference() noexcept {
+ luaL_unref(L, LUA_REGISTRYINDEX, ref);
+ }
+
+ reference(reference&& o) noexcept {
+ L = o.L;
+ ref = o.ref;
+
+ o.L = nullptr;
+ o.ref = LUA_NOREF;
+ }
+
+ reference& operator=(reference&& o) noexcept {
+ L = o.L;
+ ref = o.ref;
+
+ o.L = nullptr;
+ o.ref = LUA_NOREF;
+
+ return *this;
+ }
+
+ reference(const reference& o) noexcept {
+ L = o.L;
+ ref = o.copy();
+ }
+
+ reference& operator=(const reference& o) noexcept {
+ L = o.L;
+ ref = o.copy();
+ return *this;
+ }
+
+ int push() const noexcept {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
+ return 1;
+ }
+
+ void pop(int n = 1) const noexcept {
+ lua_pop(lua_state(), n);
+ }
+
+ int registry_index() const noexcept {
+ return ref;
+ }
+
+ bool valid() const noexcept {
+ return !(ref == LUA_NOREF || ref == LUA_REFNIL);
+ }
+
+ explicit operator bool() const noexcept {
+ return valid();
+ }
+
+ type get_type() const noexcept {
+ auto pp = stack::push_pop(*this);
+ int result = lua_type(L, -1);
+ return static_cast<type>(result);
+ }
+
+ lua_State* lua_state() const noexcept {
+ return L;
+ }
+ };
+
+ inline bool operator== (const reference& l, const reference& r) {
+ auto ppl = stack::push_pop(l);
+ auto ppr = stack::push_pop(r);
+ return lua_compare(l.lua_state(), -1, -2, LUA_OPEQ) == 1;
+ }
+
+ inline bool operator!= (const reference& l, const reference& r) {
+ return !operator==(l, r);
+ }
+} // sol
+
+// end of sol/reference.hpp
+
+// beginning of sol/stack.hpp
+
+// beginning of sol/stack_core.hpp
+
+// beginning of sol/userdata.hpp
+
+namespace sol {
+ template <typename base_t>
+ class basic_userdata : public base_t {
+ public:
+ basic_userdata() noexcept = default;
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_userdata>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_userdata(T&& r) noexcept : base_t(std::forward<T>(r)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!is_userdata<meta::unqualified_t<T>>::value) {
+ auto pp = stack::push_pop(*this);
+ type_assert(base_t::lua_state(), -1, type::userdata);
+ }
+#endif // Safety
+ }
+ basic_userdata(const basic_userdata&) = default;
+ basic_userdata(basic_userdata&&) = default;
+ basic_userdata& operator=(const basic_userdata&) = default;
+ basic_userdata& operator=(basic_userdata&&) = default;
+ basic_userdata(const stack_reference& r) : basic_userdata(r.lua_state(), r.stack_index()) {}
+ basic_userdata(stack_reference&& r) : basic_userdata(r.lua_state(), r.stack_index()) {}
+ basic_userdata(lua_State* L, int index = -1) : base_t(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ type_assert(L, index, type::userdata);
+#endif // Safety
+ }
+ };
+
+ template <typename base_t>
+ class basic_lightuserdata : public base_t {
+ public:
+ basic_lightuserdata() noexcept = default;
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_lightuserdata>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_lightuserdata(T&& r) noexcept : base_t(std::forward<T>(r)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!is_userdata<meta::unqualified_t<T>>::value) {
+ auto pp = stack::push_pop(*this);
+ type_assert(base_t::lua_state(), -1, type::lightuserdata);
+ }
+#endif // Safety
+ }
+ basic_lightuserdata(const basic_lightuserdata&) = default;
+ basic_lightuserdata(basic_lightuserdata&&) = default;
+ basic_lightuserdata& operator=(const basic_lightuserdata&) = default;
+ basic_lightuserdata& operator=(basic_lightuserdata&&) = default;
+ basic_lightuserdata(const stack_reference& r) : basic_lightuserdata(r.lua_state(), r.stack_index()) {}
+ basic_lightuserdata(stack_reference&& r) : basic_lightuserdata(r.lua_state(), r.stack_index()) {}
+ basic_lightuserdata(lua_State* L, int index = -1) : base_t(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ type_assert(L, index, type::lightuserdata);
+#endif // Safety
+ }
+ };
+
+} // sol
+
+// end of sol/userdata.hpp
+
+// beginning of sol/tie.hpp
+
+namespace sol {
+
+ namespace detail {
+ template <typename T>
+ struct is_speshul : std::false_type {};
+ }
+
+ template <typename T>
+ struct tie_size : std::tuple_size<T> {};
+
+ template <typename T>
+ struct is_tieable : std::integral_constant<bool, (::sol::tie_size<T>::value > 0)> {};
+
+ template <typename... Tn>
+ struct tie_t : public std::tuple<std::add_lvalue_reference_t<Tn>...> {
+ private:
+ typedef std::tuple<std::add_lvalue_reference_t<Tn>...> base_t;
+
+ template <typename T>
+ void set(std::false_type, T&& target) {
+ std::get<0>(*this) = std::forward<T>(target);
+ }
+
+ template <typename T>
+ void set(std::true_type, T&& target) {
+ typedef tie_size<meta::unqualified_t<T>> value_size;
+ typedef tie_size<std::tuple<Tn...>> tie_size;
+ typedef std::conditional_t<(value_size::value < tie_size::value), value_size, tie_size> indices_size;
+ typedef std::make_index_sequence<indices_size::value> indices;
+ set_extra(detail::is_speshul<meta::unqualified_t<T>>(), indices(), std::forward<T>(target));
+ }
+
+ template <std::size_t... I, typename T>
+ void set_extra(std::true_type, std::index_sequence<I...>, T&& target) {
+ using std::get;
+ (void)detail::swallow{ 0,
+ (get<I>(*this) = get<I>(types<Tn...>(), target), 0)...
+ , 0 };
+ }
+
+ template <std::size_t... I, typename T>
+ void set_extra(std::false_type, std::index_sequence<I...>, T&& target) {
+ using std::get;
+ (void)detail::swallow{ 0,
+ (get<I>(*this) = get<I>(target), 0)...
+ , 0 };
+ }
+
+ public:
+ using base_t::base_t;
+
+ template <typename T>
+ tie_t& operator= (T&& value) {
+ typedef is_tieable<meta::unqualified_t<T>> tieable;
+ set(tieable(), std::forward<T>(value));
+ return *this;
+ }
+
+ };
+
+ template <typename... Tn>
+ struct tie_size< tie_t<Tn...> > : std::tuple_size< std::tuple<Tn...> > { };
+
+ namespace adl_barrier_detail {
+ template <typename... Tn>
+ inline tie_t<std::remove_reference_t<Tn>...> tie(Tn&&... argn) {
+ return tie_t<std::remove_reference_t<Tn>...>(std::forward<Tn>(argn)...);
+ }
+ }
+
+ using namespace adl_barrier_detail;
+
+} // sol
+
+// end of sol/tie.hpp
+
+// beginning of sol/stack_guard.hpp
+
+namespace sol {
+ namespace detail {
+ inline void stack_fail(int, int) {
+#ifndef SOL_NO_EXCEPTIONS
+ throw error(detail::direct_error, "imbalanced stack after operation finish");
+#else
+ // Lol, what do you want, an error printout? :3c
+ // There's no sane default here. The right way would be C-style abort(), and that's not acceptable, so
+ // hopefully someone will register their own stack_fail thing for the `fx` parameter of stack_guard.
+#endif // No Exceptions
+ }
+ } // detail
+
+ struct stack_guard {
+ lua_State* L;
+ int top;
+ std::function<void(int, int)> on_mismatch;
+
+ stack_guard(lua_State* L) : stack_guard(L, lua_gettop(L)) {}
+ stack_guard(lua_State* L, int top, std::function<void(int, int)> fx = detail::stack_fail) : L(L), top(top), on_mismatch(std::move(fx)) {}
+ bool check_stack(int modification = 0) const {
+ int bottom = lua_gettop(L) + modification;
+ if (top == bottom) {
+ return true;
+ }
+ on_mismatch(top, bottom);
+ return false;
+ }
+ ~stack_guard() {
+ check_stack();
+ }
+ };
+} // sol
+
+// end of sol/stack_guard.hpp
+
+#include <vector>
+
+namespace sol {
+ namespace detail {
+ struct as_reference_tag {};
+ template <typename T>
+ struct as_pointer_tag {};
+ template <typename T>
+ struct as_value_tag {};
+
+ using special_destruct_func = void(*)(void*);
+
+ template <typename T, typename Real>
+ inline void special_destruct(void* memory) {
+ T** pointerpointer = static_cast<T**>(memory);
+ special_destruct_func* dx = static_cast<special_destruct_func*>(static_cast<void*>(pointerpointer + 1));
+ Real* target = static_cast<Real*>(static_cast<void*>(dx + 1));
+ target->~Real();
+ }
+
+ template <typename T>
+ inline int unique_destruct(lua_State* L) {
+ void* memory = lua_touserdata(L, 1);
+ T** pointerpointer = static_cast<T**>(memory);
+ special_destruct_func& dx = *static_cast<special_destruct_func*>(static_cast<void*>(pointerpointer + 1));
+ (dx)(memory);
+ return 0;
+ }
+
+ template <typename T>
+ inline int user_alloc_destroy(lua_State* L) {
+ void* rawdata = lua_touserdata(L, upvalue_index(1));
+ T* data = static_cast<T*>(rawdata);
+ std::allocator<T> alloc;
+ alloc.destroy(data);
+ return 0;
+ }
+
+ template <typename T>
+ inline int usertype_alloc_destroy(lua_State* L) {
+ void* rawdata = lua_touserdata(L, 1);
+ T** pdata = static_cast<T**>(rawdata);
+ T* data = *pdata;
+ std::allocator<T> alloc{};
+ alloc.destroy(data);
+ return 0;
+ }
+
+ template <typename T>
+ void reserve(T&, std::size_t) {}
+
+ template <typename T, typename Al>
+ void reserve(std::vector<T, Al>& arr, std::size_t hint) {
+ arr.reserve(hint);
+ }
+
+ template <typename T, typename Tr, typename Al>
+ void reserve(std::basic_string<T, Tr, Al>& arr, std::size_t hint) {
+ arr.reserve(hint);
+ }
+ } // detail
+
+ namespace stack {
+
+ template<typename T, bool global = false, bool raw = false, typename = void>
+ struct field_getter;
+ template <typename T, bool global = false, bool raw = false, typename = void>
+ struct probe_field_getter;
+ template<typename T, bool global = false, bool raw = false, typename = void>
+ struct field_setter;
+ template<typename T, typename = void>
+ struct getter;
+ template<typename T, typename = void>
+ struct popper;
+ template<typename T, typename = void>
+ struct pusher;
+ template<typename T, type = lua_type_of<T>::value, typename = void>
+ struct checker;
+ template<typename T, typename = void>
+ struct check_getter;
+
+ struct probe {
+ bool success;
+ int levels;
+
+ probe(bool s, int l) : success(s), levels(l) {}
+
+ operator bool() const { return success; };
+ };
+
+ struct record {
+ int last;
+ int used;
+
+ record() : last(), used() {}
+ void use(int count) {
+ last = count;
+ used += count;
+ }
+ };
+
+ namespace stack_detail {
+ template <typename T>
+ struct strip {
+ typedef T type;
+ };
+ template <typename T>
+ struct strip<std::reference_wrapper<T>> {
+ typedef T& type;
+ };
+ template <typename T>
+ struct strip<user<T>> {
+ typedef T& type;
+ };
+ template <typename T>
+ struct strip<non_null<T>> {
+ typedef T type;
+ };
+ template <typename T>
+ using strip_t = typename strip<T>::type;
+ const bool default_check_arguments =
+#ifdef SOL_CHECK_ARGUMENTS
+ true;
+#else
+ false;
+#endif
+ template<typename T>
+ inline decltype(auto) unchecked_get(lua_State* L, int index, record& tracking) {
+ return getter<meta::unqualified_t<T>>{}.get(L, index, tracking);
+ }
+ } // stack_detail
+
+ inline bool maybe_indexable(lua_State* L, int index = -1) {
+ type t = type_of(L, index);
+ return t == type::userdata || t == type::table;
+ }
+
+ template<typename T, typename... Args>
+ inline int push(lua_State* L, T&& t, Args&&... args) {
+ return pusher<meta::unqualified_t<T>>{}.push(L, std::forward<T>(t), std::forward<Args>(args)...);
+ }
+
+ // overload allows to use a pusher of a specific type, but pass in any kind of args
+ template<typename T, typename Arg, typename... Args, typename = std::enable_if_t<!std::is_same<T, Arg>::value>>
+ inline int push(lua_State* L, Arg&& arg, Args&&... args) {
+ return pusher<meta::unqualified_t<T>>{}.push(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
+ }
+
+ template<typename T, typename... Args>
+ inline int push_reference(lua_State* L, T&& t, Args&&... args) {
+ typedef meta::all<
+ std::is_lvalue_reference<T>,
+ meta::neg<std::is_const<T>>,
+ meta::neg<is_lua_primitive<meta::unqualified_t<T>>>,
+ meta::neg<is_unique_usertype<meta::unqualified_t<T>>>
+ > use_reference_tag;
+ return pusher<std::conditional_t<use_reference_tag::value, detail::as_reference_tag, meta::unqualified_t<T>>>{}.push(L, std::forward<T>(t), std::forward<Args>(args)...);
+ }
+
+ inline int multi_push(lua_State*) {
+ // do nothing
+ return 0;
+ }
+
+ template<typename T, typename... Args>
+ inline int multi_push(lua_State* L, T&& t, Args&&... args) {
+ int pushcount = push(L, std::forward<T>(t));
+ void(sol::detail::swallow{ (pushcount += sol::stack::push(L, std::forward<Args>(args)), 0)... });
+ return pushcount;
+ }
+
+ inline int multi_push_reference(lua_State*) {
+ // do nothing
+ return 0;
+ }
+
+ template<typename T, typename... Args>
+ inline int multi_push_reference(lua_State* L, T&& t, Args&&... args) {
+ int pushcount = push_reference(L, std::forward<T>(t));
+ void(sol::detail::swallow{ (pushcount += sol::stack::push_reference(L, std::forward<Args>(args)), 0)... });
+ return pushcount;
+ }
+
+ template <typename T, typename Handler>
+ bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ typedef meta::unqualified_t<T> Tu;
+ checker<Tu> c;
+ // VC++ has a bad warning here: shut it up
+ (void)c;
+ return c.check(L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template <typename T, typename Handler>
+ bool check(lua_State* L, int index, Handler&& handler) {
+ record tracking{};
+ return check<T>(L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template <typename T>
+ bool check(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
+ auto handler = no_panic;
+ return check<T>(L, index, handler);
+ }
+
+ template<typename T, typename Handler>
+ inline decltype(auto) check_get(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return check_getter<meta::unqualified_t<T>>{}.get(L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template<typename T, typename Handler>
+ inline decltype(auto) check_get(lua_State* L, int index, Handler&& handler) {
+ record tracking{};
+ return check_get<T>(L, index, handler, tracking);
+ }
+
+ template<typename T>
+ inline decltype(auto) check_get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
+ auto handler = no_panic;
+ return check_get<T>(L, index, handler);
+ }
+
+ namespace stack_detail {
+
+#ifdef SOL_CHECK_ARGUMENTS
+ template <typename T>
+ inline auto tagged_get(types<T>, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) {
+ auto op = check_get<T>(L, index, type_panic, tracking);
+ return *op;
+ }
+#else
+ template <typename T>
+ inline decltype(auto) tagged_get(types<T>, lua_State* L, int index, record& tracking) {
+ return stack_detail::unchecked_get<T>(L, index, tracking);
+ }
+#endif
+
+ template <typename T>
+ inline decltype(auto) tagged_get(types<optional<T>>, lua_State* L, int index, record& tracking) {
+ return stack_detail::unchecked_get<optional<T>>(L, index, tracking);
+ }
+
+ template <bool b>
+ struct check_types {
+ template <typename T, typename... Args, typename Handler>
+ static bool check(types<T, Args...>, lua_State* L, int firstargument, Handler&& handler, record& tracking) {
+ if (!stack::check<T>(L, firstargument + tracking.used, handler, tracking))
+ return false;
+ return check(types<Args...>(), L, firstargument, std::forward<Handler>(handler), tracking);
+ }
+
+ template <typename Handler>
+ static bool check(types<>, lua_State*, int, Handler&&, record&) {
+ return true;
+ }
+ };
+
+ template <>
+ struct check_types<false> {
+ template <typename... Args, typename Handler>
+ static bool check(types<Args...>, lua_State*, int, Handler&&, record&) {
+ return true;
+ }
+ };
+
+ } // stack_detail
+
+ template <bool b, typename... Args, typename Handler>
+ bool multi_check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return stack_detail::check_types<b>{}.check(types<meta::unqualified_t<Args>...>(), L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template <bool b, typename... Args, typename Handler>
+ bool multi_check(lua_State* L, int index, Handler&& handler) {
+ record tracking{};
+ return multi_check<b, Args...>(L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template <bool b, typename... Args>
+ bool multi_check(lua_State* L, int index) {
+ auto handler = no_panic;
+ return multi_check<b, Args...>(L, index, handler);
+ }
+
+ template <typename... Args, typename Handler>
+ bool multi_check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return multi_check<true, Args...>(L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template <typename... Args, typename Handler>
+ bool multi_check(lua_State* L, int index, Handler&& handler) {
+ return multi_check<true, Args...>(L, index, std::forward<Handler>(handler));
+ }
+
+ template <typename... Args>
+ bool multi_check(lua_State* L, int index) {
+ return multi_check<true, Args...>(L, index);
+ }
+
+ template<typename T>
+ inline decltype(auto) get(lua_State* L, int index, record& tracking) {
+ return stack_detail::tagged_get(types<T>(), L, index, tracking);
+ }
+
+ template<typename T>
+ inline decltype(auto) get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
+ record tracking{};
+ return get<T>(L, index, tracking);
+ }
+
+ template<typename T>
+ inline decltype(auto) pop(lua_State* L) {
+ return popper<meta::unqualified_t<T>>{}.pop(L);
+ }
+
+ template <bool global = false, bool raw = false, typename Key>
+ void get_field(lua_State* L, Key&& key) {
+ field_getter<meta::unqualified_t<Key>, global, raw>{}.get(L, std::forward<Key>(key));
+ }
+
+ template <bool global = false, bool raw = false, typename Key>
+ void get_field(lua_State* L, Key&& key, int tableindex) {
+ field_getter<meta::unqualified_t<Key>, global, raw>{}.get(L, std::forward<Key>(key), tableindex);
+ }
+
+ template <bool global = false, typename Key>
+ void raw_get_field(lua_State* L, Key&& key) {
+ get_field<global, true>(L, std::forward<Key>(key));
+ }
+
+ template <bool global = false, typename Key>
+ void raw_get_field(lua_State* L, Key&& key, int tableindex) {
+ get_field<global, true>(L, std::forward<Key>(key), tableindex);
+ }
+
+ template <bool global = false, bool raw = false, typename Key>
+ probe probe_get_field(lua_State* L, Key&& key) {
+ return probe_field_getter<meta::unqualified_t<Key>, global, raw>{}.get(L, std::forward<Key>(key));
+ }
+
+ template <bool global = false, bool raw = false, typename Key>
+ probe probe_get_field(lua_State* L, Key&& key, int tableindex) {
+ return probe_field_getter<meta::unqualified_t<Key>, global, raw>{}.get(L, std::forward<Key>(key), tableindex);
+ }
+
+ template <bool global = false, typename Key>
+ probe probe_raw_get_field(lua_State* L, Key&& key) {
+ return probe_get_field<global, true>(L, std::forward<Key>(key));
+ }
+
+ template <bool global = false, typename Key>
+ probe probe_raw_get_field(lua_State* L, Key&& key, int tableindex) {
+ return probe_get_field<global, true>(L, std::forward<Key>(key), tableindex);
+ }
+
+ template <bool global = false, bool raw = false, typename Key, typename Value>
+ void set_field(lua_State* L, Key&& key, Value&& value) {
+ field_setter<meta::unqualified_t<Key>, global, raw>{}.set(L, std::forward<Key>(key), std::forward<Value>(value));
+ }
+
+ template <bool global = false, bool raw = false, typename Key, typename Value>
+ void set_field(lua_State* L, Key&& key, Value&& value, int tableindex) {
+ field_setter<meta::unqualified_t<Key>, global, raw>{}.set(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
+ }
+
+ template <bool global = false, typename Key, typename Value>
+ void raw_set_field(lua_State* L, Key&& key, Value&& value) {
+ set_field<global, true>(L, std::forward<Key>(key), std::forward<Value>(value));
+ }
+
+ template <bool global = false, typename Key, typename Value>
+ void raw_set_field(lua_State* L, Key&& key, Value&& value, int tableindex) {
+ set_field<global, true>(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
+ }
+ } // stack
+} // sol
+
+// end of sol/stack_core.hpp
+
+// beginning of sol/stack_check.hpp
+
+// beginning of sol/usertype_traits.hpp
+
+// beginning of sol/demangle.hpp
+
+#include <cctype>
+
+namespace sol {
+ namespace detail {
+#ifdef _MSC_VER
+ template <typename T>
+ inline std::string ctti_get_type_name() {
+ const static std::array<std::string, 7> removals = { { "public:", "private:", "protected:", "struct ", "class ", "`anonymous-namespace'", "`anonymous namespace'" } };
+ std::string name = __FUNCSIG__;
+ std::size_t start = name.find("get_type_name");
+ if (start == std::string::npos)
+ start = 0;
+ else
+ start += 13;
+ if (start < name.size() - 1)
+ start += 1;
+ std::size_t end = name.find_last_of('>');
+ if (end == std::string::npos)
+ end = name.size();
+ name = name.substr(start, end - start);
+ if (name.find("struct", 0) == 0)
+ name.replace(0, 6, "", 0);
+ if (name.find("class", 0) == 0)
+ name.replace(0, 5, "", 0);
+ while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
+ while (!name.empty() && std::isblank(name.back())) name.pop_back();
+
+ for (std::size_t r = 0; r < removals.size(); ++r) {
+ auto found = name.find(removals[r]);
+ while (found != std::string::npos) {
+ name.erase(found, removals[r].size());
+ found = name.find(removals[r]);
+ }
+ }
+
+ return name;
+ }
+#elif defined(__GNUC__) || defined(__clang__)
+ template <typename T, class seperator_mark = int>
+ inline std::string ctti_get_type_name() {
+ const static std::array<std::string, 2> removals = { { "{anonymous}", "(anonymous namespace)" } };
+ std::string name = __PRETTY_FUNCTION__;
+ std::size_t start = name.find_first_of('[');
+ start = name.find_first_of('=', start);
+ std::size_t end = name.find_last_of(']');
+ if (end == std::string::npos)
+ end = name.size();
+ if (start == std::string::npos)
+ start = 0;
+ if (start < name.size() - 1)
+ start += 1;
+ name = name.substr(start, end - start);
+ start = name.rfind("seperator_mark");
+ if (start != std::string::npos) {
+ name.erase(start - 2, name.length());
+ }
+ while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
+ while (!name.empty() && std::isblank(name.back())) name.pop_back();
+
+ for (std::size_t r = 0; r < removals.size(); ++r) {
+ auto found = name.find(removals[r]);
+ while (found != std::string::npos) {
+ name.erase(found, removals[r].size());
+ found = name.find(removals[r]);
+ }
+ }
+
+ return name;
+ }
+#else
+#error Compiler not supported for demangling
+#endif // compilers
+
+ template <typename T>
+ inline std::string demangle_once() {
+ std::string realname = ctti_get_type_name<T>();
+ return realname;
+ }
+
+ template <typename T>
+ inline std::string short_demangle_once() {
+ std::string realname = ctti_get_type_name<T>();
+ // This isn't the most complete but it'll do for now...?
+ static const std::array<std::string, 10> ops = { { "operator<", "operator<<", "operator<<=", "operator<=", "operator>", "operator>>", "operator>>=", "operator>=", "operator->", "operator->*" } };
+ int level = 0;
+ std::ptrdiff_t idx = 0;
+ for (idx = static_cast<std::ptrdiff_t>(realname.empty() ? 0 : realname.size() - 1); idx > 0; --idx) {
+ if (level == 0 && realname[idx] == ':') {
+ break;
+ }
+ bool isleft = realname[idx] == '<';
+ bool isright = realname[idx] == '>';
+ if (!isleft && !isright)
+ continue;
+ bool earlybreak = false;
+ for (const auto& op : ops) {
+ std::size_t nisop = realname.rfind(op, idx);
+ if (nisop == std::string::npos)
+ continue;
+ std::size_t nisopidx = idx - op.size() + 1;
+ if (nisop == nisopidx) {
+ idx = static_cast<std::ptrdiff_t>(nisopidx);
+ earlybreak = true;
+ }
+ break;
+ }
+ if (earlybreak) {
+ continue;
+ }
+ level += isleft ? -1 : 1;
+ }
+ if (idx > 0) {
+ realname.erase(0, realname.length() < static_cast<std::size_t>(idx) ? realname.length() : idx + 1);
+ }
+ return realname;
+ }
+
+ template <typename T>
+ inline std::string demangle() {
+ static const std::string d = demangle_once<T>();
+ return d;
+ }
+
+ template <typename T>
+ inline std::string short_demangle() {
+ static const std::string d = short_demangle_once<T>();
+ return d;
+ }
+ } // detail
+} // sol
+
+// end of sol/demangle.hpp
+
+namespace sol {
+
+ template<typename T>
+ struct usertype_traits {
+ static const std::string name;
+ static const std::string qualified_name;
+ static const std::string metatable;
+ static const std::string user_gc_metatable;
+ static const std::string gc_table;
+ };
+
+ template<typename T>
+ const std::string usertype_traits<T>::name = detail::short_demangle<T>();
+
+ template<typename T>
+ const std::string usertype_traits<T>::qualified_name = detail::demangle<T>();
+
+ template<typename T>
+ const std::string usertype_traits<T>::metatable = std::string("sol.").append(detail::demangle<T>());
+
+ template<typename T>
+ const std::string usertype_traits<T>::user_gc_metatable = std::string("sol.").append(detail::demangle<T>()).append(".user\xE2\x99\xBB");
+
+ template<typename T>
+ const std::string usertype_traits<T>::gc_table = std::string("sol.").append(detail::demangle<T>().append(".\xE2\x99\xBB"));
+
+}
+
+// end of sol/usertype_traits.hpp
+
+// beginning of sol/inheritance.hpp
+
+#include <atomic>
+
+namespace sol {
+ template <typename... Args>
+ struct base_list { };
+ template <typename... Args>
+ using bases = base_list<Args...>;
+
+ typedef bases<> base_classes_tag;
+ const auto base_classes = base_classes_tag();
+
+ namespace detail {
+
+ template <typename T>
+ struct has_derived {
+ static bool value;
+ };
+
+ template <typename T>
+ bool has_derived<T>::value = false;
+
+ inline std::size_t unique_id() {
+ static std::atomic<std::size_t> x(0);
+ return ++x;
+ }
+
+ template <typename T>
+ struct id_for {
+ static const std::size_t value;
+ };
+
+ template <typename T>
+ const std::size_t id_for<T>::value = unique_id();
+
+ inline decltype(auto) base_class_check_key() {
+ static const auto& key = "class_check";
+ return key;
+ }
+
+ inline decltype(auto) base_class_cast_key() {
+ static const auto& key = "class_cast";
+ return key;
+ }
+
+ inline decltype(auto) base_class_index_propogation_key() {
+ static const auto& key = u8"\xF0\x9F\x8C\xB2.index";
+ return key;
+ }
+
+ inline decltype(auto) base_class_new_index_propogation_key() {
+ static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index";
+ return key;
+ }
+
+ template <typename T, typename... Bases>
+ struct inheritance {
+ static bool type_check_bases(types<>, std::size_t) {
+ return false;
+ }
+
+ template <typename Base, typename... Args>
+ static bool type_check_bases(types<Base, Args...>, std::size_t ti) {
+ return ti == id_for<Base>::value || type_check_bases(types<Args...>(), ti);
+ }
+
+ static bool type_check(std::size_t ti) {
+ return ti == id_for<T>::value || type_check_bases(types<Bases...>(), ti);
+ }
+
+ static void* type_cast_bases(types<>, T*, std::size_t) {
+ return nullptr;
+ }
+
+ template <typename Base, typename... Args>
+ static void* type_cast_bases(types<Base, Args...>, T* data, std::size_t ti) {
+ // Make sure to convert to T first, and then dynamic cast to the proper type
+ return ti != id_for<Base>::value ? type_cast_bases(types<Args...>(), data, ti) : static_cast<void*>(static_cast<Base*>(data));
+ }
+
+ static void* type_cast(void* voiddata, std::size_t ti) {
+ T* data = static_cast<T*>(voiddata);
+ return static_cast<void*>(ti != id_for<T>::value ? type_cast_bases(types<Bases...>(), data, ti) : data);
+ }
+ };
+
+ using inheritance_check_function = decltype(&inheritance<void>::type_check);
+ using inheritance_cast_function = decltype(&inheritance<void>::type_cast);
+
+ } // detail
+} // sol
+
+// end of sol/inheritance.hpp
+
+#include <utility>
+
+namespace sol {
+ namespace stack {
+ namespace stack_detail {
+ template <typename T, bool poptable = true>
+ inline bool check_metatable(lua_State* L, int index = -2) {
+ const auto& metakey = usertype_traits<T>::metatable;
+ luaL_getmetatable(L, &metakey[0]);
+ const type expectedmetatabletype = static_cast<type>(lua_type(L, -1));
+ if (expectedmetatabletype != type::nil) {
+ if (lua_rawequal(L, -1, index) == 1) {
+ lua_pop(L, 1 + static_cast<int>(poptable));
+ return true;
+ }
+ }
+ lua_pop(L, 1);
+ return false;
+ }
+
+ template <type expected, int(*check_func)(lua_State*, int)>
+ struct basic_check {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ bool success = check_func(L, index) == 1;
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, expected, type_of(L, index));
+ }
+ return success;
+ }
+ };
+ } // stack_detail
+
+ template <typename T, type expected, typename>
+ struct checker {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ const type indextype = type_of(L, index);
+ bool success = expected == indextype;
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, expected, indextype);
+ }
+ return success;
+ }
+ };
+
+ template <type expected, typename C>
+ struct checker<nil_t, expected, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ bool success = lua_isnil(L, index);
+ if (success) {
+ tracking.use(1);
+ return success;
+ }
+ tracking.use(0);
+ success = lua_isnone(L, index);
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, expected, type_of(L, index));
+ }
+ return success;
+ }
+ };
+
+ template <type expected, typename C>
+ struct checker<nullopt_t, expected, C> : checker<nil_t> {};
+
+ template <typename C>
+ struct checker<this_state, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State*, int, Handler&&, record& tracking) {
+ tracking.use(0);
+ return true;
+ }
+ };
+
+ template <typename C>
+ struct checker<variadic_args, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State*, int, Handler&&, record& tracking) {
+ tracking.use(0);
+ return true;
+ }
+ };
+
+ template <typename C>
+ struct checker<type, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State*, int, Handler&&, record& tracking) {
+ tracking.use(0);
+ return true;
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<T, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ bool success = !lua_isnone(L, index);
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, type::none, type_of(L, index));
+ }
+ return success;
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<T, type::lightuserdata, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ type t = type_of(L, index);
+ bool success = t == type::userdata || t == type::lightuserdata;
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, type::lightuserdata, t);
+ }
+ return success;
+ }
+ };
+
+ template <typename C>
+ struct checker<userdata_value, type::userdata, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ type t = type_of(L, index);
+ bool success = t == type::userdata;
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, type::userdata, t);
+ }
+ return success;
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<user<T>, type::userdata, C> : checker<user<T>, type::lightuserdata, C> {};
+
+ template <typename T, typename C>
+ struct checker<non_null<T>, type::userdata, C> : checker<T, lua_type_of<T>::value, C> {};
+
+ template <typename C>
+ struct checker<lua_CFunction, type::function, C> : stack_detail::basic_check<type::function, lua_iscfunction> {};
+ template <typename C>
+ struct checker<std::remove_pointer_t<lua_CFunction>, type::function, C> : checker<lua_CFunction, type::function, C> {};
+ template <typename C>
+ struct checker<c_closure, type::function, C> : checker<lua_CFunction, type::function, C> {};
+
+ template <typename T, typename C>
+ struct checker<T, type::function, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ type t = type_of(L, index);
+ if (t == type::nil || t == type::none || t == type::function) {
+ // allow for nil to be returned
+ return true;
+ }
+ if (t != type::userdata && t != type::table) {
+ handler(L, index, type::function, t);
+ return false;
+ }
+ // Do advanced check for call-style userdata?
+ static const auto& callkey = name_of(meta_function::call);
+ if (lua_getmetatable(L, index) == 0) {
+ // No metatable, no __call key possible
+ handler(L, index, type::function, t);
+ return false;
+ }
+ if (lua_isnoneornil(L, -1)) {
+ lua_pop(L, 1);
+ handler(L, index, type::function, t);
+ return false;
+ }
+ lua_getfield(L, -1, &callkey[0]);
+ if (lua_isnoneornil(L, -1)) {
+ lua_pop(L, 2);
+ handler(L, index, type::function, t);
+ return false;
+ }
+ // has call, is definitely a function
+ lua_pop(L, 2);
+ return true;
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<T, type::table, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ type t = type_of(L, index);
+ if (t == type::table) {
+ return true;
+ }
+ if (t != type::userdata) {
+ handler(L, index, type::function, t);
+ return false;
+ }
+ return true;
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<T*, type::userdata, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ const type indextype = type_of(L, index);
+ // Allow nil to be transformed to nullptr
+ if (indextype == type::nil) {
+ tracking.use(1);
+ return true;
+ }
+ return checker<meta::unqualified_t<T>, type::userdata, C>{}.check(types<meta::unqualified_t<T>>(), L, indextype, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<T, type::userdata, C> {
+ template <typename U, typename Handler>
+ static bool check(types<U>, lua_State* L, type indextype, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ if (indextype != type::userdata) {
+ handler(L, index, type::userdata, indextype);
+ return false;
+ }
+ if (meta::any<std::is_same<T, lightuserdata_value>, std::is_same<T, userdata_value>, std::is_same<T, userdata>, std::is_same<T, lightuserdata>>::value)
+ return true;
+ if (lua_getmetatable(L, index) == 0) {
+ return true;
+ }
+ int metatableindex = lua_gettop(L);
+ if (stack_detail::check_metatable<U>(L, metatableindex))
+ return true;
+ if (stack_detail::check_metatable<U*>(L, metatableindex))
+ return true;
+ if (stack_detail::check_metatable<detail::unique_usertype<U>>(L, metatableindex))
+ return true;
+ bool success = false;
+ if (detail::has_derived<T>::value) {
+ auto pn = stack::pop_n(L, 1);
+ lua_pushstring(L, &detail::base_class_check_key()[0]);
+ lua_rawget(L, metatableindex);
+ if (type_of(L, -1) != type::nil) {
+ void* basecastdata = lua_touserdata(L, -1);
+ detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata;
+ success = ic(detail::id_for<T>::value);
+ }
+ }
+ if (!success) {
+ lua_pop(L, 1);
+ handler(L, index, type::userdata, indextype);
+ return false;
+ }
+ lua_pop(L, 1);
+ return true;
+ }
+
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ const type indextype = type_of(L, index);
+ return check(types<T>(), L, indextype, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template<typename T>
+ struct checker<T, type::userdata, std::enable_if_t<is_unique_usertype<T>::value>> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return checker<typename unique_usertype_traits<T>::type, type::userdata>{}.check(L, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template<typename T, typename C>
+ struct checker<std::reference_wrapper<T>, type::userdata, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return checker<T, type::userdata, C>{}.check(L, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template<typename... Args, typename C>
+ struct checker<std::tuple<Args...>, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return stack::multi_check<Args...>(L, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template<typename A, typename B, typename C>
+ struct checker<std::pair<A, B>, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return stack::multi_check<A, B>(L, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template<typename T, typename C>
+ struct checker<optional<T>, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ type t = type_of(L, index);
+ if (t == type::none) {
+ tracking.use(0);
+ return true;
+ }
+ return t == type::nil || stack::check<T>(L, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+ } // stack
+} // sol
+
+// end of sol/stack_check.hpp
+
+// beginning of sol/stack_get.hpp
+
+// beginning of sol/overload.hpp
+
+namespace sol {
+ template <typename... Functions>
+ struct overload_set {
+ std::tuple<Functions...> functions;
+ template <typename Arg, typename... Args, meta::disable<std::is_same<overload_set, meta::unqualified_t<Arg>>> = meta::enabler>
+ overload_set (Arg&& arg, Args&&... args) : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+ overload_set(const overload_set&) = default;
+ overload_set(overload_set&&) = default;
+ overload_set& operator=(const overload_set&) = default;
+ overload_set& operator=(overload_set&&) = default;
+ };
+
+ template <typename... Args>
+ decltype(auto) overload(Args&&... args) {
+ return overload_set<std::decay_t<Args>...>(std::forward<Args>(args)...);
+ }
+}
+
+// end of sol/overload.hpp
+
+#ifdef SOL_CODECVT_SUPPORT
+#include <codecvt>
+#include <locale>
+#endif
+
+namespace sol {
+ namespace stack {
+
+ template<typename T, typename>
+ struct getter {
+ static T& get(lua_State* L, int index, record& tracking) {
+ return getter<T&>{}.get(L, index, tracking);
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<std::is_floating_point<T>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<T>(lua_tonumber(L, index));
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_signed<T>>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<T>(lua_tointeger(L, index));
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_unsigned<T>>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<T>(lua_tointeger(L, index));
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<std::is_enum<T>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<T>(lua_tointegerx(L, index, nullptr));
+ }
+ };
+
+ template<typename T>
+ struct getter<as_table_t<T>, std::enable_if_t<!meta::has_key_value_pair<meta::unqualified_t<T>>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ typedef typename T::value_type V;
+ tracking.use(1);
+
+ index = lua_absindex(L, index);
+ T arr;
+ get_field<false, true>(L, static_cast<lua_Integer>(-1), index);
+ int isnum;
+ std::size_t sizehint = static_cast<std::size_t>(lua_tointegerx(L, -1, &isnum));
+ if (isnum != 0) {
+ detail::reserve(arr, sizehint);
+ }
+ lua_pop(L, 1);
+#if SOL_LUA_VERSION >= 503
+ // This method is HIGHLY performant over regular table iteration thanks to the Lua API changes in 5.3
+ for (lua_Integer i = 0; ; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
+ for (int vi = 0; vi < lua_size<V>::value; ++vi) {
+ type t = static_cast<type>(lua_geti(L, index, i + vi));
+ if (t == type::nil) {
+ if (i == 0) {
+ continue;
+ }
+ else {
+ lua_pop(L, (vi + 1));
+ return arr;
+ }
+ }
+ }
+ arr.push_back(stack::get<V>(L, -lua_size<V>::value));
+ }
+#else
+ // Zzzz slower but necessary thanks to the lower version API and missing functions qq
+ for (lua_Integer i = 0; ; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
+ for (int vi = 0; vi < lua_size<V>::value; ++vi) {
+ lua_pushinteger(L, i);
+ lua_gettable(L, index);
+ type t = type_of(L, -1);
+ if (t == type::nil) {
+ if (i == 0) {
+ continue;
+ }
+ else {
+ lua_pop(L, (vi + 1));
+ return arr;
+ }
+ }
+ }
+ arr.push_back(stack::get<V>(L, -1));
+ }
+#endif
+ return arr;
+ }
+ };
+
+ template<typename T>
+ struct getter<as_table_t<T>, std::enable_if_t<meta::has_key_value_pair<meta::unqualified_t<T>>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ typedef typename T::value_type P;
+ typedef typename P::first_type K;
+ typedef typename P::second_type V;
+ tracking.use(1);
+
+ T associative;
+ index = lua_absindex(L, index);
+ lua_pushnil(L);
+ while (lua_next(L, index) != 0) {
+ decltype(auto) key = stack::check_get<K>(L, -2);
+ if (!key) {
+ lua_pop(L, 1);
+ continue;
+ }
+ associative.emplace(std::forward<decltype(*key)>(*key), stack::get<V>(L, -1));
+ lua_pop(L, 1);
+ }
+ return associative;
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<std::is_base_of<reference, T>::value || std::is_base_of<stack_reference, T>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return T(L, index);
+ }
+ };
+
+ template<>
+ struct getter<userdata_value> {
+ static userdata_value get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return userdata_value(lua_touserdata(L, index));
+ }
+ };
+
+ template<>
+ struct getter<lightuserdata_value> {
+ static lightuserdata_value get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return lightuserdata_value(lua_touserdata(L, index));
+ }
+ };
+
+ template<typename T>
+ struct getter<light<T>> {
+ static light<T> get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return light<T>(static_cast<T*>(lua_touserdata(L, index)));
+ }
+ };
+
+ template<typename T>
+ struct getter<user<T>> {
+ static T& get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return *static_cast<T*>(lua_touserdata(L, index));
+ }
+ };
+
+ template<typename T>
+ struct getter<user<T*>> {
+ static T* get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<T*>(lua_touserdata(L, index));
+ }
+ };
+
+ template<>
+ struct getter<type> {
+ static type get(lua_State *L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<type>(lua_type(L, index));
+ }
+ };
+
+ template<>
+ struct getter<bool> {
+ static bool get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return lua_toboolean(L, index) != 0;
+ }
+ };
+
+ template<>
+ struct getter<std::string> {
+ static std::string get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ std::size_t len;
+ auto str = lua_tolstring(L, index, &len);
+ return std::string( str, len );
+ }
+ };
+
+ template <>
+ struct getter<string_detail::string_shim> {
+ string_detail::string_shim get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t len;
+ const char* p = lua_tolstring(L, index, &len);
+ return string_detail::string_shim(p, len);
+ }
+ };
+
+ template<>
+ struct getter<const char*> {
+ static const char* get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return lua_tostring(L, index);
+ }
+ };
+
+ template<>
+ struct getter<char> {
+ static char get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t len;
+ auto str = lua_tolstring(L, index, &len);
+ return len > 0 ? str[0] : '\0';
+ }
+ };
+
+#ifdef SOL_CODECVT_SUPPORT
+ template<>
+ struct getter<std::wstring> {
+ static std::wstring get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t len;
+ auto str = lua_tolstring(L, index, &len);
+ if (len < 1)
+ return std::wstring();
+ if (sizeof(wchar_t) == 2) {
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
+ std::wstring r = convert.from_bytes(str, str + len);
+#ifdef __MINGW32__
+ // Fuck you, MinGW, and fuck you libstdc++ for introducing this absolutely asinine bug
+ // https://sourceforge.net/p/mingw-w64/bugs/538/
+ // http://chat.stackoverflow.com/transcript/message/32271369#32271369
+ for (auto& c : r) {
+ uint8_t* b = reinterpret_cast<uint8_t*>(&c);
+ std::swap(b[0], b[1]);
+ }
+#endif
+ return r;
+ }
+ std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
+ std::wstring r = convert.from_bytes(str, str + len);
+ return r;
+ }
+ };
+
+ template<>
+ struct getter<std::u16string> {
+ static std::u16string get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t len;
+ auto str = lua_tolstring(L, index, &len);
+ if (len < 1)
+ return std::u16string();
+#ifdef _MSC_VER
+ std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert;
+ auto intd = convert.from_bytes(str, str + len);
+ std::u16string r(intd.size(), '\0');
+ std::memcpy(&r[0], intd.data(), intd.size() * sizeof(char16_t));
+#else
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+ std::u16string r = convert.from_bytes(str, str + len);
+#endif // VC++ is a shit
+ return r;
+ }
+ };
+
+ template<>
+ struct getter<std::u32string> {
+ static std::u32string get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t len;
+ auto str = lua_tolstring(L, index, &len);
+ if (len < 1)
+ return std::u32string();
+#ifdef _MSC_VER
+ std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> convert;
+ auto intd = convert.from_bytes(str, str + len);
+ std::u32string r(intd.size(), '\0');
+ std::memcpy(&r[0], intd.data(), r.size() * sizeof(char32_t));
+#else
+ std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
+ std::u32string r = convert.from_bytes(str, str + len);
+#endif // VC++ is a shit
+ return r;
+ }
+ };
+
+ template<>
+ struct getter<wchar_t> {
+ static wchar_t get(lua_State* L, int index, record& tracking) {
+ auto str = getter<std::wstring>{}.get(L, index, tracking);
+ return str.size() > 0 ? str[0] : wchar_t(0);
+ }
+ };
+
+ template<>
+ struct getter<char16_t> {
+ static char16_t get(lua_State* L, int index, record& tracking) {
+ auto str = getter<std::u16string>{}.get(L, index, tracking);
+ return str.size() > 0 ? str[0] : char16_t(0);
+ }
+ };
+
+ template<>
+ struct getter<char32_t> {
+ static char32_t get(lua_State* L, int index, record& tracking) {
+ auto str = getter<std::u32string>{}.get(L, index, tracking);
+ return str.size() > 0 ? str[0] : char32_t(0);
+ }
+ };
+#endif // codecvt header support
+
+ template<>
+ struct getter<meta_function> {
+ static meta_function get(lua_State *L, int index, record& tracking) {
+ tracking.use(1);
+ const char* name = getter<const char*>{}.get(L, index, tracking);
+ for (std::size_t i = 0; i < meta_function_names.size(); ++i)
+ if (meta_function_names[i] == name)
+ return static_cast<meta_function>(i);
+ return meta_function::construct;
+ }
+ };
+
+ template<>
+ struct getter<nil_t> {
+ static nil_t get(lua_State*, int, record& tracking) {
+ tracking.use(1);
+ return nil;
+ }
+ };
+
+ template<>
+ struct getter<std::nullptr_t> {
+ static std::nullptr_t get(lua_State*, int, record& tracking) {
+ tracking.use(1);
+ return nullptr;
+ }
+ };
+
+ template<>
+ struct getter<nullopt_t> {
+ static nullopt_t get(lua_State*, int, record& tracking) {
+ tracking.use(1);
+ return nullopt;
+ }
+ };
+
+ template<>
+ struct getter<this_state> {
+ static this_state get(lua_State* L, int, record& tracking) {
+ tracking.use(0);
+ return this_state{ L };
+ }
+ };
+
+ template<>
+ struct getter<lua_CFunction> {
+ static lua_CFunction get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return lua_tocfunction(L, index);
+ }
+ };
+
+ template<>
+ struct getter<c_closure> {
+ static c_closure get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return c_closure(lua_tocfunction(L, index), -1);
+ }
+ };
+
+ template<>
+ struct getter<error> {
+ static error get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t sz = 0;
+ const char* err = lua_tolstring(L, index, &sz);
+ if (err == nullptr) {
+ return error(detail::direct_error, "");
+ }
+ return error(detail::direct_error, std::string(err, sz));
+ }
+ };
+
+ template<>
+ struct getter<void*> {
+ static void* get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return lua_touserdata(L, index);
+ }
+ };
+
+ template<typename T>
+ struct getter<T*> {
+ static T* get_no_nil(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ void** pudata = static_cast<void**>(lua_touserdata(L, index));
+ void* udata = *pudata;
+ return get_no_nil_from(L, udata, index, tracking);
+ }
+
+ static T* get_no_nil_from(lua_State* L, void* udata, int index, record&) {
+ if (detail::has_derived<T>::value && luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) {
+ void* basecastdata = lua_touserdata(L, -1);
+ detail::inheritance_cast_function ic = (detail::inheritance_cast_function)basecastdata;
+ // use the casting function to properly adjust the pointer for the desired T
+ udata = ic(udata, detail::id_for<T>::value);
+ lua_pop(L, 1);
+ }
+ T* obj = static_cast<T*>(udata);
+ return obj;
+ }
+
+ static T* get(lua_State* L, int index, record& tracking) {
+ type t = type_of(L, index);
+ if (t == type::nil) {
+ tracking.use(1);
+ return nullptr;
+ }
+ return get_no_nil(L, index, tracking);
+ }
+ };
+
+ template<typename T>
+ struct getter<non_null<T*>> {
+ static T* get(lua_State* L, int index, record& tracking) {
+ return getter<T*>::get_no_nil(L, index, tracking);
+ }
+ };
+
+ template<typename T>
+ struct getter<T&> {
+ static T& get(lua_State* L, int index, record& tracking) {
+ return *getter<T*>::get_no_nil(L, index, tracking);
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<is_unique_usertype<T>::value>> {
+ typedef typename unique_usertype_traits<T>::type P;
+ typedef typename unique_usertype_traits<T>::actual_type Real;
+
+ static Real& get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ P** pref = static_cast<P**>(lua_touserdata(L, index));
+ detail::special_destruct_func* fx = static_cast<detail::special_destruct_func*>(static_cast<void*>(pref + 1));
+ Real* mem = static_cast<Real*>(static_cast<void*>(fx + 1));
+ return *mem;
+ }
+ };
+
+ template<typename T>
+ struct getter<std::reference_wrapper<T>> {
+ static T& get(lua_State* L, int index, record& tracking) {
+ return getter<T&>{}.get(L, index, tracking);
+ }
+ };
+
+ template<typename... Args>
+ struct getter<std::tuple<Args...>> {
+ typedef std::tuple<decltype(stack::get<Args>(nullptr, 0))...> R;
+
+ template <typename... TArgs>
+ static R apply(std::index_sequence<>, lua_State*, int, record&, TArgs&&... args) {
+ // Fuck you too, VC++
+ return R{std::forward<TArgs>(args)...};
+ }
+
+ template <std::size_t I, std::size_t... Ix, typename... TArgs>
+ static R apply(std::index_sequence<I, Ix...>, lua_State* L, int index, record& tracking, TArgs&&... args) {
+ // Fuck you too, VC++
+ typedef std::tuple_element_t<I, std::tuple<Args...>> T;
+ return apply(std::index_sequence<Ix...>(), L, index, tracking, std::forward<TArgs>(args)..., stack::get<T>(L, index + tracking.used, tracking));
+ }
+
+ static R get(lua_State* L, int index, record& tracking) {
+ return apply(std::make_index_sequence<sizeof...(Args)>(), L, index, tracking);
+ }
+ };
+
+ template<typename A, typename B>
+ struct getter<std::pair<A, B>> {
+ static decltype(auto) get(lua_State* L, int index, record& tracking) {
+ return std::pair<decltype(stack::get<A>(L, index)), decltype(stack::get<B>(L, index))>{stack::get<A>(L, index, tracking), stack::get<B>(L, index + tracking.used, tracking)};
+ }
+ };
+
+ } // stack
+} // sol
+
+// end of sol/stack_get.hpp
+
+// beginning of sol/stack_check_get.hpp
+
+namespace sol {
+ namespace stack {
+ template <typename T, typename>
+ struct check_getter {
+ typedef decltype(stack_detail::unchecked_get<T>(nullptr, 0, std::declval<record&>())) R;
+
+ template <typename Handler>
+ static optional<R> get(lua_State* L, int index, Handler&& handler, record& tracking) {
+ if (!check<T>(L, index, std::forward<Handler>(handler))) {
+ tracking.use(static_cast<int>(!lua_isnone(L, index)));
+ return nullopt;
+ }
+ return stack_detail::unchecked_get<T>(L, index, tracking);
+ }
+ };
+
+ template <typename T>
+ struct check_getter<optional<T>> {
+ template <typename Handler>
+ static decltype(auto) get(lua_State* L, int index, Handler&&, record& tracking) {
+ return check_get<T>(L, index, no_panic, tracking);
+ }
+ };
+
+ template <typename T>
+ struct check_getter<T, std::enable_if_t<std::is_integral<T>::value && lua_type_of<T>::value == type::number>> {
+ template <typename Handler>
+ static optional<T> get(lua_State* L, int index, Handler&& handler, record& tracking) {
+ int isnum = 0;
+ lua_Integer value = lua_tointegerx(L, index, &isnum);
+ if (isnum == 0) {
+ type t = type_of(L, index);
+ tracking.use(static_cast<int>(t != type::none));
+ handler(L, index, type::number, t);
+ return nullopt;
+ }
+ tracking.use(1);
+ return static_cast<T>(value);
+ }
+ };
+
+ template <typename T>
+ struct check_getter<T, std::enable_if_t<std::is_enum<T>::value && !meta::any_same<T, meta_function, type>::value>> {
+ template <typename Handler>
+ static optional<T> get(lua_State* L, int index, Handler&& handler, record& tracking) {
+ int isnum = 0;
+ lua_Integer value = lua_tointegerx(L, index, &isnum);
+ if (isnum == 0) {
+ type t = type_of(L, index);
+ tracking.use(static_cast<int>(t != type::none));
+ handler(L, index, type::number, t);
+ return nullopt;
+ }
+ tracking.use(1);
+ return static_cast<T>(value);
+ }
+ };
+
+ template <typename T>
+ struct check_getter<T, std::enable_if_t<std::is_floating_point<T>::value>> {
+ template <typename Handler>
+ static optional<T> get(lua_State* L, int index, Handler&& handler, record& tracking) {
+ int isnum = 0;
+ lua_Number value = lua_tonumberx(L, index, &isnum);
+ if (isnum == 0) {
+ type t = type_of(L, index);
+ tracking.use(static_cast<int>(t != type::none));
+ handler(L, index, type::number, t);
+ return nullopt;
+ }
+ tracking.use(1);
+ return static_cast<T>(value);
+ }
+ };
+
+ template <typename T>
+ struct getter<optional<T>> {
+ static decltype(auto) get(lua_State* L, int index, record& tracking) {
+ return check_get<T>(L, index, no_panic, tracking);
+ }
+ };
+ } // stack
+} // sol
+
+// end of sol/stack_check_get.hpp
+
+// beginning of sol/stack_push.hpp
+
+// beginning of sol/raii.hpp
+
+namespace sol {
+ namespace detail {
+ struct default_construct {
+ template<typename T, typename... Args>
+ static void construct(T&& obj, Args&&... args) {
+ std::allocator<meta::unqualified_t<T>> alloc{};
+ alloc.construct(obj, std::forward<Args>(args)...);
+ }
+
+ template<typename T, typename... Args>
+ void operator()(T&& obj, Args&&... args) const {
+ construct(std::forward<T>(obj), std::forward<Args>(args)...);
+ }
+ };
+
+ struct default_destruct {
+ template<typename T>
+ static void destroy(T&& obj) {
+ std::allocator<meta::unqualified_t<T>> alloc{};
+ alloc.destroy(obj);
+ }
+
+ template<typename T>
+ void operator()(T&& obj) const {
+ destroy(std::forward<T>(obj));
+ }
+ };
+
+ struct deleter {
+ template <typename T>
+ void operator()(T* p) const {
+ delete p;
+ }
+ };
+
+ template <typename T, typename Dx, typename... Args>
+ inline std::unique_ptr<T, Dx> make_unique_deleter(Args&&... args) {
+ return std::unique_ptr<T, Dx>(new T(std::forward<Args>(args)...));
+ }
+
+ template <typename Tag, typename T>
+ struct tagged {
+ T value;
+ template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, tagged>> = meta::enabler>
+ tagged(Arg&& arg, Args&&... args) : value(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+ };
+ } // detail
+
+ template <typename... Args>
+ struct constructor_list {};
+
+ template<typename... Args>
+ using constructors = constructor_list<Args...>;
+
+ const auto default_constructor = constructors<types<>>{};
+
+ struct no_construction {};
+ const auto no_constructor = no_construction{};
+
+ struct call_construction {};
+ const auto call_constructor = call_construction{};
+
+ template <typename... Functions>
+ struct constructor_wrapper {
+ std::tuple<Functions...> functions;
+ template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, constructor_wrapper>> = meta::enabler>
+ constructor_wrapper(Arg&& arg, Args&&... args) : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+ };
+
+ template <typename... Functions>
+ inline auto initializers(Functions&&... functions) {
+ return constructor_wrapper<std::decay_t<Functions>...>(std::forward<Functions>(functions)...);
+ }
+
+ template <typename... Functions>
+ struct factory_wrapper {
+ std::tuple<Functions...> functions;
+ template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, factory_wrapper>> = meta::enabler>
+ factory_wrapper(Arg&& arg, Args&&... args) : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+ };
+
+ template <typename... Functions>
+ inline auto factories(Functions&&... functions) {
+ return factory_wrapper<std::decay_t<Functions>...>(std::forward<Functions>(functions)...);
+ }
+
+ template <typename Function>
+ struct destructor_wrapper {
+ Function fx;
+ destructor_wrapper(Function f) : fx(std::move(f)) {}
+ };
+
+ template <>
+ struct destructor_wrapper<void> {};
+
+ const destructor_wrapper<void> default_destructor{};
+
+ template <typename Fx>
+ inline auto destructor(Fx&& fx) {
+ return destructor_wrapper<std::decay_t<Fx>>(std::forward<Fx>(fx));
+ }
+
+} // sol
+
+// end of sol/raii.hpp
+
+#ifdef SOL_CODECVT_SUPPORT
+#endif
+
+namespace sol {
+ namespace stack {
+ template <typename T>
+ struct pusher<detail::as_value_tag<T>> {
+ template <typename F, typename... Args>
+ static int push_fx(lua_State* L, F&& f, Args&&... args) {
+ // Basically, we store all user-data like this:
+ // If it's a movable/copyable value (no std::ref(x)), then we store the pointer to the new
+ // data in the first sizeof(T*) bytes, and then however many bytes it takes to
+ // do the actual object. Things that are std::ref or plain T* are stored as
+ // just the sizeof(T*), and nothing else.
+ T** pointerpointer = static_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
+ T*& referencereference = *pointerpointer;
+ T* allocationtarget = reinterpret_cast<T*>(pointerpointer + 1);
+ referencereference = allocationtarget;
+ std::allocator<T> alloc{};
+ alloc.construct(allocationtarget, std::forward<Args>(args)...);
+ f();
+ return 1;
+ }
+
+ template <typename K, typename... Args>
+ static int push_keyed(lua_State* L, K&& k, Args&&... args) {
+ return push_fx(L, [&L, &k]() {
+ luaL_newmetatable(L, &k[0]);
+ lua_setmetatable(L, -2);
+ }, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static int push(lua_State* L, Args&&... args) {
+ return push_keyed(L, usertype_traits<T>::metatable, std::forward<Args>(args)...);
+ }
+ };
+
+ template <typename T>
+ struct pusher<detail::as_pointer_tag<T>> {
+ template <typename F>
+ static int push_fx(lua_State* L, F&& f, T* obj) {
+ if (obj == nullptr)
+ return stack::push(L, nil);
+ T** pref = static_cast<T**>(lua_newuserdata(L, sizeof(T*)));
+ *pref = obj;
+ f();
+ return 1;
+ }
+
+ template <typename K>
+ static int push_keyed(lua_State* L, K&& k, T* obj) {
+ return push_fx(L, [&L, &k]() {
+ luaL_newmetatable(L, &k[0]);
+ lua_setmetatable(L, -2);
+ }, obj);
+ }
+
+ static int push(lua_State* L, T* obj) {
+ return push_keyed(L, usertype_traits<meta::unqualified_t<T>*>::metatable, obj);
+ }
+ };
+
+ template <>
+ struct pusher<detail::as_reference_tag> {
+ template <typename T>
+ static int push(lua_State* L, T&& obj) {
+ return stack::push(L, detail::ptr(obj));
+ }
+ };
+
+ template<typename T, typename>
+ struct pusher {
+ template <typename... Args>
+ static int push(lua_State* L, Args&&... args) {
+ return pusher<detail::as_value_tag<T>>{}.push(L, std::forward<Args>(args)...);
+ }
+ };
+
+ template<typename T>
+ struct pusher<T*, meta::disable_if_t<meta::all<meta::has_begin_end<meta::unqualified_t<T>>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
+ template <typename... Args>
+ static int push(lua_State* L, Args&&... args) {
+ return pusher<detail::as_pointer_tag<T>>{}.push(L, std::forward<Args>(args)...);
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<is_unique_usertype<T>::value>> {
+ typedef typename unique_usertype_traits<T>::type P;
+ typedef typename unique_usertype_traits<T>::actual_type Real;
+
+ template <typename Arg, meta::enable<std::is_base_of<Real, meta::unqualified_t<Arg>>> = meta::enabler>
+ static int push(lua_State* L, Arg&& arg) {
+ if (unique_usertype_traits<T>::is_null(arg))
+ return stack::push(L, nil);
+ return push_deep(L, std::forward<Arg>(arg));
+ }
+
+ template <typename Arg0, typename Arg1, typename... Args>
+ static int push(lua_State* L, Arg0&& arg0, Arg0&& arg1, Args&&... args) {
+ return push_deep(L, std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static int push_deep(lua_State* L, Args&&... args) {
+ P** pref = static_cast<P**>(lua_newuserdata(L, sizeof(P*) + sizeof(detail::special_destruct_func) + sizeof(Real)));
+ detail::special_destruct_func* fx = static_cast<detail::special_destruct_func*>(static_cast<void*>(pref + 1));
+ Real* mem = static_cast<Real*>(static_cast<void*>(fx + 1));
+ *fx = detail::special_destruct<P, Real>;
+ detail::default_construct::construct(mem, std::forward<Args>(args)...);
+ *pref = unique_usertype_traits<T>::get(*mem);
+ if (luaL_newmetatable(L, &usertype_traits<detail::unique_usertype<P>>::metatable[0]) == 1) {
+ set_field(L, "__gc", detail::unique_destruct<P>);
+ }
+ lua_setmetatable(L, -2);
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<std::reference_wrapper<T>> {
+ static int push(lua_State* L, const std::reference_wrapper<T>& t) {
+ return stack::push(L, std::addressof(detail::deref(t.get())));
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<std::is_floating_point<T>::value>> {
+ static int push(lua_State* L, const T& value) {
+ lua_pushnumber(L, value);
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_signed<T>>::value>> {
+ static int push(lua_State* L, const T& value) {
+ lua_pushinteger(L, static_cast<lua_Integer>(value));
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<std::is_enum<T>::value>> {
+ static int push(lua_State* L, const T& value) {
+ if (std::is_same<char, T>::value) {
+ return stack::push(L, static_cast<int>(value));
+ }
+ return stack::push(L, static_cast<std::underlying_type_t<T>>(value));
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_unsigned<T>>::value>> {
+ static int push(lua_State* L, const T& value) {
+ lua_pushinteger(L, static_cast<lua_Integer>(value));
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<as_table_t<T>, std::enable_if_t<!meta::has_key_value_pair<meta::unqualified_t<std::remove_pointer_t<T>>>::value>> {
+ static int push(lua_State* L, const as_table_t<T>& tablecont) {
+ auto& cont = detail::deref(detail::unwrap(tablecont.source));
+ lua_createtable(L, static_cast<int>(cont.size()), 0);
+ int tableindex = lua_gettop(L);
+ std::size_t index = 1;
+ for (const auto& i : cont) {
+#if SOL_LUA_VERSION >= 503
+ int p = stack::push(L, i);
+ for (int pi = 0; pi < p; ++pi) {
+ lua_seti(L, tableindex, static_cast<lua_Integer>(index++));
+ }
+#else
+ lua_pushinteger(L, static_cast<lua_Integer>(index));
+ int p = stack::push(L, i);
+ if (p == 1) {
+ ++index;
+ lua_settable(L, tableindex);
+ }
+ else {
+ int firstindex = tableindex + 1 + 1;
+ for (int pi = 0; pi < p; ++pi) {
+ stack::push(L, index);
+ lua_pushvalue(L, firstindex);
+ lua_settable(L, tableindex);
+ ++index;
+ ++firstindex;
+ }
+ lua_pop(L, 1 + p);
+ }
+#endif
+ }
+ // TODO: figure out a better way to do this...?
+ //set_field(L, -1, cont.size());
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<as_table_t<T>, std::enable_if_t<meta::has_key_value_pair<meta::unqualified_t<std::remove_pointer_t<T>>>::value>> {
+ static int push(lua_State* L, const as_table_t<T>& tablecont) {
+ auto& cont = detail::deref(detail::unwrap(tablecont.source));
+ lua_createtable(L, static_cast<int>(cont.size()), 0);
+ int tableindex = lua_gettop(L);
+ for (const auto& pair : cont) {
+ set_field(L, pair.first, pair.second, tableindex);
+ }
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<std::is_base_of<reference, T>::value || std::is_base_of<stack_reference, T>::value>> {
+ static int push(lua_State*, const T& ref) {
+ return ref.push();
+ }
+
+ static int push(lua_State*, T&& ref) {
+ return ref.push();
+ }
+ };
+
+ template<>
+ struct pusher<bool> {
+ static int push(lua_State* L, bool b) {
+ lua_pushboolean(L, b);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<nil_t> {
+ static int push(lua_State* L, nil_t) {
+ lua_pushnil(L);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<metatable_key_t> {
+ static int push(lua_State* L, metatable_key_t) {
+ lua_pushlstring(L, "__mt", 4);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<std::remove_pointer_t<lua_CFunction>> {
+ static int push(lua_State* L, lua_CFunction func, int n = 0) {
+ lua_pushcclosure(L, func, n);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<lua_CFunction> {
+ static int push(lua_State* L, lua_CFunction func, int n = 0) {
+ lua_pushcclosure(L, func, n);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<c_closure> {
+ static int push(lua_State* L, c_closure cc) {
+ lua_pushcclosure(L, cc.c_function, cc.upvalues);
+ return 1;
+ }
+ };
+
+ template<typename Arg, typename... Args>
+ struct pusher<closure<Arg, Args...>> {
+ template <std::size_t... I, typename T>
+ static int push(std::index_sequence<I...>, lua_State* L, T&& c) {
+ int pushcount = multi_push(L, detail::forward_get<I>(c.upvalues)...);
+ return stack::push(L, c_closure(c.c_function, pushcount));
+ }
+
+ template <typename T>
+ static int push(lua_State* L, T&& c) {
+ return push(std::make_index_sequence<1 + sizeof...(Args)>(), L, std::forward<T>(c));
+ }
+ };
+
+ template<>
+ struct pusher<void*> {
+ static int push(lua_State* L, void* userdata) {
+ lua_pushlightuserdata(L, userdata);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<lightuserdata_value> {
+ static int push(lua_State* L, lightuserdata_value userdata) {
+ lua_pushlightuserdata(L, userdata);
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<light<T>> {
+ static int push(lua_State* L, light<T> l) {
+ lua_pushlightuserdata(L, static_cast<void*>(l.value));
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<user<T>> {
+ template <bool with_meta = true, typename Key, typename... Args>
+ static int push_with(lua_State* L, Key&& name, Args&&... args) {
+ // A dumb pusher
+ void* rawdata = lua_newuserdata(L, sizeof(T));
+ T* data = static_cast<T*>(rawdata);
+ std::allocator<T> alloc;
+ alloc.construct(data, std::forward<Args>(args)...);
+ if (with_meta) {
+ lua_CFunction cdel = detail::user_alloc_destroy<T>;
+ // Make sure we have a plain GC set for this data
+ if (luaL_newmetatable(L, name) != 0) {
+ lua_pushlightuserdata(L, rawdata);
+ lua_pushcclosure(L, cdel, 1);
+ lua_setfield(L, -2, "__gc");
+ }
+ lua_setmetatable(L, -2);
+ }
+ return 1;
+ }
+
+ template <typename Arg, typename... Args, meta::disable<meta::any_same<meta::unqualified_t<Arg>, no_metatable_t, metatable_key_t>> = meta::enabler>
+ static int push(lua_State* L, Arg&& arg, Args&&... args) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with(L, name, std::forward<Arg>(arg), std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static int push(lua_State* L, no_metatable_t, Args&&... args) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with<false>(L, name, std::forward<Args>(args)...);
+ }
+
+ template <typename Key, typename... Args>
+ static int push(lua_State* L, metatable_key_t, Key&& key, Args&&... args) {
+ const auto name = &key[0];
+ return push_with<true>(L, name, std::forward<Args>(args)...);
+ }
+
+ static int push(lua_State* L, const user<T>& u) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with(L, name, u.value);
+ }
+
+ static int push(lua_State* L, user<T>&& u) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with(L, name, std::move(u.value));
+ }
+
+ static int push(lua_State* L, no_metatable_t, const user<T>& u) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with<false>(L, name, u.value);
+ }
+
+ static int push(lua_State* L, no_metatable_t, user<T>&& u) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with<false>(L, name, std::move(u.value));
+ }
+ };
+
+ template<>
+ struct pusher<userdata_value> {
+ static int push(lua_State* L, userdata_value data) {
+ void** ud = static_cast<void**>(lua_newuserdata(L, sizeof(void*)));
+ *ud = data.value;
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<const char*> {
+ static int push_sized(lua_State* L, const char* str, std::size_t len) {
+ lua_pushlstring(L, str, len);
+ return 1;
+ }
+
+ static int push(lua_State* L, const char* str) {
+ return push_sized(L, str, std::char_traits<char>::length(str));
+ }
+
+ static int push(lua_State* L, const char* strb, const char* stre) {
+ return push_sized(L, strb, stre - strb);
+ }
+
+ static int push(lua_State* L, const char* str, std::size_t len) {
+ return push_sized(L, str, len);
+ }
+ };
+
+ template<size_t N>
+ struct pusher<char[N]> {
+ static int push(lua_State* L, const char(&str)[N]) {
+ lua_pushlstring(L, str, N - 1);
+ return 1;
+ }
+
+ static int push(lua_State* L, const char(&str)[N], std::size_t sz) {
+ lua_pushlstring(L, str, sz);
+ return 1;
+ }
+ };
+
+ template <>
+ struct pusher<char> {
+ static int push(lua_State* L, char c) {
+ const char str[2] = { c, '\0' };
+ return stack::push(L, str, 1);
+ }
+ };
+
+ template<>
+ struct pusher<std::string> {
+ static int push(lua_State* L, const std::string& str) {
+ lua_pushlstring(L, str.c_str(), str.size());
+ return 1;
+ }
+
+ static int push(lua_State* L, const std::string& str, std::size_t sz) {
+ lua_pushlstring(L, str.c_str(), sz);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<meta_function> {
+ static int push(lua_State* L, meta_function m) {
+ const std::string& str = name_of(m);
+ lua_pushlstring(L, str.c_str(), str.size());
+ return 1;
+ }
+ };
+
+#ifdef SOL_CODECVT_SUPPORT
+ template<>
+ struct pusher<const wchar_t*> {
+ static int push(lua_State* L, const wchar_t* wstr) {
+ return push(L, wstr, std::char_traits<wchar_t>::length(wstr));
+ }
+
+ static int push(lua_State* L, const wchar_t* wstr, std::size_t sz) {
+ return push(L, wstr, wstr + sz);
+ }
+
+ static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) {
+ if (sizeof(wchar_t) == 2) {
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
+ std::string u8str = convert.to_bytes(strb, stre);
+ return stack::push(L, u8str);
+ }
+ std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
+ std::string u8str = convert.to_bytes(strb, stre);
+ return stack::push(L, u8str);
+ }
+ };
+
+ template<>
+ struct pusher<const char16_t*> {
+ static int push(lua_State* L, const char16_t* u16str) {
+ return push(L, u16str, std::char_traits<char16_t>::length(u16str));
+ }
+
+ static int push(lua_State* L, const char16_t* u16str, std::size_t sz) {
+ return push(L, u16str, u16str + sz);
+ }
+
+ static int push(lua_State* L, const char16_t* strb, const char16_t* stre) {
+#ifdef _MSC_VER
+ std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert;
+ std::string u8str = convert.to_bytes(reinterpret_cast<const int16_t*>(strb), reinterpret_cast<const int16_t*>(stre));
+#else
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+ std::string u8str = convert.to_bytes(strb, stre);
+#endif // VC++ is a shit
+ return stack::push(L, u8str);
+ }
+ };
+
+ template<>
+ struct pusher<const char32_t*> {
+ static int push(lua_State* L, const char32_t* u32str) {
+ return push(L, u32str, u32str + std::char_traits<char32_t>::length(u32str));
+ }
+
+ static int push(lua_State* L, const char32_t* u32str, std::size_t sz) {
+ return push(L, u32str, u32str + sz);
+ }
+
+ static int push(lua_State* L, const char32_t* strb, const char32_t* stre) {
+#ifdef _MSC_VER
+ std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> convert;
+ std::string u8str = convert.to_bytes(reinterpret_cast<const int32_t*>(strb), reinterpret_cast<const int32_t*>(stre));
+#else
+ std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
+ std::string u8str = convert.to_bytes(strb, stre);
+#endif // VC++ is a shit
+ return stack::push(L, u8str);
+ }
+ };
+
+ template<size_t N>
+ struct pusher<wchar_t[N]> {
+ static int push(lua_State* L, const wchar_t(&str)[N]) {
+ return push(L, str, N - 1);
+ }
+
+ static int push(lua_State* L, const wchar_t(&str)[N], std::size_t sz) {
+ return stack::push<const wchar_t*>(L, str, str + sz);
+ }
+ };
+
+ template<size_t N>
+ struct pusher<char16_t[N]> {
+ static int push(lua_State* L, const char16_t(&str)[N]) {
+ return push(L, str, N - 1);
+ }
+
+ static int push(lua_State* L, const char16_t(&str)[N], std::size_t sz) {
+ return stack::push<const char16_t*>(L, str, str + sz);
+ }
+ };
+
+ template<size_t N>
+ struct pusher<char32_t[N]> {
+ static int push(lua_State* L, const char32_t(&str)[N]) {
+ return push(L, str, N - 1);
+ }
+
+ static int push(lua_State* L, const char32_t(&str)[N], std::size_t sz) {
+ return stack::push<const char32_t*>(L, str, str + sz);
+ }
+ };
+
+ template <>
+ struct pusher<wchar_t> {
+ static int push(lua_State* L, wchar_t c) {
+ const wchar_t str[2] = { c, '\0' };
+ return stack::push(L, str, 1);
+ }
+ };
+
+ template <>
+ struct pusher<char16_t> {
+ static int push(lua_State* L, char16_t c) {
+ const char16_t str[2] = { c, '\0' };
+ return stack::push(L, str, 1);
+ }
+ };
+
+ template <>
+ struct pusher<char32_t> {
+ static int push(lua_State* L, char32_t c) {
+ const char32_t str[2] = { c, '\0' };
+ return stack::push(L, str, 1);
+ }
+ };
+
+ template<>
+ struct pusher<std::wstring> {
+ static int push(lua_State* L, const std::wstring& wstr) {
+ return push(L, wstr.data(), wstr.size());
+ }
+
+ static int push(lua_State* L, const std::wstring& wstr, std::size_t sz) {
+ return stack::push(L, wstr.data(), wstr.data() + sz);
+ }
+ };
+
+ template<>
+ struct pusher<std::u16string> {
+ static int push(lua_State* L, const std::u16string& u16str) {
+ return push(L, u16str, u16str.size());
+ }
+
+ static int push(lua_State* L, const std::u16string& u16str, std::size_t sz) {
+ return stack::push(L, u16str.data(), u16str.data() + sz);
+ }
+ };
+
+ template<>
+ struct pusher<std::u32string> {
+ static int push(lua_State* L, const std::u32string& u32str) {
+ return push(L, u32str, u32str.size());
+ }
+
+ static int push(lua_State* L, const std::u32string& u32str, std::size_t sz) {
+ return stack::push(L, u32str.data(), u32str.data() + sz);
+ }
+ };
+#endif // codecvt Header Support
+
+ template<typename... Args>
+ struct pusher<std::tuple<Args...>> {
+ template <std::size_t... I, typename T>
+ static int push(std::index_sequence<I...>, lua_State* L, T&& t) {
+ int pushcount = 0;
+ (void)detail::swallow{ 0, (pushcount += stack::push(L,
+ detail::forward_get<I>(t)
+ ), 0)... };
+ return pushcount;
+ }
+
+ template <typename T>
+ static int push(lua_State* L, T&& t) {
+ return push(std::index_sequence_for<Args...>(), L, std::forward<T>(t));
+ }
+ };
+
+ template<typename A, typename B>
+ struct pusher<std::pair<A, B>> {
+ template <typename T>
+ static int push(lua_State* L, T&& t) {
+ int pushcount = stack::push(L, detail::forward_get<0>(t));
+ pushcount += stack::push(L, detail::forward_get<1>(t));
+ return pushcount;
+ }
+ };
+
+ template<typename O>
+ struct pusher<optional<O>> {
+ template <typename T>
+ static int push(lua_State* L, T&& t) {
+ if (t == nullopt) {
+ return stack::push(L, nullopt);
+ }
+ return stack::push(L, t.value());
+ }
+ };
+
+ template<>
+ struct pusher<nullopt_t> {
+ static int push(lua_State* L, nullopt_t) {
+ return stack::push(L, nil);
+ }
+ };
+
+ template<>
+ struct pusher<std::nullptr_t> {
+ static int push(lua_State* L, std::nullptr_t) {
+ return stack::push(L, nil);
+ }
+ };
+
+ template<>
+ struct pusher<this_state> {
+ static int push(lua_State*, const this_state&) {
+ return 0;
+ }
+ };
+ } // stack
+} // sol
+
+// end of sol/stack_push.hpp
+
+// beginning of sol/stack_pop.hpp
+
+namespace sol {
+ namespace stack {
+ template <typename T, typename>
+ struct popper {
+ inline static decltype(auto) pop(lua_State* L) {
+ record tracking{};
+ decltype(auto) r = get<T>(L, -lua_size<T>::value, tracking);
+ lua_pop(L, tracking.used);
+ return r;
+ }
+ };
+
+ template <typename T>
+ struct popper<T, std::enable_if_t<std::is_base_of<stack_reference, meta::unqualified_t<T>>::value>> {
+ static_assert(meta::neg<std::is_base_of<stack_reference, meta::unqualified_t<T>>>::value, "You cannot pop something that derives from stack_reference: it will not remain on the stack and thusly will go out of scope!");
+ };
+ } // stack
+} // sol
+
+// end of sol/stack_pop.hpp
+
+// beginning of sol/stack_field.hpp
+
+namespace sol {
+ namespace stack {
+ template <typename T, bool, bool, typename>
+ struct field_getter {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int tableindex = -2) {
+ push(L, std::forward<Key>(key));
+ lua_gettable(L, tableindex);
+ }
+ };
+
+ template <typename T, bool global, typename C>
+ struct field_getter<T, global, true, C> {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int tableindex = -2) {
+ push(L, std::forward<Key>(key));
+ lua_rawget(L, tableindex);
+ }
+ };
+
+ template <bool b, bool raw, typename C>
+ struct field_getter<metatable_key_t, b, raw, C> {
+ void get(lua_State* L, metatable_key_t, int tableindex = -1) {
+ if (lua_getmetatable(L, tableindex) == 0)
+ push(L, nil);
+ }
+ };
+
+ template <typename T, bool raw>
+ struct field_getter<T, true, raw, std::enable_if_t<meta::is_c_str<T>::value>> {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int = -1) {
+ lua_getglobal(L, &key[0]);
+ }
+ };
+
+ template <typename T>
+ struct field_getter<T, false, false, std::enable_if_t<meta::is_c_str<T>::value>> {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int tableindex = -1) {
+ lua_getfield(L, tableindex, &key[0]);
+ }
+ };
+
+#if SOL_LUA_VERSION >= 503
+ template <typename T>
+ struct field_getter<T, false, false, std::enable_if_t<std::is_integral<T>::value>> {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int tableindex = -1) {
+ lua_geti(L, tableindex, static_cast<lua_Integer>(key));
+ }
+ };
+#endif // Lua 5.3.x
+
+#if SOL_LUA_VERSION >= 502
+ template <typename C>
+ struct field_getter<void*, false, true, C> {
+ void get(lua_State* L, void* key, int tableindex = -1) {
+ lua_rawgetp(L, tableindex, key);
+ }
+ };
+#endif // Lua 5.3.x
+
+ template <typename T>
+ struct field_getter<T, false, true, std::enable_if_t<std::is_integral<T>::value>> {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int tableindex = -1) {
+ lua_rawgeti(L, tableindex, static_cast<lua_Integer>(key));
+ }
+ };
+
+ template <typename... Args, bool b, bool raw, typename C>
+ struct field_getter<std::tuple<Args...>, b, raw, C> {
+ template <std::size_t... I, typename Keys>
+ void apply(std::index_sequence<0, I...>, lua_State* L, Keys&& keys, int tableindex) {
+ get_field<b, raw>(L, detail::forward_get<0>(keys), tableindex);
+ void(detail::swallow{ (get_field<false, raw>(L, detail::forward_get<I>(keys)), 0)... });
+ reference saved(L, -1);
+ lua_pop(L, static_cast<int>(sizeof...(I)));
+ saved.push();
+ }
+
+ template <typename Keys>
+ void get(lua_State* L, Keys&& keys) {
+ apply(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), lua_absindex(L, -1));
+ }
+
+ template <typename Keys>
+ void get(lua_State* L, Keys&& keys, int tableindex) {
+ apply(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), tableindex);
+ }
+ };
+
+ template <typename A, typename B, bool b, bool raw, typename C>
+ struct field_getter<std::pair<A, B>, b, raw, C> {
+ template <typename Keys>
+ void get(lua_State* L, Keys&& keys, int tableindex) {
+ get_field<b, raw>(L, detail::forward_get<0>(keys), tableindex);
+ get_field<false, raw>(L, detail::forward_get<1>(keys));
+ reference saved(L, -1);
+ lua_pop(L, static_cast<int>(2));
+ saved.push();
+ }
+
+ template <typename Keys>
+ void get(lua_State* L, Keys&& keys) {
+ get_field<b, raw>(L, detail::forward_get<0>(keys));
+ get_field<false, raw>(L, detail::forward_get<1>(keys));
+ reference saved(L, -1);
+ lua_pop(L, static_cast<int>(2));
+ saved.push();
+ }
+ };
+
+ template <typename T, bool, bool, typename>
+ struct field_setter {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int tableindex = -3) {
+ push(L, std::forward<Key>(key));
+ push(L, std::forward<Value>(value));
+ lua_settable(L, tableindex);
+ }
+ };
+
+ template <typename T, bool b, typename C>
+ struct field_setter<T, b, true, C> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int tableindex = -3) {
+ push(L, std::forward<Key>(key));
+ push(L, std::forward<Value>(value));
+ lua_rawset(L, tableindex);
+ }
+ };
+
+ template <bool b, bool raw, typename C>
+ struct field_setter<metatable_key_t, b, raw, C> {
+ template <typename Value>
+ void set(lua_State* L, metatable_key_t, Value&& value, int tableindex = -2) {
+ push(L, std::forward<Value>(value));
+ lua_setmetatable(L, tableindex);
+ }
+ };
+
+ template <typename T, bool raw>
+ struct field_setter<T, true, raw, std::enable_if_t<meta::is_c_str<T>::value>> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int = -2) {
+ push(L, std::forward<Value>(value));
+ lua_setglobal(L, &key[0]);
+ }
+ };
+
+ template <typename T>
+ struct field_setter<T, false, false, std::enable_if_t<meta::is_c_str<T>::value>> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
+ push(L, std::forward<Value>(value));
+ lua_setfield(L, tableindex, &key[0]);
+ }
+ };
+
+#if SOL_LUA_VERSION >= 503
+ template <typename T>
+ struct field_setter<T, false, false, std::enable_if_t<std::is_integral<T>::value>> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
+ push(L, std::forward<Value>(value));
+ lua_seti(L, tableindex, static_cast<lua_Integer>(key));
+ }
+ };
+#endif // Lua 5.3.x
+
+ template <typename T>
+ struct field_setter<T, false, true, std::enable_if_t<std::is_integral<T>::value>> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
+ push(L, std::forward<Value>(value));
+ lua_rawseti(L, tableindex, static_cast<lua_Integer>(key));
+ }
+ };
+
+#if SOL_LUA_VERSION >= 502
+ template <typename C>
+ struct field_setter<void*, false, true, C> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, void* key, Value&& value, int tableindex = -2) {
+ push(L, std::forward<Value>(value));
+ lua_rawsetp(L, tableindex, key);
+ }
+ };
+#endif // Lua 5.2.x
+
+ template <typename... Args, bool b, bool raw, typename C>
+ struct field_setter<std::tuple<Args...>, b, raw, C> {
+ template <bool g, std::size_t I, typename Key, typename Value>
+ void apply(std::index_sequence<I>, lua_State* L, Key&& keys, Value&& value, int tableindex) {
+ I < 1 ?
+ set_field<g, raw>(L, detail::forward_get<I>(keys), std::forward<Value>(value), tableindex) :
+ set_field<g, raw>(L, detail::forward_get<I>(keys), std::forward<Value>(value));
+ }
+
+ template <bool g, std::size_t I0, std::size_t I1, std::size_t... I, typename Keys, typename Value>
+ void apply(std::index_sequence<I0, I1, I...>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
+ I0 < 1 ? get_field<g, raw>(L, detail::forward_get<I0>(keys), tableindex) : get_field<g, raw>(L, detail::forward_get<I0>(keys), -1);
+ apply<false>(std::index_sequence<I1, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), -1);
+ }
+
+ template <bool g, std::size_t I0, std::size_t... I, typename Keys, typename Value>
+ void top_apply(std::index_sequence<I0, I...>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
+ apply<g>(std::index_sequence<I0, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
+ lua_pop(L, static_cast<int>(sizeof...(I)));
+ }
+
+ template <typename Keys, typename Value>
+ void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -3) {
+ top_apply<b>(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
+ }
+ };
+
+ template <typename A, typename B, bool b, bool raw, typename C>
+ struct field_setter<std::pair<A, B>, b, raw, C> {
+ template <typename Keys, typename Value>
+ void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -1) {
+ get_field<b, raw>(L, detail::forward_get<0>(keys), tableindex);
+ set_field<false, raw>(L, detail::forward_get<1>(keys), std::forward<Value>(value));
+ lua_pop(L, 1);
+ }
+ };
+ } // stack
+} // sol
+
+// end of sol/stack_field.hpp
+
+// beginning of sol/stack_probe.hpp
+
+namespace sol {
+ namespace stack {
+ template <typename T, bool b, bool raw, typename>
+ struct probe_field_getter {
+ template <typename Key>
+ probe get(lua_State* L, Key&& key, int tableindex = -2) {
+ if (!b && !maybe_indexable(L, tableindex)) {
+ return probe(false, 0);
+ }
+ get_field<b, raw>(L, std::forward<Key>(key), tableindex);
+ return probe(!check<nil_t>(L), 1);
+ }
+ };
+
+ template <typename A, typename B, bool b, bool raw, typename C>
+ struct probe_field_getter<std::pair<A, B>, b, raw, C> {
+ template <typename Keys>
+ probe get(lua_State* L, Keys&& keys, int tableindex = -2) {
+ if (!b && !maybe_indexable(L, tableindex)) {
+ return probe(false, 0);
+ }
+ get_field<b, raw>(L, std::get<0>(keys), tableindex);
+ if (!maybe_indexable(L)) {
+ return probe(false, 1);
+ }
+ get_field<false, raw>(L, std::get<1>(keys), tableindex);
+ return probe(!check<nil_t>(L), 2);
+ }
+ };
+
+ template <typename... Args, bool b, bool raw, typename C>
+ struct probe_field_getter<std::tuple<Args...>, b, raw, C> {
+ template <std::size_t I, typename Keys>
+ probe apply(std::index_sequence<I>, int sofar, lua_State* L, Keys&& keys, int tableindex) {
+ get_field < I < 1 && b, raw>(L, std::get<I>(keys), tableindex);
+ return probe(!check<nil_t>(L), sofar);
+ }
+
+ template <std::size_t I, std::size_t I1, std::size_t... In, typename Keys>
+ probe apply(std::index_sequence<I, I1, In...>, int sofar, lua_State* L, Keys&& keys, int tableindex) {
+ get_field < I < 1 && b, raw>(L, std::get<I>(keys), tableindex);
+ if (!maybe_indexable(L)) {
+ return probe(false, sofar);
+ }
+ return apply(std::index_sequence<I1, In...>(), sofar + 1, L, std::forward<Keys>(keys), -1);
+ }
+
+ template <typename Keys>
+ probe get(lua_State* L, Keys&& keys, int tableindex = -2) {
+ if (!b && !maybe_indexable(L, tableindex)) {
+ return probe(false, 0);
+ }
+ return apply(std::index_sequence_for<Args...>(), 1, L, std::forward<Keys>(keys), tableindex);
+ }
+ };
+ } // stack
+} // sol
+
+// end of sol/stack_probe.hpp
+
+#include <cstring>
+
+namespace sol {
+ namespace stack {
+ namespace stack_detail {
+ template<typename T>
+ inline int push_as_upvalues(lua_State* L, T& item) {
+ typedef std::decay_t<T> TValue;
+ const static std::size_t itemsize = sizeof(TValue);
+ const static std::size_t voidsize = sizeof(void*);
+ const static std::size_t voidsizem1 = voidsize - 1;
+ const static std::size_t data_t_count = (sizeof(TValue) + voidsizem1) / voidsize;
+ typedef std::array<void*, data_t_count> data_t;
+
+ data_t data{ {} };
+ std::memcpy(&data[0], std::addressof(item), itemsize);
+ int pushcount = 0;
+ for (auto&& v : data) {
+ pushcount += push(L, lightuserdata_value(v));
+ }
+ return pushcount;
+ }
+
+ template<typename T>
+ inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 1) {
+ const static std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
+ typedef std::array<void*, data_t_count> data_t;
+ data_t voiddata{ {} };
+ for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) {
+ voiddata[i] = get<lightuserdata_value>(L, upvalue_index(index++));
+ }
+ return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
+ }
+
+ struct evaluator {
+ template <typename Fx, typename... Args>
+ static decltype(auto) eval(types<>, std::index_sequence<>, lua_State*, int, record&, Fx&& fx, Args&&... args) {
+ return std::forward<Fx>(fx)(std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename Arg, typename... Args, std::size_t I, std::size_t... Is, typename... FxArgs>
+ static decltype(auto) eval(types<Arg, Args...>, std::index_sequence<I, Is...>, lua_State* L, int start, record& tracking, Fx&& fx, FxArgs&&... fxargs) {
+ return eval(types<Args...>(), std::index_sequence<Is...>(), L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)..., stack_detail::unchecked_get<Arg>(L, start + tracking.used, tracking));
+ }
+ };
+
+ template <bool checkargs = default_check_arguments, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
+ inline decltype(auto) call(types<R>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
+#ifndef _MSC_VER
+ static_assert(meta::all<meta::is_not_move_only<Args>...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention.");
+#endif // This compiler make me so fucking sad
+ multi_check<checkargs, Args...>(L, start, type_panic);
+ record tracking{};
+ return evaluator{}.eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool checkargs = default_check_arguments, std::size_t... I, typename... Args, typename Fx, typename... FxArgs>
+ inline void call(types<void>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
+#ifndef _MSC_VER
+ static_assert(meta::all<meta::is_not_move_only<Args>...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention.");
+#endif // This compiler make me so fucking sad
+ multi_check<checkargs, Args...>(L, start, type_panic);
+ record tracking{};
+ evaluator{}.eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+ } // stack_detail
+
+ template <typename T>
+ int set_ref(lua_State* L, T&& arg, int tableindex = -2) {
+ push(L, std::forward<T>(arg));
+ return luaL_ref(L, tableindex);
+ }
+
+ inline void remove(lua_State* L, int index, int count) {
+ if (count < 1)
+ return;
+ int top = lua_gettop(L);
+ if (index == -1 || top == index) {
+ // Slice them right off the top
+ lua_pop(L, static_cast<int>(count));
+ return;
+ }
+
+ // Remove each item one at a time using stack operations
+ // Probably slower, maybe, haven't benchmarked,
+ // but necessary
+ if (index < 0) {
+ index = lua_gettop(L) + (index + 1);
+ }
+ int last = index + count;
+ for (int i = index; i < last; ++i) {
+ lua_remove(L, i);
+ }
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
+ inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
+ typedef std::make_index_sequence<sizeof...(Args)> args_indices;
+ return stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
+ inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
+ return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
+ inline void call(types<void> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
+ typedef std::make_index_sequence<sizeof...(Args)> args_indices;
+ stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
+ inline void call(types<void> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
+ call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
+ inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
+ return call<check_args>(tr, ta, L, static_cast<int>(lua_gettop(L) - sizeof...(Args)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
+ inline void call_from_top(types<void> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
+ call<check_args>(tr, ta, L, static_cast<int>(lua_gettop(L) - sizeof...(Args)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template<bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
+ inline int call_into_lua(types<void> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
+ call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
+ lua_settop(L, 0);
+ return 0;
+ }
+
+ template<bool check_args = stack_detail::default_check_arguments, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
+ inline int call_into_lua(types<Ret0, Ret...>, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
+ decltype(auto) r = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
+ lua_settop(L, 0);
+ return push_reference(L, std::forward<decltype(r)>(r));
+ }
+
+ template<bool check_args = stack_detail::default_check_arguments, typename Fx, typename... FxArgs>
+ inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
+ typedef lua_bind_traits<meta::unqualified_t<Fx>> traits_type;
+ typedef typename traits_type::args_list args_list;
+ typedef typename traits_type::returns_list returns_list;
+ return call_into_lua(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
+ }
+
+ inline call_syntax get_call_syntax(lua_State* L, const std::string& key, int index = -2) {
+ luaL_getmetatable(L, key.c_str());
+ auto pn = pop_n(L, 1);
+ if (lua_compare(L, -1, index, LUA_OPEQ) == 1) {
+ return call_syntax::colon;
+ }
+ return call_syntax::dot;
+ }
+
+ inline void script(lua_State* L, const std::string& code) {
+ if (luaL_dostring(L, code.c_str())) {
+ lua_error(L);
+ }
+ }
+
+ inline void script_file(lua_State* L, const std::string& filename) {
+ if (luaL_dofile(L, filename.c_str())) {
+ lua_error(L);
+ }
+ }
+
+ inline void luajit_exception_handler(lua_State* L, int(*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) {
+#ifdef SOL_LUAJIT
+ lua_pushlightuserdata(L, (void*)handler);
+ auto pn = pop_n(L, 1);
+ luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
+#else
+ (void)L;
+ (void)handler;
+#endif
+ }
+
+ inline void luajit_exception_off(lua_State* L) {
+#ifdef SOL_LUAJIT
+ luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_OFF);
+#else
+ (void)L;
+#endif
+ }
+ } // stack
+} // sol
+
+// end of sol/stack.hpp
+
+// beginning of sol/variadic_args.hpp
+
+// beginning of sol/stack_proxy.hpp
+
+// beginning of sol/function.hpp
+
+// beginning of sol/function_result.hpp
+
+// beginning of sol/proxy_base.hpp
+
+namespace sol {
+ template <typename Super>
+ struct proxy_base {
+ operator std::string() const {
+ const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
+ return super.template get<std::string>();
+ }
+
+ template<typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, is_proxy_primitive<meta::unqualified_t<T>>> = meta::enabler>
+ operator T () const {
+ const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
+ return super.template get<T>();
+ }
+
+ template<typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, meta::neg<is_proxy_primitive<meta::unqualified_t<T>>>> = meta::enabler>
+ operator T& () const {
+ const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
+ return super.template get<T&>();
+ }
+ };
+} // sol
+
+// end of sol/proxy_base.hpp
+
+#include <cstdint>
+
+namespace sol {
+ struct function_result : public proxy_base<function_result> {
+ private:
+ lua_State* L;
+ int index;
+ int returncount;
+
+ public:
+ function_result() = default;
+ function_result(lua_State* L, int index = -1, int returncount = 0) : L(L), index(index), returncount(returncount) {
+
+ }
+ function_result(const function_result&) = default;
+ function_result& operator=(const function_result&) = default;
+ function_result(function_result&& o) : L(o.L), index(o.index), returncount(o.returncount) {
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ }
+ function_result& operator=(function_result&& o) {
+ L = o.L;
+ index = o.index;
+ returncount = o.returncount;
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ return *this;
+ }
+
+ template<typename T>
+ decltype(auto) get() const {
+ return stack::get<T>(L, index);
+ }
+
+ call_status status() const noexcept {
+ return call_status::ok;
+ }
+
+ bool valid() const noexcept {
+ return status() == call_status::ok || status() == call_status::yielded;
+ }
+
+ lua_State* lua_state() const { return L; };
+ int stack_index() const { return index; };
+
+ ~function_result() {
+ lua_pop(L, returncount);
+ }
+ };
+} // sol
+
+// end of sol/function_result.hpp
+
+// beginning of sol/function_types.hpp
+
+// beginning of sol/function_types_core.hpp
+
+// beginning of sol/wrapper.hpp
+
+namespace sol {
+
+ template <typename F, typename = void>
+ struct wrapper {
+ typedef lua_bind_traits<F> traits_type;
+ typedef typename traits_type::args_list args_list;
+ typedef typename traits_type::args_list free_args_list;
+ typedef typename traits_type::returns_list returns_list;
+
+ template <typename... Args>
+ static decltype(auto) call(F& f, Args&&... args) {
+ return f(std::forward<Args>(args)...);
+ }
+
+ struct caller {
+ template <typename... Args>
+ decltype(auto) operator()(F& fx, Args&&... args) const {
+ return call(fx, std::forward<Args>(args)...);
+ }
+ };
+ };
+
+ template <typename F>
+ struct wrapper<F, std::enable_if_t<std::is_function<meta::unqualified_t<std::remove_pointer_t<F>>>::value>> {
+ typedef lua_bind_traits<F> traits_type;
+ typedef typename traits_type::args_list args_list;
+ typedef typename traits_type::args_list free_args_list;
+ typedef typename traits_type::returns_list returns_list;
+
+ template <F fx, typename... Args>
+ static decltype(auto) invoke(Args&&... args) {
+ return fx(std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static decltype(auto) call(F& fx, Args&&... args) {
+ return fx(std::forward<Args>(args)...);
+ }
+
+ struct caller {
+ template <typename... Args>
+ decltype(auto) operator()(F& fx, Args&&... args) const {
+ return call(fx, std::forward<Args>(args)...);
+ }
+ };
+
+ template <F fx>
+ struct invoker {
+ template <typename... Args>
+ decltype(auto) operator()(Args&&... args) const {
+ return invoke<fx>(std::forward<Args>(args)...);
+ }
+ };
+ };
+
+ template <typename F>
+ struct wrapper<F, std::enable_if_t<std::is_member_object_pointer<meta::unqualified_t<F>>::value>> {
+ typedef lua_bind_traits<F> traits_type;
+ typedef typename traits_type::object_type object_type;
+ typedef typename traits_type::return_type return_type;
+ typedef typename traits_type::args_list args_list;
+ typedef types<object_type&, return_type> free_args_list;
+ typedef typename traits_type::returns_list returns_list;
+
+ template <F fx, typename... Args>
+ static decltype(auto) invoke(object_type& mem, Args&&... args) {
+ return (mem.*fx)(std::forward<Args>(args)...);
+ }
+
+ template <typename Fx>
+ static decltype(auto) call(Fx&& fx, object_type& mem) {
+ return (mem.*fx);
+ }
+
+ template <typename Fx, typename Arg, typename... Args>
+ static void call(Fx&& fx, object_type& mem, Arg&& arg, Args&&...) {
+ (mem.*fx) = std::forward<Arg>(arg);
+ }
+
+ struct caller {
+ template <typename Fx, typename... Args>
+ decltype(auto) operator()(Fx&& fx, object_type& mem, Args&&... args) const {
+ return call(std::forward<Fx>(fx), mem, std::forward<Args>(args)...);
+ }
+ };
+
+ template <F fx>
+ struct invoker {
+ template <typename... Args>
+ decltype(auto) operator()(Args&&... args) const {
+ return invoke<fx>(std::forward<Args>(args)...);
+ }
+ };
+ };
+
+ template <typename F, typename R, typename O, typename... FArgs>
+ struct member_function_wrapper {
+ typedef O object_type;
+ typedef lua_bind_traits<F> traits_type;
+ typedef typename traits_type::args_list args_list;
+ typedef types<object_type&, FArgs...> free_args_list;
+ typedef meta::tuple_types<R> returns_list;
+
+ template <F fx, typename... Args>
+ static R invoke(O& mem, Args&&... args) {
+ return (mem.*fx)(std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename... Args>
+ static R call(Fx&& fx, O& mem, Args&&... args) {
+ return (mem.*fx)(std::forward<Args>(args)...);
+ }
+
+ struct caller {
+ template <typename Fx, typename... Args>
+ decltype(auto) operator()(Fx&& fx, O& mem, Args&&... args) const {
+ return call(std::forward<Fx>(fx), mem, std::forward<Args>(args)...);
+ }
+ };
+
+ template <F fx>
+ struct invoker {
+ template <typename... Args>
+ decltype(auto) operator()(O& mem, Args&&... args) const {
+ return invoke<fx>(mem, std::forward<Args>(args)...);
+ }
+ };
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...)> : public member_function_wrapper<R(O:: *)(Args...), R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const> : public member_function_wrapper<R(O:: *)(Args...) const, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const volatile> : public member_function_wrapper<R(O:: *)(Args...) const volatile, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) &> : public member_function_wrapper<R(O:: *)(Args...) &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const &> : public member_function_wrapper<R(O:: *)(Args...) const &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const volatile &> : public member_function_wrapper<R(O:: *)(Args...) const volatile &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) &> : public member_function_wrapper<R(O:: *)(Args..., ...) &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) const &> : public member_function_wrapper<R(O:: *)(Args..., ...) const &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) const volatile &> : public member_function_wrapper<R(O:: *)(Args..., ...) const volatile &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) && > : public member_function_wrapper<R(O:: *)(Args...) &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const &&> : public member_function_wrapper<R(O:: *)(Args...) const &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const volatile &&> : public member_function_wrapper<R(O:: *)(Args...) const volatile &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) && > : public member_function_wrapper<R(O:: *)(Args..., ...) &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) const &&> : public member_function_wrapper<R(O:: *)(Args..., ...) const &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) const volatile &&> : public member_function_wrapper<R(O:: *)(Args..., ...) const volatile &, R, O, Args...> {
+
+ };
+
+} // sol
+
+// end of sol/wrapper.hpp
+
+namespace sol {
+ namespace function_detail {
+ template <typename Fx>
+ inline int call(lua_State* L) {
+ Fx& fx = stack::get<user<Fx>>(L, upvalue_index(1));
+ return fx(L);
+ }
+ } // function_detail
+} // sol
+
+// end of sol/function_types_core.hpp
+
+// beginning of sol/function_types_templated.hpp
+
+// beginning of sol/call.hpp
+
+// beginning of sol/protect.hpp
+
+namespace sol {
+
+ template <typename T>
+ struct protect_t {
+ T value;
+
+ template <typename Arg, typename... Args, meta::disable<std::is_same<protect_t, meta::unqualified_t<Arg>>> = meta::enabler>
+ protect_t(Arg&& arg, Args&&... args) : value(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+
+ protect_t(const protect_t&) = default;
+ protect_t(protect_t&&) = default;
+ protect_t& operator=(const protect_t&) = default;
+ protect_t& operator=(protect_t&&) = default;
+
+ };
+
+ template <typename T>
+ auto protect(T&& value) {
+ return protect_t<std::decay_t<T>>(std::forward<T>(value));
+ }
+
+} // sol
+
+// end of sol/protect.hpp
+
+// beginning of sol/property.hpp
+
+namespace sol {
+
+ struct no_prop { };
+
+ template <typename R, typename W>
+ struct property_wrapper {
+ typedef std::integral_constant<bool, !std::is_void<R>::value> can_read;
+ typedef std::integral_constant<bool, !std::is_void<W>::value> can_write;
+ typedef std::conditional_t<can_read::value, R, no_prop> Read;
+ typedef std::conditional_t<can_write::value, W, no_prop> Write;
+ Read read;
+ Write write;
+
+ template <typename Rx, typename Wx>
+ property_wrapper(Rx&& r, Wx&& w) : read(std::forward<Rx>(r)), write(std::forward<Wx>(w)) {}
+ };
+
+ namespace property_detail {
+ template <typename R, typename W>
+ inline decltype(auto) property(std::true_type, R&& read, W&& write) {
+ return property_wrapper<std::decay_t<R>, std::decay_t<W>>(std::forward<R>(read), std::forward<W>(write));
+ }
+ template <typename W, typename R>
+ inline decltype(auto) property(std::false_type, W&& write, R&& read) {
+ return property_wrapper<std::decay_t<R>, std::decay_t<W>>(std::forward<R>(read), std::forward<W>(write));
+ }
+ template <typename R>
+ inline decltype(auto) property(std::true_type, R&& read) {
+ return property_wrapper<std::decay_t<R>, void>(std::forward<R>(read), no_prop());
+ }
+ template <typename W>
+ inline decltype(auto) property(std::false_type, W&& write) {
+ return property_wrapper<void, std::decay_t<W>>(no_prop(), std::forward<W>(write));
+ }
+ } // property_detail
+
+ template <typename F, typename G>
+ inline decltype(auto) property(F&& f, G&& g) {
+ typedef lua_bind_traits<meta::unqualified_t<F>> left_traits;
+ typedef lua_bind_traits<meta::unqualified_t<G>> right_traits;
+ return property_detail::property(meta::boolean<(left_traits::free_arity < right_traits::free_arity)>(), std::forward<F>(f), std::forward<G>(g));
+ }
+
+ template <typename F>
+ inline decltype(auto) property(F&& f) {
+ typedef lua_bind_traits<meta::unqualified_t<F>> left_traits;
+ return property_detail::property(meta::boolean<(left_traits::free_arity < 2)>(), std::forward<F>(f));
+ }
+
+ template <typename F>
+ inline decltype(auto) readonly_property(F&& f) {
+ return property_detail::property(std::true_type(), std::forward<F>(f));
+ }
+
+ // Allow someone to make a member variable readonly (const)
+ template <typename R, typename T>
+ inline auto readonly(R T::* v) {
+ typedef const R C;
+ return static_cast<C T::*>(v);
+ }
+
+ template <typename T>
+ struct var_wrapper {
+ T value;
+ template <typename... Args>
+ var_wrapper(Args&&... args) : value(std::forward<Args>(args)...) {}
+ var_wrapper(const var_wrapper&) = default;
+ var_wrapper(var_wrapper&&) = default;
+ var_wrapper& operator=(const var_wrapper&) = default;
+ var_wrapper& operator=(var_wrapper&&) = default;
+ };
+
+ template <typename V>
+ inline auto var(V&& v) {
+ typedef meta::unqualified_t<V> T;
+ return var_wrapper<T>(std::forward<V>(v));
+ }
+
+} // sol
+
+// end of sol/property.hpp
+
+namespace sol {
+ namespace call_detail {
+
+ template <typename R, typename W>
+ inline auto& pick(std::true_type, property_wrapper<R, W>& f) {
+ return f.read;
+ }
+
+ template <typename R, typename W>
+ inline auto& pick(std::false_type, property_wrapper<R, W>& f) {
+ return f.write;
+ }
+
+ template <typename T, typename List>
+ struct void_call;
+
+ template <typename T, typename... Args>
+ struct void_call<T, types<Args...>> {
+ static void call(Args...) {}
+ };
+
+ template <typename T>
+ struct constructor_match {
+ T* obj;
+
+ constructor_match(T* obj) : obj(obj) {}
+
+ template <typename Fx, std::size_t I, typename... R, typename... Args>
+ int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
+ detail::default_construct func{};
+ return stack::call_into_lua<false>(r, a, L, start, func, obj);
+ }
+ };
+
+ namespace overload_detail {
+ template <std::size_t... M, typename Match, typename... Args>
+ inline int overload_match_arity(types<>, std::index_sequence<>, std::index_sequence<M...>, Match&&, lua_State* L, int, int, Args&&...) {
+ return luaL_error(L, "sol: no matching function call takes this number of arguments and the specified types");
+ }
+
+ template <typename Fx, typename... Fxs, std::size_t I, std::size_t... In, std::size_t... M, typename Match, typename... Args>
+ inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
+ typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
+ typedef meta::tuple_types<typename traits::return_type> return_types;
+ typedef typename traits::free_args_list args_list;
+ // compile-time eliminate any functions that we know ahead of time are of improper arity
+ if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
+ return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+ if (traits::free_arity != fxarity) {
+ return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+ stack::record tracking{};
+ if (!stack::stack_detail::check_types<true>{}.check(args_list(), L, start, no_panic, tracking)) {
+ return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+ return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
+ }
+ } // overload_detail
+
+ template <typename... Functions, typename Match, typename... Args>
+ inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
+ return overload_detail::overload_match_arity(types<Functions...>(), std::make_index_sequence<sizeof...(Functions)>(), std::index_sequence<>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+
+ template <typename... Functions, typename Match, typename... Args>
+ inline int overload_match(Match&& matchfx, lua_State* L, int start, Args&&... args) {
+ int fxarity = lua_gettop(L) - (start - 1);
+ return overload_match_arity<Functions...>(std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+
+ template <typename T, typename... TypeLists, typename Match, typename... Args>
+ inline int construct_match(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
+ // use same overload resolution matching as all other parts of the framework
+ return overload_match_arity<decltype(void_call<T, TypeLists>::call)...>(std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+
+ template <typename T, typename... TypeLists>
+ inline int construct(lua_State* L) {
+ static const auto& meta = usertype_traits<T>::metatable;
+ int argcount = lua_gettop(L);
+ call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, meta, 1) : call_syntax::dot;
+ argcount -= static_cast<int>(syntax);
+
+ T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
+ T*& referencepointer = *pointerpointer;
+ T* obj = reinterpret_cast<T*>(pointerpointer + 1);
+ referencepointer = obj;
+ reference userdataref(L, -1);
+ userdataref.pop();
+
+ construct_match<T, TypeLists...>(constructor_match<T>(obj), L, argcount, 1 + static_cast<int>(syntax));
+
+ userdataref.push();
+ luaL_getmetatable(L, &meta[0]);
+ if (type_of(L, -1) == type::nil) {
+ lua_pop(L, 1);
+ return luaL_error(L, "sol: unable to get usertype metatable");
+ }
+
+ lua_setmetatable(L, -2);
+ return 1;
+ }
+
+ template <typename F, bool is_index, bool is_variable, bool checked, int boost, typename = void>
+ struct agnostic_lua_call_wrapper {
+ template <typename Fx, typename... Args>
+ static int call(lua_State* L, Fx&& f, Args&&... args) {
+ typedef wrapper<meta::unqualified_t<F>> wrap;
+ typedef typename wrap::returns_list returns_list;
+ typedef typename wrap::free_args_list args_list;
+ typedef typename wrap::caller caller;
+ return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f), std::forward<Args>(args)...);
+ }
+ };
+
+ template <typename T, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<var_wrapper<T>, true, is_variable, checked, boost, C> {
+ template <typename F>
+ static int call(lua_State* L, F&& f) {
+ return stack::push_reference(L, detail::unwrap(f.value));
+ }
+ };
+
+ template <typename T, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<var_wrapper<T>, false, is_variable, checked, boost, C> {
+ template <typename V>
+ static int call_assign(std::true_type, lua_State* L, V&& f) {
+ detail::unwrap(f.value) = stack::get<meta::unwrapped_t<T>>(L, boost + (is_variable ? 3 : 1));
+ return 0;
+ }
+
+ template <typename... Args>
+ static int call_assign(std::false_type, lua_State* L, Args&&...) {
+ return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
+ }
+
+ template <typename... Args>
+ static int call_const(std::false_type, lua_State* L, Args&&... args) {
+ typedef meta::unwrapped_t<T> R;
+ return call_assign(std::is_assignable<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>(), L, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static int call_const(std::true_type, lua_State* L, Args&&...) {
+ return luaL_error(L, "sol: cannot write to a readonly (const) variable");
+ }
+
+ template <typename V>
+ static int call(lua_State* L, V&& f) {
+ return call_const(std::is_const<meta::unwrapped_t<T>>(), L, f);
+ }
+ };
+
+ template <bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<lua_r_CFunction, is_index, is_variable, checked, boost, C> {
+ static int call(lua_State* L, lua_r_CFunction f) {
+ return f(L);
+ }
+ };
+
+ template <bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, C> {
+ static int call(lua_State* L, lua_CFunction f) {
+ return f(L);
+ }
+ };
+
+ template <bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, checked, boost, C> {
+ static int call(lua_State* L, const no_prop&) {
+ return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property");
+ }
+ };
+
+ template <bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, C> {
+ static int call(lua_State* L, const no_construction&) {
+ return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
+ }
+ };
+
+ template <typename... Args, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, C> {
+ static int call(lua_State*, const bases<Args...>&) {
+ // Uh. How did you even call this, lul
+ return 0;
+ }
+ };
+
+ template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, int boost = 0, typename = void>
+ struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost> {};
+
+ template <typename T, typename F, bool is_index, bool is_variable, bool checked, int boost>
+ struct lua_call_wrapper<T, F, is_index, is_variable, checked, boost, std::enable_if_t<std::is_member_function_pointer<F>::value>> {
+ typedef wrapper<meta::unqualified_t<F>> wrap;
+ typedef typename wrap::object_type object_type;
+
+ template <typename Fx>
+ static int call(lua_State* L, Fx&& f, object_type& o) {
+ typedef typename wrap::returns_list returns_list;
+ typedef typename wrap::args_list args_list;
+ typedef typename wrap::caller caller;
+ return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), std::forward<Fx>(f), o);
+ }
+
+ template <typename Fx>
+ static int call(lua_State* L, Fx&& f) {
+ typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
+#ifdef SOL_SAFE_USERTYPE
+ object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
+ if (o == nullptr) {
+ return luaL_error(L, "sol: received null for 'self' argument (use ':' for accessing member functions, make sure member variables are preceeded by the actual object with '.' syntax)");
+ }
+ return call(L, std::forward<Fx>(f), *o);
+#else
+ object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
+ return call(L, std::forward<Fx>(f), o);
+#endif // Safety
+ }
+ };
+
+ template <typename T, typename F, bool is_variable, bool checked, int boost>
+ struct lua_call_wrapper<T, F, false, is_variable, checked, boost, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
+ typedef lua_bind_traits<F> traits_type;
+ typedef wrapper<meta::unqualified_t<F>> wrap;
+ typedef typename wrap::object_type object_type;
+
+ template <typename V>
+ static int call_assign(std::true_type, lua_State* L, V&& f, object_type& o) {
+ typedef typename wrap::args_list args_list;
+ typedef typename wrap::caller caller;
+ return stack::call_into_lua<checked>(types<void>(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
+ }
+
+ template <typename V>
+ static int call_assign(std::true_type, lua_State* L, V&& f) {
+ typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
+#ifdef SOL_SAFE_USERTYPE
+ object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
+ if (o == nullptr) {
+ if (is_variable) {
+ return luaL_error(L, "sol: received nil for 'self' argument (bad '.' access?)");
+ }
+ return luaL_error(L, "sol: received nil for 'self' argument (pass 'self' as first argument)");
+ }
+ return call_assign(std::true_type(), L, f, *o);
+#else
+ object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
+ return call_assign(std::true_type(), L, f, o);
+#endif // Safety
+ }
+
+ template <typename... Args>
+ static int call_assign(std::false_type, lua_State* L, Args&&...) {
+ return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
+ }
+
+ template <typename... Args>
+ static int call_const(std::false_type, lua_State* L, Args&&... args) {
+ typedef typename traits_type::return_type R;
+ return call_assign(std::is_assignable<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>(), L, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static int call_const(std::true_type, lua_State* L, Args&&...) {
+ return luaL_error(L, "sol: cannot write to a readonly (const) variable");
+ }
+
+ template <typename V>
+ static int call(lua_State* L, V&& f) {
+ return call_const(std::is_const<typename traits_type::return_type>(), L, f);
+ }
+
+ template <typename V>
+ static int call(lua_State* L, V&& f, object_type& o) {
+ return call_const(std::is_const<typename traits_type::return_type>(), L, f, o);
+ }
+ };
+
+ template <typename T, typename F, bool is_variable, bool checked, int boost>
+ struct lua_call_wrapper<T, F, true, is_variable, checked, boost, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
+ typedef lua_bind_traits<F> traits_type;
+ typedef wrapper<meta::unqualified_t<F>> wrap;
+ typedef typename wrap::object_type object_type;
+
+ template <typename V>
+ static int call(lua_State* L, V&& f, object_type& o) {
+ typedef typename wrap::returns_list returns_list;
+ typedef typename wrap::caller caller;
+ return stack::call_into_lua<checked>(returns_list(), types<>(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
+ }
+
+ template <typename V>
+ static int call(lua_State* L, V&& f) {
+ typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
+#ifdef SOL_SAFE_USERTYPE
+ object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
+ if (o == nullptr) {
+ if (is_variable) {
+ return luaL_error(L, "sol: 'self' argument is nil (bad '.' access?)");
+ }
+ return luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument)");
+ }
+ return call(L, f, *o);
+#else
+ object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
+ return call(L, f, o);
+#endif // Safety
+ }
+ };
+
+ template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, constructor_list<Args...>, is_index, is_variable, checked, boost, C> {
+ typedef constructor_list<Args...> F;
+
+ static int call(lua_State* L, F&) {
+ const auto& metakey = usertype_traits<T>::metatable;
+ int argcount = lua_gettop(L);
+ call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, metakey, 1) : call_syntax::dot;
+ argcount -= static_cast<int>(syntax);
+
+ T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
+ reference userdataref(L, -1);
+ T*& referencepointer = *pointerpointer;
+ T* obj = reinterpret_cast<T*>(pointerpointer + 1);
+ referencepointer = obj;
+
+ construct_match<T, Args...>(constructor_match<T>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
+
+ userdataref.push();
+ luaL_getmetatable(L, &metakey[0]);
+ if (type_of(L, -1) == type::nil) {
+ lua_pop(L, 1);
+ return luaL_error(L, "sol: unable to get usertype metatable");
+ }
+
+ lua_setmetatable(L, -2);
+ return 1;
+ }
+ };
+
+ template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, C> {
+ typedef constructor_wrapper<Cxs...> F;
+
+ struct onmatch {
+ template <typename Fx, std::size_t I, typename... R, typename... Args>
+ int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start, F& f) {
+ const auto& metakey = usertype_traits<T>::metatable;
+ T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
+ reference userdataref(L, -1);
+ T*& referencepointer = *pointerpointer;
+ T* obj = reinterpret_cast<T*>(pointerpointer + 1);
+ referencepointer = obj;
+
+ auto& func = std::get<I>(f.functions);
+ stack::call_into_lua<checked>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj));
+
+ userdataref.push();
+ luaL_getmetatable(L, &metakey[0]);
+ if (type_of(L, -1) == type::nil) {
+ lua_pop(L, 1);
+ std::string err = "sol: unable to get usertype metatable for ";
+ err += usertype_traits<T>::name;
+ return luaL_error(L, err.c_str());
+ }
+ lua_setmetatable(L, -2);
+
+ return 1;
+ }
+ };
+
+ static int call(lua_State* L, F& f) {
+ call_syntax syntax = stack::get_call_syntax(L, usertype_traits<T>::metatable);
+ int syntaxval = static_cast<int>(syntax);
+ int argcount = lua_gettop(L) - syntaxval;
+ return construct_match<T, meta::pop_front_type_t<meta::function_args_t<Cxs>>...>(onmatch(), L, argcount, 1 + syntaxval, f);
+ }
+
+ };
+
+ template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost>
+ struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, std::enable_if_t<std::is_void<Fx>::value>> {
+ typedef destructor_wrapper<Fx> F;
+
+ static int call(lua_State* L, const F&) {
+ return detail::usertype_alloc_destroy<T>(L);
+ }
+ };
+
+ template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost>
+ struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, std::enable_if_t<!std::is_void<Fx>::value>> {
+ typedef destructor_wrapper<Fx> F;
+
+ static int call(lua_State* L, const F& f) {
+ T& obj = stack::get<T>(L);
+ f.fx(detail::implicit_wrapper<T>(obj));
+ return 0;
+ }
+ };
+
+ template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, C> {
+ typedef overload_set<Fs...> F;
+
+ struct on_match {
+ template <typename Fx, std::size_t I, typename... R, typename... Args>
+ int operator()(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, F& fx) {
+ auto& f = std::get<I>(fx.functions);
+ return lua_call_wrapper<T, Fx, is_index, is_variable, checked, boost>{}.call(L, f);
+ }
+ };
+
+ static int call(lua_State* L, F& fx) {
+ return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L), 1, fx);
+ }
+ };
+
+ template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, factory_wrapper<Fs...>, is_index, is_variable, checked, boost, C> {
+ typedef factory_wrapper<Fs...> F;
+
+ struct on_match {
+ template <typename Fx, std::size_t I, typename... R, typename... Args>
+ int operator()(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, F& fx) {
+ auto& f = std::get<I>(fx.functions);
+ return lua_call_wrapper<T, Fx, is_index, is_variable, checked, boost>{}.call(L, f);
+ }
+ };
+
+ static int call(lua_State* L, F& fx) {
+ return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L), 1, fx);
+ }
+ };
+
+ template <typename T, typename R, typename W, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, property_wrapper<R, W>, is_index, is_variable, checked, boost, C> {
+ typedef std::conditional_t<is_index, R, W> P;
+ typedef meta::unqualified_t<P> U;
+ typedef lua_bind_traits<U> traits_type;
+
+ template <typename F>
+ static int self_call(lua_State* L, F&& f) {
+ typedef wrapper<U> wrap;
+ typedef meta::unqualified_t<typename traits_type::template arg_at<0>> object_type;
+ typedef meta::pop_front_type_t<typename traits_type::free_args_list> args_list;
+ typedef T Ta;
+#ifdef SOL_SAFE_USERTYPE
+ object_type* po = static_cast<object_type*>(stack::get<Ta*>(L, 1));
+ if (po == nullptr) {
+ if (is_variable) {
+ return luaL_error(L, "sol: 'self' argument is nil (bad '.' access?)");
+ }
+ return luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument)");
+ }
+ object_type& o = *po;
+#else
+ object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
+#endif // Safety
+ typedef typename wrap::returns_list returns_list;
+ typedef typename wrap::caller caller;
+ return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), f, o);
+ }
+
+ template <typename F, typename... Args>
+ static int defer_call(std::false_type, lua_State* L, F&& f, Args&&... args) {
+ return self_call(L, pick(meta::boolean<is_index>(), f), std::forward<Args>(args)...);
+ }
+
+ template <typename F, typename... Args>
+ static int defer_call(std::true_type, lua_State* L, F&& f, Args&&... args) {
+ auto& p = pick(meta::boolean<is_index>(), std::forward<F>(f));
+ return lua_call_wrapper<T, meta::unqualified_t<decltype(p)>, is_index, is_variable, checked, boost>{}.call(L, p, std::forward<Args>(args)...);
+ }
+
+ template <typename F, typename... Args>
+ static int call(lua_State* L, F&& f, Args&&... args) {
+ typedef meta::any<
+ std::is_void<U>,
+ std::is_same<U, no_prop>,
+ meta::is_specialization_of<var_wrapper, U>,
+ meta::is_specialization_of<constructor_wrapper, U>,
+ meta::is_specialization_of<constructor_list, U>,
+ std::is_member_pointer<U>
+ > is_specialized;
+ return defer_call(is_specialized(), L, std::forward<F>(f), std::forward<Args>(args)...);
+ }
+ };
+
+ template <typename T, typename V, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, C> {
+ typedef protect_t<V> F;
+
+ template <typename... Args>
+ static int call(lua_State* L, F& fx, Args&&... args) {
+ return lua_call_wrapper<T, V, is_index, is_variable, true, boost>{}.call(L, fx.value, std::forward<Args>(args)...);
+ }
+ };
+
+ template <typename T, typename Sig, typename P, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, function_arguments<Sig, P>, is_index, is_variable, checked, boost, C> {
+ template <typename F>
+ static int call(lua_State* L, F&& f) {
+ return lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, stack::stack_detail::default_check_arguments, boost>{}.call(L, std::get<0>(f.arguments));
+ }
+ };
+
+ template <typename T, bool is_index, bool is_variable, int boost = 0, typename Fx, typename... Args>
+ inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
+ return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable, stack::stack_detail::default_check_arguments, boost>{}.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename T, bool is_index, bool is_variable, typename F>
+ inline int call_user(lua_State* L) {
+ auto& fx = stack::get<user<F>>(L, upvalue_index(1));
+ return call_wrapped<T, is_index, is_variable>(L, fx);
+ }
+
+ template <typename T, typename = void>
+ struct is_var_bind : std::false_type {};
+
+ template <typename T>
+ struct is_var_bind<T, std::enable_if_t<std::is_member_object_pointer<T>::value>> : std::true_type {};
+
+ template <>
+ struct is_var_bind<no_prop> : std::true_type {};
+
+ template <typename R, typename W>
+ struct is_var_bind<property_wrapper<R, W>> : std::true_type {};
+
+ template <typename T>
+ struct is_var_bind<var_wrapper<T>> : std::true_type {};
+ } // call_detail
+
+ template <typename T>
+ struct is_variable_binding : call_detail::is_var_bind<meta::unqualified_t<T>> {};
+
+ template <typename T>
+ struct is_function_binding : meta::neg<is_variable_binding<T>> {};
+
+} // sol
+
+// end of sol/call.hpp
+
+namespace sol {
+ namespace function_detail {
+ template <typename F, F fx>
+ inline int call_wrapper_variable(std::false_type, lua_State* L) {
+ typedef meta::bind_traits<meta::unqualified_t<F>> traits_type;
+ typedef typename traits_type::args_list args_list;
+ typedef meta::tuple_types<typename traits_type::return_type> return_type;
+ return stack::call_into_lua(return_type(), args_list(), L, 1, fx);
+ }
+
+ template <typename R, typename V, V, typename T>
+ inline int call_set_assignable(std::false_type, T&&, lua_State* L) {
+ return luaL_error(L, "cannot write to this type: copy assignment/constructor not available");
+ }
+
+ template <typename R, typename V, V variable, typename T>
+ inline int call_set_assignable(std::true_type, lua_State* L, T&& mem) {
+ (mem.*variable) = stack::get<R>(L, 2);
+ return 0;
+ }
+
+ template <typename R, typename V, V, typename T>
+ inline int call_set_variable(std::false_type, lua_State* L, T&&) {
+ return luaL_error(L, "cannot write to a const variable");
+ }
+
+ template <typename R, typename V, V variable, typename T>
+ inline int call_set_variable(std::true_type, lua_State* L, T&& mem) {
+ return call_set_assignable<R, V, variable>(std::is_assignable<std::add_lvalue_reference_t<R>, R>(), L, std::forward<T>(mem));
+ }
+
+ template <typename V, V variable>
+ inline int call_wrapper_variable(std::true_type, lua_State* L) {
+ typedef meta::bind_traits<meta::unqualified_t<V>> traits_type;
+ typedef typename traits_type::object_type T;
+ typedef typename traits_type::return_type R;
+ auto& mem = stack::get<T>(L, 1);
+ switch (lua_gettop(L)) {
+ case 1: {
+ decltype(auto) r = (mem.*variable);
+ stack::push_reference(L, std::forward<decltype(r)>(r));
+ return 1; }
+ case 2:
+ return call_set_variable<R, V, variable>(meta::neg<std::is_const<R>>(), L, mem);
+ default:
+ return luaL_error(L, "incorrect number of arguments to member variable function call");
+ }
+ }
+
+ template <typename F, F fx>
+ inline int call_wrapper_function(std::false_type, lua_State* L) {
+ return call_wrapper_variable<F, fx>(std::is_member_object_pointer<F>(), L);
+ }
+
+ template <typename F, F fx>
+ inline int call_wrapper_function(std::true_type, lua_State* L) {
+ return call_detail::call_wrapped<void, false, false>(L, fx);
+ }
+
+ template <typename F, F fx>
+ int call_wrapper_entry(lua_State* L) {
+ return call_wrapper_function<F, fx>(std::is_member_function_pointer<meta::unqualified_t<F>>(), L);
+ }
+
+ template <typename... Fxs>
+ struct c_call_matcher {
+ template <typename Fx, std::size_t I, typename R, typename... Args>
+ int operator()(types<Fx>, index_value<I>, types<R>, types<Args...>, lua_State* L, int, int) const {
+ typedef meta::at_in_pack_t<I, Fxs...> target;
+ return target::call(L);
+ }
+ };
+
+ } // function_detail
+
+ template <typename F, F fx>
+ inline int c_call(lua_State* L) {
+#ifdef __clang__
+ return detail::trampoline(L, function_detail::call_wrapper_entry<F, fx>);
+#else
+ return detail::static_trampoline<(&function_detail::call_wrapper_entry<F, fx>)>(L);
+#endif // fuck you clang :c
+ }
+
+ template <typename F, F f>
+ struct wrap {
+ typedef F type;
+
+ static int call(lua_State* L) {
+ return c_call<type, f>(L);
+ }
+ };
+
+ template <typename... Fxs>
+ inline int c_call(lua_State* L) {
+ if (sizeof...(Fxs) < 2) {
+ return meta::at_in_pack_t<0, Fxs...>::call(L);
+ }
+ else {
+ return call_detail::overload_match_arity<typename Fxs::type...>(function_detail::c_call_matcher<Fxs...>(), L, lua_gettop(L), 1);
+ }
+ }
+
+} // sol
+
+// end of sol/function_types_templated.hpp
+
+// beginning of sol/function_types_stateless.hpp
+
+namespace sol {
+ namespace function_detail {
+ template<typename Function>
+ struct upvalue_free_function {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef lua_bind_traits<function_type> traits_type;
+
+ static int real_call(lua_State* L) {
+ auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
+ function_type* fx = udata.first;
+ return call_detail::call_wrapped<void, true, false>(L, fx);
+ }
+
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call)>(L);
+ }
+
+ int operator()(lua_State* L) {
+ return call(L);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct upvalue_member_function {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef lua_bind_traits<function_type> traits_type;
+
+ static int real_call(lua_State* L) {
+ // Layout:
+ // idx 1...n: verbatim data of member function pointer
+ // idx n + 1: is the object's void pointer
+ // We don't need to store the size, because the other side is templated
+ // with the same member function pointer type
+ auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
+ auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
+ function_type& memfx = memberdata.first;
+ auto& item = *objdata.first;
+ return call_detail::call_wrapped<T, true, false, -1>(L, memfx, item);
+ }
+
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call)>(L);
+ }
+
+ int operator()(lua_State* L) {
+ return call(L);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct upvalue_member_variable {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef lua_bind_traits<function_type> traits_type;
+
+ static int real_call(lua_State* L) {
+ // Layout:
+ // idx 1...n: verbatim data of member variable pointer
+ // idx n + 1: is the object's void pointer
+ // We don't need to store the size, because the other side is templated
+ // with the same member function pointer type
+ auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
+ auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
+ auto& mem = *objdata.first;
+ function_type& var = memberdata.first;
+ switch (lua_gettop(L)) {
+ case 0:
+ return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
+ case 1:
+ return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
+ default:
+ return luaL_error(L, "sol: incorrect number of arguments to member variable function");
+ }
+ }
+
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call)>(L);
+ }
+
+ int operator()(lua_State* L) {
+ return call(L);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct upvalue_this_member_function {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef lua_bind_traits<function_type> traits_type;
+
+ static int real_call(lua_State* L) {
+ // Layout:
+ // idx 1...n: verbatim data of member variable pointer
+ auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
+ function_type& memfx = memberdata.first;
+ return call_detail::call_wrapped<T, false, false>(L, memfx);
+ }
+
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call)>(L);
+ }
+
+ int operator()(lua_State* L) {
+ return call(L);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct upvalue_this_member_variable {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef lua_bind_traits<function_type> traits_type;
+
+ static int real_call(lua_State* L) {
+ // Layout:
+ // idx 1...n: verbatim data of member variable pointer
+ auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
+ function_type& var = memberdata.first;
+ switch (lua_gettop(L)) {
+ case 1:
+ return call_detail::call_wrapped<T, true, false>(L, var);
+ case 2:
+ return call_detail::call_wrapped<T, false, false>(L, var);
+ default:
+ return luaL_error(L, "sol: incorrect number of arguments to member variable function");
+ }
+ }
+
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call)>(L);
+ }
+
+ int operator()(lua_State* L) {
+ return call(L);
+ }
+ };
+ } // function_detail
+} // sol
+
+// end of sol/function_types_stateless.hpp
+
+// beginning of sol/function_types_stateful.hpp
+
+namespace sol {
+ namespace function_detail {
+ template<typename Func>
+ struct functor_function {
+ typedef meta::unwrapped_t<meta::unqualified_t<Func>> Function;
+ typedef decltype(&Function::operator()) function_type;
+ typedef meta::function_return_t<function_type> return_type;
+ typedef meta::function_args_t<function_type> args_lists;
+ Function fx;
+
+ template<typename... Args>
+ functor_function(Function f, Args&&... args) : fx(std::move(f), std::forward<Args>(args)...) {}
+
+ int call(lua_State* L) {
+ return call_detail::call_wrapped<void, true, false>(L, fx);
+ }
+
+ int operator()(lua_State* L) {
+ auto f = [&](lua_State* L) -> int { return this->call(L); };
+ return detail::trampoline(L, f);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct member_function {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef meta::function_return_t<function_type> return_type;
+ typedef meta::function_args_t<function_type> args_lists;
+ function_type invocation;
+ T member;
+
+ template<typename... Args>
+ member_function(function_type f, Args&&... args) : invocation(std::move(f)), member(std::forward<Args>(args)...) {}
+
+ int call(lua_State* L) {
+ return call_detail::call_wrapped<T, true, false, -1>(L, invocation, detail::unwrap(detail::deref(member)));
+ }
+
+ int operator()(lua_State* L) {
+ auto f = [&](lua_State* L) -> int { return this->call(L); };
+ return detail::trampoline(L, f);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct member_variable {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef typename meta::bind_traits<function_type>::return_type return_type;
+ typedef typename meta::bind_traits<function_type>::args_list args_lists;
+ function_type var;
+ T member;
+ typedef std::add_lvalue_reference_t<meta::unwrapped_t<std::remove_reference_t<decltype(detail::deref(member))>>> M;
+
+ template<typename... Args>
+ member_variable(function_type v, Args&&... args) : var(std::move(v)), member(std::forward<Args>(args)...) {}
+
+ int call(lua_State* L) {
+ M mem = detail::unwrap(detail::deref(member));
+ switch (lua_gettop(L)) {
+ case 0:
+ return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
+ case 1:
+ return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
+ default:
+ return luaL_error(L, "sol: incorrect number of arguments to member variable function");
+ }
+ }
+
+ int operator()(lua_State* L) {
+ auto f = [&](lua_State* L) -> int { return this->call(L); };
+ return detail::trampoline(L, f);
+ }
+ };
+ } // function_detail
+} // sol
+
+// end of sol/function_types_stateful.hpp
+
+// beginning of sol/function_types_overloaded.hpp
+
+namespace sol {
+ namespace function_detail {
+ template <typename... Functions>
+ struct overloaded_function {
+ typedef std::tuple<Functions...> overload_list;
+ typedef std::make_index_sequence<sizeof...(Functions)> indices;
+ overload_list overloads;
+
+ overloaded_function(overload_list set)
+ : overloads(std::move(set)) {}
+
+ overloaded_function(Functions... fxs)
+ : overloads(fxs...) {
+
+ }
+
+ template <typename Fx, std::size_t I, typename... R, typename... Args>
+ int call(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int) {
+ auto& func = std::get<I>(overloads);
+ return call_detail::call_wrapped<void, true, false>(L, func);
+ }
+
+ int operator()(lua_State* L) {
+ auto mfx = [&](auto&&... args) { return this->call(std::forward<decltype(args)>(args)...); };
+ return call_detail::overload_match<Functions...>(mfx, L, 1);
+ }
+ };
+ } // function_detail
+} // sol
+
+// end of sol/function_types_overloaded.hpp
+
+// beginning of sol/resolve.hpp
+
+namespace sol {
+ namespace detail {
+ template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
+ inline auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
+ using Sig = R(Args...);
+ typedef meta::unqualified_t<F> Fu;
+ return static_cast<Sig Fu::*>(&Fu::operator());
+ }
+
+ template<typename F, typename U = meta::unqualified_t<F>>
+ inline auto resolve_f(std::true_type, F&& f)
+ -> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
+ return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
+ }
+
+ template<typename F>
+ inline void resolve_f(std::false_type, F&&) {
+ static_assert(meta::has_deducible_signature<F>::value,
+ "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
+ }
+
+ template<typename F, typename U = meta::unqualified_t<F>>
+ inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
+ return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
+ }
+
+ template<typename... Args, typename F, typename R = std::result_of_t<F&(Args...)>>
+ inline auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
+ return resolve_i(types<R(Args...)>(), std::forward<F>(f));
+ }
+
+ template<typename Sig, typename C>
+ inline Sig C::* resolve_v(std::false_type, Sig C::* mem_func_ptr) {
+ return mem_func_ptr;
+ }
+
+ template<typename Sig, typename C>
+ inline Sig C::* resolve_v(std::true_type, Sig C::* mem_variable_ptr) {
+ return mem_variable_ptr;
+ }
+ } // detail
+
+ template<typename... Args, typename R>
+ inline auto resolve(R fun_ptr(Args...))->R(*)(Args...) {
+ return fun_ptr;
+ }
+
+ template<typename Sig>
+ inline Sig* resolve(Sig* fun_ptr) {
+ return fun_ptr;
+ }
+
+ template<typename... Args, typename R, typename C>
+ inline auto resolve(R(C::*mem_ptr)(Args...))->R(C::*)(Args...) {
+ return mem_ptr;
+ }
+
+ template<typename Sig, typename C>
+ inline Sig C::* resolve(Sig C::* mem_ptr) {
+ return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
+ }
+
+ template<typename... Sig, typename F>
+ inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
+ return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
+ }
+} // sol
+
+// end of sol/resolve.hpp
+
+namespace sol {
+ namespace stack {
+ template<typename... Sigs>
+ struct pusher<function_sig<Sigs...>> {
+ template <typename... Sig, typename Fx, typename... Args>
+ static void select_convertible(std::false_type, types<Sig...>, lua_State* L, Fx&& fx, Args&&... args) {
+ typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
+ typedef function_detail::functor_function<clean_fx> F;
+ set_fx<F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename R, typename... A, typename Fx, typename... Args>
+ static void select_convertible(std::true_type, types<R(A...)>, lua_State* L, Fx&& fx, Args&&... args) {
+ using fx_ptr_t = R(*)(A...);
+ fx_ptr_t fxptr = detail::unwrap(std::forward<Fx>(fx));
+ select_function(std::true_type(), L, fxptr, std::forward<Args>(args)...);
+ }
+
+ template <typename R, typename... A, typename Fx, typename... Args>
+ static void select_convertible(types<R(A...)> t, lua_State* L, Fx&& fx, Args&&... args) {
+ typedef std::decay_t<meta::unwrap_unqualified_t<Fx>> raw_fx_t;
+ typedef R(*fx_ptr_t)(A...);
+ typedef std::is_convertible<raw_fx_t, fx_ptr_t> is_convertible;
+ select_convertible(is_convertible(), t, L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename... Args>
+ static void select_convertible(types<>, lua_State* L, Fx&& fx, Args&&... args) {
+ typedef meta::function_signature_t<meta::unwrap_unqualified_t<Fx>> Sig;
+ select_convertible(types<Sig>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_reference_member_variable(std::false_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
+ typedef function_detail::member_variable<meta::unwrap_unqualified_t<T>, clean_fx> F;
+ set_fx<F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_reference_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef std::decay_t<Fx> dFx;
+ dFx memfxptr(std::forward<Fx>(fx));
+ auto userptr = detail::ptr(std::forward<T>(obj), std::forward<Args>(args)...);
+ lua_CFunction freefunc = &function_detail::upvalue_member_variable<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>>::call;
+
+ int upvalues = stack::stack_detail::push_as_upvalues(L, memfxptr);
+ upvalues += stack::push(L, lightuserdata_value(static_cast<void*>(userptr)));
+ stack::push(L, c_closure(freefunc, upvalues));
+ }
+
+ template <typename Fx, typename... Args>
+ static void select_member_variable(std::false_type, lua_State* L, Fx&& fx, Args&&... args) {
+ select_convertible(types<Sigs...>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef meta::boolean<meta::is_specialization_of<std::reference_wrapper, meta::unqualified_t<T>>::value || std::is_pointer<T>::value> is_reference;
+ select_reference_member_variable(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx>
+ static void select_member_variable(std::true_type, lua_State* L, Fx&& fx) {
+ typedef typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type C;
+ lua_CFunction freefunc = &function_detail::upvalue_this_member_variable<C, Fx>::call;
+ int upvalues = stack::stack_detail::push_as_upvalues(L, fx);
+ stack::push(L, c_closure(freefunc, upvalues));
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_reference_member_function(std::false_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef std::decay_t<Fx> clean_fx;
+ typedef function_detail::member_function<meta::unwrap_unqualified_t<T>, clean_fx> F;
+ set_fx<F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_reference_member_function(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef std::decay_t<Fx> dFx;
+ dFx memfxptr(std::forward<Fx>(fx));
+ auto userptr = detail::ptr(std::forward<T>(obj), std::forward<Args>(args)...);
+ lua_CFunction freefunc = &function_detail::upvalue_member_function<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>>::call;
+
+ int upvalues = stack::stack_detail::push_as_upvalues(L, memfxptr);
+ upvalues += stack::push(L, lightuserdata_value(static_cast<void*>(userptr)));
+ stack::push(L, c_closure(freefunc, upvalues));
+ }
+
+ template <typename Fx, typename... Args>
+ static void select_member_function(std::false_type, lua_State* L, Fx&& fx, Args&&... args) {
+ select_member_variable(std::is_member_object_pointer<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_member_function(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef meta::boolean<meta::is_specialization_of<std::reference_wrapper, meta::unqualified_t<T>>::value || std::is_pointer<T>::value> is_reference;
+ select_reference_member_function(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx>
+ static void select_member_function(std::true_type, lua_State* L, Fx&& fx) {
+ typedef typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type C;
+ lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, Fx>::call;
+ int upvalues = stack::stack_detail::push_as_upvalues(L, fx);
+ stack::push(L, c_closure(freefunc, upvalues));
+ }
+
+ template <typename Fx, typename... Args>
+ static void select_function(std::false_type, lua_State* L, Fx&& fx, Args&&... args) {
+ select_member_function(std::is_member_function_pointer<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename... Args>
+ static void select_function(std::true_type, lua_State* L, Fx&& fx, Args&&... args) {
+ std::decay_t<Fx> target(std::forward<Fx>(fx), std::forward<Args>(args)...);
+ lua_CFunction freefunc = &function_detail::upvalue_free_function<Fx>::call;
+
+ int upvalues = stack::stack_detail::push_as_upvalues(L, target);
+ stack::push(L, c_closure(freefunc, upvalues));
+ }
+
+ static void select_function(std::true_type, lua_State* L, lua_CFunction f) {
+ stack::push(L, f);
+ }
+
+ template <typename Fx, typename... Args>
+ static void select(lua_State* L, Fx&& fx, Args&&... args) {
+ select_function(std::is_function<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename... Args>
+ static void set_fx(lua_State* L, Args&&... args) {
+ lua_CFunction freefunc = function_detail::call<meta::unqualified_t<Fx>>;
+
+ stack::push<user<Fx>>(L, std::forward<Args>(args)...);
+ stack::push(L, c_closure(freefunc, 1));
+ }
+
+ template<typename... Args>
+ static int push(lua_State* L, Args&&... args) {
+ // Set will always place one thing (function) on the stack
+ select(L, std::forward<Args>(args)...);
+ return 1;
+ }
+ };
+
+ template<typename T, typename... Args>
+ struct pusher<function_arguments<T, Args...>> {
+ template <std::size_t... I, typename FP>
+ static int push_func(std::index_sequence<I...>, lua_State* L, FP&& fp) {
+ return stack::push<T>(L, detail::forward_get<I>(fp.arguments)...);
+ }
+
+ static int push(lua_State* L, const function_arguments<T, Args...>& fp) {
+ return push_func(std::make_index_sequence<sizeof...(Args)>(), L, fp);
+ }
+
+ static int push(lua_State* L, function_arguments<T, Args...>&& fp) {
+ return push_func(std::make_index_sequence<sizeof...(Args)>(), L, std::move(fp));
+ }
+ };
+
+ template<typename Signature>
+ struct pusher<std::function<Signature>> {
+ static int push(lua_State* L, std::function<Signature> fx) {
+ return pusher<function_sig<Signature>>{}.push(L, std::move(fx));
+ }
+ };
+
+ template<typename Signature>
+ struct pusher<Signature, std::enable_if_t<std::is_member_pointer<Signature>::value>> {
+ template <typename F>
+ static int push(lua_State* L, F&& f) {
+ return pusher<function_sig<>>{}.push(L, std::forward<F>(f));
+ }
+ };
+
+ template<typename Signature>
+ struct pusher<Signature, std::enable_if_t<meta::all<std::is_function<Signature>, meta::neg<std::is_same<Signature, lua_CFunction>>, meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>>::value>> {
+ template <typename F>
+ static int push(lua_State* L, F&& f) {
+ return pusher<function_sig<>>{}.push(L, std::forward<F>(f));
+ }
+ };
+
+ template<typename... Functions>
+ struct pusher<overload_set<Functions...>> {
+ static int push(lua_State* L, overload_set<Functions...>&& set) {
+ typedef function_detail::overloaded_function<Functions...> F;
+ pusher<function_sig<>>{}.set_fx<F>(L, std::move(set.functions));
+ return 1;
+ }
+
+ static int push(lua_State* L, const overload_set<Functions...>& set) {
+ typedef function_detail::overloaded_function<Functions...> F;
+ pusher<function_sig<>>{}.set_fx<F>(L, set.functions);
+ return 1;
+ }
+ };
+
+ template <typename T>
+ struct pusher<protect_t<T>> {
+ static int push(lua_State* L, protect_t<T>&& pw) {
+ lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>>;
+ int closures = stack::push<user<protect_t<T>>>(L, std::move(pw.value));
+ return stack::push(L, c_closure(cf, closures));
+ }
+
+ static int push(lua_State* L, const protect_t<T>& pw) {
+ lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>>;
+ int closures = stack::push<user<protect_t<T>>>(L, pw.value);
+ return stack::push(L, c_closure(cf, closures));
+ }
+ };
+
+ template <typename F, typename G>
+ struct pusher<property_wrapper<F, G>, std::enable_if_t<!std::is_void<F>::value && !std::is_void<G>::value>> {
+ static int push(lua_State* L, property_wrapper<F, G>&& pw) {
+ return stack::push(L, sol::overload(std::move(pw.read), std::move(pw.write)));
+ }
+ static int push(lua_State* L, const property_wrapper<F, G>& pw) {
+ return stack::push(L, sol::overload(pw.read, pw.write));
+ }
+ };
+
+ template <typename F>
+ struct pusher<property_wrapper<F, void>> {
+ static int push(lua_State* L, property_wrapper<F, void>&& pw) {
+ return stack::push(L, std::move(pw.read));
+ }
+ static int push(lua_State* L, const property_wrapper<F, void>& pw) {
+ return stack::push(L, pw.read);
+ }
+ };
+
+ template <typename F>
+ struct pusher<property_wrapper<void, F>> {
+ static int push(lua_State* L, property_wrapper<void, F>&& pw) {
+ return stack::push(L, std::move(pw.write));
+ }
+ static int push(lua_State* L, const property_wrapper<void, F>& pw) {
+ return stack::push(L, pw.write);
+ }
+ };
+
+ template <typename T>
+ struct pusher<var_wrapper<T>> {
+ static int push(lua_State* L, var_wrapper<T>&& vw) {
+ return stack::push(L, std::move(vw.value));
+ }
+ static int push(lua_State* L, const var_wrapper<T>& vw) {
+ return stack::push(L, vw.value);
+ }
+ };
+
+ template <typename... Functions>
+ struct pusher<factory_wrapper<Functions...>> {
+ static int push(lua_State* L, const factory_wrapper<Functions...>& fw) {
+ typedef function_detail::overloaded_function<Functions...> F;
+ pusher<function_sig<>>{}.set_fx<F>(L, fw.functions);
+ return 1;
+ }
+
+ static int push(lua_State* L, factory_wrapper<Functions...>&& fw) {
+ typedef function_detail::overloaded_function<Functions...> F;
+ pusher<function_sig<>>{}.set_fx<F>(L, std::move(fw.functions));
+ return 1;
+ }
+ };
+
+ template <typename T, typename... Lists>
+ struct pusher<detail::tagged<T, constructor_list<Lists...>>> {
+ static int push(lua_State* L, detail::tagged<T, constructor_list<Lists...>>) {
+ lua_CFunction cf = call_detail::construct<T, Lists...>;
+ return stack::push(L, cf);
+ }
+ };
+
+ template <typename T, typename... Fxs>
+ struct pusher<detail::tagged<T, constructor_wrapper<Fxs...>>> {
+ template <typename C>
+ static int push(lua_State* L, C&& c) {
+ lua_CFunction cf = call_detail::call_user<T, false, false, constructor_wrapper<Fxs...>>;
+ int closures = stack::push<user<constructor_wrapper<Fxs...>>>(L, std::forward<C>(c));
+ return stack::push(L, c_closure(cf, closures));
+ }
+ };
+
+ template <typename T>
+ struct pusher<detail::tagged<T, destructor_wrapper<void>>> {
+ static int push(lua_State* L, destructor_wrapper<void>) {
+ lua_CFunction cf = detail::usertype_alloc_destroy<T>;
+ return stack::push(L, cf);
+ }
+ };
+
+ template <typename T, typename Fx>
+ struct pusher<detail::tagged<T, destructor_wrapper<Fx>>> {
+ static int push(lua_State* L, destructor_wrapper<Fx> c) {
+ lua_CFunction cf = call_detail::call_user<T, false, false, destructor_wrapper<Fx>>;
+ int closures = stack::push<user<T>>(L, std::move(c));
+ return stack::push(L, c_closure(cf, closures));
+ }
+ };
+
+ } // stack
+} // sol
+
+// end of sol/function_types.hpp
+
+namespace sol {
+ template <typename base_t>
+ class basic_function : public base_t {
+ private:
+ void luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount) const {
+ lua_callk(base_t::lua_state(), static_cast<int>(argcount), static_cast<int>(resultcount), 0, nullptr);
+ }
+
+ template<std::size_t... I, typename... Ret>
+ auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) const {
+ luacall(n, lua_size<std::tuple<Ret...>>::value);
+ return stack::pop<std::tuple<Ret...>>(base_t::lua_state());
+ }
+
+ template<std::size_t I, typename Ret>
+ Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) const {
+ luacall(n, lua_size<Ret>::value);
+ return stack::pop<Ret>(base_t::lua_state());
+ }
+
+ template <std::size_t I>
+ void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) const {
+ luacall(n, 0);
+ }
+
+ function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) const {
+ int stacksize = lua_gettop(base_t::lua_state());
+ int firstreturn = (std::max)(1, stacksize - static_cast<int>(n));
+ luacall(n, LUA_MULTRET);
+ int poststacksize = lua_gettop(base_t::lua_state());
+ int returncount = poststacksize - (firstreturn - 1);
+ return function_result(base_t::lua_state(), firstreturn, returncount);
+ }
+
+ public:
+ basic_function() = default;
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_function>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_function(T&& r) noexcept : base_t(std::forward<T>(r)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!is_function<meta::unqualified_t<T>>::value) {
+ auto pp = stack::push_pop(*this);
+ stack::check<basic_function>(base_t::lua_state(), -1, type_panic);
+ }
+#endif // Safety
+ }
+ basic_function(const basic_function&) = default;
+ basic_function& operator=(const basic_function&) = default;
+ basic_function(basic_function&&) = default;
+ basic_function& operator=(basic_function&&) = default;
+ basic_function(const stack_reference& r) : basic_function(r.lua_state(), r.stack_index()) {}
+ basic_function(stack_reference&& r) : basic_function(r.lua_state(), r.stack_index()) {}
+ basic_function(lua_State* L, int index = -1) : base_t(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ stack::check<basic_function>(L, index, type_panic);
+#endif // Safety
+ }
+
+ template<typename... Args>
+ function_result operator()(Args&&... args) const {
+ return call<>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) operator()(types<Ret...>, Args&&... args) const {
+ return call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) const {
+ base_t::push();
+ int pushcount = stack::multi_push_reference(base_t::lua_state(), std::forward<Args>(args)...);
+ return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
+ }
+ };
+
+ namespace stack {
+ template<typename Signature>
+ struct getter<std::function<Signature>> {
+ typedef meta::bind_traits<Signature> fx_t;
+ typedef typename fx_t::args_list args_lists;
+ typedef meta::tuple_types<typename fx_t::return_type> return_types;
+
+ template<typename... Args, typename... Ret>
+ static std::function<Signature> get_std_func(types<Ret...>, types<Args...>, lua_State* L, int index) {
+ sol::function f(L, index);
+ auto fx = [f, L, index](Args&&... args) -> meta::return_type_t<Ret...> {
+ return f.call<Ret...>(std::forward<Args>(args)...);
+ };
+ return std::move(fx);
+ }
+
+ template<typename... FxArgs>
+ static std::function<Signature> get_std_func(types<void>, types<FxArgs...>, lua_State* L, int index) {
+ sol::function f(L, index);
+ auto fx = [f, L, index](FxArgs&&... args) -> void {
+ f(std::forward<FxArgs>(args)...);
+ };
+ return std::move(fx);
+ }
+
+ template<typename... FxArgs>
+ static std::function<Signature> get_std_func(types<>, types<FxArgs...> t, lua_State* L, int index) {
+ return get_std_func(types<void>(), t, L, index);
+ }
+
+ static std::function<Signature> get(lua_State* L, int index, record& tracking) {
+ tracking.last = 1;
+ tracking.used += 1;
+ type t = type_of(L, index);
+ if (t == type::none || t == type::nil) {
+ return nullptr;
+ }
+ return get_std_func(return_types(), args_lists(), L, index);
+ }
+ };
+ } // stack
+} // sol
+
+// end of sol/function.hpp
+
+// beginning of sol/protected_function.hpp
+
+// beginning of sol/protected_function_result.hpp
+
+namespace sol {
+ struct protected_function_result : public proxy_base<protected_function_result> {
+ private:
+ lua_State* L;
+ int index;
+ int returncount;
+ int popcount;
+ call_status err;
+
+ template <typename T>
+ decltype(auto) tagged_get(types<sol::optional<T>>) const {
+ if (!valid()) {
+ return sol::optional<T>(nullopt);
+ }
+ return stack::get<sol::optional<T>>(L, index);
+ }
+
+ template <typename T>
+ decltype(auto) tagged_get(types<T>) const {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!valid()) {
+ type_panic(L, index, type_of(L, index), type::none);
+ }
+#endif // Check Argument Safety
+ return stack::get<T>(L, index);
+ }
+
+ optional<error> tagged_get(types<optional<error>>) const {
+ if (valid()) {
+ return nullopt;
+ }
+ return error(detail::direct_error, stack::get<std::string>(L, index));
+ }
+
+ error tagged_get(types<error>) const {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (valid()) {
+ type_panic(L, index, type_of(L, index), type::none);
+ }
+#endif // Check Argument Safety
+ return error(detail::direct_error, stack::get<std::string>(L, index));
+ }
+
+ public:
+ protected_function_result() = default;
+ protected_function_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, call_status err = call_status::ok) noexcept : L(L), index(index), returncount(returncount), popcount(popcount), err(err) {
+
+ }
+ protected_function_result(const protected_function_result&) = default;
+ protected_function_result& operator=(const protected_function_result&) = default;
+ protected_function_result(protected_function_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but we will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ o.popcount = 0;
+ o.err = call_status::runtime;
+ }
+ protected_function_result& operator=(protected_function_result&& o) noexcept {
+ L = o.L;
+ index = o.index;
+ returncount = o.returncount;
+ popcount = o.popcount;
+ err = o.err;
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but we will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ o.popcount = 0;
+ o.err = call_status::runtime;
+ return *this;
+ }
+
+ call_status status() const noexcept {
+ return err;
+ }
+
+ bool valid() const noexcept {
+ return status() == call_status::ok || status() == call_status::yielded;
+ }
+
+ template<typename T>
+ decltype(auto) get() const {
+ return tagged_get(types<meta::unqualified_t<T>>());
+ }
+
+ lua_State* lua_state() const noexcept { return L; };
+ int stack_index() const noexcept { return index; };
+
+ ~protected_function_result() {
+ stack::remove(L, index, popcount);
+ }
+ };
+} // sol
+
+// end of sol/protected_function_result.hpp
+
+#include <algorithm>
+
+namespace sol {
+ namespace detail {
+ inline reference& handler_storage() {
+ static sol::reference h;
+ return h;
+ }
+
+ struct handler {
+ const reference& target;
+ int stackindex;
+ handler(const reference& target) : target(target), stackindex(0) {
+ if (target.valid()) {
+ stackindex = lua_gettop(target.lua_state()) + 1;
+ target.push();
+ }
+ }
+ bool valid() const { return stackindex != 0; }
+ ~handler() {
+ if (valid()) {
+ lua_remove(target.lua_state(), stackindex);
+ }
+ }
+ };
+ }
+
+ template <typename base_t>
+ class basic_protected_function : public base_t {
+ public:
+ static reference& get_default_handler() {
+ return detail::handler_storage();
+ }
+
+ static void set_default_handler(const reference& ref) {
+ detail::handler_storage() = ref;
+ }
+
+ static void set_default_handler(reference&& ref) {
+ detail::handler_storage() = std::move(ref);
+ }
+
+ private:
+ call_status luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, detail::handler& h) const {
+ return static_cast<call_status>(lua_pcallk(base_t::lua_state(), static_cast<int>(argcount), static_cast<int>(resultcount), h.stackindex, 0, nullptr));
+ }
+
+ template<std::size_t... I, typename... Ret>
+ auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n, detail::handler& h) const {
+ luacall(n, sizeof...(Ret), h);
+ return stack::pop<std::tuple<Ret...>>(base_t::lua_state());
+ }
+
+ template<std::size_t I, typename Ret>
+ Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n, detail::handler& h) const {
+ luacall(n, 1, h);
+ return stack::pop<Ret>(base_t::lua_state());
+ }
+
+ template <std::size_t I>
+ void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n, detail::handler& h) const {
+ luacall(n, 0, h);
+ }
+
+ protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n, detail::handler& h) const {
+ int stacksize = lua_gettop(base_t::lua_state());
+ int poststacksize = stacksize;
+ int firstreturn = 1;
+ int returncount = 0;
+ call_status code = call_status::ok;
+#ifndef SOL_NO_EXCEPTIONS
+ auto onexcept = [&](const char* error) {
+ h.stackindex = 0;
+ if (h.target.valid()) {
+ h.target.push();
+ stack::push(base_t::lua_state(), error);
+ lua_call(base_t::lua_state(), 1, 1);
+ }
+ else {
+ stack::push(base_t::lua_state(), error);
+ }
+ };
+ try {
+#endif // No Exceptions
+ firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid())));
+ code = luacall(n, LUA_MULTRET, h);
+ poststacksize = lua_gettop(base_t::lua_state()) - static_cast<int>(h.valid());
+ returncount = poststacksize - (firstreturn - 1);
+#ifndef SOL_NO_EXCEPTIONS
+ }
+ // Handle C++ errors thrown from C++ functions bound inside of lua
+ catch (const char* error) {
+ onexcept(error);
+ firstreturn = lua_gettop(base_t::lua_state());
+ return protected_function_result(base_t::lua_state(), firstreturn, 0, 1, call_status::runtime);
+ }
+ catch (const std::exception& error) {
+ onexcept(error.what());
+ firstreturn = lua_gettop(base_t::lua_state());
+ return protected_function_result(base_t::lua_state(), firstreturn, 0, 1, call_status::runtime);
+ }
+ catch (...) {
+ onexcept("caught (...) unknown error during protected_function call");
+ firstreturn = lua_gettop(base_t::lua_state());
+ return protected_function_result(base_t::lua_state(), firstreturn, 0, 1, call_status::runtime);
+ }
+#endif // No Exceptions
+ return protected_function_result(base_t::lua_state(), firstreturn, returncount, returncount, code);
+ }
+
+ public:
+ reference error_handler;
+
+ basic_protected_function() = default;
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_protected_function>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_protected_function(T&& r) noexcept : base_t(std::forward<T>(r)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!is_function<meta::unqualified_t<T>>::value) {
+ auto pp = stack::push_pop(*this);
+ stack::check<basic_protected_function>(base_t::lua_state(), -1, type_panic);
+ }
+#endif // Safety
+ }
+ basic_protected_function(const basic_protected_function&) = default;
+ basic_protected_function& operator=(const basic_protected_function&) = default;
+ basic_protected_function(basic_protected_function&&) = default;
+ basic_protected_function& operator=(basic_protected_function&&) = default;
+ basic_protected_function(const basic_function<base_t>& b, reference eh = get_default_handler()) : base_t(b), error_handler(std::move(eh)) {}
+ basic_protected_function(basic_function<base_t>&& b, reference eh = get_default_handler()) : base_t(std::move(b)), error_handler(std::move(eh)) {}
+ basic_protected_function(const stack_reference& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {}
+ basic_protected_function(stack_reference&& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {}
+ template <typename Super>
+ basic_protected_function(proxy_base<Super>&& p, reference eh = get_default_handler()) : basic_protected_function(p.operator basic_function<base_t>(), std::move(eh)) {}
+ template <typename Super>
+ basic_protected_function(const proxy_base<Super>& p, reference eh = get_default_handler()) : basic_protected_function(static_cast<basic_function<base_t>>(p), std::move(eh)) {}
+ basic_protected_function(lua_State* L, int index = -1, reference eh = get_default_handler()) : base_t(L, index), error_handler(std::move(eh)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ stack::check<basic_protected_function>(L, index, type_panic);
+#endif // Safety
+ }
+
+ template<typename... Args>
+ protected_function_result operator()(Args&&... args) const {
+ return call<>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) operator()(types<Ret...>, Args&&... args) const {
+ return call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) const {
+ detail::handler h(error_handler);
+ base_t::push();
+ int pushcount = stack::multi_push_reference(base_t::lua_state(), std::forward<Args>(args)...);
+ return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
+ }
+ };
+} // sol
+
+// end of sol/protected_function.hpp
+
+namespace sol {
+ struct stack_proxy : public proxy_base<stack_proxy> {
+ private:
+ lua_State* L;
+ int index;
+
+ public:
+ stack_proxy() : L(nullptr), index(0) {}
+ stack_proxy(lua_State* L, int index) : L(L), index(index) {}
+
+ template<typename T>
+ decltype(auto) get() const {
+ return stack::get<T>(L, stack_index());
+ }
+
+ int push() const {
+ lua_pushvalue(L, index);
+ return 1;
+ }
+
+ lua_State* lua_state() const { return L; }
+ int stack_index() const { return index; }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) {
+ return get<function>().template call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Args>
+ decltype(auto) operator()(Args&&... args) {
+ return call<>(std::forward<Args>(args)...);
+ }
+ };
+
+ namespace stack {
+ template <>
+ struct getter<stack_proxy> {
+ static stack_proxy get(lua_State* L, int index = -1) {
+ return stack_proxy(L, index);
+ }
+ };
+
+ template <>
+ struct pusher<stack_proxy> {
+ static int push(lua_State*, const stack_proxy& ref) {
+ return ref.push();
+ }
+ };
+ } // stack
+
+ namespace detail {
+ template <>
+ struct is_speshul<function_result> : std::true_type {};
+ template <>
+ struct is_speshul<protected_function_result> : std::true_type {};
+
+ template <std::size_t I, typename... Args, typename T>
+ stack_proxy get(types<Args...>, index_value<0>, index_value<I>, const T& fr) {
+ return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
+ }
+
+ template <std::size_t I, std::size_t N, typename Arg, typename... Args, typename T, meta::enable<meta::boolean<(N > 0)>> = meta::enabler>
+ stack_proxy get(types<Arg, Args...>, index_value<N>, index_value<I>, const T& fr) {
+ return get(types<Args...>(), index_value<N - 1>(), index_value<I + lua_size<Arg>::value>(), fr);
+ }
+ }
+
+ template <>
+ struct tie_size<function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
+
+ template <std::size_t I>
+ stack_proxy get(const function_result& fr) {
+ return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
+ }
+
+ template <std::size_t I, typename... Args>
+ stack_proxy get(types<Args...> t, const function_result& fr) {
+ return detail::get(t, index_value<I>(), index_value<0>(), fr);
+ }
+
+ template <>
+ struct tie_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
+
+ template <std::size_t I>
+ stack_proxy get(const protected_function_result& fr) {
+ return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
+ }
+
+ template <std::size_t I, typename... Args>
+ stack_proxy get(types<Args...> t, const protected_function_result& fr) {
+ return detail::get(t, index_value<I>(), index_value<0>(), fr);
+ }
+} // sol
+
+// end of sol/stack_proxy.hpp
+
+#include <limits>
+#include <iterator>
+
+namespace sol {
+ template <bool is_const>
+ struct va_iterator : std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const stack_proxy, stack_proxy>, std::ptrdiff_t, std::conditional_t<is_const, const stack_proxy*, stack_proxy*>, std::conditional_t<is_const, const stack_proxy, stack_proxy>> {
+ typedef std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const stack_proxy, stack_proxy>, std::ptrdiff_t, std::conditional_t<is_const, const stack_proxy*, stack_proxy*>, std::conditional_t<is_const, const stack_proxy, stack_proxy>> base_t;
+ typedef typename base_t::reference reference;
+ typedef typename base_t::pointer pointer;
+ typedef typename base_t::value_type value_type;
+ typedef typename base_t::difference_type difference_type;
+ typedef typename base_t::iterator_category iterator_category;
+ lua_State* L;
+ int index;
+ int stacktop;
+ stack_proxy sp;
+
+ va_iterator() : L(nullptr), index((std::numeric_limits<int>::max)()), stacktop((std::numeric_limits<int>::max)()) {}
+ va_iterator(lua_State* L, int index, int stacktop) : L(L), index(index), stacktop(stacktop), sp(L, index) {}
+
+ reference operator*() {
+ return stack_proxy(L, index);
+ }
+
+ pointer operator->() {
+ sp = stack_proxy(L, index);
+ return &sp;
+ }
+
+ va_iterator& operator++ () {
+ ++index;
+ return *this;
+ }
+
+ va_iterator operator++ (int) {
+ auto r = *this;
+ this->operator ++();
+ return r;
+ }
+
+ va_iterator& operator-- () {
+ --index;
+ return *this;
+ }
+
+ va_iterator operator-- (int) {
+ auto r = *this;
+ this->operator --();
+ return r;
+ }
+
+ va_iterator& operator+= (difference_type idx) {
+ index += static_cast<int>(idx);
+ return *this;
+ }
+
+ va_iterator& operator-= (difference_type idx) {
+ index -= static_cast<int>(idx);
+ return *this;
+ }
+
+ difference_type operator- (const va_iterator& r) const {
+ return index - r.index;
+ }
+
+ va_iterator operator+ (difference_type idx) const {
+ va_iterator r = *this;
+ r += idx;
+ return r;
+ }
+
+ reference operator[](difference_type idx) {
+ return stack_proxy(L, index + static_cast<int>(idx));
+ }
+
+ bool operator==(const va_iterator& r) const {
+ if (stacktop == (std::numeric_limits<int>::max)()) {
+ return r.index == r.stacktop;
+ }
+ else if (r.stacktop == (std::numeric_limits<int>::max)()) {
+ return index == stacktop;
+ }
+ return index == r.index;
+ }
+
+ bool operator != (const va_iterator& r) const {
+ return !(this->operator==(r));
+ }
+
+ bool operator < (const va_iterator& r) const {
+ return index < r.index;
+ }
+
+ bool operator > (const va_iterator& r) const {
+ return index > r.index;
+ }
+
+ bool operator <= (const va_iterator& r) const {
+ return index <= r.index;
+ }
+
+ bool operator >= (const va_iterator& r) const {
+ return index >= r.index;
+ }
+ };
+
+ template <bool is_const>
+ inline va_iterator<is_const> operator+(typename va_iterator<is_const>::difference_type n, const va_iterator<is_const>& r) {
+ return r + n;
+ }
+
+ struct variadic_args {
+ private:
+ lua_State* L;
+ int index;
+ int stacktop;
+
+ public:
+ typedef stack_proxy reference_type;
+ typedef stack_proxy value_type;
+ typedef stack_proxy* pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::size_t size_type;
+ typedef va_iterator<false> iterator;
+ typedef va_iterator<true> const_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ variadic_args() = default;
+ variadic_args(lua_State* L, int index = -1) : L(L), index(lua_absindex(L, index)), stacktop(lua_gettop(L)) {}
+ variadic_args(const variadic_args&) = default;
+ variadic_args& operator=(const variadic_args&) = default;
+ variadic_args(variadic_args&& o) : L(o.L), index(o.index), stacktop(o.stacktop) {
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.stacktop = 0;
+ }
+ variadic_args& operator=(variadic_args&& o) {
+ L = o.L;
+ index = o.index;
+ stacktop = o.stacktop;
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.stacktop = 0;
+ return *this;
+ }
+
+ iterator begin() { return iterator(L, index, stacktop + 1); }
+ iterator end() { return iterator(L, stacktop + 1, stacktop + 1); }
+ const_iterator begin() const { return const_iterator(L, index, stacktop + 1); }
+ const_iterator end() const { return const_iterator(L, stacktop + 1, stacktop + 1); }
+ const_iterator cbegin() const { return begin(); }
+ const_iterator cend() const { return end(); }
+
+ reverse_iterator rbegin() { return std::reverse_iterator<iterator>(begin()); }
+ reverse_iterator rend() { return std::reverse_iterator<iterator>(end()); }
+ const_reverse_iterator rbegin() const { return std::reverse_iterator<const_iterator>(begin()); }
+ const_reverse_iterator rend() const { return std::reverse_iterator<const_iterator>(end()); }
+ const_reverse_iterator crbegin() const { return std::reverse_iterator<const_iterator>(cbegin()); }
+ const_reverse_iterator crend() const { return std::reverse_iterator<const_iterator>(cend()); }
+
+ int push() const {
+ int pushcount = 0;
+ for (int i = index; i <= stacktop; ++i) {
+ lua_pushvalue(L, i);
+ pushcount += 1;
+ }
+ return pushcount;
+ }
+
+ template<typename T>
+ decltype(auto) get(difference_type start = 0) const {
+ return stack::get<T>(L, index + static_cast<int>(start));
+ }
+
+ stack_proxy operator[](difference_type start) const {
+ return stack_proxy(L, index + static_cast<int>(start));
+ }
+
+ lua_State* lua_state() const { return L; };
+ int stack_index() const { return index; };
+ int leftover_count() const { return stacktop - (index - 1); }
+ int top() const { return stacktop; }
+ };
+
+ namespace stack {
+ template <>
+ struct getter<variadic_args> {
+ static variadic_args get(lua_State* L, int index, record& tracking) {
+ tracking.last = 0;
+ return variadic_args(L, index);
+ }
+ };
+
+ template <>
+ struct pusher<variadic_args> {
+ static int push(lua_State*, const variadic_args& ref) {
+ return ref.push();
+ }
+ };
+ } // stack
+} // sol
+
+// end of sol/variadic_args.hpp
+
+namespace sol {
+
+ template <typename R = reference, bool should_pop = !std::is_base_of<stack_reference, R>::value, typename T>
+ R make_reference(lua_State* L, T&& value) {
+ int backpedal = stack::push(L, std::forward<T>(value));
+ R r = stack::get<R>(L, -backpedal);
+ if (should_pop) {
+ lua_pop(L, backpedal);
+ }
+ return r;
+ }
+
+ template <typename T, typename R = reference, bool should_pop = !std::is_base_of<stack_reference, R>::value, typename... Args>
+ R make_reference(lua_State* L, Args&&... args) {
+ int backpedal = stack::push<T>(L, std::forward<Args>(args)...);
+ R r = stack::get<R>(L, -backpedal);
+ if (should_pop) {
+ lua_pop(L, backpedal);
+ }
+ return r;
+ }
+
+ template <typename base_t>
+ class basic_object : public base_t {
+ private:
+ template<typename T>
+ decltype(auto) as_stack(std::true_type) const {
+ return stack::get<T>(base_t::lua_state(), base_t::stack_index());
+ }
+
+ template<typename T>
+ decltype(auto) as_stack(std::false_type) const {
+ base_t::push();
+ return stack::pop<T>(base_t::lua_state());
+ }
+
+ template<typename T>
+ bool is_stack(std::true_type) const {
+ return stack::check<T>(base_t::lua_state(), base_t::stack_index(), no_panic);
+ }
+
+ template<typename T>
+ bool is_stack(std::false_type) const {
+ auto pp = stack::push_pop(*this);
+ return stack::check<T>(base_t::lua_state(), -1, no_panic);
+ }
+
+ template <bool invert_and_pop = false>
+ basic_object(std::integral_constant<bool, invert_and_pop>, lua_State* L, int index = -1) noexcept : base_t(L, index) {
+ if (invert_and_pop) {
+ lua_pop(L, -index);
+ }
+ }
+
+ public:
+ basic_object() noexcept = default;
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_object(T&& r) : base_t(std::forward<T>(r)) {}
+ basic_object(nil_t r) : base_t(r) {}
+ basic_object(const basic_object&) = default;
+ basic_object(basic_object&&) = default;
+ basic_object& operator=(const basic_object&) = default;
+ basic_object& operator=(basic_object&&) = default;
+ basic_object& operator=(const base_t& b) { base_t::operator=(b); return *this; }
+ basic_object& operator=(base_t&& b) { base_t::operator=(std::move(b)); return *this; }
+ basic_object(const stack_reference& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {}
+ basic_object(stack_reference&& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {}
+ template <typename Super>
+ basic_object(const proxy_base<Super>& r) noexcept : basic_object(r.operator basic_object()) {}
+ template <typename Super>
+ basic_object(proxy_base<Super>&& r) noexcept : basic_object(r.operator basic_object()) {}
+ template <typename Super>
+ basic_object& operator=(const proxy_base<Super>& r) { this->operator=(r.operator basic_object()); return *this; }
+ template <typename Super>
+ basic_object& operator=(proxy_base<Super>&& r) { this->operator=(r.operator basic_object()); return *this; }
+ basic_object(lua_State* L, int index = -1) noexcept : base_t(L, index) {}
+ template <typename T, typename... Args>
+ basic_object(lua_State* L, in_place_type_t<T>, Args&&... args) noexcept : basic_object(std::integral_constant<bool, !std::is_base_of<stack_reference, base_t>::value>(), L, -stack::push<T>(L, std::forward<Args>(args)...)) {}
+ template <typename T, typename... Args>
+ basic_object(lua_State* L, in_place_t, T&& arg, Args&&... args) noexcept : basic_object(L, in_place<T>, std::forward<T>(arg), std::forward<Args>(args)...) {}
+
+ template<typename T>
+ decltype(auto) as() const {
+ return as_stack<T>(std::is_same<base_t, stack_reference>());
+ }
+
+ template<typename T>
+ bool is() const {
+ if (!base_t::valid())
+ return false;
+ return is_stack<T>(std::is_same<base_t, stack_reference>());
+ }
+ };
+
+ template <typename T>
+ object make_object(lua_State* L, T&& value) {
+ return make_reference<object, true>(L, std::forward<T>(value));
+ }
+
+ template <typename T, typename... Args>
+ object make_object(lua_State* L, Args&&... args) {
+ return make_reference<T, object, true>(L, std::forward<Args>(args)...);
+ }
+
+ inline bool operator==(const object& lhs, const nil_t&) {
+ return !lhs.valid();
+ }
+
+ inline bool operator==(const nil_t&, const object& rhs) {
+ return !rhs.valid();
+ }
+
+ inline bool operator!=(const object& lhs, const nil_t&) {
+ return lhs.valid();
+ }
+
+ inline bool operator!=(const nil_t&, const object& rhs) {
+ return rhs.valid();
+ }
+} // sol
+
+// end of sol/object.hpp
+
+namespace sol {
+ template<typename Table, typename Key>
+ struct proxy : public proxy_base<proxy<Table, Key>> {
+ private:
+ typedef meta::condition<meta::is_specialization_of<std::tuple, Key>, Key, std::tuple<meta::condition<std::is_array<meta::unqualified_t<Key>>, Key&, meta::unqualified_t<Key>>>> key_type;
+
+ template<typename T, std::size_t... I>
+ decltype(auto) tuple_get(std::index_sequence<I...>) const {
+ return tbl.template traverse_get<T>(std::get<I>(key)...);
+ }
+
+ template<std::size_t... I, typename T>
+ void tuple_set(std::index_sequence<I...>, T&& value) {
+ tbl.traverse_set(std::get<I>(key)..., std::forward<T>(value));
+ }
+
+ public:
+ Table tbl;
+ key_type key;
+
+ template<typename T>
+ proxy(Table table, T&& key) : tbl(table), key(std::forward<T>(key)) {}
+
+ template<typename T>
+ proxy& set(T&& item) {
+ tuple_set(std::make_index_sequence<std::tuple_size<meta::unqualified_t<key_type>>::value>(), std::forward<T>(item));
+ return *this;
+ }
+
+ template<typename... Args>
+ proxy& set_function(Args&&... args) {
+ tbl.set_function(key, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename U, meta::enable<meta::neg<is_lua_reference<meta::unwrap_unqualified_t<U>>>, meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
+ proxy& operator=(U&& other) {
+ return set_function(std::forward<U>(other));
+ }
+
+ template<typename U, meta::disable<meta::neg<is_lua_reference<meta::unwrap_unqualified_t<U>>>, meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
+ proxy& operator=(U&& other) {
+ return set(std::forward<U>(other));
+ }
+
+ template<typename T>
+ decltype(auto) get() const {
+ return tuple_get<T>(std::make_index_sequence<std::tuple_size<meta::unqualified_t<key_type>>::value>());
+ }
+
+ template<typename T>
+ decltype(auto) get_or(T&& otherwise) const {
+ typedef decltype(get<T>()) U;
+ sol::optional<U> option = get<sol::optional<U>>();
+ if (option) {
+ return static_cast<U>(option.value());
+ }
+ return static_cast<U>(std::forward<T>(otherwise));
+ }
+
+ template<typename T, typename D>
+ decltype(auto) get_or(D&& otherwise) const {
+ sol::optional<T> option = get<sol::optional<T>>();
+ if (option) {
+ return static_cast<T>(option.value());
+ }
+ return static_cast<T>(std::forward<D>(otherwise));
+ }
+
+ template <typename K>
+ decltype(auto) operator[](K&& k) const {
+ auto keys = meta::tuplefy(key, std::forward<K>(k));
+ return proxy<Table, decltype(keys)>(tbl, std::move(keys));
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) {
+ return get<function>().template call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Args>
+ decltype(auto) operator()(Args&&... args) {
+ return call<>(std::forward<Args>(args)...);
+ }
+
+ bool valid() const {
+ stack::push_pop(tbl);
+ auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(tbl.lua_state(), key, lua_gettop(tbl.lua_state()));
+ lua_pop(tbl.lua_state(), p.levels);
+ return p;
+ }
+ };
+
+ template<typename Table, typename Key, typename T>
+ inline bool operator==(T&& left, const proxy<Table, Key>& right) {
+ return left == right.template get<std::decay_t<T>>();
+ }
+
+ template<typename Table, typename Key, typename T>
+ inline bool operator==(const proxy<Table, Key>& right, T&& left) {
+ return right.template get<std::decay_t<T>>() == left;
+ }
+
+ template<typename Table, typename Key, typename T>
+ inline bool operator!=(T&& left, const proxy<Table, Key>& right) {
+ return right.template get<std::decay_t<T>>() != left;
+ }
+
+ template<typename Table, typename Key, typename T>
+ inline bool operator!=(const proxy<Table, Key>& right, T&& left) {
+ return right.template get<std::decay_t<T>>() != left;
+ }
+
+ template<typename Table, typename Key>
+ inline bool operator==(nil_t, const proxy<Table, Key>& right) {
+ return !right.valid();
+ }
+
+ template<typename Table, typename Key>
+ inline bool operator==(const proxy<Table, Key>& right, nil_t) {
+ return !right.valid();
+ }
+
+ template<typename Table, typename Key>
+ inline bool operator!=(nil_t, const proxy<Table, Key>& right) {
+ return right.valid();
+ }
+
+ template<typename Table, typename Key>
+ inline bool operator!=(const proxy<Table, Key>& right, nil_t) {
+ return right.valid();
+ }
+
+ namespace stack {
+ template <typename Table, typename Key>
+ struct pusher<proxy<Table, Key>> {
+ static int push(lua_State*, const proxy<Table, Key>& p) {
+ sol::reference r = p;
+ return r.push();
+ }
+ };
+ } // stack
+} // sol
+
+// end of sol/proxy.hpp
+
+// beginning of sol/usertype.hpp
+
+// beginning of sol/usertype_metatable.hpp
+
+// beginning of sol/deprecate.hpp
+
+#ifndef SOL_DEPRECATED
+ #ifdef _MSC_VER
+ #define SOL_DEPRECATED __declspec(deprecated)
+ #elif __GNUC__
+ #define SOL_DEPRECATED __attribute__((deprecated))
+ #else
+ #define SOL_DEPRECATED [[deprecated]]
+ #endif // compilers
+#endif // SOL_DEPRECATED
+
+namespace sol {
+ namespace detail {
+ template <typename T>
+ struct SOL_DEPRECATED deprecate_type {
+ using type = T;
+ };
+ } // detail
+} // sol
+
+// end of sol/deprecate.hpp
+
+#include <unordered_map>
+#include <cstdio>
+
+namespace sol {
+ namespace usertype_detail {
+ struct no_comp {
+ template <typename A, typename B>
+ bool operator()(A&&, B&&) const {
+ return false;
+ }
+ };
+
+ typedef void(*base_walk)(lua_State*, bool&, int&, string_detail::string_shim&);
+ typedef int(*member_search)(lua_State*, void*);
+
+ struct find_call_pair {
+ member_search first;
+ member_search second;
+
+ find_call_pair(member_search first, member_search second) : first(first), second(second) {}
+ };
+
+ inline bool is_indexer(string_detail::string_shim s) {
+ return s == name_of(meta_function::index) || s == name_of(meta_function::new_index);
+ }
+
+ inline bool is_indexer(meta_function mf) {
+ return mf == meta_function::index || mf == meta_function::new_index;
+ }
+
+ inline bool is_indexer(call_construction) {
+ return false;
+ }
+
+ inline bool is_indexer(base_classes_tag) {
+ return false;
+ }
+
+ inline auto make_shim(string_detail::string_shim s) {
+ return s;
+ }
+
+ inline auto make_shim(call_construction) {
+ return string_detail::string_shim(name_of(meta_function::call_function));
+ }
+
+ inline auto make_shim(meta_function mf) {
+ return string_detail::string_shim(name_of(mf));
+ }
+
+ inline auto make_shim(base_classes_tag) {
+ return string_detail::string_shim(detail::base_class_cast_key());
+ }
+
+ template <typename Arg>
+ inline std::string make_string(Arg&& arg) {
+ string_detail::string_shim s = make_shim(arg);
+ return std::string(s.c_str(), s.size());
+ }
+
+ template <typename N>
+ inline luaL_Reg make_reg(N&& n, lua_CFunction f) {
+ luaL_Reg l{ make_shim(std::forward<N>(n)).c_str(), f };
+ return l;
+ }
+
+ struct registrar {
+ virtual int push_um(lua_State* L) = 0;
+ virtual ~registrar() {}
+ };
+
+ template <bool is_index>
+ inline int indexing_fail(lua_State* L) {
+ auto maybeaccessor = stack::get<optional<string_detail::string_shim>>(L, is_index ? -1 : -2);
+ string_detail::string_shim accessor = maybeaccessor.value_or(string_detail::string_shim("(unknown)"));
+ if (is_index)
+ return luaL_error(L, "sol: attempt to index (get) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str());
+ else
+ return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str());
+ }
+
+ template <bool is_index, typename Base>
+ static void walk_single_base(lua_State* L, bool& found, int& ret, string_detail::string_shim&) {
+ if (found)
+ return;
+ const char* metakey = &usertype_traits<Base>::metatable[0];
+ const char* gcmetakey = &usertype_traits<Base>::gc_table[0];
+ const char* basewalkkey = is_index ? detail::base_class_index_propogation_key() : detail::base_class_new_index_propogation_key();
+
+ luaL_getmetatable(L, metakey);
+ if (type_of(L, -1) == type::nil) {
+ lua_pop(L, 1);
+ return;
+ }
+
+ stack::get_field(L, basewalkkey);
+ if (type_of(L, -1) == type::nil) {
+ lua_pop(L, 2);
+ return;
+ }
+ lua_CFunction basewalkfunc = stack::pop<lua_CFunction>(L);
+ lua_pop(L, 1);
+
+ stack::get_field<true>(L, gcmetakey);
+ int value = basewalkfunc(L);
+ if (value > -1) {
+ found = true;
+ ret = value;
+ }
+ }
+
+ template <bool is_index, typename... Bases>
+ static void walk_all_bases(lua_State* L, bool& found, int& ret, string_detail::string_shim& accessor) {
+ (void)L;
+ (void)found;
+ (void)ret;
+ (void)accessor;
+ (void)detail::swallow{ 0, (walk_single_base<is_index, Bases>(L, found, ret, accessor), 0)... };
+ }
+
+ template <typename T, typename Op>
+ inline int operator_wrap(lua_State* L) {
+ auto maybel = stack::check_get<T>(L, 1);
+ if (maybel) {
+ auto mayber = stack::check_get<T>(L, 2);
+ if (mayber) {
+ auto& l = *maybel;
+ auto& r = *mayber;
+ if (std::is_same<no_comp, Op>::value) {
+ return stack::push(L, detail::ptr(l) == detail::ptr(r));
+ }
+ else {
+ Op op;
+ return stack::push(L, (detail::ptr(l) == detail::ptr(r)) || op(detail::deref(l), detail::deref(r)));
+ }
+ }
+ }
+ return stack::push(L, false);
+ }
+
+ template <typename T, typename Op, typename Supports, typename Regs, meta::enable<Supports> = meta::enabler>
+ inline void make_reg_op(Regs& l, int& index, const char* name) {
+ l[index] = { name, &operator_wrap<T, Op> };
+ ++index;
+ }
+
+ template <typename T, typename Op, typename Supports, typename Regs, meta::disable<Supports> = meta::enabler>
+ inline void make_reg_op(Regs&, int&, const char*) {
+ // Do nothing if there's no support
+ }
+
+ struct add_destructor_tag {};
+ struct check_destructor_tag {};
+ struct verified_tag {} const verified{};
+
+ template <typename T>
+ struct is_constructor : std::false_type {};
+
+ template <typename... Args>
+ struct is_constructor<constructors<Args...>> : std::true_type {};
+
+ template <typename... Args>
+ struct is_constructor<constructor_wrapper<Args...>> : std::true_type {};
+
+ template <typename... Args>
+ struct is_constructor<factory_wrapper<Args...>> : std::true_type {};
+
+ template <>
+ struct is_constructor<no_construction> : std::true_type {};
+
+ template <typename... Args>
+ using has_constructor = meta::any<is_constructor<meta::unqualified_t<Args>>...>;
+
+ template <typename T>
+ struct is_destructor : std::false_type {};
+
+ template <typename Fx>
+ struct is_destructor<destructor_wrapper<Fx>> : std::true_type {};
+
+ template <typename... Args>
+ using has_destructor = meta::any<is_destructor<meta::unqualified_t<Args>>...>;
+
+ } // usertype_detail
+
+ template <typename T>
+ struct clean_type {
+ typedef std::conditional_t<std::is_array<meta::unqualified_t<T>>::value, T&, std::decay_t<T>> type;
+ };
+
+ template <typename T>
+ using clean_type_t = typename clean_type<T>::type;
+
+ template <typename T, typename IndexSequence, typename... Tn>
+ struct usertype_metatable : usertype_detail::registrar {};
+
+ template <typename T, std::size_t... I, typename... Tn>
+ struct usertype_metatable<T, std::index_sequence<I...>, Tn...> : usertype_detail::registrar {
+ typedef std::make_index_sequence<sizeof...(I) * 2> indices;
+ typedef std::index_sequence<I...> half_indices;
+ typedef std::array<luaL_Reg, sizeof...(Tn) / 2 + 1 + 3> regs_t;
+ typedef std::tuple<Tn...> RawTuple;
+ typedef std::tuple<clean_type_t<Tn> ...> Tuple;
+ template <std::size_t Idx>
+ struct check_binding : is_variable_binding<meta::unqualified_tuple_element_t<Idx, Tuple>> {};
+ typedef std::unordered_map<std::string, usertype_detail::find_call_pair> mapping_t;
+ Tuple functions;
+ mapping_t mapping;
+ lua_CFunction indexfunc;
+ lua_CFunction newindexfunc;
+ lua_CFunction destructfunc;
+ lua_CFunction callconstructfunc;
+ lua_CFunction indexbase;
+ lua_CFunction newindexbase;
+ usertype_detail::base_walk indexbaseclasspropogation;
+ usertype_detail::base_walk newindexbaseclasspropogation;
+ void* baseclasscheck;
+ void* baseclasscast;
+ bool mustindex;
+ bool secondarymeta;
+ bool hasequals;
+ bool hasless;
+ bool haslessequals;
+
+ template <std::size_t Idx, meta::enable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
+ inline lua_CFunction make_func() {
+ return std::get<Idx + 1>(functions);
+ }
+
+ template <std::size_t Idx, meta::disable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
+ inline lua_CFunction make_func() {
+ return call<Idx + 1>;
+ }
+
+ static bool contains_variable() {
+ typedef meta::any<check_binding<(I * 2 + 1)>...> has_variables;
+ return has_variables::value;
+ }
+
+ bool contains_index() const {
+ bool idx = false;
+ (void)detail::swallow{ 0, ((idx |= usertype_detail::is_indexer(std::get<I * 2>(functions))), 0) ... };
+ return idx;
+ }
+
+ int finish_regs(regs_t& l, int& index) {
+ if (!hasless) {
+ const char* name = name_of(meta_function::less_than).c_str();
+ usertype_detail::make_reg_op<T, std::less<>, meta::supports_op_less<T>>(l, index, name);
+ }
+ if (!haslessequals) {
+ const char* name = name_of(meta_function::less_than_or_equal_to).c_str();
+ usertype_detail::make_reg_op<T, std::less_equal<>, meta::supports_op_less_equal<T>>(l, index, name);
+ }
+ if (!hasequals) {
+ const char* name = name_of(meta_function::equal_to).c_str();
+ usertype_detail::make_reg_op<T, std::conditional_t<meta::supports_op_equal<T>::value, std::equal_to<>, usertype_detail::no_comp>, std::true_type>(l, index, name);
+ }
+ if (destructfunc != nullptr) {
+ l[index] = { name_of(meta_function::garbage_collect).c_str(), destructfunc };
+ ++index;
+ }
+ return index;
+ }
+
+ template <std::size_t Idx, typename F>
+ void make_regs(regs_t&, int&, call_construction, F&&) {
+ callconstructfunc = call<Idx + 1>;
+ secondarymeta = true;
+ }
+
+ template <std::size_t, typename... Bases>
+ void make_regs(regs_t&, int&, base_classes_tag, bases<Bases...>) {
+ if (sizeof...(Bases) < 1) {
+ return;
+ }
+ mustindex = true;
+ (void)detail::swallow{ 0, ((detail::has_derived<Bases>::value = true), 0)... };
+
+ static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
+ static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
+ baseclasscheck = (void*)&detail::inheritance<T, Bases...>::type_check;
+ baseclasscast = (void*)&detail::inheritance<T, Bases...>::type_cast;
+ indexbaseclasspropogation = usertype_detail::walk_all_bases<true, Bases...>;
+ newindexbaseclasspropogation = usertype_detail::walk_all_bases<false, Bases...>;
+ }
+
+ template <std::size_t Idx, typename N, typename F, typename = std::enable_if_t<!meta::any_same<meta::unqualified_t<N>, base_classes_tag, call_construction>::value>>
+ void make_regs(regs_t& l, int& index, N&& n, F&&) {
+ if (is_variable_binding<meta::unqualified_t<F>>::value) {
+ return;
+ }
+ luaL_Reg reg = usertype_detail::make_reg(std::forward<N>(n), make_func<Idx>());
+ // Returnable scope
+ // That would be a neat keyword for C++
+ // returnable { ... };
+ if (reg.name == name_of(meta_function::equal_to)) {
+ hasequals = true;
+ }
+ if (reg.name == name_of(meta_function::less_than)) {
+ hasless = true;
+ }
+ if (reg.name == name_of(meta_function::less_than_or_equal_to)) {
+ haslessequals = true;
+ }
+ if (reg.name == name_of(meta_function::garbage_collect)) {
+ destructfunc = reg.func;
+ return;
+ }
+ else if (reg.name == name_of(meta_function::index)) {
+ indexfunc = reg.func;
+ mustindex = true;
+ return;
+ }
+ else if (reg.name == name_of(meta_function::new_index)) {
+ newindexfunc = reg.func;
+ mustindex = true;
+ return;
+ }
+ l[index] = reg;
+ ++index;
+ }
+
+ template <typename... Args, typename = std::enable_if_t<sizeof...(Args) == sizeof...(Tn)>>
+ usertype_metatable(Args&&... args) : functions(std::forward<Args>(args)...),
+ mapping(),
+ indexfunc(usertype_detail::indexing_fail<true>), newindexfunc(usertype_detail::indexing_fail<false>),
+ destructfunc(nullptr), callconstructfunc(nullptr),
+ indexbase(&core_indexing_call<true>), newindexbase(&core_indexing_call<false>),
+ indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(usertype_detail::walk_all_bases<false>),
+ baseclasscheck(nullptr), baseclasscast(nullptr),
+ mustindex(contains_variable() || contains_index()), secondarymeta(contains_variable()),
+ hasequals(false), hasless(false), haslessequals(false) {
+ std::initializer_list<typename mapping_t::value_type> ilist{ {
+ std::pair<std::string, usertype_detail::find_call_pair>(
+ usertype_detail::make_string(std::get<I * 2>(functions)),
+ usertype_detail::find_call_pair(&usertype_metatable::real_find_call<I * 2, I * 2 + 1, false>,
+ &usertype_metatable::real_find_call<I * 2, I * 2 + 1, true>)
+ )
+ }... };
+ mapping.insert(ilist);
+ }
+
+ template <std::size_t I0, std::size_t I1, bool is_index>
+ static int real_find_call(lua_State* L, void* um) {
+ auto& f = *static_cast<usertype_metatable*>(um);
+ if (is_variable_binding<decltype(std::get<I1>(f.functions))>::value) {
+ return real_call_with<I1, is_index, true>(L, f);
+ }
+ return stack::push(L, c_closure(call<I1, is_index>, stack::push(L, light<usertype_metatable>(f))));
+ }
+
+ template <bool is_index, bool toplevel = false>
+ static int core_indexing_call(lua_State* L) {
+ usertype_metatable& f = toplevel ? stack::get<light<usertype_metatable>>(L, upvalue_index(1)) : stack::pop<light<usertype_metatable>>(L);
+ static const int keyidx = -2 + static_cast<int>(is_index);
+ if (toplevel && stack::get<type>(L, keyidx) != type::string) {
+ return is_index ? f.indexfunc(L) : f.newindexfunc(L);
+ }
+ std::string name = stack::get<std::string>(L, keyidx);
+ auto memberit = f.mapping.find(name);
+ if (memberit != f.mapping.cend()) {
+ auto& member = is_index ? memberit->second.second : memberit->second.first;
+ return (member)(L, static_cast<void*>(&f));
+ }
+ string_detail::string_shim accessor = name;
+ int ret = 0;
+ bool found = false;
+ // Otherwise, we need to do propagating calls through the bases
+ if (is_index)
+ f.indexbaseclasspropogation(L, found, ret, accessor);
+ else
+ f.newindexbaseclasspropogation(L, found, ret, accessor);
+ if (found) {
+ return ret;
+ }
+ return toplevel ? (is_index ? f.indexfunc(L) : f.newindexfunc(L)) : -1;
+ }
+
+ static int real_index_call(lua_State* L) {
+ return core_indexing_call<true, true>(L);
+ }
+
+ static int real_new_index_call(lua_State* L) {
+ return core_indexing_call<false, true>(L);
+ }
+
+ template <std::size_t Idx, bool is_index = true, bool is_variable = false>
+ static int real_call(lua_State* L) {
+ usertype_metatable& f = stack::get<light<usertype_metatable>>(L, upvalue_index(1));
+ return real_call_with<Idx, is_index, is_variable>(L, f);
+ }
+
+ template <std::size_t Idx, bool is_index = true, bool is_variable = false>
+ static int real_call_with(lua_State* L, usertype_metatable& um) {
+ auto& f = std::get<Idx>(um.functions);
+ return call_detail::call_wrapped<T, is_index, is_variable>(L, f);
+ }
+
+ template <std::size_t Idx, bool is_index = true, bool is_variable = false>
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call<Idx, is_index, is_variable>)>(L);
+ }
+
+ template <std::size_t Idx, bool is_index = true, bool is_variable = false>
+ static int call_with(lua_State* L) {
+ return detail::static_trampoline<(&real_call_with<Idx, is_index, is_variable>)>(L);
+ }
+
+ static int index_call(lua_State* L) {
+ return detail::static_trampoline<(&real_index_call)>(L);
+ }
+
+ static int new_index_call(lua_State* L) {
+ return detail::static_trampoline<(&real_new_index_call)>(L);
+ }
+
+ virtual int push_um(lua_State* L) override {
+ return stack::push(L, std::move(*this));
+ }
+
+ ~usertype_metatable() override {
+
+ }
+ };
+
+ namespace stack {
+
+ template <typename T, std::size_t... I, typename... Args>
+ struct pusher<usertype_metatable<T, std::index_sequence<I...>, Args...>> {
+ typedef usertype_metatable<T, std::index_sequence<I...>, Args...> umt_t;
+ typedef typename umt_t::regs_t regs_t;
+
+ static umt_t& make_cleanup(lua_State* L, umt_t&& umx) {
+ // ensure some sort of uniqueness
+ static int uniqueness = 0;
+ std::string uniquegcmetakey = usertype_traits<T>::user_gc_metatable;
+ // std::to_string doesn't exist in android still, with NDK, so this bullshit
+ // is necessary
+ // thanks, Android :v
+ int appended = snprintf(nullptr, 0, "%d", uniqueness);
+ std::size_t insertionpoint = uniquegcmetakey.length() - 1;
+ uniquegcmetakey.append(appended, '\0');
+ char* uniquetarget = &uniquegcmetakey[insertionpoint];
+ snprintf(uniquetarget, uniquegcmetakey.length(), "%d", uniqueness);
+ ++uniqueness;
+
+ const char* gcmetakey = &usertype_traits<T>::gc_table[0];
+ // Make sure userdata's memory is properly in lua first,
+ // otherwise all the light userdata we make later will become invalid
+ stack::push<user<umt_t>>(L, metatable_key, uniquegcmetakey, std::move(umx));
+ // Create the top level thing that will act as our deleter later on
+ stack_reference umt(L, -1);
+ stack::set_field<true>(L, gcmetakey, umt);
+ umt.pop();
+
+ stack::get_field<true>(L, gcmetakey);
+ return stack::pop<light<umt_t>>(L);
+ }
+
+ static int push(lua_State* L, umt_t&& umx) {
+
+ umt_t& um = make_cleanup(L, std::move(umx));
+ regs_t value_table{ {} };
+ int lastreg = 0;
+ (void)detail::swallow{ 0, (um.template make_regs<(I * 2)>(value_table, lastreg, std::get<(I * 2)>(um.functions), std::get<(I * 2 + 1)>(um.functions)), 0)... };
+ um.finish_regs(value_table, lastreg);
+ value_table[lastreg] = { nullptr, nullptr };
+ regs_t ref_table = value_table;
+ regs_t unique_table = value_table;
+ bool hasdestructor = !value_table.empty() && name_of(meta_function::garbage_collect) == value_table[lastreg - 1].name;
+ if (hasdestructor) {
+ ref_table[lastreg - 1] = { nullptr, nullptr };
+ unique_table[lastreg - 1] = { value_table[lastreg - 1].name, detail::unique_destruct<T> };
+ }
+
+ // Now use um
+ const bool& mustindex = um.mustindex;
+ for (std::size_t i = 0; i < 3; ++i) {
+ // Pointer types, AKA "references" from C++
+ const char* metakey = nullptr;
+ luaL_Reg* metaregs = nullptr;
+ switch (i) {
+ case 0:
+ metakey = &usertype_traits<T*>::metatable[0];
+ metaregs = ref_table.data();
+ break;
+ case 1:
+ metakey = &usertype_traits<detail::unique_usertype<T>>::metatable[0];
+ metaregs = unique_table.data();
+ break;
+ case 2:
+ default:
+ metakey = &usertype_traits<T>::metatable[0];
+ metaregs = value_table.data();
+ break;
+ }
+ luaL_newmetatable(L, metakey);
+ stack_reference t(L, -1);
+ stack::push(L, make_light(um));
+ luaL_setfuncs(L, metaregs, 1);
+
+ if (um.baseclasscheck != nullptr) {
+ stack::set_field(L, detail::base_class_check_key(), um.baseclasscheck, t.stack_index());
+ }
+ if (um.baseclasscast != nullptr) {
+ stack::set_field(L, detail::base_class_cast_key(), um.baseclasscast, t.stack_index());
+ }
+
+ stack::set_field(L, detail::base_class_index_propogation_key(), make_closure(um.indexbase, make_light(um)), t.stack_index());
+ stack::set_field(L, detail::base_class_new_index_propogation_key(), make_closure(um.newindexbase, make_light(um)), t.stack_index());
+
+ if (mustindex) {
+ // Basic index pushing: specialize
+ // index and newindex to give variables and stuff
+ stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um)), t.stack_index());
+ stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um)), t.stack_index());
+ }
+ else {
+ // If there's only functions, we can use the fast index version
+ stack::set_field(L, meta_function::index, t, t.stack_index());
+ }
+ // metatable on the metatable
+ // for call constructor purposes and such
+ lua_createtable(L, 0, 1);
+ stack_reference metabehind(L, -1);
+ if (um.callconstructfunc != nullptr) {
+ stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um)), metabehind.stack_index());
+ }
+ if (um.secondarymeta) {
+ stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um)), metabehind.stack_index());
+ stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um)), metabehind.stack_index());
+ }
+ stack::set_field(L, metatable_key, metabehind, t.stack_index());
+ metabehind.pop();
+ // We want to just leave the table
+ // in the registry only, otherwise we return it
+ if (i < 2) {
+ t.pop();
+ }
+ }
+
+ return 1;
+ }
+ };
+
+ } // stack
+
+} // sol
+
+// end of sol/usertype_metatable.hpp
+
+// beginning of sol/simple_usertype_metatable.hpp
+
+namespace sol {
+
+ namespace usertype_detail {
+ struct variable_wrapper {
+ virtual int index(lua_State* L) = 0;
+ virtual int new_index(lua_State* L) = 0;
+ virtual ~variable_wrapper() {};
+ };
+
+ template <typename T, typename F>
+ struct callable_binding : variable_wrapper {
+ F fx;
+
+ template <typename Arg>
+ callable_binding(Arg&& arg) : fx(std::forward<Arg>(arg)) {}
+
+ virtual int index(lua_State* L) override {
+ return call_detail::call_wrapped<T, true, true>(L, fx);
+ }
+
+ virtual int new_index(lua_State* L) override {
+ return call_detail::call_wrapped<T, false, true>(L, fx);
+ }
+ };
+
+ typedef std::unordered_map<std::string, std::unique_ptr<variable_wrapper>> variable_map;
+ typedef std::unordered_map<std::string, object> function_map;
+
+ struct simple_map {
+ const char* metakey;
+ variable_map variables;
+ function_map functions;
+ base_walk indexbaseclasspropogation;
+ base_walk newindexbaseclasspropogation;
+
+ simple_map(const char* mkey, base_walk index, base_walk newindex, variable_map&& vars, function_map&& funcs) : metakey(mkey), variables(std::move(vars)), functions(std::move(funcs)), indexbaseclasspropogation(index), newindexbaseclasspropogation(newindex) {}
+ };
+
+ template <typename T>
+ inline int simple_metatable_newindex(lua_State* L) {
+ if (stack::stack_detail::check_metatable<T, false>(L, 1)) {
+ stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), 1);
+ lua_settop(L, 0);
+ return 0;
+ }
+ lua_pop(L, 1);
+ return indexing_fail<false>(L);
+ }
+
+ template <bool is_index, bool toplevel = false>
+ inline int simple_core_indexing_call(lua_State* L) {
+ simple_map& sm = toplevel ? stack::get<user<simple_map>>(L, upvalue_index(1)) : stack::pop<user<simple_map>>(L);
+ variable_map& variables = sm.variables;
+ function_map& functions = sm.functions;
+ static const int keyidx = -2 + static_cast<int>(is_index);
+ if (toplevel) {
+ if (stack::get<type>(L, keyidx) != type::string) {
+ lua_CFunction indexingfunc = is_index ? stack::get<lua_CFunction>(L, upvalue_index(2)) : stack::get<lua_CFunction>(L, upvalue_index(3));
+ return indexingfunc(L);
+ }
+ }
+ string_detail::string_shim accessor = stack::get<string_detail::string_shim>(L, keyidx);
+ std::string accessorkey = accessor.c_str();
+ auto vit = variables.find(accessorkey);
+ if (vit != variables.cend()) {
+ auto& varwrap = *(vit->second);
+ if (is_index) {
+ return varwrap.index(L);
+ }
+ return varwrap.new_index(L);
+ }
+ auto fit = functions.find(accessorkey);
+ if (fit != functions.cend()) {
+ auto& func = (fit->second);
+ return stack::push(L, func);
+ }
+ // Check table storage first for a method that works
+ luaL_getmetatable(L, sm.metakey);
+ if (type_of(L, -1) != type::nil) {
+ stack::get_field<false, true>(L, accessor.c_str(), lua_gettop(L));
+ if (type_of(L, -1) != type::nil) {
+ // Woo, we found it?
+ lua_remove(L, -2);
+ return 1;
+ }
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
+
+ int ret = 0;
+ bool found = false;
+ // Otherwise, we need to do propagating calls through the bases
+ if (is_index) {
+ sm.indexbaseclasspropogation(L, found, ret, accessor);
+ }
+ else {
+ sm.newindexbaseclasspropogation(L, found, ret, accessor);
+ }
+ if (found) {
+ return ret;
+ }
+ if (toplevel) {
+ lua_CFunction indexingfunc = is_index ? stack::get<lua_CFunction>(L, upvalue_index(2)) : stack::get<lua_CFunction>(L, upvalue_index(3));
+ return indexingfunc(L);
+ }
+ return -1;
+ }
+
+ inline int simple_real_index_call(lua_State* L) {
+ return simple_core_indexing_call<true, true>(L);
+ }
+
+ inline int simple_real_new_index_call(lua_State* L) {
+ return simple_core_indexing_call<false, true>(L);
+ }
+
+ inline int simple_index_call(lua_State* L) {
+ return detail::static_trampoline<(&simple_real_index_call)>(L);
+ }
+
+ inline int simple_new_index_call(lua_State* L) {
+ return detail::static_trampoline<(&simple_real_new_index_call)>(L);
+ }
+ }
+
+ struct simple_tag {} const simple{};
+
+ template <typename T>
+ struct simple_usertype_metatable : usertype_detail::registrar {
+ public:
+ usertype_detail::function_map registrations;
+ usertype_detail::variable_map varmap;
+ object callconstructfunc;
+ lua_CFunction indexfunc;
+ lua_CFunction newindexfunc;
+ lua_CFunction indexbase;
+ lua_CFunction newindexbase;
+ usertype_detail::base_walk indexbaseclasspropogation;
+ usertype_detail::base_walk newindexbaseclasspropogation;
+ void* baseclasscheck;
+ void* baseclasscast;
+ bool mustindex;
+ bool secondarymeta;
+
+ template <typename N>
+ void insert(N&& n, object&& o) {
+ std::string key = usertype_detail::make_string(std::forward<N>(n));
+ auto hint = registrations.find(key);
+ if (hint == registrations.cend()) {
+ registrations.emplace_hint(hint, std::move(key), std::move(o));
+ return;
+ }
+ hint->second = std::move(o);
+ }
+
+ template <typename N, typename F, meta::enable<meta::is_callable<meta::unwrap_unqualified_t<F>>> = meta::enabler>
+ void add_function(lua_State* L, N&& n, F&& f) {
+ insert(std::forward<N>(n), make_object(L, as_function_reference(std::forward<F>(f))));
+ }
+
+ template <typename N, typename F, meta::disable<meta::is_callable<meta::unwrap_unqualified_t<F>>> = meta::enabler>
+ void add_function(lua_State* L, N&& n, F&& f) {
+ object o = make_object(L, std::forward<F>(f));
+ if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
+ callconstructfunc = std::move(o);
+ return;
+ }
+ insert(std::forward<N>(n), std::move(o));
+ }
+
+ template <typename N, typename F, meta::disable<is_variable_binding<meta::unqualified_t<F>>> = meta::enabler>
+ void add(lua_State* L, N&& n, F&& f) {
+ add_function(L, std::forward<N>(n), std::forward<F>(f));
+ }
+
+ template <typename N, typename F, meta::enable<is_variable_binding<meta::unqualified_t<F>>> = meta::enabler>
+ void add(lua_State*, N&& n, F&& f) {
+ mustindex = true;
+ secondarymeta = true;
+ std::string key = usertype_detail::make_string(std::forward<N>(n));
+ auto o = std::make_unique<usertype_detail::callable_binding<T, std::decay_t<F>>>(std::forward<F>(f));
+ auto hint = varmap.find(key);
+ if (hint == varmap.cend()) {
+ varmap.emplace_hint(hint, std::move(key), std::move(o));
+ return;
+ }
+ hint->second = std::move(o);
+ }
+
+ template <typename N, typename... Fxs>
+ void add(lua_State* L, N&& n, constructor_wrapper<Fxs...> c) {
+ object o(L, in_place<detail::tagged<T, constructor_wrapper<Fxs...>>>, std::move(c));
+ if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
+ callconstructfunc = std::move(o);
+ return;
+ }
+ insert(std::forward<N>(n), std::move(o));
+ }
+
+ template <typename N, typename... Lists>
+ void add(lua_State* L, N&& n, constructor_list<Lists...> c) {
+ object o(L, in_place<detail::tagged<T, constructor_list<Lists...>>>, std::move(c));
+ if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
+ callconstructfunc = std::move(o);
+ return;
+ }
+ insert(std::forward<N>(n), std::move(o));
+ }
+
+ template <typename N>
+ void add(lua_State* L, N&& n, destructor_wrapper<void> c) {
+ object o(L, in_place<detail::tagged<T, destructor_wrapper<void>>>, std::move(c));
+ if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
+ callconstructfunc = std::move(o);
+ return;
+ }
+ insert(std::forward<N>(n), std::move(o));
+ }
+
+ template <typename N, typename Fx>
+ void add(lua_State* L, N&& n, destructor_wrapper<Fx> c) {
+ object o(L, in_place<detail::tagged<T, destructor_wrapper<Fx>>>, std::move(c));
+ if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
+ callconstructfunc = std::move(o);
+ return;
+ }
+ insert(std::forward<N>(n), std::move(o));
+ }
+
+ template <typename... Bases>
+ void add(lua_State*, base_classes_tag, bases<Bases...>) {
+ static_assert(sizeof(usertype_detail::base_walk) <= sizeof(void*), "size of function pointer is greater than sizeof(void*); cannot work on this platform");
+ if (sizeof...(Bases) < 1) {
+ return;
+ }
+ mustindex = true;
+ (void)detail::swallow{ 0, ((detail::has_derived<Bases>::value = true), 0)... };
+
+ static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
+ static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
+ baseclasscheck = (void*)&detail::inheritance<T, Bases...>::type_check;
+ baseclasscast = (void*)&detail::inheritance<T, Bases...>::type_cast;
+ indexbaseclasspropogation = usertype_detail::walk_all_bases<true, Bases...>;
+ newindexbaseclasspropogation = usertype_detail::walk_all_bases<false, Bases...>;
+ }
+
+ private:
+ template<std::size_t... I, typename Tuple>
+ simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
+ : callconstructfunc(nil),
+ indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::simple_metatable_newindex<T>),
+ indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>),
+ indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
+ baseclasscheck(nullptr), baseclasscast(nullptr),
+ mustindex(true), secondarymeta(true) {
+ (void)detail::swallow{ 0,
+ (add(L, detail::forward_get<I * 2>(args), detail::forward_get<I * 2 + 1>(args)),0)...
+ };
+ }
+
+ template<typename... Args>
+ simple_usertype_metatable(lua_State* L, usertype_detail::verified_tag v, Args&&... args) : simple_usertype_metatable(v, std::make_index_sequence<sizeof...(Args) / 2>(), L, std::forward_as_tuple(std::forward<Args>(args)...)) {}
+
+ template<typename... Args>
+ simple_usertype_metatable(lua_State* L, usertype_detail::add_destructor_tag, Args&&... args) : simple_usertype_metatable(L, usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}
+
+ template<typename... Args>
+ simple_usertype_metatable(lua_State* L, usertype_detail::check_destructor_tag, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_destructible<T>, meta::neg<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward<Args>(args)...) {}
+
+ public:
+ simple_usertype_metatable(lua_State* L) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_default_constructible<T>>, decltype(default_constructor), usertype_detail::check_destructor_tag>()) {}
+
+ template<typename Arg, typename... Args, meta::disable_any<
+ meta::any_same<meta::unqualified_t<Arg>,
+ usertype_detail::verified_tag,
+ usertype_detail::add_destructor_tag,
+ usertype_detail::check_destructor_tag
+ >,
+ meta::is_specialization_of<constructors, meta::unqualified_t<Arg>>,
+ meta::is_specialization_of<constructor_wrapper, meta::unqualified_t<Arg>>
+ > = meta::enabler>
+ simple_usertype_metatable(lua_State* L, Arg&& arg, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+
+ template<typename... Args, typename... CArgs>
+ simple_usertype_metatable(lua_State* L, constructors<CArgs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
+
+ template<typename... Args, typename... Fxs>
+ simple_usertype_metatable(lua_State* L, constructor_wrapper<Fxs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
+
+ virtual int push_um(lua_State* L) override {
+ return stack::push(L, std::move(*this));
+ }
+ };
+
+ namespace stack {
+ template <typename T>
+ struct pusher<simple_usertype_metatable<T>> {
+ typedef simple_usertype_metatable<T> umt_t;
+
+ static usertype_detail::simple_map& make_cleanup(lua_State* L, umt_t& umx) {
+ static int uniqueness = 0;
+ std::string uniquegcmetakey = usertype_traits<T>::user_gc_metatable;
+ // std::to_string doesn't exist in android still, with NDK, so this bullshit
+ // is necessary
+ // thanks, Android :v
+ int appended = snprintf(nullptr, 0, "%d", uniqueness);
+ std::size_t insertionpoint = uniquegcmetakey.length() - 1;
+ uniquegcmetakey.append(appended, '\0');
+ char* uniquetarget = &uniquegcmetakey[insertionpoint];
+ snprintf(uniquetarget, uniquegcmetakey.length(), "%d", uniqueness);
+ ++uniqueness;
+
+ const char* gcmetakey = &usertype_traits<T>::gc_table[0];
+ stack::push<user<usertype_detail::simple_map>>(L, metatable_key, uniquegcmetakey, &usertype_traits<T>::metatable[0], umx.indexbaseclasspropogation, umx.newindexbaseclasspropogation, std::move(umx.varmap), std::move(umx.registrations));
+ stack_reference stackvarmap(L, -1);
+ stack::set_field<true>(L, gcmetakey, stackvarmap);
+ stackvarmap.pop();
+
+ stack::get_field<true>(L, gcmetakey);
+ usertype_detail::simple_map& varmap = stack::pop<light<usertype_detail::simple_map>>(L);
+ return varmap;
+ }
+
+ static int push(lua_State* L, umt_t&& umx) {
+ auto& varmap = make_cleanup(L, umx);
+ bool hasequals = false;
+ bool hasless = false;
+ bool haslessequals = false;
+ for (std::size_t i = 0; i < 3; ++i) {
+ // Pointer types, AKA "references" from C++
+ const char* metakey = nullptr;
+ switch (i) {
+ case 0:
+ metakey = &usertype_traits<T*>::metatable[0];
+ break;
+ case 1:
+ metakey = &usertype_traits<detail::unique_usertype<T>>::metatable[0];
+ break;
+ case 2:
+ default:
+ metakey = &usertype_traits<T>::metatable[0];
+ break;
+ }
+ luaL_newmetatable(L, metakey);
+ stack_reference t(L, -1);
+ for (auto& kvp : varmap.functions) {
+ auto& first = std::get<0>(kvp);
+ auto& second = std::get<1>(kvp);
+ if (first == name_of(meta_function::equal_to)) {
+ hasequals = true;
+ }
+ else if (first == name_of(meta_function::less_than)) {
+ hasless = true;
+ }
+ else if (first == name_of(meta_function::less_than_or_equal_to)) {
+ haslessequals = true;
+ }
+ else if (first == name_of(meta_function::index)) {
+ umx.indexfunc = second.template as<lua_CFunction>();
+ }
+ else if (first == name_of(meta_function::new_index)) {
+ umx.newindexfunc = second.template as<lua_CFunction>();
+ }
+ switch (i) {
+ case 0:
+ if (first == name_of(meta_function::garbage_collect)) {
+ continue;
+ }
+ break;
+ case 1:
+ if (first == name_of(meta_function::garbage_collect)) {
+ stack::set_field(L, first, detail::unique_destruct<T>, t.stack_index());
+ continue;
+ }
+ break;
+ case 2:
+ default:
+ break;
+ }
+ stack::set_field(L, first, second, t.stack_index());
+ }
+ luaL_Reg opregs[4]{};
+ int opregsindex = 0;
+ if (!hasless) {
+ const char* name = name_of(meta_function::less_than).c_str();
+ usertype_detail::make_reg_op<T, std::less<>, meta::supports_op_less<T>>(opregs, opregsindex, name);
+ }
+ if (!haslessequals) {
+ const char* name = name_of(meta_function::less_than_or_equal_to).c_str();
+ usertype_detail::make_reg_op<T, std::less_equal<>, meta::supports_op_less_equal<T>>(opregs, opregsindex, name);
+ }
+ if (!hasequals) {
+ const char* name = name_of(meta_function::equal_to).c_str();
+ usertype_detail::make_reg_op<T, std::conditional_t<meta::supports_op_equal<T>::value, std::equal_to<>, usertype_detail::no_comp>, std::true_type>(opregs, opregsindex, name);
+ }
+ t.push();
+ luaL_setfuncs(L, opregs, 0);
+ t.pop();
+
+ if (umx.baseclasscheck != nullptr) {
+ stack::set_field(L, detail::base_class_check_key(), umx.baseclasscheck, t.stack_index());
+ }
+ if (umx.baseclasscast != nullptr) {
+ stack::set_field(L, detail::base_class_cast_key(), umx.baseclasscast, t.stack_index());
+ }
+
+ // Base class propagation features
+ stack::set_field(L, detail::base_class_index_propogation_key(), umx.indexbase, t.stack_index());
+ stack::set_field(L, detail::base_class_new_index_propogation_key(), umx.newindexbase, t.stack_index());
+
+ if (umx.mustindex) {
+ // use indexing function
+ static_assert(sizeof(usertype_detail::base_walk) <= sizeof(void*), "The size of this data pointer is too small to fit the base class index propagation key: file a bug report.");
+ stack::set_field(L, meta_function::index,
+ make_closure(&usertype_detail::simple_index_call,
+ make_light(varmap),
+ umx.indexfunc,
+ umx.newindexfunc
+ ), t.stack_index());
+ stack::set_field(L, meta_function::new_index,
+ make_closure(&usertype_detail::simple_new_index_call,
+ make_light(varmap),
+ umx.indexfunc,
+ umx.newindexfunc
+ ), t.stack_index());
+ }
+ else {
+ // Metatable indexes itself
+ stack::set_field(L, meta_function::index, t, t.stack_index());
+ }
+ // metatable on the metatable
+ // for call constructor purposes and such
+ lua_createtable(L, 0, 1);
+ stack_reference metabehind(L, -1);
+ if (umx.callconstructfunc.valid()) {
+ stack::set_field(L, sol::meta_function::call_function, umx.callconstructfunc, metabehind.stack_index());
+ }
+ if (umx.secondarymeta) {
+ stack::set_field(L, meta_function::index,
+ make_closure(&usertype_detail::simple_index_call,
+ make_light(varmap),
+ umx.indexfunc,
+ umx.newindexfunc
+ ), metabehind.stack_index());
+ stack::set_field(L, meta_function::new_index,
+ make_closure(&usertype_detail::simple_new_index_call,
+ make_light(varmap),
+ umx.indexfunc,
+ umx.newindexfunc
+ ), metabehind.stack_index());
+ }
+ stack::set_field(L, metatable_key, metabehind, t.stack_index());
+ metabehind.pop();
+
+ if (i < 2)
+ t.pop();
+ }
+ return 1;
+ }
+ };
+ } // stack
+} // sol
+
+// end of sol/simple_usertype_metatable.hpp
+
+// beginning of sol/container_usertype_metatable.hpp
+
+namespace sol {
+
+ namespace detail {
+
+ template <typename T>
+ struct has_find {
+ private:
+ typedef std::array<char, 1> one;
+ typedef std::array<char, 2> two;
+
+ template <typename C> static one test(decltype(&C::find));
+ template <typename C> static two test(...);
+
+ public:
+ static const bool value = sizeof(test<T>(0)) == sizeof(char);
+ };
+
+ template <typename T>
+ T& get_first(const T& t) {
+ return std::forward<T>(t);
+ }
+
+ template <typename A, typename B>
+ decltype(auto) get_first(const std::pair<A, B>& t) {
+ return t.first;
+ }
+
+ template <typename C, typename I, meta::enable<has_find<meta::unqualified_t<C>>> = meta::enabler>
+ auto find(C& c, I&& i) {
+ return c.find(std::forward<I>(i));
+ }
+
+ template <typename C, typename I, meta::disable<has_find<meta::unqualified_t<C>>> = meta::enabler>
+ auto find(C& c, I&& i) {
+ using std::begin;
+ using std::end;
+ return std::find_if(begin(c), end(c), [&i](auto&& x) {
+ return i == get_first(x);
+ });
+ }
+
+ }
+
+ template <typename Raw, typename C = void>
+ struct container_usertype_metatable {
+ typedef meta::unqualified_t<Raw> T;
+ typedef std::size_t K;
+ typedef typename T::value_type V;
+ typedef typename T::iterator I;
+ typedef std::remove_reference_t<decltype(*std::declval<I&>())> IR;
+
+ struct iter {
+ T& source;
+ I it;
+
+ iter(T& source, I it) : source(source), it(std::move(it)) {}
+ };
+
+ static auto& get_src(lua_State* L) {
+#ifdef SOL_SAFE_USERTYPE
+ auto p = stack::get<T*>(L, 1);
+ if (p == nullptr) {
+ luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument or call on proper type)");
+ }
+ return *p;
+#else
+ return stack::get<T>(L, 1);
+#endif
+ }
+
+ static int real_index_call(lua_State* L) {
+ auto& src = get_src(L);
+#ifdef SOL_SAFE_USERTYPE
+ auto maybek = stack::check_get<K>(L, 2);
+ if (maybek) {
+ using std::begin;
+ auto it = begin(src);
+ K k = *maybek;
+ if (k <= src.size() && k > 0) {
+ --k;
+ std::advance(it, k);
+ return stack::push_reference(L, *it);
+ }
+ }
+ return stack::push(L, nil);
+#else
+ using std::begin;
+ auto it = begin(src);
+ K k = stack::get<K>(L, 2);
+ --k;
+ std::advance(it, k);
+ return stack::push_reference(L, *it);
+#endif // Safety
+ }
+
+ template <bool b, meta::disable<meta::boolean<b>> = meta::enabler>
+ static int real_new_index_call_const(std::integral_constant<bool, b>, lua_State* L) {
+ luaL_error(L, "sol: cannot write to a const value type or an immutable iterator (e.g., std::set)");
+ return 0;
+ }
+
+ template <bool b, meta::enable<meta::boolean<b>> = meta::enabler>
+ static int real_new_index_call_const(std::integral_constant<bool, b>, lua_State* L) {
+ auto& src = get_src(L);
+#ifdef SOL_SAFE_USERTYPE
+ auto maybek = stack::check_get<K>(L, 2);
+ if (maybek) {
+ K k = *maybek;
+ if (k <= src.size() && k > 0) {
+ --k;
+ using std::begin;
+ auto it = begin(src);
+ std::advance(it, k);
+ *it = stack::get<V>(L, 3);
+ }
+ }
+#else
+ using std::begin;
+ auto it = begin(src);
+ K k = stack::get<K>(L, 2);
+ --k;
+ std::advance(it, k);
+ *it = stack::get<V>(L, 3);
+#endif
+ return 0;
+ }
+
+ static int real_new_index_call(lua_State* L) {
+ return real_new_index_call_const(meta::neg<meta::any<std::is_const<V>, std::is_const<IR>>>(), L);
+ }
+
+ static int real_pairs_next_call(lua_State* L) {
+ using std::end;
+ iter& i = stack::get<user<iter>>(L, 1);
+ auto& source = i.source;
+ auto& it = i.it;
+ K k = stack::get<K>(L, 2);
+ if (it == end(source)) {
+ return 0;
+ }
+ int p = stack::multi_push_reference(L, k + 1, *it);
+ std::advance(it, 1);
+ return p;
+ }
+
+ static int real_pairs_call(lua_State* L) {
+ auto& src = get_src(L);
+ using std::begin;
+ stack::push(L, pairs_next_call);
+ stack::push<user<iter>>(L, src, begin(src));
+ stack::push(L, 0);
+ return 3;
+ }
+
+ static int real_length_call(lua_State*L) {
+ auto& src = get_src(L);
+ return stack::push(L, src.size());
+ }
+
+#if 0
+ static int real_push_back_call(lua_State*L) {
+ auto& src = get_src(L);
+ src.push_back(stack::get<V>(L, 2));
+ return 0;
+ }
+
+ static int real_insert_call(lua_State*L) {
+ using std::begin;
+ auto& src = get_src(L);
+ src.insert(std::next(begin(src), stack::get<K>(L, 2)), stack::get<V>(L, 3));
+ return 0;
+ }
+
+ static int push_back_call(lua_State*L) {
+ return detail::static_trampoline<(&real_length_call)>(L);
+ }
+
+ static int insert_call(lua_State*L) {
+ return detail::static_trampoline<(&real_insert_call)>(L);
+ }
+#endif // Sometime later, in a distant universe...
+
+ static int length_call(lua_State*L) {
+ return detail::static_trampoline<(&real_length_call)>(L);
+ }
+
+ static int pairs_next_call(lua_State*L) {
+ return detail::static_trampoline<(&real_pairs_next_call)>(L);
+ }
+
+ static int pairs_call(lua_State*L) {
+ return detail::static_trampoline<(&real_pairs_call)>(L);
+ }
+
+ static int index_call(lua_State*L) {
+ return detail::static_trampoline<(&real_index_call)>(L);
+ }
+
+ static int new_index_call(lua_State*L) {
+ return detail::static_trampoline<(&real_new_index_call)>(L);
+ }
+ };
+
+ template <typename Raw>
+ struct container_usertype_metatable<Raw, std::enable_if_t<meta::has_key_value_pair<meta::unqualified_t<Raw>>::value>> {
+ typedef meta::unqualified_t<Raw> T;
+ typedef typename T::value_type KV;
+ typedef typename KV::first_type K;
+ typedef typename KV::second_type V;
+ typedef typename T::iterator I;
+ struct iter {
+ T& source;
+ I it;
+
+ iter(T& source, I it) : source(source), it(std::move(it)) {}
+ };
+
+ static auto& get_src(lua_State* L) {
+#ifdef SOL_SAFE_USERTYPE
+ auto p = stack::get<T*>(L, 1);
+ if (p == nullptr) {
+ luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument or call on proper type)");
+ }
+ return *p;
+#else
+ return stack::get<T>(L, 1);
+#endif
+ }
+
+ static int real_index_call(lua_State* L) {
+ auto& src = get_src(L);
+ auto k = stack::check_get<K>(L, 2);
+ if (k) {
+ using std::end;
+ auto it = detail::find(src, *k);
+ if (it != end(src)) {
+ auto& v = *it;
+ return stack::push_reference(L, v.second);
+ }
+ }
+ return stack::push(L, nil);
+ }
+
+ static int real_new_index_call_const(std::false_type, lua_State* L) {
+ luaL_error(L, "sol: cannot write to a const value type");
+ return 0;
+ }
+
+ static int real_new_index_call_const(std::true_type, lua_State* L) {
+ auto& src = get_src(L);
+ auto k = stack::check_get<K>(L, 2);
+ if (k) {
+ using std::end;
+ auto it = detail::find(src, *k);
+ if (it != end(src)) {
+ auto& v = *it;
+ v.second = stack::get<V>(L, 3);
+ }
+ else {
+ src.insert(it, { std::move(*k), stack::get<V>(L, 3) });
+ }
+ }
+ return 0;
+ }
+
+ static int real_new_index_call(lua_State* L) {
+ return real_new_index_call_const(meta::neg<std::is_const<V>>(), L);
+ }
+
+ static int real_pairs_next_call(lua_State* L) {
+ using std::end;
+ iter& i = stack::get<user<iter>>(L, 1);
+ auto& source = i.source;
+ auto& it = i.it;
+ std::advance(it, 1);
+ if (it == end(source)) {
+ return 0;
+ }
+ return stack::multi_push_reference(L, it->first, it->second);
+ }
+
+ static int real_pairs_call(lua_State* L) {
+ auto& src = get_src(L);
+ using std::begin;
+ stack::push(L, pairs_next_call);
+ stack::push<user<iter>>(L, src, begin(src));
+ stack::push(L, 1);
+ return 3;
+ }
+
+ static int real_length_call(lua_State*L) {
+ auto& src = get_src(L);
+ return stack::push(L, src.size());
+ }
+
+ static int length_call(lua_State*L) {
+ return detail::static_trampoline<(&real_length_call)>(L);
+ }
+
+ static int pairs_next_call(lua_State*L) {
+ return detail::static_trampoline<(&real_pairs_next_call)>(L);
+ }
+
+ static int pairs_call(lua_State*L) {
+ return detail::static_trampoline<(&real_pairs_call)>(L);
+ }
+
+ static int index_call(lua_State*L) {
+ return detail::static_trampoline<(&real_index_call)>(L);
+ }
+
+ static int new_index_call(lua_State*L) {
+ return detail::static_trampoline<(&real_new_index_call)>(L);
+ }
+ };
+
+ namespace stack {
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<meta::all<meta::has_begin_end<T>, meta::neg<meta::any<std::is_base_of<reference, T>, std::is_base_of<stack_reference, T>>>>::value>> {
+ typedef container_usertype_metatable<T> cumt;
+ static int push(lua_State* L, const T& cont) {
+ auto fx = [&L]() {
+ const char* metakey = &usertype_traits<T>::metatable[0];
+ if (luaL_newmetatable(L, metakey) == 1) {
+ luaL_Reg reg[] = {
+ { "__index", &cumt::index_call },
+ { "__newindex", &cumt::new_index_call },
+ { "__pairs", &cumt::pairs_call },
+ { "__len", &cumt::length_call },
+ { "__gc", &detail::usertype_alloc_destroy<T> },
+ { nullptr, nullptr }
+ };
+ luaL_setfuncs(L, reg, 0);
+ }
+ lua_setmetatable(L, -2);
+ };
+ return pusher<detail::as_value_tag<T>>{}.push_fx(L, fx, cont);
+ }
+
+ static int push(lua_State* L, T&& cont) {
+ auto fx = [&L]() {
+ const char* metakey = &usertype_traits<T>::metatable[0];
+ if (luaL_newmetatable(L, metakey) == 1) {
+ luaL_Reg reg[] = {
+ { "__index", &cumt::index_call },
+ { "__newindex", &cumt::new_index_call },
+ { "__pairs", &cumt::pairs_call },
+ { "__len", &cumt::length_call },
+ { "__gc", &detail::usertype_alloc_destroy<T> },
+ { nullptr, nullptr }
+ };
+ luaL_setfuncs(L, reg, 0);
+ }
+ lua_setmetatable(L, -2);
+ };
+ return pusher<detail::as_value_tag<T>>{}.push_fx(L, fx, std::move(cont));
+ }
+ };
+
+ template<typename T>
+ struct pusher<T*, std::enable_if_t<meta::all<meta::has_begin_end<meta::unqualified_t<T>>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
+ typedef container_usertype_metatable<T> cumt;
+ static int push(lua_State* L, T* cont) {
+ auto fx = [&L]() {
+ const char* metakey = &usertype_traits<meta::unqualified_t<T>*>::metatable[0];
+ if (luaL_newmetatable(L, metakey) == 1) {
+ luaL_Reg reg[] = {
+ { "__index", &cumt::index_call },
+ { "__newindex", &cumt::new_index_call },
+ { "__pairs", &cumt::pairs_call },
+ { "__len", &cumt::length_call },
+ { nullptr, nullptr }
+ };
+ luaL_setfuncs(L, reg, 0);
+ }
+ lua_setmetatable(L, -2);
+ };
+ return pusher<detail::as_pointer_tag<T>>{}.push_fx(L, fx, cont);
+ }
+ };
+ } // stack
+
+} // sol
+
+// end of sol/container_usertype_metatable.hpp
+
+namespace sol {
+
+ template<typename T>
+ class usertype {
+ private:
+ std::unique_ptr<usertype_detail::registrar, detail::deleter> metatableregister;
+
+ template<typename... Args>
+ usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister(detail::make_unique_deleter<usertype_metatable<T, std::make_index_sequence<sizeof...(Args) / 2>, Args...>, detail::deleter>(std::forward<Args>(args)...)) {}
+
+ template<typename... Args>
+ usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}
+
+ template<typename... Args>
+ usertype(usertype_detail::check_destructor_tag, Args&&... args) : usertype(meta::condition<meta::all<std::is_destructible<T>, meta::neg<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward<Args>(args)...) {}
+
+ public:
+
+ template<typename... Args>
+ usertype(Args&&... args) : usertype(meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward<Args>(args)...) {}
+
+ template<typename... Args, typename... CArgs>
+ usertype(constructors<CArgs...> constructorlist, Args&&... args) : usertype(usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
+
+ template<typename... Args, typename... Fxs>
+ usertype(constructor_wrapper<Fxs...> constructorlist, Args&&... args) : usertype(usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
+
+ template<typename... Args>
+ usertype(simple_tag, lua_State* L, Args&&... args) : metatableregister(detail::make_unique_deleter<simple_usertype_metatable<T>, detail::deleter>(L, std::forward<Args>(args)...)) {}
+
+ usertype_detail::registrar* registrar_data() {
+ return metatableregister.get();
+ }
+
+ int push(lua_State* L) {
+ return metatableregister->push_um(L);
+ }
+ };
+
+ template<typename T>
+ class simple_usertype : public usertype<T> {
+ private:
+ typedef usertype<T> base_t;
+ lua_State* state;
+
+ public:
+ template<typename... Args>
+ simple_usertype(lua_State* L, Args&&... args) : base_t(simple, L, std::forward<Args>(args)...), state(L) {}
+
+ template <typename N, typename F>
+ void set(N&& n, F&& f) {
+ auto meta = static_cast<simple_usertype_metatable<T>*>(base_t::registrar_data());
+ meta->add(state, n, f);
+ }
+ };
+
+ namespace stack {
+ template<typename T>
+ struct pusher<usertype<T>> {
+ static int push(lua_State* L, usertype<T>& user) {
+ return user.push(L);
+ }
+ };
+ } // stack
+} // sol
+
+// end of sol/usertype.hpp
+
+// beginning of sol/table_iterator.hpp
+
+namespace sol {
+
+ template <typename reference_type>
+ class basic_table_iterator : public std::iterator<std::input_iterator_tag, std::pair<object, object>> {
+ private:
+ typedef std::iterator<std::input_iterator_tag, std::pair<object, object>> base_t;
+ public:
+ typedef object key_type;
+ typedef object mapped_type;
+ typedef base_t::value_type value_type;
+ typedef base_t::iterator_category iterator_category;
+ typedef base_t::difference_type difference_type;
+ typedef base_t::pointer pointer;
+ typedef base_t::reference reference;
+ typedef const value_type& const_reference;
+
+ private:
+ std::pair<object, object> kvp;
+ reference_type ref;
+ int tableidx = 0;
+ int keyidx = 0;
+ std::ptrdiff_t idx = 0;
+
+ public:
+
+ basic_table_iterator() : keyidx(-1), idx(-1) {
+
+ }
+
+ basic_table_iterator(reference_type x) : ref(std::move(x)) {
+ ref.push();
+ tableidx = lua_gettop(ref.lua_state());
+ stack::push(ref.lua_state(), nil);
+ this->operator++();
+ if (idx == -1) {
+ return;
+ }
+ --idx;
+ }
+
+ basic_table_iterator& operator++() {
+ if (idx == -1)
+ return *this;
+
+ if (lua_next(ref.lua_state(), tableidx) == 0) {
+ idx = -1;
+ keyidx = -1;
+ return *this;
+ }
+ ++idx;
+ kvp.first = object(ref.lua_state(), -2);
+ kvp.second = object(ref.lua_state(), -1);
+ lua_pop(ref.lua_state(), 1);
+ // leave key on the stack
+ keyidx = lua_gettop(ref.lua_state());
+ return *this;
+ }
+
+ basic_table_iterator operator++(int) {
+ auto saved = *this;
+ this->operator++();
+ return saved;
+ }
+
+ reference operator*() {
+ return kvp;
+ }
+
+ const_reference operator*() const {
+ return kvp;
+ }
+
+ bool operator== (const basic_table_iterator& right) const {
+ return idx == right.idx;
+ }
+
+ bool operator!= (const basic_table_iterator& right) const {
+ return idx != right.idx;
+ }
+
+ ~basic_table_iterator() {
+ if (keyidx != -1) {
+ stack::remove(ref.lua_state(), keyidx, 1);
+ }
+ if (ref.valid()) {
+ stack::remove(ref.lua_state(), tableidx, 1);
+ }
+ }
+ };
+
+} // sol
+
+// end of sol/table_iterator.hpp
+
+namespace sol {
+ namespace detail {
+ template <std::size_t n>
+ struct clean { lua_State* L; clean(lua_State* L) : L(L) {} ~clean() { lua_pop(L, static_cast<int>(n)); } };
+ struct ref_clean { lua_State* L; int& n; ref_clean(lua_State* L, int& n) : L(L), n(n) {} ~ref_clean() { lua_pop(L, static_cast<int>(n)); } };
+ inline int fail_on_newindex(lua_State* L) {
+ return luaL_error(L, "sol: cannot modify the elements of an enumeration table");
+ }
+ }
+
+ template <bool top_level, typename base_t>
+ class basic_table_core : public base_t {
+ friend class state;
+ friend class state_view;
+
+ template <typename... Args>
+ using is_global = meta::all<meta::boolean<top_level>, meta::is_c_str<Args>...>;
+
+ template<typename Fx>
+ void for_each(std::true_type, Fx&& fx) const {
+ auto pp = stack::push_pop(*this);
+ stack::push(base_t::lua_state(), nil);
+ while (lua_next(base_t::lua_state(), -2)) {
+ sol::object key(base_t::lua_state(), -2);
+ sol::object value(base_t::lua_state(), -1);
+ std::pair<sol::object&, sol::object&> keyvalue(key, value);
+ auto pn = stack::pop_n(base_t::lua_state(), 1);
+ fx(keyvalue);
+ }
+ }
+
+ template<typename Fx>
+ void for_each(std::false_type, Fx&& fx) const {
+ auto pp = stack::push_pop(*this);
+ stack::push(base_t::lua_state(), nil);
+ while (lua_next(base_t::lua_state(), -2)) {
+ sol::object key(base_t::lua_state(), -2);
+ sol::object value(base_t::lua_state(), -1);
+ auto pn = stack::pop_n(base_t::lua_state(), 1);
+ fx(key, value);
+ }
+ }
+
+ template<typename Ret0, typename Ret1, typename... Ret, std::size_t... I, typename Keys>
+ auto tuple_get(types<Ret0, Ret1, Ret...>, std::index_sequence<0, 1, I...>, Keys&& keys) const
+ -> decltype(stack::pop<std::tuple<Ret0, Ret1, Ret...>>(nullptr)) {
+ typedef decltype(stack::pop<std::tuple<Ret0, Ret1, Ret...>>(nullptr)) Tup;
+ return Tup(
+ traverse_get_optional<top_level, Ret0>(meta::is_specialization_of<sol::optional, meta::unqualified_t<Ret0>>(), detail::forward_get<0>(keys)),
+ traverse_get_optional<top_level, Ret1>(meta::is_specialization_of<sol::optional, meta::unqualified_t<Ret1>>(), detail::forward_get<1>(keys)),
+ traverse_get_optional<top_level, Ret>(meta::is_specialization_of<sol::optional, meta::unqualified_t<Ret>>(), detail::forward_get<I>(keys))...
+ );
+ }
+
+ template<typename Ret, std::size_t I, typename Keys>
+ decltype(auto) tuple_get(types<Ret>, std::index_sequence<I>, Keys&& keys) const {
+ return traverse_get_optional<top_level, Ret>(meta::is_specialization_of<sol::optional, meta::unqualified_t<Ret>>(), detail::forward_get<I>(keys));
+ }
+
+ template<typename Pairs, std::size_t... I>
+ void tuple_set(std::index_sequence<I...>, Pairs&& pairs) {
+ auto pp = stack::push_pop<top_level && (is_global<decltype(detail::forward_get<I * 2>(pairs))...>::value)>(*this);
+ void(detail::swallow{ (stack::set_field<top_level>(base_t::lua_state(),
+ detail::forward_get<I * 2>(pairs),
+ detail::forward_get<I * 2 + 1>(pairs),
+ lua_gettop(base_t::lua_state())
+ ), 0)... });
+ }
+
+ template <bool global, typename T, typename Key>
+ decltype(auto) traverse_get_deep(Key&& key) const {
+ stack::get_field<global>(base_t::lua_state(), std::forward<Key>(key));
+ return stack::get<T>(base_t::lua_state());
+ }
+
+ template <bool global, typename T, typename Key, typename... Keys>
+ decltype(auto) traverse_get_deep(Key&& key, Keys&&... keys) const {
+ stack::get_field<global>(base_t::lua_state(), std::forward<Key>(key));
+ return traverse_get_deep<false, T>(std::forward<Keys>(keys)...);
+ }
+
+ template <bool global, typename T, std::size_t I, typename Key>
+ decltype(auto) traverse_get_deep_optional(int& popcount, Key&& key) const {
+ typedef decltype(stack::get<T>(base_t::lua_state())) R;
+ auto p = stack::probe_get_field<global>(base_t::lua_state(), std::forward<Key>(key), lua_gettop(base_t::lua_state()));
+ popcount += p.levels;
+ if (!p.success)
+ return R(nullopt);
+ return stack::get<T>(base_t::lua_state());
+ }
+
+ template <bool global, typename T, std::size_t I, typename Key, typename... Keys>
+ decltype(auto) traverse_get_deep_optional(int& popcount, Key&& key, Keys&&... keys) const {
+ auto p = I > 0 ? stack::probe_get_field<global>(base_t::lua_state(), std::forward<Key>(key), -1) : stack::probe_get_field<global>(base_t::lua_state(), std::forward<Key>(key), lua_gettop(base_t::lua_state()));
+ popcount += p.levels;
+ if (!p.success)
+ return T(nullopt);
+ return traverse_get_deep_optional<false, T, I + 1>(popcount, std::forward<Keys>(keys)...);
+ }
+
+ template <bool global, typename T, typename... Keys>
+ decltype(auto) traverse_get_optional(std::false_type, Keys&&... keys) const {
+ detail::clean<sizeof...(Keys)> c(base_t::lua_state());
+ return traverse_get_deep<top_level, T>(std::forward<Keys>(keys)...);
+ }
+
+ template <bool global, typename T, typename... Keys>
+ decltype(auto) traverse_get_optional(std::true_type, Keys&&... keys) const {
+ int popcount = 0;
+ detail::ref_clean c(base_t::lua_state(), popcount);
+ return traverse_get_deep_optional<top_level, T, 0>(popcount, std::forward<Keys>(keys)...);
+ }
+
+ template <bool global, typename Key, typename Value>
+ void traverse_set_deep(Key&& key, Value&& value) const {
+ stack::set_field<global>(base_t::lua_state(), std::forward<Key>(key), std::forward<Value>(value));
+ }
+
+ template <bool global, typename Key, typename... Keys>
+ void traverse_set_deep(Key&& key, Keys&&... keys) const {
+ stack::get_field<global>(base_t::lua_state(), std::forward<Key>(key));
+ traverse_set_deep<false>(std::forward<Keys>(keys)...);
+ }
+
+ basic_table_core(lua_State* L, detail::global_tag t) noexcept : reference(L, t) { }
+
+ public:
+ typedef basic_table_iterator<base_t> iterator;
+ typedef iterator const_iterator;
+
+ basic_table_core() noexcept : base_t() { }
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_table_core(T&& r) noexcept : base_t(std::forward<T>(r)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!is_table<meta::unqualified_t<T>>::value) {
+ auto pp = stack::push_pop(*this);
+ stack::check<basic_table_core>(base_t::lua_state(), -1, type_panic);
+ }
+#endif // Safety
+ }
+ basic_table_core(const basic_table_core&) = default;
+ basic_table_core(basic_table_core&&) = default;
+ basic_table_core& operator=(const basic_table_core&) = default;
+ basic_table_core& operator=(basic_table_core&&) = default;
+ basic_table_core(const stack_reference& r) : basic_table_core(r.lua_state(), r.stack_index()) {}
+ basic_table_core(stack_reference&& r) : basic_table_core(r.lua_state(), r.stack_index()) {}
+ basic_table_core(lua_State* L, int index = -1) : base_t(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ stack::check<basic_table_core>(L, index, type_panic);
+#endif // Safety
+ }
+
+ iterator begin() const {
+ return iterator(*this);
+ }
+
+ iterator end() const {
+ return iterator();
+ }
+
+ const_iterator cbegin() const {
+ return begin();
+ }
+
+ const_iterator cend() const {
+ return end();
+ }
+
+ template<typename... Ret, typename... Keys>
+ decltype(auto) get(Keys&&... keys) const {
+ static_assert(sizeof...(Keys) == sizeof...(Ret), "number of keys and number of return types do not match");
+ auto pp = stack::push_pop<is_global<Keys...>::value>(*this);
+ return tuple_get(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), std::forward_as_tuple(std::forward<Keys>(keys)...));
+ }
+
+ template<typename T, typename Key>
+ decltype(auto) get_or(Key&& key, T&& otherwise) const {
+ typedef decltype(get<T>("")) U;
+ sol::optional<U> option = get<sol::optional<U>>(std::forward<Key>(key));
+ if (option) {
+ return static_cast<U>(option.value());
+ }
+ return static_cast<U>(std::forward<T>(otherwise));
+ }
+
+ template<typename T, typename Key, typename D>
+ decltype(auto) get_or(Key&& key, D&& otherwise) const {
+ sol::optional<T> option = get<sol::optional<T>>(std::forward<Key>(key));
+ if (option) {
+ return static_cast<T>(option.value());
+ }
+ return static_cast<T>(std::forward<D>(otherwise));
+ }
+
+ template <typename T, typename... Keys>
+ decltype(auto) traverse_get(Keys&&... keys) const {
+ auto pp = stack::push_pop<is_global<Keys...>::value>(*this);
+ return traverse_get_optional<top_level, T>(meta::is_specialization_of<sol::optional, meta::unqualified_t<T>>(), std::forward<Keys>(keys)...);
+ }
+
+ template <typename... Keys>
+ basic_table_core& traverse_set(Keys&&... keys) {
+ auto pp = stack::push_pop<is_global<Keys...>::value>(*this);
+ auto pn = stack::pop_n(base_t::lua_state(), static_cast<int>(sizeof...(Keys)-2));
+ traverse_set_deep<top_level>(std::forward<Keys>(keys)...);
+ return *this;
+ }
+
+ template<typename... Args>
+ basic_table_core& set(Args&&... args) {
+ tuple_set(std::make_index_sequence<sizeof...(Args) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...));
+ return *this;
+ }
+
+ template<typename T>
+ basic_table_core& set_usertype(usertype<T>& user) {
+ return set_usertype(usertype_traits<T>::name, user);
+ }
+
+ template<typename Key, typename T>
+ basic_table_core& set_usertype(Key&& key, usertype<T>& user) {
+ return set(std::forward<Key>(key), user);
+ }
+
+ template<typename Class, typename... Args>
+ basic_table_core& new_usertype(const std::string& name, Args&&... args) {
+ usertype<Class> utype(std::forward<Args>(args)...);
+ set_usertype(name, utype);
+ return *this;
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ basic_table_core& new_usertype(const std::string& name, Args&&... args) {
+ constructors<types<CTor0, CTor...>> ctor{};
+ return new_usertype<Class>(name, ctor, std::forward<Args>(args)...);
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ basic_table_core& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
+ usertype<Class> utype(ctor, std::forward<Args>(args)...);
+ set_usertype(name, utype);
+ return *this;
+ }
+
+ template<typename Class, typename... Args>
+ basic_table_core& new_simple_usertype(const std::string& name, Args&&... args) {
+ simple_usertype<Class> utype(base_t::lua_state(), std::forward<Args>(args)...);
+ set_usertype(name, utype);
+ return *this;
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ basic_table_core& new_simple_usertype(const std::string& name, Args&&... args) {
+ constructors<types<CTor0, CTor...>> ctor{};
+ return new_simple_usertype<Class>(name, ctor, std::forward<Args>(args)...);
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ basic_table_core& new_simple_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
+ simple_usertype<Class> utype(base_t::lua_state(), ctor, std::forward<Args>(args)...);
+ set_usertype(name, utype);
+ return *this;
+ }
+
+ template<typename Class, typename... Args>
+ simple_usertype<Class> create_simple_usertype(Args&&... args) {
+ simple_usertype<Class> utype(base_t::lua_state(), std::forward<Args>(args)...);
+ return utype;
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ simple_usertype<Class> create_simple_usertype(Args&&... args) {
+ constructors<types<CTor0, CTor...>> ctor{};
+ return create_simple_usertype<Class>(ctor, std::forward<Args>(args)...);
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ simple_usertype<Class> create_simple_usertype(constructors<CArgs...> ctor, Args&&... args) {
+ simple_usertype<Class> utype(base_t::lua_state(), ctor, std::forward<Args>(args)...);
+ return utype;
+ }
+
+ template<bool read_only = true, typename... Args>
+ basic_table_core& new_enum(const std::string& name, Args&&... args) {
+ if (read_only) {
+ table idx = create_with(std::forward<Args>(args)...);
+ table x = create_with(
+ meta_function::new_index, detail::fail_on_newindex,
+ meta_function::index, idx
+ );
+ table target = create_named(name);
+ target[metatable_key] = x;
+ }
+ else {
+ create_named(name, std::forward<Args>(args)...);
+ }
+ return *this;
+ }
+
+ template<typename Fx>
+ void for_each(Fx&& fx) const {
+ typedef meta::is_invokable<Fx(std::pair<sol::object, sol::object>)> is_paired;
+ for_each(is_paired(), std::forward<Fx>(fx));
+ }
+
+ size_t size() const {
+ auto pp = stack::push_pop(*this);
+ lua_len(base_t::lua_state(), -1);
+ return stack::pop<size_t>(base_t::lua_state());
+ }
+
+ bool empty() const {
+ return cbegin() == cend();
+ }
+
+ template<typename T>
+ proxy<basic_table_core&, T> operator[](T&& key) & {
+ return proxy<basic_table_core&, T>(*this, std::forward<T>(key));
+ }
+
+ template<typename T>
+ proxy<const basic_table_core&, T> operator[](T&& key) const & {
+ return proxy<const basic_table_core&, T>(*this, std::forward<T>(key));
+ }
+
+ template<typename T>
+ proxy<basic_table_core, T> operator[](T&& key) && {
+ return proxy<basic_table_core, T>(*this, std::forward<T>(key));
+ }
+
+ template<typename Sig, typename Key, typename... Args>
+ basic_table_core& set_function(Key&& key, Args&&... args) {
+ set_fx(types<Sig>(), std::forward<Key>(key), std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Key, typename... Args>
+ basic_table_core& set_function(Key&& key, Args&&... args) {
+ set_fx(types<>(), std::forward<Key>(key), std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template <typename... Args>
+ basic_table_core& add(Args&&... args) {
+ auto pp = stack::push_pop(*this);
+ (void)detail::swallow{0,
+ (stack::set_ref(base_t::lua_state(), std::forward<Args>(args)), 0)...
+ };
+ return *this;
+ }
+
+ private:
+ template<typename R, typename... Args, typename Fx, typename Key, typename = std::result_of_t<Fx(Args...)>>
+ void set_fx(types<R(Args...)>, Key&& key, Fx&& fx) {
+ set_resolved_function<R(Args...)>(std::forward<Key>(key), std::forward<Fx>(fx));
+ }
+
+ template<typename Fx, typename Key, meta::enable<meta::is_specialization_of<overload_set, meta::unqualified_t<Fx>>> = meta::enabler>
+ void set_fx(types<>, Key&& key, Fx&& fx) {
+ set(std::forward<Key>(key), std::forward<Fx>(fx));
+ }
+
+ template<typename Fx, typename Key, typename... Args, meta::disable<meta::is_specialization_of<overload_set, meta::unqualified_t<Fx>>> = meta::enabler>
+ void set_fx(types<>, Key&& key, Fx&& fx, Args&&... args) {
+ set(std::forward<Key>(key), as_function_reference(std::forward<Fx>(fx), std::forward<Args>(args)...));
+ }
+
+ template<typename... Sig, typename... Args, typename Key>
+ void set_resolved_function(Key&& key, Args&&... args) {
+ set(std::forward<Key>(key), as_function_reference<function_sig<Sig...>>(std::forward<Args>(args)...));
+ }
+
+ public:
+ static inline table create(lua_State* L, int narr = 0, int nrec = 0) {
+ lua_createtable(L, narr, nrec);
+ table result(L);
+ lua_pop(L, 1);
+ return result;
+ }
+
+ template <typename Key, typename Value, typename... Args>
+ static inline table create(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ lua_createtable(L, narr, nrec);
+ table result(L);
+ result.set(std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ lua_pop(L, 1);
+ return result;
+ }
+
+ template <typename... Args>
+ static inline table create_with(lua_State* L, Args&&... args) {
+ static const int narr = static_cast<int>(meta::count_2_for_pack<std::is_integral, Args...>::value);
+ return create(L, narr, static_cast<int>((sizeof...(Args) / 2) - narr), std::forward<Args>(args)...);
+ }
+
+ table create(int narr = 0, int nrec = 0) {
+ return create(base_t::lua_state(), narr, nrec);
+ }
+
+ template <typename Key, typename Value, typename... Args>
+ table create(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ return create(base_t::lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ }
+
+ template <typename Name>
+ table create(Name&& name, int narr = 0, int nrec = 0) {
+ table x = create(base_t::lua_state(), narr, nrec);
+ this->set(std::forward<Name>(name), x);
+ return x;
+ }
+
+ template <typename Name, typename Key, typename Value, typename... Args>
+ table create(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ table x = create(base_t::lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ this->set(std::forward<Name>(name), x);
+ return x;
+ }
+
+ template <typename... Args>
+ table create_with(Args&&... args) {
+ return create_with(base_t::lua_state(), std::forward<Args>(args)...);
+ }
+
+ template <typename Name, typename... Args>
+ table create_named(Name&& name, Args&&... args) {
+ static const int narr = static_cast<int>(meta::count_2_for_pack<std::is_integral, Args...>::value);
+ return create(std::forward<Name>(name), narr, sizeof...(Args) / 2 - narr, std::forward<Args>(args)...);
+ }
+ };
+} // sol
+
+// end of sol/table_core.hpp
+
+namespace sol {
+ typedef table_core<false> table;
+} // sol
+
+// end of sol/table.hpp
+
+// beginning of sol/load_result.hpp
+
+namespace sol {
+ struct load_result : public proxy_base<load_result> {
+ private:
+ lua_State* L;
+ int index;
+ int returncount;
+ int popcount;
+ load_status err;
+
+ template <typename T>
+ decltype(auto) tagged_get(types<sol::optional<T>>) const {
+ if (!valid()) {
+ return sol::optional<T>(nullopt);
+ }
+ return stack::get<sol::optional<T>>(L, index);
+ }
+
+ template <typename T>
+ decltype(auto) tagged_get(types<T>) const {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!valid()) {
+ type_panic(L, index, type_of(L, index), type::none);
+ }
+#endif // Check Argument Safety
+ return stack::get<T>(L, index);
+ }
+
+ sol::optional<sol::error> tagged_get(types<sol::optional<sol::error>>) const {
+ if (valid()) {
+ return nullopt;
+ }
+ return sol::error(detail::direct_error, stack::get<std::string>(L, index));
+ }
+
+ sol::error tagged_get(types<sol::error>) const {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (valid()) {
+ type_panic(L, index, type_of(L, index), type::none);
+ }
+#endif // Check Argument Safety
+ return sol::error(detail::direct_error, stack::get<std::string>(L, index));
+ }
+
+ public:
+ load_result() = default;
+ load_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, load_status err = load_status::ok) noexcept : L(L), index(index), returncount(returncount), popcount(popcount), err(err) {
+
+ }
+ load_result(const load_result&) = default;
+ load_result& operator=(const load_result&) = default;
+ load_result(load_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but we will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ o.popcount = 0;
+ o.err = load_status::syntax;
+ }
+ load_result& operator=(load_result&& o) noexcept {
+ L = o.L;
+ index = o.index;
+ returncount = o.returncount;
+ popcount = o.popcount;
+ err = o.err;
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but we will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ o.popcount = 0;
+ o.err = load_status::syntax;
+ return *this;
+ }
+
+ load_status status() const noexcept {
+ return err;
+ }
+
+ bool valid() const noexcept {
+ return status() == load_status::ok;
+ }
+
+ template<typename T>
+ T get() const {
+ return tagged_get(types<meta::unqualified_t<T>>());
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) {
+ return get<function>().template call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Args>
+ decltype(auto) operator()(Args&&... args) {
+ return call<>(std::forward<Args>(args)...);
+ }
+
+ lua_State* lua_state() const noexcept { return L; };
+ int stack_index() const noexcept { return index; };
+
+ ~load_result() {
+ stack::remove(L, index, popcount);
+ }
+ };
+} // sol
+
+// end of sol/load_result.hpp
+
+namespace sol {
+ enum class lib : char {
+ base,
+ package,
+ coroutine,
+ string,
+ os,
+ math,
+ table,
+ debug,
+ bit32,
+ io,
+ ffi,
+ jit,
+ utf8,
+ count
+ };
+
+ class state_view {
+ private:
+ lua_State* L;
+ table reg;
+ global_table global;
+
+ optional<object> is_loaded_package(const std::string& key) {
+ auto loaded = reg.traverse_get<optional<object>>("_LOADED", key);
+ bool is53mod = loaded && !(loaded->is<bool>() && !loaded->as<bool>());
+ if (is53mod)
+ return loaded;
+#if SOL_LUA_VERSION <= 501
+ auto loaded51 = global.traverse_get<optional<object>>("package", "loaded", key);
+ bool is51mod = loaded51 && !(loaded51->is<bool>() && !loaded51->as<bool>());
+ if (is51mod)
+ return loaded51;
+#endif
+ return nullopt;
+ }
+
+ template <typename T>
+ void ensure_package(const std::string& key, T&& sr) {
+#if SOL_LUA_VERSION <= 501
+ auto pkg = global["package"];
+ if (!pkg.valid()) {
+ pkg = create_table_with("loaded", create_table_with(key, sr));
+ }
+ else {
+ auto ld = pkg["loaded"];
+ if (!ld.valid()) {
+ ld = create_table_with(key, sr);
+ }
+ else {
+ ld[key] = sr;
+ }
+ }
+#endif
+ auto loaded = reg["_LOADED"];
+ if (!loaded.valid()) {
+ loaded = create_table_with(key, sr);
+ }
+ else {
+ loaded[key] = sr;
+ }
+ }
+
+ template <typename Fx>
+ object require_core(const std::string& key, Fx&& action, bool create_global = true) {
+ optional<object> loaded = is_loaded_package(key);
+ if (loaded && loaded->valid())
+ return std::move(*loaded);
+ action();
+ auto sr = stack::get<stack_reference>(L);
+ if (create_global)
+ set(key, sr);
+ ensure_package(key, sr);
+ return stack::pop<object>(L);
+ }
+
+ public:
+ typedef global_table::iterator iterator;
+ typedef global_table::const_iterator const_iterator;
+
+ state_view(lua_State* L) :
+ L(L),
+ reg(L, LUA_REGISTRYINDEX),
+ global(L, detail::global_) {
+
+ }
+
+ lua_State* lua_state() const {
+ return L;
+ }
+
+ template<typename... Args>
+ void open_libraries(Args&&... args) {
+ static_assert(meta::all_same<lib, Args...>::value, "all types must be libraries");
+ if (sizeof...(args) == 0) {
+ luaL_openlibs(L);
+ return;
+ }
+
+ lib libraries[1 + sizeof...(args)] = { lib::count, std::forward<Args>(args)... };
+
+ for (auto&& library : libraries) {
+ switch (library) {
+#if SOL_LUA_VERSION <= 501 && defined(SOL_LUAJIT)
+ case lib::coroutine:
+#endif // luajit opens coroutine base stuff
+ case lib::base:
+ luaL_requiref(L, "base", luaopen_base, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::package:
+ luaL_requiref(L, "package", luaopen_package, 1);
+ lua_pop(L, 1);
+ break;
+#if !defined(SOL_LUAJIT)
+ case lib::coroutine:
+#if SOL_LUA_VERSION > 501
+ luaL_requiref(L, "coroutine", luaopen_coroutine, 1);
+ lua_pop(L, 1);
+#endif // Lua 5.2+ only
+ break;
+#endif // Not LuaJIT
+ case lib::string:
+ luaL_requiref(L, "string", luaopen_string, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::table:
+ luaL_requiref(L, "table", luaopen_table, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::math:
+ luaL_requiref(L, "math", luaopen_math, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::bit32:
+#ifdef SOL_LUAJIT
+ luaL_requiref(L, "bit32", luaopen_bit, 1);
+ lua_pop(L, 1);
+#elif SOL_LUA_VERSION == 502
+ luaL_requiref(L, "bit32", luaopen_bit32, 1);
+ lua_pop(L, 1);
+#else
+#endif // Lua 5.2 only (deprecated in 5.3 (503))
+ break;
+ case lib::io:
+ luaL_requiref(L, "io", luaopen_io, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::os:
+ luaL_requiref(L, "os", luaopen_os, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::debug:
+ luaL_requiref(L, "debug", luaopen_debug, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::utf8:
+#if SOL_LUA_VERSION > 502 && !defined(SOL_LUAJIT)
+ luaL_requiref(L, "utf8", luaopen_utf8, 1);
+ lua_pop(L, 1);
+#endif // Lua 5.3+ only
+ break;
+ case lib::ffi:
+#ifdef SOL_LUAJIT
+ luaL_requiref(L, "ffi", luaopen_ffi, 1);
+ lua_pop(L, 1);
+#endif
+ break;
+ case lib::jit:
+#ifdef SOL_LUAJIT
+ luaL_requiref(L, "jit", luaopen_jit, 1);
+ lua_pop(L, 1);
+#endif
+ break;
+ case lib::count:
+ default:
+ break;
+ }
+ }
+ }
+
+ object require(const std::string& key, lua_CFunction open_function, bool create_global = true) {
+ luaL_requiref(L, key.c_str(), open_function, create_global ? 1 : 0);
+ return stack::pop<object>(L);
+ }
+
+ object require_script(const std::string& key, const std::string& code, bool create_global = true) {
+ return require_core(key, [this, &code]() {stack::script(L, code); }, create_global);
+ }
+
+ object require_file(const std::string& key, const std::string& filename, bool create_global = true) {
+ return require_core(key, [this, &filename]() {stack::script_file(L, filename); }, create_global);
+ }
+
+ function_result script(const std::string& code) {
+ int index = (::std::max)(lua_gettop(L), 1);
+ stack::script(L, code);
+ int returns = lua_gettop(L) - (index - 1);
+ return function_result(L, index, returns);
+ }
+
+ function_result script_file(const std::string& filename) {
+ int index = (::std::max)(lua_gettop(L), 1);
+ stack::script_file(L, filename);
+ int returns = lua_gettop(L) - (index - 1);
+ return function_result(L, index, returns);
+ }
+
+ load_result load(const std::string& code) {
+ load_status x = static_cast<load_status>(luaL_loadstring(L, code.c_str()));
+ return load_result(L, lua_absindex(L, -1), 1, 1, x);
+ }
+
+ load_result load_file(const std::string& filename) {
+ load_status x = static_cast<load_status>(luaL_loadfile(L, filename.c_str()));
+ return load_result(L, lua_absindex(L, -1), 1, 1, x);
+ }
+
+ load_result load_buffer(const char *buff, size_t size, const char *name, const char* mode = nullptr) {
+ load_status x = static_cast<load_status>(luaL_loadbufferx(L, buff, size, name, mode));
+ return load_result(L, lua_absindex(L, -1), 1, 1, x);
+ }
+
+ iterator begin() const {
+ return global.begin();
+ }
+
+ iterator end() const {
+ return global.end();
+ }
+
+ const_iterator cbegin() const {
+ return global.cbegin();
+ }
+
+ const_iterator cend() const {
+ return global.cend();
+ }
+
+ global_table globals() const {
+ return global;
+ }
+
+ table registry() const {
+ return reg;
+ }
+
+ operator lua_State* () const {
+ return lua_state();
+ }
+
+ void set_panic(lua_CFunction panic) {
+ lua_atpanic(L, panic);
+ }
+
+ template<typename... Args, typename... Keys>
+ decltype(auto) get(Keys&&... keys) const {
+ return global.get<Args...>(std::forward<Keys>(keys)...);
+ }
+
+ template<typename T, typename Key>
+ decltype(auto) get_or(Key&& key, T&& otherwise) const {
+ return global.get_or(std::forward<Key>(key), std::forward<T>(otherwise));
+ }
+
+ template<typename T, typename Key, typename D>
+ decltype(auto) get_or(Key&& key, D&& otherwise) const {
+ return global.get_or<T>(std::forward<Key>(key), std::forward<D>(otherwise));
+ }
+
+ template<typename... Args>
+ state_view& set(Args&&... args) {
+ global.set(std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename T, typename... Keys>
+ decltype(auto) traverse_get(Keys&&... keys) const {
+ return global.traverse_get<T>(std::forward<Keys>(keys)...);
+ }
+
+ template<typename... Args>
+ state_view& traverse_set(Args&&... args) {
+ global.traverse_set(std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename T>
+ state_view& set_usertype(usertype<T>& user) {
+ return set_usertype(usertype_traits<T>::name, user);
+ }
+
+ template<typename Key, typename T>
+ state_view& set_usertype(Key&& key, usertype<T>& user) {
+ global.set_usertype(std::forward<Key>(key), user);
+ return *this;
+ }
+
+ template<typename Class, typename... Args>
+ state_view& new_usertype(const std::string& name, Args&&... args) {
+ global.new_usertype<Class>(name, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ state_view& new_usertype(const std::string& name, Args&&... args) {
+ global.new_usertype<Class, CTor0, CTor...>(name, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ state_view& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
+ global.new_usertype<Class>(name, ctor, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename... Args>
+ state_view& new_simple_usertype(const std::string& name, Args&&... args) {
+ global.new_simple_usertype<Class>(name, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ state_view& new_simple_usertype(const std::string& name, Args&&... args) {
+ global.new_simple_usertype<Class, CTor0, CTor...>(name, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ state_view& new_simple_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
+ global.new_simple_usertype<Class>(name, ctor, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename... Args>
+ simple_usertype<Class> create_simple_usertype(Args&&... args) {
+ return global.create_simple_usertype<Class>(std::forward<Args>(args)...);
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ simple_usertype<Class> create_simple_usertype(Args&&... args) {
+ return global.create_simple_usertype<Class, CTor0, CTor...>(std::forward<Args>(args)...);
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ simple_usertype<Class> create_simple_usertype(constructors<CArgs...> ctor, Args&&... args) {
+ return global.create_simple_usertype<Class>(ctor, std::forward<Args>(args)...);
+ }
+
+ template<bool read_only = true, typename... Args>
+ state_view& new_enum(const std::string& name, Args&&... args) {
+ global.new_enum<read_only>(name, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template <typename Fx>
+ void for_each(Fx&& fx) {
+ global.for_each(std::forward<Fx>(fx));
+ }
+
+ template<typename T>
+ proxy<global_table&, T> operator[](T&& key) {
+ return global[std::forward<T>(key)];
+ }
+
+ template<typename T>
+ proxy<const global_table&, T> operator[](T&& key) const {
+ return global[std::forward<T>(key)];
+ }
+
+ template<typename Sig, typename... Args, typename Key>
+ state_view& set_function(Key&& key, Args&&... args) {
+ global.set_function<Sig>(std::forward<Key>(key), std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename... Args, typename Key>
+ state_view& set_function(Key&& key, Args&&... args) {
+ global.set_function(std::forward<Key>(key), std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template <typename Name>
+ table create_table(Name&& name, int narr = 0, int nrec = 0) {
+ return global.create(std::forward<Name>(name), narr, nrec);
+ }
+
+ template <typename Name, typename Key, typename Value, typename... Args>
+ table create_table(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ return global.create(std::forward<Name>(name), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ }
+
+ template <typename Name, typename... Args>
+ table create_named_table(Name&& name, Args&&... args) {
+ table x = global.create_with(std::forward<Args>(args)...);
+ global.set(std::forward<Name>(name), x);
+ return x;
+ }
+
+ table create_table(int narr = 0, int nrec = 0) {
+ return create_table(lua_state(), narr, nrec);
+ }
+
+ template <typename Key, typename Value, typename... Args>
+ table create_table(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ return create_table(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ table create_table_with(Args&&... args) {
+ return create_table_with(lua_state(), std::forward<Args>(args)...);
+ }
+
+ static inline table create_table(lua_State* L, int narr = 0, int nrec = 0) {
+ return global_table::create(L, narr, nrec);
+ }
+
+ template <typename Key, typename Value, typename... Args>
+ static inline table create_table(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ return global_table::create(L, narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static inline table create_table_with(lua_State* L, Args&&... args) {
+ return global_table::create_with(L, std::forward<Args>(args)...);
+ }
+ };
+} // sol
+
+// end of sol/state_view.hpp
+
+namespace sol {
+ inline int default_at_panic(lua_State* L) {
+#ifdef SOL_NO_EXCEPTIONS
+ (void)L;
+ return -1;
+#else
+ const char* message = lua_tostring(L, -1);
+ std::string err = message ? message : "An unexpected error occurred and forced the lua state to call atpanic";
+ throw error(err);
+#endif
+ }
+
+ class state : private std::unique_ptr<lua_State, void(*)(lua_State*)>, public state_view {
+ private:
+ typedef std::unique_ptr<lua_State, void(*)(lua_State*)> unique_base;
+ public:
+ state(lua_CFunction panic = default_at_panic) : unique_base(luaL_newstate(), lua_close),
+ state_view(unique_base::get()) {
+ set_panic(panic);
+ stack::luajit_exception_handler(unique_base::get());
+ }
+
+ state(lua_CFunction panic, lua_Alloc alfunc, void* alpointer = nullptr) : unique_base(lua_newstate(alfunc, alpointer), lua_close),
+ state_view(unique_base::get()) {
+ set_panic(panic);
+ stack::luajit_exception_handler(unique_base::get());
+ }
+
+ using state_view::get;
+ };
+} // sol
+
+// end of sol/state.hpp
+
+// beginning of sol/coroutine.hpp
+
+// beginning of sol/thread.hpp
+
+namespace sol {
+ class thread : public reference {
+ public:
+ thread() noexcept = default;
+ thread(const thread&) = default;
+ thread(thread&&) = default;
+ thread(const stack_reference& r) : thread(r.lua_state(), r.stack_index()) {};
+ thread(stack_reference&& r) : thread(r.lua_state(), r.stack_index()) {};
+ thread& operator=(const thread&) = default;
+ thread& operator=(thread&&) = default;
+ thread(lua_State* L, int index = -1) : reference(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ type_assert(L, index, type::thread);
+#endif // Safety
+ }
+
+ state_view state() const {
+ return state_view(this->thread_state());
+ }
+
+ lua_State* thread_state() const {
+ auto pp = stack::push_pop(*this);
+ lua_State* lthread = lua_tothread(lua_state(), -1);
+ return lthread;
+ }
+
+ thread_status status() const {
+ lua_State* lthread = thread_state();
+ thread_status lstat = static_cast<thread_status>(lua_status(lthread));
+ if (lstat != thread_status::ok && lua_gettop(lthread) == 0) {
+ // No thing on the thread's stack means its dead
+ return thread_status::dead;
+ }
+ return lstat;
+ }
+
+ thread create() {
+ return create(lua_state());
+ }
+
+ static thread create(lua_State* L) {
+ lua_newthread(L);
+ thread result(L);
+ lua_pop(L, 1);
+ return result;
+ }
+ };
+} // sol
+
+// end of sol/thread.hpp
+
+namespace sol {
+ class coroutine : public reference {
+ private:
+ call_status stats = call_status::yielded;
+
+ void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
+#if SOL_LUA_VERSION < 502
+ stats = static_cast<call_status>(lua_resume(lua_state(), static_cast<int>(argcount)));
+#else
+ stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount)));
+#endif // Lua 5.1 compat
+ }
+
+ template<std::size_t... I, typename... Ret>
+ auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) {
+ luacall(n, sizeof...(Ret));
+ return stack::pop<std::tuple<Ret...>>(lua_state());
+ }
+
+ template<std::size_t I, typename Ret>
+ Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) {
+ luacall(n, 1);
+ return stack::pop<Ret>(lua_state());
+ }
+
+ template <std::size_t I>
+ void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) {
+ luacall(n, 0);
+ }
+
+ protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) {
+ int stacksize = lua_gettop(lua_state());
+ int firstreturn = (std::max)(1, stacksize - static_cast<int>(n));
+ luacall(n, LUA_MULTRET);
+ int poststacksize = lua_gettop(lua_state());
+ int returncount = poststacksize - (firstreturn - 1);
+ if (error()) {
+ return protected_function_result(lua_state(), lua_absindex(lua_state(), -1), 1, returncount, status());
+ }
+ return protected_function_result(lua_state(), firstreturn, returncount, returncount, status());
+ }
+
+ public:
+ coroutine() noexcept = default;
+ coroutine(const coroutine&) noexcept = default;
+ coroutine& operator=(const coroutine&) noexcept = default;
+ coroutine(lua_State* L, int index = -1) : reference(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ stack::check<coroutine>(L, index, type_panic);
+#endif // Safety
+ }
+
+ call_status status() const noexcept {
+ return stats;
+ }
+
+ bool error() const noexcept {
+ call_status cs = status();
+ return cs != call_status::ok && cs != call_status::yielded;
+ }
+
+ bool runnable() const noexcept {
+ return valid()
+ && (status() == call_status::yielded);
+ }
+
+ explicit operator bool() const noexcept {
+ return runnable();
+ }
+
+ template<typename... Args>
+ protected_function_result operator()(Args&&... args) {
+ return call<>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) operator()(types<Ret...>, Args&&... args) {
+ return call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) {
+ push();
+ int pushcount = stack::multi_push(lua_state(), std::forward<Args>(args)...);
+ return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
+ }
+ };
+} // sol
+
+// end of sol/coroutine.hpp
+
+#endif // SOL_SINGLE_INCLUDE_HPP
diff --git a/3rdparty/sol2/sol.hpp b/3rdparty/sol2/sol.hpp
new file mode 100644
index 00000000000..fcde72bbdef
--- /dev/null
+++ b/3rdparty/sol2/sol.hpp
@@ -0,0 +1,50 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_HPP
+#define SOL_HPP
+
+#if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER)
+#define SOL_INSIDE_UNREAL
+#endif // Unreal Engine 4 bullshit
+
+#ifdef SOL_INSIDE_UNREAL
+#ifdef check
+#define SOL_INSIDE_UNREAL_REMOVED_CHECK
+#undef check
+#endif
+#endif // Unreal Engine 4 Bullshit
+
+#include "sol/state.hpp"
+#include "sol/object.hpp"
+#include "sol/function.hpp"
+#include "sol/protected_function.hpp"
+#include "sol/state.hpp"
+#include "sol/coroutine.hpp"
+#include "sol/variadic_args.hpp"
+
+#ifdef SOL_INSIDE_UNREAL
+#ifdef SOL_INSIDE_UNREAL_REMOVED_CHECK
+#define check(expr) { if(UNLIKELY(!(expr))) { FDebug::LogAssertFailedMessage( #expr, __FILE__, __LINE__ ); _DebugBreakAndPromptForRemote(); FDebug::AssertFailed( #expr, __FILE__, __LINE__ ); CA_ASSUME(false); } }}
+#endif
+#endif // Unreal Engine 4 Bullshit
+
+#endif // SOL_HPP
diff --git a/3rdparty/sol2/sol/bind_traits.hpp b/3rdparty/sol2/sol/bind_traits.hpp
new file mode 100644
index 00000000000..a78cb6a3ee1
--- /dev/null
+++ b/3rdparty/sol2/sol/bind_traits.hpp
@@ -0,0 +1,243 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rappt1101010z, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_BIND_TRAITS_HPP
+#define SOL_BIND_TRAITS_HPP
+
+#include "tuple.hpp"
+
+namespace sol {
+ namespace meta {
+ namespace meta_detail {
+
+ template<class F>
+ struct check_deducible_signature {
+ struct nat {};
+ template<class G>
+ static auto test(int) -> decltype(&G::operator(), void());
+ template<class>
+ static auto test(...)->nat;
+
+ using type = std::is_void<decltype(test<F>(0))>;
+ };
+ } // meta_detail
+
+ template<class F>
+ struct has_deducible_signature : meta_detail::check_deducible_signature<F>::type { };
+
+ namespace meta_detail {
+
+ template <std::size_t I, typename T>
+ struct void_tuple_element : meta::tuple_element<I, T> {};
+
+ template <std::size_t I>
+ struct void_tuple_element<I, std::tuple<>> { typedef void type; };
+
+ template <std::size_t I, typename T>
+ using void_tuple_element_t = typename void_tuple_element<I, T>::type;
+
+ template <bool has_c_variadic, typename T, typename R, typename... Args>
+ struct basic_traits {
+ private:
+ typedef std::conditional_t<std::is_void<T>::value, int, T>& first_type;
+
+ public:
+ static const bool is_member_function = std::is_void<T>::value;
+ static const bool has_c_var_arg = has_c_variadic;
+ static const std::size_t arity = sizeof...(Args);
+ static const std::size_t free_arity = sizeof...(Args)+static_cast<std::size_t>(!std::is_void<T>::value);
+ typedef types<Args...> args_list;
+ typedef std::tuple<Args...> args_tuple;
+ typedef T object_type;
+ typedef R return_type;
+ typedef tuple_types<R> returns_list;
+ typedef R(function_type)(Args...);
+ typedef std::conditional_t<std::is_void<T>::value, args_list, types<first_type, Args...>> free_args_list;
+ typedef std::conditional_t<std::is_void<T>::value, R(Args...), R(first_type, Args...)> free_function_type;
+ typedef std::conditional_t<std::is_void<T>::value, R(*)(Args...), R(*)(first_type, Args...)> free_function_pointer_type;
+ typedef std::remove_pointer_t<free_function_pointer_type> signature_type;
+ template<std::size_t i>
+ using arg_at = void_tuple_element_t<i, args_tuple>;
+ };
+
+ template<typename Signature, bool b = has_deducible_signature<Signature>::value>
+ struct fx_traits : basic_traits<false, void, void> {};
+
+ // Free Functions
+ template<typename R, typename... Args>
+ struct fx_traits<R(Args...), false> : basic_traits<false, void, R, Args...> {
+ typedef R(*function_pointer_type)(Args...);
+ };
+
+ template<typename R, typename... Args>
+ struct fx_traits<R(*)(Args...), false> : basic_traits<false, void, R, Args...> {
+ typedef R(*function_pointer_type)(Args...);
+ };
+
+ template<typename R, typename... Args>
+ struct fx_traits<R(Args..., ...), false> : basic_traits<true, void, R, Args...> {
+ typedef R(*function_pointer_type)(Args..., ...);
+ };
+
+ template<typename R, typename... Args>
+ struct fx_traits<R(*)(Args..., ...), false> : basic_traits<true, void, R, Args...> {
+ typedef R(*function_pointer_type)(Args..., ...);
+ };
+
+ // Member Functions
+ /* C-Style Variadics */
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...), false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...);
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...), false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...);
+ };
+
+ /* Const Volatile */
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const volatile, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const volatile;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const volatile, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const volatile;
+ };
+
+ /* Member Function Qualifiers */
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) &, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) &, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const &, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const &, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const volatile &, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const volatile &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const volatile &, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const volatile &;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) && , false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) && ;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) && , false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) && ;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const &&, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const &&;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const &&, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const &&;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args...) const volatile &&, false> : basic_traits<false, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args...) const volatile &&;
+ };
+
+ template<typename T, typename R, typename... Args>
+ struct fx_traits<R(T::*)(Args..., ...) const volatile &&, false> : basic_traits<true, T, R, Args...> {
+ typedef R(T::* function_pointer_type)(Args..., ...) const volatile &&;
+ };
+
+ template<typename Signature>
+ struct fx_traits<Signature, true> : fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> {};
+
+ template<typename Signature, bool b = std::is_member_object_pointer<Signature>::value>
+ struct callable_traits : fx_traits<std::decay_t<Signature>> {
+
+ };
+
+ template<typename R, typename T>
+ struct callable_traits<R(T::*), true> {
+ typedef R Arg;
+ typedef T object_type;
+ using signature_type = R(T::*);
+ static const bool is_member_function = false;
+ static const std::size_t arity = 1;
+ static const std::size_t free_arity = 2;
+ typedef std::tuple<Arg> args_tuple;
+ typedef R return_type;
+ typedef types<Arg> args_list;
+ typedef types<T, Arg> free_args_list;
+ typedef meta::tuple_types<R> returns_list;
+ typedef R(function_type)(T&, R);
+ typedef R(*function_pointer_type)(T&, R);
+ typedef R(*free_function_pointer_type)(T&, R);
+ template<std::size_t i>
+ using arg_at = void_tuple_element_t<i, args_tuple>;
+ };
+ } // meta_detail
+
+ template<typename Signature>
+ struct bind_traits : meta_detail::callable_traits<Signature> {};
+
+ template<typename Signature>
+ using function_args_t = typename bind_traits<Signature>::args_list;
+
+ template<typename Signature>
+ using function_signature_t = typename bind_traits<Signature>::signature_type;
+
+ template<typename Signature>
+ using function_return_t = typename bind_traits<Signature>::return_type;
+
+ } // meta
+} // sol
+
+#endif // SOL_BIND_TRAITS_HPP
diff --git a/3rdparty/sol2/sol/call.hpp b/3rdparty/sol2/sol/call.hpp
new file mode 100644
index 00000000000..0abeeefaa18
--- /dev/null
+++ b/3rdparty/sol2/sol/call.hpp
@@ -0,0 +1,573 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_CALL_HPP
+#define SOL_CALL_HPP
+
+#include "protect.hpp"
+#include "wrapper.hpp"
+#include "property.hpp"
+#include "stack.hpp"
+
+namespace sol {
+ namespace call_detail {
+
+ template <typename R, typename W>
+ inline auto& pick(std::true_type, property_wrapper<R, W>& f) {
+ return f.read;
+ }
+
+ template <typename R, typename W>
+ inline auto& pick(std::false_type, property_wrapper<R, W>& f) {
+ return f.write;
+ }
+
+ template <typename T, typename List>
+ struct void_call;
+
+ template <typename T, typename... Args>
+ struct void_call<T, types<Args...>> {
+ static void call(Args...) {}
+ };
+
+ template <typename T>
+ struct constructor_match {
+ T* obj;
+
+ constructor_match(T* obj) : obj(obj) {}
+
+ template <typename Fx, std::size_t I, typename... R, typename... Args>
+ int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
+ detail::default_construct func{};
+ return stack::call_into_lua<false>(r, a, L, start, func, obj);
+ }
+ };
+
+ namespace overload_detail {
+ template <std::size_t... M, typename Match, typename... Args>
+ inline int overload_match_arity(types<>, std::index_sequence<>, std::index_sequence<M...>, Match&&, lua_State* L, int, int, Args&&...) {
+ return luaL_error(L, "sol: no matching function call takes this number of arguments and the specified types");
+ }
+
+ template <typename Fx, typename... Fxs, std::size_t I, std::size_t... In, std::size_t... M, typename Match, typename... Args>
+ inline int overload_match_arity(types<Fx, Fxs...>, std::index_sequence<I, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
+ typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
+ typedef meta::tuple_types<typename traits::return_type> return_types;
+ typedef typename traits::free_args_list args_list;
+ // compile-time eliminate any functions that we know ahead of time are of improper arity
+ if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
+ return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+ if (traits::free_arity != fxarity) {
+ return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+ stack::record tracking{};
+ if (!stack::stack_detail::check_types<true>{}.check(args_list(), L, start, no_panic, tracking)) {
+ return overload_match_arity(types<Fxs...>(), std::index_sequence<In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+ return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
+ }
+ } // overload_detail
+
+ template <typename... Functions, typename Match, typename... Args>
+ inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
+ return overload_detail::overload_match_arity(types<Functions...>(), std::make_index_sequence<sizeof...(Functions)>(), std::index_sequence<>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+
+ template <typename... Functions, typename Match, typename... Args>
+ inline int overload_match(Match&& matchfx, lua_State* L, int start, Args&&... args) {
+ int fxarity = lua_gettop(L) - (start - 1);
+ return overload_match_arity<Functions...>(std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+
+ template <typename T, typename... TypeLists, typename Match, typename... Args>
+ inline int construct_match(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
+ // use same overload resolution matching as all other parts of the framework
+ return overload_match_arity<decltype(void_call<T, TypeLists>::call)...>(std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
+ }
+
+ template <typename T, typename... TypeLists>
+ inline int construct(lua_State* L) {
+ static const auto& meta = usertype_traits<T>::metatable;
+ int argcount = lua_gettop(L);
+ call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, meta, 1) : call_syntax::dot;
+ argcount -= static_cast<int>(syntax);
+
+ T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
+ T*& referencepointer = *pointerpointer;
+ T* obj = reinterpret_cast<T*>(pointerpointer + 1);
+ referencepointer = obj;
+ reference userdataref(L, -1);
+ userdataref.pop();
+
+ construct_match<T, TypeLists...>(constructor_match<T>(obj), L, argcount, 1 + static_cast<int>(syntax));
+
+ userdataref.push();
+ luaL_getmetatable(L, &meta[0]);
+ if (type_of(L, -1) == type::nil) {
+ lua_pop(L, 1);
+ return luaL_error(L, "sol: unable to get usertype metatable");
+ }
+
+ lua_setmetatable(L, -2);
+ return 1;
+ }
+
+ template <typename F, bool is_index, bool is_variable, bool checked, int boost, typename = void>
+ struct agnostic_lua_call_wrapper {
+ template <typename Fx, typename... Args>
+ static int call(lua_State* L, Fx&& f, Args&&... args) {
+ typedef wrapper<meta::unqualified_t<F>> wrap;
+ typedef typename wrap::returns_list returns_list;
+ typedef typename wrap::free_args_list args_list;
+ typedef typename wrap::caller caller;
+ return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + 1, caller(), std::forward<Fx>(f), std::forward<Args>(args)...);
+ }
+ };
+
+ template <typename T, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<var_wrapper<T>, true, is_variable, checked, boost, C> {
+ template <typename F>
+ static int call(lua_State* L, F&& f) {
+ return stack::push_reference(L, detail::unwrap(f.value));
+ }
+ };
+
+ template <typename T, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<var_wrapper<T>, false, is_variable, checked, boost, C> {
+ template <typename V>
+ static int call_assign(std::true_type, lua_State* L, V&& f) {
+ detail::unwrap(f.value) = stack::get<meta::unwrapped_t<T>>(L, boost + (is_variable ? 3 : 1));
+ return 0;
+ }
+
+ template <typename... Args>
+ static int call_assign(std::false_type, lua_State* L, Args&&...) {
+ return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
+ }
+
+ template <typename... Args>
+ static int call_const(std::false_type, lua_State* L, Args&&... args) {
+ typedef meta::unwrapped_t<T> R;
+ return call_assign(std::is_assignable<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>(), L, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static int call_const(std::true_type, lua_State* L, Args&&...) {
+ return luaL_error(L, "sol: cannot write to a readonly (const) variable");
+ }
+
+ template <typename V>
+ static int call(lua_State* L, V&& f) {
+ return call_const(std::is_const<meta::unwrapped_t<T>>(), L, f);
+ }
+ };
+
+ template <bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<lua_r_CFunction, is_index, is_variable, checked, boost, C> {
+ static int call(lua_State* L, lua_r_CFunction f) {
+ return f(L);
+ }
+ };
+
+ template <bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<lua_CFunction, is_index, is_variable, checked, boost, C> {
+ static int call(lua_State* L, lua_CFunction f) {
+ return f(L);
+ }
+ };
+
+ template <bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<no_prop, is_index, is_variable, checked, boost, C> {
+ static int call(lua_State* L, const no_prop&) {
+ return luaL_error(L, is_index ? "sol: cannot read from a writeonly property" : "sol: cannot write to a readonly property");
+ }
+ };
+
+ template <bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<no_construction, is_index, is_variable, checked, boost, C> {
+ static int call(lua_State* L, const no_construction&) {
+ return luaL_error(L, "sol: cannot call this constructor (tagged as non-constructible)");
+ }
+ };
+
+ template <typename... Args, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct agnostic_lua_call_wrapper<bases<Args...>, is_index, is_variable, checked, boost, C> {
+ static int call(lua_State*, const bases<Args...>&) {
+ // Uh. How did you even call this, lul
+ return 0;
+ }
+ };
+
+ template <typename T, typename F, bool is_index, bool is_variable, bool checked = stack::stack_detail::default_check_arguments, int boost = 0, typename = void>
+ struct lua_call_wrapper : agnostic_lua_call_wrapper<F, is_index, is_variable, checked, boost> {};
+
+ template <typename T, typename F, bool is_index, bool is_variable, bool checked, int boost>
+ struct lua_call_wrapper<T, F, is_index, is_variable, checked, boost, std::enable_if_t<std::is_member_function_pointer<F>::value>> {
+ typedef wrapper<meta::unqualified_t<F>> wrap;
+ typedef typename wrap::object_type object_type;
+
+ template <typename Fx>
+ static int call(lua_State* L, Fx&& f, object_type& o) {
+ typedef typename wrap::returns_list returns_list;
+ typedef typename wrap::args_list args_list;
+ typedef typename wrap::caller caller;
+ return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), std::forward<Fx>(f), o);
+ }
+
+ template <typename Fx>
+ static int call(lua_State* L, Fx&& f) {
+ typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
+#ifdef SOL_SAFE_USERTYPE
+ object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
+ if (o == nullptr) {
+ return luaL_error(L, "sol: received null for 'self' argument (use ':' for accessing member functions, make sure member variables are preceeded by the actual object with '.' syntax)");
+ }
+ return call(L, std::forward<Fx>(f), *o);
+#else
+ object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
+ return call(L, std::forward<Fx>(f), o);
+#endif // Safety
+ }
+ };
+
+ template <typename T, typename F, bool is_variable, bool checked, int boost>
+ struct lua_call_wrapper<T, F, false, is_variable, checked, boost, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
+ typedef lua_bind_traits<F> traits_type;
+ typedef wrapper<meta::unqualified_t<F>> wrap;
+ typedef typename wrap::object_type object_type;
+
+ template <typename V>
+ static int call_assign(std::true_type, lua_State* L, V&& f, object_type& o) {
+ typedef typename wrap::args_list args_list;
+ typedef typename wrap::caller caller;
+ return stack::call_into_lua<checked>(types<void>(), args_list(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
+ }
+
+ template <typename V>
+ static int call_assign(std::true_type, lua_State* L, V&& f) {
+ typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
+#ifdef SOL_SAFE_USERTYPE
+ object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
+ if (o == nullptr) {
+ if (is_variable) {
+ return luaL_error(L, "sol: received nil for 'self' argument (bad '.' access?)");
+ }
+ return luaL_error(L, "sol: received nil for 'self' argument (pass 'self' as first argument)");
+ }
+ return call_assign(std::true_type(), L, f, *o);
+#else
+ object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
+ return call_assign(std::true_type(), L, f, o);
+#endif // Safety
+ }
+
+ template <typename... Args>
+ static int call_assign(std::false_type, lua_State* L, Args&&...) {
+ return luaL_error(L, "sol: cannot write to this variable: copy assignment/constructor not available");
+ }
+
+ template <typename... Args>
+ static int call_const(std::false_type, lua_State* L, Args&&... args) {
+ typedef typename traits_type::return_type R;
+ return call_assign(std::is_assignable<std::add_lvalue_reference_t<meta::unqualified_t<R>>, R>(), L, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static int call_const(std::true_type, lua_State* L, Args&&...) {
+ return luaL_error(L, "sol: cannot write to a readonly (const) variable");
+ }
+
+ template <typename V>
+ static int call(lua_State* L, V&& f) {
+ return call_const(std::is_const<typename traits_type::return_type>(), L, f);
+ }
+
+ template <typename V>
+ static int call(lua_State* L, V&& f, object_type& o) {
+ return call_const(std::is_const<typename traits_type::return_type>(), L, f, o);
+ }
+ };
+
+ template <typename T, typename F, bool is_variable, bool checked, int boost>
+ struct lua_call_wrapper<T, F, true, is_variable, checked, boost, std::enable_if_t<std::is_member_object_pointer<F>::value>> {
+ typedef lua_bind_traits<F> traits_type;
+ typedef wrapper<meta::unqualified_t<F>> wrap;
+ typedef typename wrap::object_type object_type;
+
+ template <typename V>
+ static int call(lua_State* L, V&& f, object_type& o) {
+ typedef typename wrap::returns_list returns_list;
+ typedef typename wrap::caller caller;
+ return stack::call_into_lua<checked>(returns_list(), types<>(), L, boost + ( is_variable ? 3 : 2 ), caller(), f, o);
+ }
+
+ template <typename V>
+ static int call(lua_State* L, V&& f) {
+ typedef std::conditional_t<std::is_void<T>::value, object_type, T> Ta;
+#ifdef SOL_SAFE_USERTYPE
+ object_type* o = static_cast<object_type*>(stack::get<Ta*>(L, 1));
+ if (o == nullptr) {
+ if (is_variable) {
+ return luaL_error(L, "sol: 'self' argument is nil (bad '.' access?)");
+ }
+ return luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument)");
+ }
+ return call(L, f, *o);
+#else
+ object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
+ return call(L, f, o);
+#endif // Safety
+ }
+ };
+
+ template <typename T, typename... Args, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, constructor_list<Args...>, is_index, is_variable, checked, boost, C> {
+ typedef constructor_list<Args...> F;
+
+ static int call(lua_State* L, F&) {
+ const auto& metakey = usertype_traits<T>::metatable;
+ int argcount = lua_gettop(L);
+ call_syntax syntax = argcount > 0 ? stack::get_call_syntax(L, metakey, 1) : call_syntax::dot;
+ argcount -= static_cast<int>(syntax);
+
+ T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
+ reference userdataref(L, -1);
+ T*& referencepointer = *pointerpointer;
+ T* obj = reinterpret_cast<T*>(pointerpointer + 1);
+ referencepointer = obj;
+
+ construct_match<T, Args...>(constructor_match<T>(obj), L, argcount, boost + 1 + static_cast<int>(syntax));
+
+ userdataref.push();
+ luaL_getmetatable(L, &metakey[0]);
+ if (type_of(L, -1) == type::nil) {
+ lua_pop(L, 1);
+ return luaL_error(L, "sol: unable to get usertype metatable");
+ }
+
+ lua_setmetatable(L, -2);
+ return 1;
+ }
+ };
+
+ template <typename T, typename... Cxs, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, constructor_wrapper<Cxs...>, is_index, is_variable, checked, boost, C> {
+ typedef constructor_wrapper<Cxs...> F;
+
+ struct onmatch {
+ template <typename Fx, std::size_t I, typename... R, typename... Args>
+ int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start, F& f) {
+ const auto& metakey = usertype_traits<T>::metatable;
+ T** pointerpointer = reinterpret_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
+ reference userdataref(L, -1);
+ T*& referencepointer = *pointerpointer;
+ T* obj = reinterpret_cast<T*>(pointerpointer + 1);
+ referencepointer = obj;
+
+ auto& func = std::get<I>(f.functions);
+ stack::call_into_lua<checked>(r, a, L, boost + start, func, detail::implicit_wrapper<T>(obj));
+
+ userdataref.push();
+ luaL_getmetatable(L, &metakey[0]);
+ if (type_of(L, -1) == type::nil) {
+ lua_pop(L, 1);
+ std::string err = "sol: unable to get usertype metatable for ";
+ err += usertype_traits<T>::name;
+ return luaL_error(L, err.c_str());
+ }
+ lua_setmetatable(L, -2);
+
+ return 1;
+ }
+ };
+
+ static int call(lua_State* L, F& f) {
+ call_syntax syntax = stack::get_call_syntax(L, usertype_traits<T>::metatable);
+ int syntaxval = static_cast<int>(syntax);
+ int argcount = lua_gettop(L) - syntaxval;
+ return construct_match<T, meta::pop_front_type_t<meta::function_args_t<Cxs>>...>(onmatch(), L, argcount, 1 + syntaxval, f);
+ }
+
+ };
+
+ template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost>
+ struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, std::enable_if_t<std::is_void<Fx>::value>> {
+ typedef destructor_wrapper<Fx> F;
+
+ static int call(lua_State* L, const F&) {
+ return detail::usertype_alloc_destroy<T>(L);
+ }
+ };
+
+ template <typename T, typename Fx, bool is_index, bool is_variable, bool checked, int boost>
+ struct lua_call_wrapper<T, destructor_wrapper<Fx>, is_index, is_variable, checked, boost, std::enable_if_t<!std::is_void<Fx>::value>> {
+ typedef destructor_wrapper<Fx> F;
+
+ static int call(lua_State* L, const F& f) {
+ T& obj = stack::get<T>(L);
+ f.fx(detail::implicit_wrapper<T>(obj));
+ return 0;
+ }
+ };
+
+ template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, overload_set<Fs...>, is_index, is_variable, checked, boost, C> {
+ typedef overload_set<Fs...> F;
+
+ struct on_match {
+ template <typename Fx, std::size_t I, typename... R, typename... Args>
+ int operator()(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, F& fx) {
+ auto& f = std::get<I>(fx.functions);
+ return lua_call_wrapper<T, Fx, is_index, is_variable, checked, boost>{}.call(L, f);
+ }
+ };
+
+ static int call(lua_State* L, F& fx) {
+ return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L), 1, fx);
+ }
+ };
+
+ template <typename T, typename... Fs, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, factory_wrapper<Fs...>, is_index, is_variable, checked, boost, C> {
+ typedef factory_wrapper<Fs...> F;
+
+ struct on_match {
+ template <typename Fx, std::size_t I, typename... R, typename... Args>
+ int operator()(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int, F& fx) {
+ auto& f = std::get<I>(fx.functions);
+ return lua_call_wrapper<T, Fx, is_index, is_variable, checked, boost>{}.call(L, f);
+ }
+ };
+
+ static int call(lua_State* L, F& fx) {
+ return overload_match_arity<Fs...>(on_match(), L, lua_gettop(L), 1, fx);
+ }
+ };
+
+ template <typename T, typename R, typename W, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, property_wrapper<R, W>, is_index, is_variable, checked, boost, C> {
+ typedef std::conditional_t<is_index, R, W> P;
+ typedef meta::unqualified_t<P> U;
+ typedef lua_bind_traits<U> traits_type;
+
+ template <typename F>
+ static int self_call(lua_State* L, F&& f) {
+ typedef wrapper<U> wrap;
+ typedef meta::unqualified_t<typename traits_type::template arg_at<0>> object_type;
+ typedef meta::pop_front_type_t<typename traits_type::free_args_list> args_list;
+ typedef T Ta;
+#ifdef SOL_SAFE_USERTYPE
+ object_type* po = static_cast<object_type*>(stack::get<Ta*>(L, 1));
+ if (po == nullptr) {
+ if (is_variable) {
+ return luaL_error(L, "sol: 'self' argument is nil (bad '.' access?)");
+ }
+ return luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument)");
+ }
+ object_type& o = *po;
+#else
+ object_type& o = static_cast<object_type&>(*stack::get<non_null<Ta*>>(L, 1));
+#endif // Safety
+ typedef typename wrap::returns_list returns_list;
+ typedef typename wrap::caller caller;
+ return stack::call_into_lua<checked>(returns_list(), args_list(), L, boost + (is_variable ? 3 : 2), caller(), f, o);
+ }
+
+ template <typename F, typename... Args>
+ static int defer_call(std::false_type, lua_State* L, F&& f, Args&&... args) {
+ return self_call(L, pick(meta::boolean<is_index>(), f), std::forward<Args>(args)...);
+ }
+
+ template <typename F, typename... Args>
+ static int defer_call(std::true_type, lua_State* L, F&& f, Args&&... args) {
+ auto& p = pick(meta::boolean<is_index>(), std::forward<F>(f));
+ return lua_call_wrapper<T, meta::unqualified_t<decltype(p)>, is_index, is_variable, checked, boost>{}.call(L, p, std::forward<Args>(args)...);
+ }
+
+ template <typename F, typename... Args>
+ static int call(lua_State* L, F&& f, Args&&... args) {
+ typedef meta::any<
+ std::is_void<U>,
+ std::is_same<U, no_prop>,
+ meta::is_specialization_of<var_wrapper, U>,
+ meta::is_specialization_of<constructor_wrapper, U>,
+ meta::is_specialization_of<constructor_list, U>,
+ std::is_member_pointer<U>
+ > is_specialized;
+ return defer_call(is_specialized(), L, std::forward<F>(f), std::forward<Args>(args)...);
+ }
+ };
+
+ template <typename T, typename V, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, protect_t<V>, is_index, is_variable, checked, boost, C> {
+ typedef protect_t<V> F;
+
+ template <typename... Args>
+ static int call(lua_State* L, F& fx, Args&&... args) {
+ return lua_call_wrapper<T, V, is_index, is_variable, true, boost>{}.call(L, fx.value, std::forward<Args>(args)...);
+ }
+ };
+
+ template <typename T, typename Sig, typename P, bool is_index, bool is_variable, bool checked, int boost, typename C>
+ struct lua_call_wrapper<T, function_arguments<Sig, P>, is_index, is_variable, checked, boost, C> {
+ template <typename F>
+ static int call(lua_State* L, F&& f) {
+ return lua_call_wrapper<T, meta::unqualified_t<P>, is_index, is_variable, stack::stack_detail::default_check_arguments, boost>{}.call(L, std::get<0>(f.arguments));
+ }
+ };
+
+ template <typename T, bool is_index, bool is_variable, int boost = 0, typename Fx, typename... Args>
+ inline int call_wrapped(lua_State* L, Fx&& fx, Args&&... args) {
+ return lua_call_wrapper<T, meta::unqualified_t<Fx>, is_index, is_variable, stack::stack_detail::default_check_arguments, boost>{}.call(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename T, bool is_index, bool is_variable, typename F>
+ inline int call_user(lua_State* L) {
+ auto& fx = stack::get<user<F>>(L, upvalue_index(1));
+ return call_wrapped<T, is_index, is_variable>(L, fx);
+ }
+
+ template <typename T, typename = void>
+ struct is_var_bind : std::false_type {};
+
+ template <typename T>
+ struct is_var_bind<T, std::enable_if_t<std::is_member_object_pointer<T>::value>> : std::true_type {};
+
+ template <>
+ struct is_var_bind<no_prop> : std::true_type {};
+
+ template <typename R, typename W>
+ struct is_var_bind<property_wrapper<R, W>> : std::true_type {};
+
+ template <typename T>
+ struct is_var_bind<var_wrapper<T>> : std::true_type {};
+ } // call_detail
+
+ template <typename T>
+ struct is_variable_binding : call_detail::is_var_bind<meta::unqualified_t<T>> {};
+
+ template <typename T>
+ struct is_function_binding : meta::neg<is_variable_binding<T>> {};
+
+} // sol
+
+#endif // SOL_CALL_HPP
diff --git a/3rdparty/sol2/sol/compatibility.hpp b/3rdparty/sol2/sol/compatibility.hpp
new file mode 100644
index 00000000000..81e7742df0c
--- /dev/null
+++ b/3rdparty/sol2/sol/compatibility.hpp
@@ -0,0 +1,47 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_COMPATIBILITY_HPP
+#define SOL_COMPATIBILITY_HPP
+
+// The various pieces of the compatibility layer
+// comes from https://github.com/keplerproject/lua-compat-5.2
+// but has been modified in many places for use with Sol and luajit,
+// though the core abstractions remain the same
+
+#include "compatibility/version.hpp"
+
+#ifndef SOL_NO_COMPAT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "compatibility/5.1.0.h"
+#include "compatibility/5.0.0.h"
+#include "compatibility/5.x.x.h"
+#include "compatibility/5.x.x.inl"
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SOL_NO_COMPAT
+
+#endif // SOL_COMPATIBILITY_HPP
diff --git a/3rdparty/sol2/sol/compatibility/5.0.0.h b/3rdparty/sol2/sol/compatibility/5.0.0.h
new file mode 100644
index 00000000000..549badba962
--- /dev/null
+++ b/3rdparty/sol2/sol/compatibility/5.0.0.h
@@ -0,0 +1,44 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_5_0_0_H
+#define SOL_5_0_0_H
+
+#include "version.hpp"
+
+#if SOL_LUA_VERSION < 501
+/* Lua 5.0 */
+
+#define LUA_QL(x) "'" x "'"
+#define LUA_QS LUA_QL("%s")
+
+#define luaL_Reg luaL_reg
+
+#define luaL_opt(L, f, n, d) \
+ (lua_isnoneornil(L, n) ? (d) : f(L, n))
+
+#define luaL_addchar(B,c) \
+ ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
+ (*(B)->p++ = (char)(c)))
+
+#endif // Lua 5.0
+
+#endif // SOL_5_0_0_H
diff --git a/3rdparty/sol2/sol/compatibility/5.1.0.h b/3rdparty/sol2/sol/compatibility/5.1.0.h
new file mode 100644
index 00000000000..0050b24eca4
--- /dev/null
+++ b/3rdparty/sol2/sol/compatibility/5.1.0.h
@@ -0,0 +1,175 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_5_1_0_H
+#define SOL_5_1_0_H
+
+#include "version.hpp"
+
+#if SOL_LUA_VERSION == 501
+/* Lua 5.1 */
+
+#include <lua.hpp>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+/* LuaJIT doesn't define these unofficial macros ... */
+#if !defined(LUAI_INT32)
+#include <limits.h>
+#if INT_MAX-20 < 32760
+#define LUAI_INT32 long
+#define LUAI_UINT32 unsigned long
+#elif INT_MAX > 2147483640L
+#define LUAI_INT32 int
+#define LUAI_UINT32 unsigned int
+#else
+#error "could not detect suitable lua_Unsigned datatype"
+#endif
+#endif
+
+/* LuaJIT does not have the updated error codes for thread status/function returns */
+#ifndef LUA_ERRGCMM
+#define LUA_ERRGCMM (LUA_ERRERR + 1)
+#endif // LUA_ERRGCMM
+
+/* LuaJIT does not support continuation contexts / return error codes? */
+#ifndef LUA_KCONTEXT
+#define LUA_KCONTEXT std::ptrdiff_t
+typedef LUA_KCONTEXT lua_KContext;
+typedef int(*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
+#endif // LUA_KCONTEXT
+
+#define LUA_OPADD 0
+#define LUA_OPSUB 1
+#define LUA_OPMUL 2
+#define LUA_OPDIV 3
+#define LUA_OPMOD 4
+#define LUA_OPPOW 5
+#define LUA_OPUNM 6
+#define LUA_OPEQ 0
+#define LUA_OPLT 1
+#define LUA_OPLE 2
+
+typedef LUAI_UINT32 lua_Unsigned;
+
+typedef struct luaL_Buffer_52 {
+ luaL_Buffer b; /* make incorrect code crash! */
+ char *ptr;
+ size_t nelems;
+ size_t capacity;
+ lua_State *L2;
+} luaL_Buffer_52;
+#define luaL_Buffer luaL_Buffer_52
+
+#define lua_tounsigned(L, i) lua_tounsignedx(L, i, NULL)
+
+#define lua_rawlen(L, i) lua_objlen(L, i)
+
+inline void lua_callk(lua_State *L, int nargs, int nresults, lua_KContext, lua_KFunction) {
+ // should probably warn the user of Lua 5.1 that continuation isn't supported...
+ lua_call(L, nargs, nresults);
+}
+inline int lua_pcallk(lua_State *L, int nargs, int nresults, int errfunc, lua_KContext, lua_KFunction) {
+ // should probably warn the user of Lua 5.1 that continuation isn't supported...
+ return lua_pcall(L, nargs, nresults, errfunc);
+}
+void lua_arith(lua_State *L, int op);
+int lua_compare(lua_State *L, int idx1, int idx2, int op);
+void lua_pushunsigned(lua_State *L, lua_Unsigned n);
+lua_Unsigned luaL_checkunsigned(lua_State *L, int i);
+lua_Unsigned lua_tounsignedx(lua_State *L, int i, int *isnum);
+lua_Unsigned luaL_optunsigned(lua_State *L, int i, lua_Unsigned def);
+lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum);
+void lua_len(lua_State *L, int i);
+int luaL_len(lua_State *L, int i);
+const char *luaL_tolstring(lua_State *L, int idx, size_t *len);
+void luaL_requiref(lua_State *L, char const* modname, lua_CFunction openf, int glb);
+
+#define luaL_buffinit luaL_buffinit_52
+void luaL_buffinit(lua_State *L, luaL_Buffer_52 *B);
+
+#define luaL_prepbuffsize luaL_prepbuffsize_52
+char *luaL_prepbuffsize(luaL_Buffer_52 *B, size_t s);
+
+#define luaL_addlstring luaL_addlstring_52
+void luaL_addlstring(luaL_Buffer_52 *B, const char *s, size_t l);
+
+#define luaL_addvalue luaL_addvalue_52
+void luaL_addvalue(luaL_Buffer_52 *B);
+
+#define luaL_pushresult luaL_pushresult_52
+void luaL_pushresult(luaL_Buffer_52 *B);
+
+#undef luaL_buffinitsize
+#define luaL_buffinitsize(L, B, s) \
+ (luaL_buffinit(L, B), luaL_prepbuffsize(B, s))
+
+#undef luaL_prepbuffer
+#define luaL_prepbuffer(B) \
+ luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
+
+#undef luaL_addchar
+#define luaL_addchar(B, c) \
+ ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize(B, 1)), \
+ ((B)->ptr[(B)->nelems++] = (c)))
+
+#undef luaL_addsize
+#define luaL_addsize(B, s) \
+ ((B)->nelems += (s))
+
+#undef luaL_addstring
+#define luaL_addstring(B, s) \
+ luaL_addlstring(B, s, strlen(s))
+
+#undef luaL_pushresultsize
+#define luaL_pushresultsize(B, s) \
+ (luaL_addsize(B, s), luaL_pushresult(B))
+
+typedef struct kepler_lua_compat_get_string_view {
+ const char *s;
+ size_t size;
+} kepler_lua_compat_get_string_view;
+
+inline const char* kepler_lua_compat_get_string(lua_State* L, void* ud, size_t* size) {
+ kepler_lua_compat_get_string_view* ls = (kepler_lua_compat_get_string_view*) ud;
+ (void)L;
+ if (ls->size == 0) return NULL;
+ *size = ls->size;
+ ls->size = 0;
+ return ls->s;
+}
+
+#if !defined(SOL_LUAJIT) || ((SOL_LUAJIT_VERSION - 020100) <= 0)
+// Luajit 2.1.0 has this function already
+
+inline int luaL_loadbufferx(lua_State* L, const char* buff, size_t size, const char* name, const char*) {
+ kepler_lua_compat_get_string_view ls;
+ ls.s = buff;
+ ls.size = size;
+ return lua_load(L, kepler_lua_compat_get_string, &ls, name/*, mode*/);
+}
+
+#endif // LuaJIT 2.1.x beta and beyond
+
+#endif /* Lua 5.1 */
+
+#endif // SOL_5_1_0_H \ No newline at end of file
diff --git a/3rdparty/sol2/sol/compatibility/5.x.x.h b/3rdparty/sol2/sol/compatibility/5.x.x.h
new file mode 100644
index 00000000000..95f48792a00
--- /dev/null
+++ b/3rdparty/sol2/sol/compatibility/5.x.x.h
@@ -0,0 +1,57 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_5_X_X_H
+#define SOL_5_X_X_H
+
+#include "version.hpp"
+
+#if SOL_LUA_VERSION < 502
+
+#define LUA_RIDX_GLOBALS LUA_GLOBALSINDEX
+
+#define LUA_OK 0
+
+#define lua_pushglobaltable(L) \
+ lua_pushvalue(L, LUA_GLOBALSINDEX)
+
+#define luaL_newlib(L, l) \
+ (lua_newtable((L)),luaL_setfuncs((L), (l), 0))
+
+void luaL_checkversion(lua_State *L);
+
+int lua_absindex(lua_State *L, int i);
+void lua_copy(lua_State *L, int from, int to);
+void lua_rawgetp(lua_State *L, int i, const void *p);
+void lua_rawsetp(lua_State *L, int i, const void *p);
+void *luaL_testudata(lua_State *L, int i, const char *tname);
+lua_Number lua_tonumberx(lua_State *L, int i, int *isnum);
+void lua_getuservalue(lua_State *L, int i);
+void lua_setuservalue(lua_State *L, int i);
+void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
+void luaL_setmetatable(lua_State *L, const char *tname);
+int luaL_getsubtable(lua_State *L, int i, const char *name);
+void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level);
+int luaL_fileresult(lua_State *L, int stat, const char *fname);
+
+#endif // Lua 5.1 and below
+
+#endif // SOL_5_X_X_H
diff --git a/3rdparty/sol2/sol/compatibility/5.x.x.inl b/3rdparty/sol2/sol/compatibility/5.x.x.inl
new file mode 100644
index 00000000000..1d420e3f3f6
--- /dev/null
+++ b/3rdparty/sol2/sol/compatibility/5.x.x.inl
@@ -0,0 +1,707 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_5_X_X_INL
+#define SOL_5_X_X_INL
+
+#include "version.hpp"
+#include "5.1.0.h"
+#include "5.0.0.h"
+#include "5.x.x.h"
+
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM == 501
+
+#include <errno.h>
+#include <string.h>
+
+#define PACKAGE_KEY "_sol.package"
+
+inline int lua_absindex(lua_State *L, int i) {
+ if (i < 0 && i > LUA_REGISTRYINDEX)
+ i += lua_gettop(L) + 1;
+ return i;
+}
+
+inline void lua_copy(lua_State *L, int from, int to) {
+ int abs_to = lua_absindex(L, to);
+ luaL_checkstack(L, 1, "not enough stack slots");
+ lua_pushvalue(L, from);
+ lua_replace(L, abs_to);
+}
+
+inline void lua_rawgetp(lua_State *L, int i, const void *p) {
+ int abs_i = lua_absindex(L, i);
+ lua_pushlightuserdata(L, (void*)p);
+ lua_rawget(L, abs_i);
+}
+
+inline void lua_rawsetp(lua_State *L, int i, const void *p) {
+ int abs_i = lua_absindex(L, i);
+ luaL_checkstack(L, 1, "not enough stack slots");
+ lua_pushlightuserdata(L, (void*)p);
+ lua_insert(L, -2);
+ lua_rawset(L, abs_i);
+}
+
+inline void *luaL_testudata(lua_State *L, int i, const char *tname) {
+ void *p = lua_touserdata(L, i);
+ luaL_checkstack(L, 2, "not enough stack slots");
+ if (p == NULL || !lua_getmetatable(L, i))
+ return NULL;
+ else {
+ int res = 0;
+ luaL_getmetatable(L, tname);
+ res = lua_rawequal(L, -1, -2);
+ lua_pop(L, 2);
+ if (!res)
+ p = NULL;
+ }
+ return p;
+}
+
+inline lua_Number lua_tonumberx(lua_State *L, int i, int *isnum) {
+ lua_Number n = lua_tonumber(L, i);
+ if (isnum != NULL) {
+ *isnum = (n != 0 || lua_isnumber(L, i));
+ }
+ return n;
+}
+
+inline static void push_package_table(lua_State *L) {
+ lua_pushliteral(L, PACKAGE_KEY);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ if (!lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ /* try to get package table from globals */
+ lua_pushliteral(L, "package");
+ lua_rawget(L, LUA_GLOBALSINDEX);
+ if (lua_istable(L, -1)) {
+ lua_pushliteral(L, PACKAGE_KEY);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ }
+ }
+}
+
+inline void lua_getuservalue(lua_State *L, int i) {
+ luaL_checktype(L, i, LUA_TUSERDATA);
+ luaL_checkstack(L, 2, "not enough stack slots");
+ lua_getfenv(L, i);
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ if (lua_rawequal(L, -1, -2)) {
+ lua_pop(L, 1);
+ lua_pushnil(L);
+ lua_replace(L, -2);
+ }
+ else {
+ lua_pop(L, 1);
+ push_package_table(L);
+ if (lua_rawequal(L, -1, -2)) {
+ lua_pop(L, 1);
+ lua_pushnil(L);
+ lua_replace(L, -2);
+ }
+ else
+ lua_pop(L, 1);
+ }
+}
+
+inline void lua_setuservalue(lua_State *L, int i) {
+ luaL_checktype(L, i, LUA_TUSERDATA);
+ if (lua_isnil(L, -1)) {
+ luaL_checkstack(L, 1, "not enough stack slots");
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ lua_replace(L, -2);
+ }
+ lua_setfenv(L, i);
+}
+
+/*
+** Adapted from Lua 5.2.0
+*/
+inline void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) {
+ luaL_checkstack(L, nup + 1, "too many upvalues");
+ for (; l->name != NULL; l++) { /* fill the table with given functions */
+ int i;
+ lua_pushstring(L, l->name);
+ for (i = 0; i < nup; i++) /* copy upvalues to the top */
+ lua_pushvalue(L, -(nup + 1));
+ lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
+ lua_settable(L, -(nup + 3)); /* table must be below the upvalues, the name and the closure */
+ }
+ lua_pop(L, nup); /* remove upvalues */
+}
+
+inline void luaL_setmetatable(lua_State *L, const char *tname) {
+ luaL_checkstack(L, 1, "not enough stack slots");
+ luaL_getmetatable(L, tname);
+ lua_setmetatable(L, -2);
+}
+
+inline int luaL_getsubtable(lua_State *L, int i, const char *name) {
+ int abs_i = lua_absindex(L, i);
+ luaL_checkstack(L, 3, "not enough stack slots");
+ lua_pushstring(L, name);
+ lua_gettable(L, abs_i);
+ if (lua_istable(L, -1))
+ return 1;
+ lua_pop(L, 1);
+ lua_newtable(L);
+ lua_pushstring(L, name);
+ lua_pushvalue(L, -2);
+ lua_settable(L, abs_i);
+ return 0;
+}
+
+#ifndef SOL_LUAJIT
+inline static int countlevels(lua_State *L) {
+ lua_Debug ar;
+ int li = 1, le = 1;
+ /* find an upper bound */
+ while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
+ /* do a binary search */
+ while (li < le) {
+ int m = (li + le) / 2;
+ if (lua_getstack(L, m, &ar)) li = m + 1;
+ else le = m;
+ }
+ return le - 1;
+}
+
+inline static int findfield(lua_State *L, int objidx, int level) {
+ if (level == 0 || !lua_istable(L, -1))
+ return 0; /* not found */
+ lua_pushnil(L); /* start 'next' loop */
+ while (lua_next(L, -2)) { /* for each pair in table */
+ if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
+ if (lua_rawequal(L, objidx, -1)) { /* found object? */
+ lua_pop(L, 1); /* remove value (but keep name) */
+ return 1;
+ }
+ else if (findfield(L, objidx, level - 1)) { /* try recursively */
+ lua_remove(L, -2); /* remove table (but keep name) */
+ lua_pushliteral(L, ".");
+ lua_insert(L, -2); /* place '.' between the two names */
+ lua_concat(L, 3);
+ return 1;
+ }
+ }
+ lua_pop(L, 1); /* remove value */
+ }
+ return 0; /* not found */
+}
+
+inline static int pushglobalfuncname(lua_State *L, lua_Debug *ar) {
+ int top = lua_gettop(L);
+ lua_getinfo(L, "f", ar); /* push function */
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ if (findfield(L, top + 1, 2)) {
+ lua_copy(L, -1, top + 1); /* move name to proper place */
+ lua_pop(L, 2); /* remove pushed values */
+ return 1;
+ }
+ else {
+ lua_settop(L, top); /* remove function and global table */
+ return 0;
+ }
+}
+
+inline static void pushfuncname(lua_State *L, lua_Debug *ar) {
+ if (*ar->namewhat != '\0') /* is there a name? */
+ lua_pushfstring(L, "function " LUA_QS, ar->name);
+ else if (*ar->what == 'm') /* main? */
+ lua_pushliteral(L, "main chunk");
+ else if (*ar->what == 'C') {
+ if (pushglobalfuncname(L, ar)) {
+ lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
+ lua_remove(L, -2); /* remove name */
+ }
+ else
+ lua_pushliteral(L, "?");
+ }
+ else
+ lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
+}
+
+#define LEVELS1 12 /* size of the first part of the stack */
+#define LEVELS2 10 /* size of the second part of the stack */
+
+inline void luaL_traceback(lua_State *L, lua_State *L1,
+ const char *msg, int level) {
+ lua_Debug ar;
+ int top = lua_gettop(L);
+ int numlevels = countlevels(L1);
+ int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;
+ if (msg) lua_pushfstring(L, "%s\n", msg);
+ lua_pushliteral(L, "stack traceback:");
+ while (lua_getstack(L1, level++, &ar)) {
+ if (level == mark) { /* too many levels? */
+ lua_pushliteral(L, "\n\t..."); /* add a '...' */
+ level = numlevels - LEVELS2; /* and skip to last ones */
+ }
+ else {
+ lua_getinfo(L1, "Slnt", &ar);
+ lua_pushfstring(L, "\n\t%s:", ar.short_src);
+ if (ar.currentline > 0)
+ lua_pushfstring(L, "%d:", ar.currentline);
+ lua_pushliteral(L, " in ");
+ pushfuncname(L, &ar);
+ lua_concat(L, lua_gettop(L) - top);
+ }
+ }
+ lua_concat(L, lua_gettop(L) - top);
+}
+#endif
+
+inline const lua_Number *lua_version(lua_State *L) {
+ static const lua_Number version = LUA_VERSION_NUM;
+ if (L == NULL) return &version;
+ // TODO: wonky hacks to get at the inside of the incomplete type lua_State?
+ //else return L->l_G->version;
+ else return &version;
+}
+
+inline static void luaL_checkversion_(lua_State *L, lua_Number ver) {
+ const lua_Number* v = lua_version(L);
+ if (v != lua_version(NULL))
+ luaL_error(L, "multiple Lua VMs detected");
+ else if (*v != ver)
+ luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
+ ver, *v);
+ /* check conversions number -> integer types */
+ lua_pushnumber(L, -(lua_Number)0x1234);
+ if (lua_tointeger(L, -1) != -0x1234 ||
+ lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
+ luaL_error(L, "bad conversion number->int;"
+ " must recompile Lua with proper settings");
+ lua_pop(L, 1);
+}
+
+inline void luaL_checkversion(lua_State* L) {
+ luaL_checkversion_(L, LUA_VERSION_NUM);
+}
+
+#ifndef SOL_LUAJIT
+inline int luaL_fileresult(lua_State *L, int stat, const char *fname) {
+ int en = errno; /* calls to Lua API may change this value */
+ if (stat) {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+ else {
+ char buf[1024];
+#ifdef __GLIBC__
+ strerror_r(en, buf, 1024);
+#else
+ strerror_s(buf, 1024, en);
+#endif
+ lua_pushnil(L);
+ if (fname)
+ lua_pushfstring(L, "%s: %s", fname, buf);
+ else
+ lua_pushstring(L, buf);
+ lua_pushnumber(L, (lua_Number)en);
+ return 3;
+ }
+}
+#endif // luajit
+#endif // Lua 5.0 or Lua 5.1
+
+
+#if SOL_LUA_VERSION == 501
+#include <limits.h>
+
+typedef LUAI_INT32 LUA_INT32;
+
+/********************************************************************/
+/* extract of 5.2's luaconf.h */
+/* detects proper defines for faster unsigned<->number conversion */
+/* see copyright notice at the end of this file */
+/********************************************************************/
+
+#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE)
+#define LUA_WIN /* enable goodies for regular Windows platforms */
+#endif
+
+
+#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
+
+/* Microsoft compiler on a Pentium (32 bit) ? */
+#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */
+
+#define LUA_MSASMTRICK
+#define LUA_IEEEENDIAN 0
+#define LUA_NANTRICK
+
+/* pentium 32 bits? */
+#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */
+
+#define LUA_IEEE754TRICK
+#define LUA_IEEELL
+#define LUA_IEEEENDIAN 0
+#define LUA_NANTRICK
+
+/* pentium 64 bits? */
+#elif defined(__x86_64) /* }{ */
+
+#define LUA_IEEE754TRICK
+#define LUA_IEEEENDIAN 0
+
+#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */
+
+#define LUA_IEEE754TRICK
+#define LUA_IEEEENDIAN 1
+
+#else /* }{ */
+
+/* assume IEEE754 and a 32-bit integer type */
+#define LUA_IEEE754TRICK
+
+#endif /* } */
+
+#endif /* } */
+
+
+/********************************************************************/
+/* extract of 5.2's llimits.h */
+/* gives us lua_number2unsigned and lua_unsigned2number */
+/* see copyright notice just below this one here */
+/********************************************************************/
+
+/*********************************************************************
+* This file contains parts of Lua 5.2's source code:
+*
+* Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*********************************************************************/
+
+#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */
+/* trick with Microsoft assembler for X86 */
+
+#define lua_number2unsigned(i,n) \
+ {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;}
+
+
+#elif defined(LUA_IEEE754TRICK) /* }{ */
+/* the next trick should work on any machine using IEEE754 with
+a 32-bit int type */
+
+union compat52_luai_Cast { double l_d; LUA_INT32 l_p[2]; };
+
+#if !defined(LUA_IEEEENDIAN) /* { */
+#define LUAI_EXTRAIEEE \
+ static const union compat52_luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)};
+#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33)
+#else
+#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN
+#define LUAI_EXTRAIEEE /* empty */
+#endif /* } */
+
+#define lua_number2int32(i,n,t) \
+ { LUAI_EXTRAIEEE \
+ volatile union compat52_luai_Cast u; u.l_d = (n) + 6755399441055744.0; \
+ (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; }
+
+#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned)
+
+#endif /* } */
+
+
+/* the following definitions always work, but may be slow */
+
+#if !defined(lua_number2unsigned) /* { */
+/* the following definition assures proper modulo behavior */
+#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT)
+#include <math.h>
+#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1)
+#define lua_number2unsigned(i,n) \
+ ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED))
+#else
+#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n))
+#endif
+#endif /* } */
+
+
+#if !defined(lua_unsigned2number)
+/* on several machines, coercion from unsigned to double is slow,
+so it may be worth to avoid */
+#define lua_unsigned2number(u) \
+ (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u))
+#endif
+
+/********************************************************************/
+
+inline static void compat52_call_lua(lua_State *L, char const code[], size_t len,
+ int nargs, int nret) {
+ lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code);
+ if (lua_type(L, -1) != LUA_TFUNCTION) {
+ lua_pop(L, 1);
+ if (luaL_loadbuffer(L, code, len, "=none"))
+ lua_error(L);
+ lua_pushvalue(L, -1);
+ lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code);
+ }
+ lua_insert(L, -nargs - 1);
+ lua_call(L, nargs, nret);
+}
+
+static const char compat52_arith_code[] = {
+ "local op,a,b=...\n"
+ "if op==0 then return a+b\n"
+ "elseif op==1 then return a-b\n"
+ "elseif op==2 then return a*b\n"
+ "elseif op==3 then return a/b\n"
+ "elseif op==4 then return a%b\n"
+ "elseif op==5 then return a^b\n"
+ "elseif op==6 then return -a\n"
+ "end\n"
+};
+
+inline void lua_arith(lua_State *L, int op) {
+ if (op < LUA_OPADD || op > LUA_OPUNM)
+ luaL_error(L, "invalid 'op' argument for lua_arith");
+ luaL_checkstack(L, 5, "not enough stack slots");
+ if (op == LUA_OPUNM)
+ lua_pushvalue(L, -1);
+ lua_pushnumber(L, op);
+ lua_insert(L, -3);
+ compat52_call_lua(L, compat52_arith_code,
+ sizeof(compat52_arith_code) - 1, 3, 1);
+}
+
+static const char compat52_compare_code[] = {
+ "local a,b=...\n"
+ "return a<=b\n"
+};
+
+inline int lua_compare(lua_State *L, int idx1, int idx2, int op) {
+ int result = 0;
+ switch (op) {
+ case LUA_OPEQ:
+ return lua_equal(L, idx1, idx2);
+ case LUA_OPLT:
+ return lua_lessthan(L, idx1, idx2);
+ case LUA_OPLE:
+ luaL_checkstack(L, 5, "not enough stack slots");
+ idx1 = lua_absindex(L, idx1);
+ idx2 = lua_absindex(L, idx2);
+ lua_pushvalue(L, idx1);
+ lua_pushvalue(L, idx2);
+ compat52_call_lua(L, compat52_compare_code,
+ sizeof(compat52_compare_code) - 1, 2, 1);
+ result = lua_toboolean(L, -1);
+ lua_pop(L, 1);
+ return result;
+ default:
+ luaL_error(L, "invalid 'op' argument for lua_compare");
+ }
+ return 0;
+}
+
+inline void lua_pushunsigned(lua_State *L, lua_Unsigned n) {
+ lua_pushnumber(L, lua_unsigned2number(n));
+}
+
+inline lua_Unsigned luaL_checkunsigned(lua_State *L, int i) {
+ lua_Unsigned result;
+ lua_Number n = lua_tonumber(L, i);
+ if (n == 0 && !lua_isnumber(L, i))
+ luaL_checktype(L, i, LUA_TNUMBER);
+ lua_number2unsigned(result, n);
+ return result;
+}
+
+inline lua_Unsigned lua_tounsignedx(lua_State *L, int i, int *isnum) {
+ lua_Unsigned result;
+ lua_Number n = lua_tonumberx(L, i, isnum);
+ lua_number2unsigned(result, n);
+ return result;
+}
+
+inline lua_Unsigned luaL_optunsigned(lua_State *L, int i, lua_Unsigned def) {
+ return luaL_opt(L, luaL_checkunsigned, i, def);
+}
+
+inline lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum) {
+ lua_Integer n = lua_tointeger(L, i);
+ if (isnum != NULL) {
+ *isnum = (n != 0 || lua_isnumber(L, i));
+ }
+ return n;
+}
+
+inline void lua_len(lua_State *L, int i) {
+ switch (lua_type(L, i)) {
+ case LUA_TSTRING: /* fall through */
+ case LUA_TTABLE:
+ if (!luaL_callmeta(L, i, "__len"))
+ lua_pushnumber(L, (int)lua_objlen(L, i));
+ break;
+ case LUA_TUSERDATA:
+ if (luaL_callmeta(L, i, "__len"))
+ break;
+ /* maybe fall through */
+ default:
+ luaL_error(L, "attempt to get length of a %s value",
+ lua_typename(L, lua_type(L, i)));
+ }
+}
+
+inline int luaL_len(lua_State *L, int i) {
+ int res = 0, isnum = 0;
+ luaL_checkstack(L, 1, "not enough stack slots");
+ lua_len(L, i);
+ res = (int)lua_tointegerx(L, -1, &isnum);
+ lua_pop(L, 1);
+ if (!isnum)
+ luaL_error(L, "object length is not a number");
+ return res;
+}
+
+inline const char *luaL_tolstring(lua_State *L, int idx, size_t *len) {
+ if (!luaL_callmeta(L, idx, "__tostring")) {
+ int t = lua_type(L, idx);
+ switch (t) {
+ case LUA_TNIL:
+ lua_pushliteral(L, "nil");
+ break;
+ case LUA_TSTRING:
+ case LUA_TNUMBER:
+ lua_pushvalue(L, idx);
+ break;
+ case LUA_TBOOLEAN:
+ if (lua_toboolean(L, idx))
+ lua_pushliteral(L, "true");
+ else
+ lua_pushliteral(L, "false");
+ break;
+ default:
+ lua_pushfstring(L, "%s: %p", lua_typename(L, t),
+ lua_topointer(L, idx));
+ break;
+ }
+ }
+ return lua_tolstring(L, -1, len);
+}
+
+inline void luaL_requiref(lua_State *L, char const* modname,
+ lua_CFunction openf, int glb) {
+ luaL_checkstack(L, 3, "not enough stack slots");
+ lua_pushcfunction(L, openf);
+ lua_pushstring(L, modname);
+ lua_call(L, 1, 1);
+ lua_getglobal(L, "package");
+ if (lua_istable(L, -1) == 0) {
+ lua_pop(L, 1);
+ lua_createtable(L, 0, 16);
+ lua_setglobal(L, "package");
+ lua_getglobal(L, "package");
+ }
+ lua_getfield(L, -1, "loaded");
+ if (lua_istable(L, -1) == 0) {
+ lua_pop(L, 1);
+ lua_createtable(L, 0, 1);
+ lua_setfield(L, -2, "loaded");
+ lua_getfield(L, -1, "loaded");
+ }
+ lua_replace(L, -2);
+ lua_pushvalue(L, -2);
+ lua_setfield(L, -2, modname);
+ lua_pop(L, 1);
+ if (glb) {
+ lua_pushvalue(L, -1);
+ lua_setglobal(L, modname);
+ }
+}
+
+inline void luaL_buffinit(lua_State *L, luaL_Buffer_52 *B) {
+ /* make it crash if used via pointer to a 5.1-style luaL_Buffer */
+ B->b.p = NULL;
+ B->b.L = NULL;
+ B->b.lvl = 0;
+ /* reuse the buffer from the 5.1-style luaL_Buffer though! */
+ B->ptr = B->b.buffer;
+ B->capacity = LUAL_BUFFERSIZE;
+ B->nelems = 0;
+ B->L2 = L;
+}
+
+inline char *luaL_prepbuffsize(luaL_Buffer_52 *B, size_t s) {
+ if (B->capacity - B->nelems < s) { /* needs to grow */
+ char* newptr = NULL;
+ size_t newcap = B->capacity * 2;
+ if (newcap - B->nelems < s)
+ newcap = B->nelems + s;
+ if (newcap < B->capacity) /* overflow */
+ luaL_error(B->L2, "buffer too large");
+ newptr = (char*)lua_newuserdata(B->L2, newcap);
+ memcpy(newptr, B->ptr, B->nelems);
+ if (B->ptr != B->b.buffer)
+ lua_replace(B->L2, -2); /* remove old buffer */
+ B->ptr = newptr;
+ B->capacity = newcap;
+ }
+ return B->ptr + B->nelems;
+}
+
+inline void luaL_addlstring(luaL_Buffer_52 *B, const char *s, size_t l) {
+ memcpy(luaL_prepbuffsize(B, l), s, l);
+ luaL_addsize(B, l);
+}
+
+inline void luaL_addvalue(luaL_Buffer_52 *B) {
+ size_t len = 0;
+ const char *s = lua_tolstring(B->L2, -1, &len);
+ if (!s)
+ luaL_error(B->L2, "cannot convert value to string");
+ if (B->ptr != B->b.buffer)
+ lua_insert(B->L2, -2); /* userdata buffer must be at stack top */
+ luaL_addlstring(B, s, len);
+ lua_remove(B->L2, B->ptr != B->b.buffer ? -2 : -1);
+}
+
+inline void luaL_pushresult(luaL_Buffer_52 *B) {
+ lua_pushlstring(B->L2, B->ptr, B->nelems);
+ if (B->ptr != B->b.buffer)
+ lua_replace(B->L2, -2); /* remove userdata buffer */
+}
+
+#endif /* SOL_LUA_VERSION == 501 */
+
+#endif // SOL_5_X_X_INL
diff --git a/3rdparty/sol2/sol/compatibility/version.hpp b/3rdparty/sol2/sol/compatibility/version.hpp
new file mode 100644
index 00000000000..5ddc23d91e6
--- /dev/null
+++ b/3rdparty/sol2/sol/compatibility/version.hpp
@@ -0,0 +1,121 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_VERSION_HPP
+#define SOL_VERSION_HPP
+
+#include <lua.hpp>
+
+#if defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
+#ifndef SOL_CODECVT_SUPPORT
+#define SOL_CODECVT_SUPPORT 1
+#endif // sol codecvt support
+#elif defined(__GNUC__)
+#if __GNUC__ >= 5
+#ifndef SOL_CODECVT_SUPPORT
+#define SOL_CODECVT_SUPPORT 1
+#endif // codecvt support
+#endif // g++ 5.x.x
+#else
+// Clang sucks and doesn't really utilize codecvt support,
+// not without checking the library versions explicitly (and we're not gonna do that, so fuck you)
+#endif // Windows/VC++ vs. g++ vs Others
+
+#ifdef LUAJIT_VERSION
+#ifndef SOL_LUAJIT
+#define SOL_LUAJIT
+#define SOL_LUAJIT_VERSION LUAJIT_VERSION_NUM
+#endif // sol luajit
+#endif // luajit
+
+#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 502
+#define SOL_LUA_VERSION LUA_VERSION_NUM
+#elif defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
+#define SOL_LUA_VERSION LUA_VERSION_NUM
+#elif !defined(LUA_VERSION_NUM)
+// Definitely 5.0
+#define SOL_LUA_VERSION 500
+#else
+// ??? Not sure, assume 502?
+#define SOL_LUA_VERSION 502
+#endif // Lua Version 502, 501 || luajit, 500
+
+#ifdef _MSC_VER
+#ifdef _DEBUG
+#ifndef NDEBUG
+#ifndef SOL_CHECK_ARGUMENTS
+// Do not define by default: let user turn it on
+//#define SOL_CHECK_ARGUMENTS
+#endif // Check Arguments
+#ifndef SOL_SAFE_USERTYPE
+#define SOL_SAFE_USERTYPE
+#endif // Safe Usertypes
+#endif // NDEBUG
+#endif // Debug
+
+#ifndef _CPPUNWIND
+#ifndef SOL_NO_EXCEPTIONS
+#define SOL_NO_EXCEPTIONS 1
+#endif
+#endif // Automatic Exceptions
+
+#ifndef _CPPRTTI
+#ifndef SOL_NO_RTTI
+#define SOL_NO_RTTI 1
+#endif
+#endif // Automatic RTTI
+
+#elif defined(__GNUC__) || defined(__clang__)
+
+#ifndef NDEBUG
+#ifndef __OPTIMIZE__
+#ifndef SOL_CHECK_ARGUMENTS
+// Do not define by default: let user choose
+//#define SOL_CHECK_ARGUMENTS
+// But do check userdata by default:
+#endif // Check Arguments
+#ifndef SOL_SAFE_USERTYPE
+#define SOL_SAFE_USERTYPE
+#endif // Safe Usertypes
+#endif // g++ optimizer flag
+#endif // Not Debug
+
+#ifndef __EXCEPTIONS
+#ifndef SOL_NO_EXCEPTIONS
+#define SOL_NO_EXCEPTIONS 1
+#endif
+#endif // No Exceptions
+
+#ifndef __GXX_RTTI
+#ifndef SOL_NO_RTII
+#define SOL_NO_RTTI 1
+#endif
+#endif // No RTTI
+
+#endif // vc++ || clang++/g++
+
+#ifndef SOL_SAFE_USERTYPE
+#ifdef SOL_CHECK_ARGUMENTS
+#define SOL_SAFE_USERTYPE
+#endif // Turn on Safety for all
+#endif // Safe Usertypes
+
+#endif // SOL_VERSION_HPP
diff --git a/3rdparty/sol2/sol/container_usertype_metatable.hpp b/3rdparty/sol2/sol/container_usertype_metatable.hpp
new file mode 100644
index 00000000000..a07b85be851
--- /dev/null
+++ b/3rdparty/sol2/sol/container_usertype_metatable.hpp
@@ -0,0 +1,412 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_CONTAINER_USERTYPE_HPP
+#define SOL_CONTAINER_USERTYPE_HPP
+
+#include "stack.hpp"
+
+namespace sol {
+
+ namespace detail {
+
+ template <typename T>
+ struct has_find {
+ private:
+ typedef std::array<char, 1> one;
+ typedef std::array<char, 2> two;
+
+ template <typename C> static one test(decltype(&C::find));
+ template <typename C> static two test(...);
+
+ public:
+ static const bool value = sizeof(test<T>(0)) == sizeof(char);
+ };
+
+ template <typename T>
+ T& get_first(const T& t) {
+ return std::forward<T>(t);
+ }
+
+ template <typename A, typename B>
+ decltype(auto) get_first(const std::pair<A, B>& t) {
+ return t.first;
+ }
+
+ template <typename C, typename I, meta::enable<has_find<meta::unqualified_t<C>>> = meta::enabler>
+ auto find(C& c, I&& i) {
+ return c.find(std::forward<I>(i));
+ }
+
+ template <typename C, typename I, meta::disable<has_find<meta::unqualified_t<C>>> = meta::enabler>
+ auto find(C& c, I&& i) {
+ using std::begin;
+ using std::end;
+ return std::find_if(begin(c), end(c), [&i](auto&& x) {
+ return i == get_first(x);
+ });
+ }
+
+ }
+
+ template <typename Raw, typename C = void>
+ struct container_usertype_metatable {
+ typedef meta::unqualified_t<Raw> T;
+ typedef std::size_t K;
+ typedef typename T::value_type V;
+ typedef typename T::iterator I;
+ typedef std::remove_reference_t<decltype(*std::declval<I&>())> IR;
+
+ struct iter {
+ T& source;
+ I it;
+
+ iter(T& source, I it) : source(source), it(std::move(it)) {}
+ };
+
+ static auto& get_src(lua_State* L) {
+#ifdef SOL_SAFE_USERTYPE
+ auto p = stack::get<T*>(L, 1);
+ if (p == nullptr) {
+ luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument or call on proper type)");
+ }
+ return *p;
+#else
+ return stack::get<T>(L, 1);
+#endif
+ }
+
+ static int real_index_call(lua_State* L) {
+ auto& src = get_src(L);
+#ifdef SOL_SAFE_USERTYPE
+ auto maybek = stack::check_get<K>(L, 2);
+ if (maybek) {
+ using std::begin;
+ auto it = begin(src);
+ K k = *maybek;
+ if (k <= src.size() && k > 0) {
+ --k;
+ std::advance(it, k);
+ return stack::push_reference(L, *it);
+ }
+ }
+ return stack::push(L, nil);
+#else
+ using std::begin;
+ auto it = begin(src);
+ K k = stack::get<K>(L, 2);
+ --k;
+ std::advance(it, k);
+ return stack::push_reference(L, *it);
+#endif // Safety
+ }
+
+ template <bool b, meta::disable<meta::boolean<b>> = meta::enabler>
+ static int real_new_index_call_const(std::integral_constant<bool, b>, lua_State* L) {
+ luaL_error(L, "sol: cannot write to a const value type or an immutable iterator (e.g., std::set)");
+ return 0;
+ }
+
+ template <bool b, meta::enable<meta::boolean<b>> = meta::enabler>
+ static int real_new_index_call_const(std::integral_constant<bool, b>, lua_State* L) {
+ auto& src = get_src(L);
+#ifdef SOL_SAFE_USERTYPE
+ auto maybek = stack::check_get<K>(L, 2);
+ if (maybek) {
+ K k = *maybek;
+ if (k <= src.size() && k > 0) {
+ --k;
+ using std::begin;
+ auto it = begin(src);
+ std::advance(it, k);
+ *it = stack::get<V>(L, 3);
+ }
+ }
+#else
+ using std::begin;
+ auto it = begin(src);
+ K k = stack::get<K>(L, 2);
+ --k;
+ std::advance(it, k);
+ *it = stack::get<V>(L, 3);
+#endif
+ return 0;
+ }
+
+ static int real_new_index_call(lua_State* L) {
+ return real_new_index_call_const(meta::neg<meta::any<std::is_const<V>, std::is_const<IR>>>(), L);
+ }
+
+ static int real_pairs_next_call(lua_State* L) {
+ using std::end;
+ iter& i = stack::get<user<iter>>(L, 1);
+ auto& source = i.source;
+ auto& it = i.it;
+ K k = stack::get<K>(L, 2);
+ if (it == end(source)) {
+ return 0;
+ }
+ int p = stack::multi_push_reference(L, k + 1, *it);
+ std::advance(it, 1);
+ return p;
+ }
+
+ static int real_pairs_call(lua_State* L) {
+ auto& src = get_src(L);
+ using std::begin;
+ stack::push(L, pairs_next_call);
+ stack::push<user<iter>>(L, src, begin(src));
+ stack::push(L, 0);
+ return 3;
+ }
+
+ static int real_length_call(lua_State*L) {
+ auto& src = get_src(L);
+ return stack::push(L, src.size());
+ }
+
+#if 0
+ static int real_push_back_call(lua_State*L) {
+ auto& src = get_src(L);
+ src.push_back(stack::get<V>(L, 2));
+ return 0;
+ }
+
+ static int real_insert_call(lua_State*L) {
+ using std::begin;
+ auto& src = get_src(L);
+ src.insert(std::next(begin(src), stack::get<K>(L, 2)), stack::get<V>(L, 3));
+ return 0;
+ }
+
+ static int push_back_call(lua_State*L) {
+ return detail::static_trampoline<(&real_length_call)>(L);
+ }
+
+ static int insert_call(lua_State*L) {
+ return detail::static_trampoline<(&real_insert_call)>(L);
+ }
+#endif // Sometime later, in a distant universe...
+
+ static int length_call(lua_State*L) {
+ return detail::static_trampoline<(&real_length_call)>(L);
+ }
+
+ static int pairs_next_call(lua_State*L) {
+ return detail::static_trampoline<(&real_pairs_next_call)>(L);
+ }
+
+ static int pairs_call(lua_State*L) {
+ return detail::static_trampoline<(&real_pairs_call)>(L);
+ }
+
+ static int index_call(lua_State*L) {
+ return detail::static_trampoline<(&real_index_call)>(L);
+ }
+
+ static int new_index_call(lua_State*L) {
+ return detail::static_trampoline<(&real_new_index_call)>(L);
+ }
+ };
+
+ template <typename Raw>
+ struct container_usertype_metatable<Raw, std::enable_if_t<meta::has_key_value_pair<meta::unqualified_t<Raw>>::value>> {
+ typedef meta::unqualified_t<Raw> T;
+ typedef typename T::value_type KV;
+ typedef typename KV::first_type K;
+ typedef typename KV::second_type V;
+ typedef typename T::iterator I;
+ struct iter {
+ T& source;
+ I it;
+
+ iter(T& source, I it) : source(source), it(std::move(it)) {}
+ };
+
+ static auto& get_src(lua_State* L) {
+#ifdef SOL_SAFE_USERTYPE
+ auto p = stack::get<T*>(L, 1);
+ if (p == nullptr) {
+ luaL_error(L, "sol: 'self' argument is nil (pass 'self' as first argument or call on proper type)");
+ }
+ return *p;
+#else
+ return stack::get<T>(L, 1);
+#endif
+ }
+
+ static int real_index_call(lua_State* L) {
+ auto& src = get_src(L);
+ auto k = stack::check_get<K>(L, 2);
+ if (k) {
+ using std::end;
+ auto it = detail::find(src, *k);
+ if (it != end(src)) {
+ auto& v = *it;
+ return stack::push_reference(L, v.second);
+ }
+ }
+ return stack::push(L, nil);
+ }
+
+ static int real_new_index_call_const(std::false_type, lua_State* L) {
+ luaL_error(L, "sol: cannot write to a const value type");
+ return 0;
+ }
+
+ static int real_new_index_call_const(std::true_type, lua_State* L) {
+ auto& src = get_src(L);
+ auto k = stack::check_get<K>(L, 2);
+ if (k) {
+ using std::end;
+ auto it = detail::find(src, *k);
+ if (it != end(src)) {
+ auto& v = *it;
+ v.second = stack::get<V>(L, 3);
+ }
+ else {
+ src.insert(it, { std::move(*k), stack::get<V>(L, 3) });
+ }
+ }
+ return 0;
+ }
+
+ static int real_new_index_call(lua_State* L) {
+ return real_new_index_call_const(meta::neg<std::is_const<V>>(), L);
+ }
+
+ static int real_pairs_next_call(lua_State* L) {
+ using std::end;
+ iter& i = stack::get<user<iter>>(L, 1);
+ auto& source = i.source;
+ auto& it = i.it;
+ std::advance(it, 1);
+ if (it == end(source)) {
+ return 0;
+ }
+ return stack::multi_push_reference(L, it->first, it->second);
+ }
+
+ static int real_pairs_call(lua_State* L) {
+ auto& src = get_src(L);
+ using std::begin;
+ stack::push(L, pairs_next_call);
+ stack::push<user<iter>>(L, src, begin(src));
+ stack::push(L, 1);
+ return 3;
+ }
+
+ static int real_length_call(lua_State*L) {
+ auto& src = get_src(L);
+ return stack::push(L, src.size());
+ }
+
+ static int length_call(lua_State*L) {
+ return detail::static_trampoline<(&real_length_call)>(L);
+ }
+
+ static int pairs_next_call(lua_State*L) {
+ return detail::static_trampoline<(&real_pairs_next_call)>(L);
+ }
+
+ static int pairs_call(lua_State*L) {
+ return detail::static_trampoline<(&real_pairs_call)>(L);
+ }
+
+ static int index_call(lua_State*L) {
+ return detail::static_trampoline<(&real_index_call)>(L);
+ }
+
+ static int new_index_call(lua_State*L) {
+ return detail::static_trampoline<(&real_new_index_call)>(L);
+ }
+ };
+
+ namespace stack {
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<meta::all<meta::has_begin_end<T>, meta::neg<meta::any<std::is_base_of<reference, T>, std::is_base_of<stack_reference, T>>>>::value>> {
+ typedef container_usertype_metatable<T> cumt;
+ static int push(lua_State* L, const T& cont) {
+ auto fx = [&L]() {
+ const char* metakey = &usertype_traits<T>::metatable[0];
+ if (luaL_newmetatable(L, metakey) == 1) {
+ luaL_Reg reg[] = {
+ { "__index", &cumt::index_call },
+ { "__newindex", &cumt::new_index_call },
+ { "__pairs", &cumt::pairs_call },
+ { "__len", &cumt::length_call },
+ { "__gc", &detail::usertype_alloc_destroy<T> },
+ { nullptr, nullptr }
+ };
+ luaL_setfuncs(L, reg, 0);
+ }
+ lua_setmetatable(L, -2);
+ };
+ return pusher<detail::as_value_tag<T>>{}.push_fx(L, fx, cont);
+ }
+
+ static int push(lua_State* L, T&& cont) {
+ auto fx = [&L]() {
+ const char* metakey = &usertype_traits<T>::metatable[0];
+ if (luaL_newmetatable(L, metakey) == 1) {
+ luaL_Reg reg[] = {
+ { "__index", &cumt::index_call },
+ { "__newindex", &cumt::new_index_call },
+ { "__pairs", &cumt::pairs_call },
+ { "__len", &cumt::length_call },
+ { "__gc", &detail::usertype_alloc_destroy<T> },
+ { nullptr, nullptr }
+ };
+ luaL_setfuncs(L, reg, 0);
+ }
+ lua_setmetatable(L, -2);
+ };
+ return pusher<detail::as_value_tag<T>>{}.push_fx(L, fx, std::move(cont));
+ }
+ };
+
+ template<typename T>
+ struct pusher<T*, std::enable_if_t<meta::all<meta::has_begin_end<meta::unqualified_t<T>>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
+ typedef container_usertype_metatable<T> cumt;
+ static int push(lua_State* L, T* cont) {
+ auto fx = [&L]() {
+ const char* metakey = &usertype_traits<meta::unqualified_t<T>*>::metatable[0];
+ if (luaL_newmetatable(L, metakey) == 1) {
+ luaL_Reg reg[] = {
+ { "__index", &cumt::index_call },
+ { "__newindex", &cumt::new_index_call },
+ { "__pairs", &cumt::pairs_call },
+ { "__len", &cumt::length_call },
+ { nullptr, nullptr }
+ };
+ luaL_setfuncs(L, reg, 0);
+ }
+ lua_setmetatable(L, -2);
+ };
+ return pusher<detail::as_pointer_tag<T>>{}.push_fx(L, fx, cont);
+ }
+ };
+ } // stack
+
+} // sol
+
+#endif // SOL_CONTAINER_USERTYPE_HPP
diff --git a/3rdparty/sol2/sol/coroutine.hpp b/3rdparty/sol2/sol/coroutine.hpp
new file mode 100644
index 00000000000..4abfa78ec2a
--- /dev/null
+++ b/3rdparty/sol2/sol/coroutine.hpp
@@ -0,0 +1,119 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_COROUTINE_HPP
+#define SOL_COROUTINE_HPP
+
+#include "reference.hpp"
+#include "stack.hpp"
+#include "function_result.hpp"
+#include "thread.hpp"
+
+namespace sol {
+ class coroutine : public reference {
+ private:
+ call_status stats = call_status::yielded;
+
+ void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
+#if SOL_LUA_VERSION < 502
+ stats = static_cast<call_status>(lua_resume(lua_state(), static_cast<int>(argcount)));
+#else
+ stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount)));
+#endif // Lua 5.1 compat
+ }
+
+ template<std::size_t... I, typename... Ret>
+ auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) {
+ luacall(n, sizeof...(Ret));
+ return stack::pop<std::tuple<Ret...>>(lua_state());
+ }
+
+ template<std::size_t I, typename Ret>
+ Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) {
+ luacall(n, 1);
+ return stack::pop<Ret>(lua_state());
+ }
+
+ template <std::size_t I>
+ void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) {
+ luacall(n, 0);
+ }
+
+ protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) {
+ int stacksize = lua_gettop(lua_state());
+ int firstreturn = (std::max)(1, stacksize - static_cast<int>(n));
+ luacall(n, LUA_MULTRET);
+ int poststacksize = lua_gettop(lua_state());
+ int returncount = poststacksize - (firstreturn - 1);
+ if (error()) {
+ return protected_function_result(lua_state(), lua_absindex(lua_state(), -1), 1, returncount, status());
+ }
+ return protected_function_result(lua_state(), firstreturn, returncount, returncount, status());
+ }
+
+ public:
+ coroutine() noexcept = default;
+ coroutine(const coroutine&) noexcept = default;
+ coroutine& operator=(const coroutine&) noexcept = default;
+ coroutine(lua_State* L, int index = -1) : reference(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ stack::check<coroutine>(L, index, type_panic);
+#endif // Safety
+ }
+
+ call_status status() const noexcept {
+ return stats;
+ }
+
+ bool error() const noexcept {
+ call_status cs = status();
+ return cs != call_status::ok && cs != call_status::yielded;
+ }
+
+ bool runnable() const noexcept {
+ return valid()
+ && (status() == call_status::yielded);
+ }
+
+ explicit operator bool() const noexcept {
+ return runnable();
+ }
+
+ template<typename... Args>
+ protected_function_result operator()(Args&&... args) {
+ return call<>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) operator()(types<Ret...>, Args&&... args) {
+ return call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) {
+ push();
+ int pushcount = stack::multi_push(lua_state(), std::forward<Args>(args)...);
+ return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
+ }
+ };
+} // sol
+
+#endif // SOL_COUROUTINE_HPP
diff --git a/3rdparty/sol2/sol/debug.hpp b/3rdparty/sol2/sol/debug.hpp
new file mode 100644
index 00000000000..1219484df3b
--- /dev/null
+++ b/3rdparty/sol2/sol/debug.hpp
@@ -0,0 +1,54 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_DEBUG_HPP
+#define SOL_DEBUG_HPP
+
+#include "stack.hpp"
+#include <iostream>
+
+namespace sol {
+ namespace detail {
+ namespace debug {
+ inline std::string dump_types(lua_State* L) {
+ std::string visual;
+ std::size_t size = lua_gettop(L) + 1;
+ for (std::size_t i = 1; i < size; ++i) {
+ if (i != 1) {
+ visual += " | ";
+ }
+ visual += type_name(L, stack::get<type>(L, static_cast<int>(i)));
+ }
+ return visual;
+ }
+
+ inline void print_stack(lua_State* L) {
+ std::cout << dump_types(L) << std::endl;
+ }
+
+ inline void print_section(const std::string& message, lua_State* L) {
+ std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl;
+ }
+ } // detail
+ } // debug
+} // sol
+
+#endif // SOL_DEBUG_HPP
diff --git a/3rdparty/sol2/sol/demangle.hpp b/3rdparty/sol2/sol/demangle.hpp
new file mode 100644
index 00000000000..2d3bc518aeb
--- /dev/null
+++ b/3rdparty/sol2/sol/demangle.hpp
@@ -0,0 +1,158 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_DEMANGLE_HPP
+#define SOL_DEMANGLE_HPP
+
+#include <string>
+#include <array>
+#include <cctype>
+
+namespace sol {
+ namespace detail {
+#ifdef _MSC_VER
+ template <typename T>
+ inline std::string ctti_get_type_name() {
+ const static std::array<std::string, 7> removals = { { "public:", "private:", "protected:", "struct ", "class ", "`anonymous-namespace'", "`anonymous namespace'" } };
+ std::string name = __FUNCSIG__;
+ std::size_t start = name.find("get_type_name");
+ if (start == std::string::npos)
+ start = 0;
+ else
+ start += 13;
+ if (start < name.size() - 1)
+ start += 1;
+ std::size_t end = name.find_last_of('>');
+ if (end == std::string::npos)
+ end = name.size();
+ name = name.substr(start, end - start);
+ if (name.find("struct", 0) == 0)
+ name.replace(0, 6, "", 0);
+ if (name.find("class", 0) == 0)
+ name.replace(0, 5, "", 0);
+ while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
+ while (!name.empty() && std::isblank(name.back())) name.pop_back();
+
+ for (std::size_t r = 0; r < removals.size(); ++r) {
+ auto found = name.find(removals[r]);
+ while (found != std::string::npos) {
+ name.erase(found, removals[r].size());
+ found = name.find(removals[r]);
+ }
+ }
+
+ return name;
+ }
+#elif defined(__GNUC__) || defined(__clang__)
+ template <typename T, class seperator_mark = int>
+ inline std::string ctti_get_type_name() {
+ const static std::array<std::string, 2> removals = { { "{anonymous}", "(anonymous namespace)" } };
+ std::string name = __PRETTY_FUNCTION__;
+ std::size_t start = name.find_first_of('[');
+ start = name.find_first_of('=', start);
+ std::size_t end = name.find_last_of(']');
+ if (end == std::string::npos)
+ end = name.size();
+ if (start == std::string::npos)
+ start = 0;
+ if (start < name.size() - 1)
+ start += 1;
+ name = name.substr(start, end - start);
+ start = name.rfind("seperator_mark");
+ if (start != std::string::npos) {
+ name.erase(start - 2, name.length());
+ }
+ while (!name.empty() && std::isblank(name.front())) name.erase(name.begin());
+ while (!name.empty() && std::isblank(name.back())) name.pop_back();
+
+ for (std::size_t r = 0; r < removals.size(); ++r) {
+ auto found = name.find(removals[r]);
+ while (found != std::string::npos) {
+ name.erase(found, removals[r].size());
+ found = name.find(removals[r]);
+ }
+ }
+
+ return name;
+ }
+#else
+#error Compiler not supported for demangling
+#endif // compilers
+
+ template <typename T>
+ inline std::string demangle_once() {
+ std::string realname = ctti_get_type_name<T>();
+ return realname;
+ }
+
+ template <typename T>
+ inline std::string short_demangle_once() {
+ std::string realname = ctti_get_type_name<T>();
+ // This isn't the most complete but it'll do for now...?
+ static const std::array<std::string, 10> ops = { { "operator<", "operator<<", "operator<<=", "operator<=", "operator>", "operator>>", "operator>>=", "operator>=", "operator->", "operator->*" } };
+ int level = 0;
+ std::ptrdiff_t idx = 0;
+ for (idx = static_cast<std::ptrdiff_t>(realname.empty() ? 0 : realname.size() - 1); idx > 0; --idx) {
+ if (level == 0 && realname[idx] == ':') {
+ break;
+ }
+ bool isleft = realname[idx] == '<';
+ bool isright = realname[idx] == '>';
+ if (!isleft && !isright)
+ continue;
+ bool earlybreak = false;
+ for (const auto& op : ops) {
+ std::size_t nisop = realname.rfind(op, idx);
+ if (nisop == std::string::npos)
+ continue;
+ std::size_t nisopidx = idx - op.size() + 1;
+ if (nisop == nisopidx) {
+ idx = static_cast<std::ptrdiff_t>(nisopidx);
+ earlybreak = true;
+ }
+ break;
+ }
+ if (earlybreak) {
+ continue;
+ }
+ level += isleft ? -1 : 1;
+ }
+ if (idx > 0) {
+ realname.erase(0, realname.length() < static_cast<std::size_t>(idx) ? realname.length() : idx + 1);
+ }
+ return realname;
+ }
+
+ template <typename T>
+ inline std::string demangle() {
+ static const std::string d = demangle_once<T>();
+ return d;
+ }
+
+ template <typename T>
+ inline std::string short_demangle() {
+ static const std::string d = short_demangle_once<T>();
+ return d;
+ }
+ } // detail
+} // sol
+
+#endif // SOL_DEMANGLE_HPP
diff --git a/3rdparty/sol2/sol/deprecate.hpp b/3rdparty/sol2/sol/deprecate.hpp
new file mode 100644
index 00000000000..0d9551a33b0
--- /dev/null
+++ b/3rdparty/sol2/sol/deprecate.hpp
@@ -0,0 +1,44 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_DEPRECATE_HPP
+#define SOL_DEPRECATE_HPP
+
+#ifndef SOL_DEPRECATED
+ #ifdef _MSC_VER
+ #define SOL_DEPRECATED __declspec(deprecated)
+ #elif __GNUC__
+ #define SOL_DEPRECATED __attribute__((deprecated))
+ #else
+ #define SOL_DEPRECATED [[deprecated]]
+ #endif // compilers
+#endif // SOL_DEPRECATED
+
+namespace sol {
+ namespace detail {
+ template <typename T>
+ struct SOL_DEPRECATED deprecate_type {
+ using type = T;
+ };
+ } // detail
+} // sol
+
+#endif // SOL_DEPRECATE_HPP
diff --git a/3rdparty/sol2/sol/error.hpp b/3rdparty/sol2/sol/error.hpp
new file mode 100644
index 00000000000..0458e0a5f65
--- /dev/null
+++ b/3rdparty/sol2/sol/error.hpp
@@ -0,0 +1,55 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_ERROR_HPP
+#define SOL_ERROR_HPP
+
+#include <stdexcept>
+#include <string>
+
+namespace sol {
+ namespace detail {
+ struct direct_error_tag {};
+ const auto direct_error = direct_error_tag{};
+ } // detail
+
+ class error : public std::runtime_error {
+ private:
+ // Because VC++ is a fuccboi
+ std::string w;
+ public:
+ error(const std::string& str) : error(detail::direct_error, "lua: error: " + str) {}
+ error(detail::direct_error_tag, const std::string& str) : std::runtime_error(""), w(str) {}
+ error(detail::direct_error_tag, std::string&& str) : std::runtime_error(""), w(std::move(str)) {}
+
+ error(const error& e) = default;
+ error(error&& e) = default;
+ error& operator=(const error& e) = default;
+ error& operator=(error&& e) = default;
+
+ virtual const char* what() const noexcept override {
+ return w.c_str();
+ }
+ };
+
+} // sol
+
+#endif // SOL_ERROR_HPP
diff --git a/3rdparty/sol2/sol/function.hpp b/3rdparty/sol2/sol/function.hpp
new file mode 100644
index 00000000000..1ec9afb1104
--- /dev/null
+++ b/3rdparty/sol2/sol/function.hpp
@@ -0,0 +1,151 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_FUNCTION_HPP
+#define SOL_FUNCTION_HPP
+
+#include "reference.hpp"
+#include "stack.hpp"
+#include "function_result.hpp"
+#include "function_types.hpp"
+#include <cstdint>
+#include <functional>
+#include <memory>
+
+namespace sol {
+ template <typename base_t>
+ class basic_function : public base_t {
+ private:
+ void luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount) const {
+ lua_callk(base_t::lua_state(), static_cast<int>(argcount), static_cast<int>(resultcount), 0, nullptr);
+ }
+
+ template<std::size_t... I, typename... Ret>
+ auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) const {
+ luacall(n, lua_size<std::tuple<Ret...>>::value);
+ return stack::pop<std::tuple<Ret...>>(base_t::lua_state());
+ }
+
+ template<std::size_t I, typename Ret>
+ Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) const {
+ luacall(n, lua_size<Ret>::value);
+ return stack::pop<Ret>(base_t::lua_state());
+ }
+
+ template <std::size_t I>
+ void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) const {
+ luacall(n, 0);
+ }
+
+ function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) const {
+ int stacksize = lua_gettop(base_t::lua_state());
+ int firstreturn = (std::max)(1, stacksize - static_cast<int>(n));
+ luacall(n, LUA_MULTRET);
+ int poststacksize = lua_gettop(base_t::lua_state());
+ int returncount = poststacksize - (firstreturn - 1);
+ return function_result(base_t::lua_state(), firstreturn, returncount);
+ }
+
+ public:
+ basic_function() = default;
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_function>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_function(T&& r) noexcept : base_t(std::forward<T>(r)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!is_function<meta::unqualified_t<T>>::value) {
+ auto pp = stack::push_pop(*this);
+ stack::check<basic_function>(base_t::lua_state(), -1, type_panic);
+ }
+#endif // Safety
+ }
+ basic_function(const basic_function&) = default;
+ basic_function& operator=(const basic_function&) = default;
+ basic_function(basic_function&&) = default;
+ basic_function& operator=(basic_function&&) = default;
+ basic_function(const stack_reference& r) : basic_function(r.lua_state(), r.stack_index()) {}
+ basic_function(stack_reference&& r) : basic_function(r.lua_state(), r.stack_index()) {}
+ basic_function(lua_State* L, int index = -1) : base_t(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ stack::check<basic_function>(L, index, type_panic);
+#endif // Safety
+ }
+
+ template<typename... Args>
+ function_result operator()(Args&&... args) const {
+ return call<>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) operator()(types<Ret...>, Args&&... args) const {
+ return call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) const {
+ base_t::push();
+ int pushcount = stack::multi_push_reference(base_t::lua_state(), std::forward<Args>(args)...);
+ return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
+ }
+ };
+
+ namespace stack {
+ template<typename Signature>
+ struct getter<std::function<Signature>> {
+ typedef meta::bind_traits<Signature> fx_t;
+ typedef typename fx_t::args_list args_lists;
+ typedef meta::tuple_types<typename fx_t::return_type> return_types;
+
+ template<typename... Args, typename... Ret>
+ static std::function<Signature> get_std_func(types<Ret...>, types<Args...>, lua_State* L, int index) {
+ sol::function f(L, index);
+ auto fx = [f, L, index](Args&&... args) -> meta::return_type_t<Ret...> {
+ return f.call<Ret...>(std::forward<Args>(args)...);
+ };
+ return std::move(fx);
+ }
+
+ template<typename... FxArgs>
+ static std::function<Signature> get_std_func(types<void>, types<FxArgs...>, lua_State* L, int index) {
+ sol::function f(L, index);
+ auto fx = [f, L, index](FxArgs&&... args) -> void {
+ f(std::forward<FxArgs>(args)...);
+ };
+ return std::move(fx);
+ }
+
+ template<typename... FxArgs>
+ static std::function<Signature> get_std_func(types<>, types<FxArgs...> t, lua_State* L, int index) {
+ return get_std_func(types<void>(), t, L, index);
+ }
+
+ static std::function<Signature> get(lua_State* L, int index, record& tracking) {
+ tracking.last = 1;
+ tracking.used += 1;
+ type t = type_of(L, index);
+ if (t == type::none || t == type::nil) {
+ return nullptr;
+ }
+ return get_std_func(return_types(), args_lists(), L, index);
+ }
+ };
+ } // stack
+} // sol
+
+#endif // SOL_FUNCTION_HPP
diff --git a/3rdparty/sol2/sol/function_result.hpp b/3rdparty/sol2/sol/function_result.hpp
new file mode 100644
index 00000000000..e7c0e6c1e99
--- /dev/null
+++ b/3rdparty/sol2/sol/function_result.hpp
@@ -0,0 +1,88 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_FUNCTION_RESULT_HPP
+#define SOL_FUNCTION_RESULT_HPP
+
+#include "reference.hpp"
+#include "tuple.hpp"
+#include "stack.hpp"
+#include "proxy_base.hpp"
+#include <cstdint>
+
+namespace sol {
+ struct function_result : public proxy_base<function_result> {
+ private:
+ lua_State* L;
+ int index;
+ int returncount;
+
+ public:
+ function_result() = default;
+ function_result(lua_State* L, int index = -1, int returncount = 0) : L(L), index(index), returncount(returncount) {
+
+ }
+ function_result(const function_result&) = default;
+ function_result& operator=(const function_result&) = default;
+ function_result(function_result&& o) : L(o.L), index(o.index), returncount(o.returncount) {
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ }
+ function_result& operator=(function_result&& o) {
+ L = o.L;
+ index = o.index;
+ returncount = o.returncount;
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ return *this;
+ }
+
+ template<typename T>
+ decltype(auto) get() const {
+ return stack::get<T>(L, index);
+ }
+
+ call_status status() const noexcept {
+ return call_status::ok;
+ }
+
+ bool valid() const noexcept {
+ return status() == call_status::ok || status() == call_status::yielded;
+ }
+
+ lua_State* lua_state() const { return L; };
+ int stack_index() const { return index; };
+
+ ~function_result() {
+ lua_pop(L, returncount);
+ }
+ };
+} // sol
+
+#endif // SOL_FUNCTION_RESULT_HPP
diff --git a/3rdparty/sol2/sol/function_types.hpp b/3rdparty/sol2/sol/function_types.hpp
new file mode 100644
index 00000000000..7c76b8d6ed0
--- /dev/null
+++ b/3rdparty/sol2/sol/function_types.hpp
@@ -0,0 +1,342 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_FUNCTION_TYPES_HPP
+#define SOL_FUNCTION_TYPES_HPP
+
+#include "function_types_core.hpp"
+#include "function_types_templated.hpp"
+#include "function_types_stateless.hpp"
+#include "function_types_stateful.hpp"
+#include "function_types_overloaded.hpp"
+#include "resolve.hpp"
+#include "call.hpp"
+
+namespace sol {
+ namespace stack {
+ template<typename... Sigs>
+ struct pusher<function_sig<Sigs...>> {
+ template <typename... Sig, typename Fx, typename... Args>
+ static void select_convertible(std::false_type, types<Sig...>, lua_State* L, Fx&& fx, Args&&... args) {
+ typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
+ typedef function_detail::functor_function<clean_fx> F;
+ set_fx<F>(L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename R, typename... A, typename Fx, typename... Args>
+ static void select_convertible(std::true_type, types<R(A...)>, lua_State* L, Fx&& fx, Args&&... args) {
+ using fx_ptr_t = R(*)(A...);
+ fx_ptr_t fxptr = detail::unwrap(std::forward<Fx>(fx));
+ select_function(std::true_type(), L, fxptr, std::forward<Args>(args)...);
+ }
+
+ template <typename R, typename... A, typename Fx, typename... Args>
+ static void select_convertible(types<R(A...)> t, lua_State* L, Fx&& fx, Args&&... args) {
+ typedef std::decay_t<meta::unwrap_unqualified_t<Fx>> raw_fx_t;
+ typedef R(*fx_ptr_t)(A...);
+ typedef std::is_convertible<raw_fx_t, fx_ptr_t> is_convertible;
+ select_convertible(is_convertible(), t, L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename... Args>
+ static void select_convertible(types<>, lua_State* L, Fx&& fx, Args&&... args) {
+ typedef meta::function_signature_t<meta::unwrap_unqualified_t<Fx>> Sig;
+ select_convertible(types<Sig>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_reference_member_variable(std::false_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef std::remove_pointer_t<std::decay_t<Fx>> clean_fx;
+ typedef function_detail::member_variable<meta::unwrap_unqualified_t<T>, clean_fx> F;
+ set_fx<F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_reference_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef std::decay_t<Fx> dFx;
+ dFx memfxptr(std::forward<Fx>(fx));
+ auto userptr = detail::ptr(std::forward<T>(obj), std::forward<Args>(args)...);
+ lua_CFunction freefunc = &function_detail::upvalue_member_variable<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>>::call;
+
+ int upvalues = stack::stack_detail::push_as_upvalues(L, memfxptr);
+ upvalues += stack::push(L, lightuserdata_value(static_cast<void*>(userptr)));
+ stack::push(L, c_closure(freefunc, upvalues));
+ }
+
+ template <typename Fx, typename... Args>
+ static void select_member_variable(std::false_type, lua_State* L, Fx&& fx, Args&&... args) {
+ select_convertible(types<Sigs...>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_member_variable(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef meta::boolean<meta::is_specialization_of<std::reference_wrapper, meta::unqualified_t<T>>::value || std::is_pointer<T>::value> is_reference;
+ select_reference_member_variable(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx>
+ static void select_member_variable(std::true_type, lua_State* L, Fx&& fx) {
+ typedef typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type C;
+ lua_CFunction freefunc = &function_detail::upvalue_this_member_variable<C, Fx>::call;
+ int upvalues = stack::stack_detail::push_as_upvalues(L, fx);
+ stack::push(L, c_closure(freefunc, upvalues));
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_reference_member_function(std::false_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef std::decay_t<Fx> clean_fx;
+ typedef function_detail::member_function<meta::unwrap_unqualified_t<T>, clean_fx> F;
+ set_fx<F>(L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_reference_member_function(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef std::decay_t<Fx> dFx;
+ dFx memfxptr(std::forward<Fx>(fx));
+ auto userptr = detail::ptr(std::forward<T>(obj), std::forward<Args>(args)...);
+ lua_CFunction freefunc = &function_detail::upvalue_member_function<std::decay_t<decltype(*userptr)>, meta::unqualified_t<Fx>>::call;
+
+ int upvalues = stack::stack_detail::push_as_upvalues(L, memfxptr);
+ upvalues += stack::push(L, lightuserdata_value(static_cast<void*>(userptr)));
+ stack::push(L, c_closure(freefunc, upvalues));
+ }
+
+ template <typename Fx, typename... Args>
+ static void select_member_function(std::false_type, lua_State* L, Fx&& fx, Args&&... args) {
+ select_member_variable(std::is_member_object_pointer<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename T, typename... Args>
+ static void select_member_function(std::true_type, lua_State* L, Fx&& fx, T&& obj, Args&&... args) {
+ typedef meta::boolean<meta::is_specialization_of<std::reference_wrapper, meta::unqualified_t<T>>::value || std::is_pointer<T>::value> is_reference;
+ select_reference_member_function(is_reference(), L, std::forward<Fx>(fx), std::forward<T>(obj), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx>
+ static void select_member_function(std::true_type, lua_State* L, Fx&& fx) {
+ typedef typename meta::bind_traits<meta::unqualified_t<Fx>>::object_type C;
+ lua_CFunction freefunc = &function_detail::upvalue_this_member_function<C, Fx>::call;
+ int upvalues = stack::stack_detail::push_as_upvalues(L, fx);
+ stack::push(L, c_closure(freefunc, upvalues));
+ }
+
+ template <typename Fx, typename... Args>
+ static void select_function(std::false_type, lua_State* L, Fx&& fx, Args&&... args) {
+ select_member_function(std::is_member_function_pointer<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename... Args>
+ static void select_function(std::true_type, lua_State* L, Fx&& fx, Args&&... args) {
+ std::decay_t<Fx> target(std::forward<Fx>(fx), std::forward<Args>(args)...);
+ lua_CFunction freefunc = &function_detail::upvalue_free_function<Fx>::call;
+
+ int upvalues = stack::stack_detail::push_as_upvalues(L, target);
+ stack::push(L, c_closure(freefunc, upvalues));
+ }
+
+ static void select_function(std::true_type, lua_State* L, lua_CFunction f) {
+ stack::push(L, f);
+ }
+
+ template <typename Fx, typename... Args>
+ static void select(lua_State* L, Fx&& fx, Args&&... args) {
+ select_function(std::is_function<meta::unqualified_t<Fx>>(), L, std::forward<Fx>(fx), std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename... Args>
+ static void set_fx(lua_State* L, Args&&... args) {
+ lua_CFunction freefunc = function_detail::call<meta::unqualified_t<Fx>>;
+
+ stack::push<user<Fx>>(L, std::forward<Args>(args)...);
+ stack::push(L, c_closure(freefunc, 1));
+ }
+
+ template<typename... Args>
+ static int push(lua_State* L, Args&&... args) {
+ // Set will always place one thing (function) on the stack
+ select(L, std::forward<Args>(args)...);
+ return 1;
+ }
+ };
+
+ template<typename T, typename... Args>
+ struct pusher<function_arguments<T, Args...>> {
+ template <std::size_t... I, typename FP>
+ static int push_func(std::index_sequence<I...>, lua_State* L, FP&& fp) {
+ return stack::push<T>(L, detail::forward_get<I>(fp.arguments)...);
+ }
+
+ static int push(lua_State* L, const function_arguments<T, Args...>& fp) {
+ return push_func(std::make_index_sequence<sizeof...(Args)>(), L, fp);
+ }
+
+ static int push(lua_State* L, function_arguments<T, Args...>&& fp) {
+ return push_func(std::make_index_sequence<sizeof...(Args)>(), L, std::move(fp));
+ }
+ };
+
+ template<typename Signature>
+ struct pusher<std::function<Signature>> {
+ static int push(lua_State* L, std::function<Signature> fx) {
+ return pusher<function_sig<Signature>>{}.push(L, std::move(fx));
+ }
+ };
+
+ template<typename Signature>
+ struct pusher<Signature, std::enable_if_t<std::is_member_pointer<Signature>::value>> {
+ template <typename F>
+ static int push(lua_State* L, F&& f) {
+ return pusher<function_sig<>>{}.push(L, std::forward<F>(f));
+ }
+ };
+
+ template<typename Signature>
+ struct pusher<Signature, std::enable_if_t<meta::all<std::is_function<Signature>, meta::neg<std::is_same<Signature, lua_CFunction>>, meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>>::value>> {
+ template <typename F>
+ static int push(lua_State* L, F&& f) {
+ return pusher<function_sig<>>{}.push(L, std::forward<F>(f));
+ }
+ };
+
+ template<typename... Functions>
+ struct pusher<overload_set<Functions...>> {
+ static int push(lua_State* L, overload_set<Functions...>&& set) {
+ typedef function_detail::overloaded_function<Functions...> F;
+ pusher<function_sig<>>{}.set_fx<F>(L, std::move(set.functions));
+ return 1;
+ }
+
+ static int push(lua_State* L, const overload_set<Functions...>& set) {
+ typedef function_detail::overloaded_function<Functions...> F;
+ pusher<function_sig<>>{}.set_fx<F>(L, set.functions);
+ return 1;
+ }
+ };
+
+ template <typename T>
+ struct pusher<protect_t<T>> {
+ static int push(lua_State* L, protect_t<T>&& pw) {
+ lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>>;
+ int closures = stack::push<user<protect_t<T>>>(L, std::move(pw.value));
+ return stack::push(L, c_closure(cf, closures));
+ }
+
+ static int push(lua_State* L, const protect_t<T>& pw) {
+ lua_CFunction cf = call_detail::call_user<void, false, false, protect_t<T>>;
+ int closures = stack::push<user<protect_t<T>>>(L, pw.value);
+ return stack::push(L, c_closure(cf, closures));
+ }
+ };
+
+ template <typename F, typename G>
+ struct pusher<property_wrapper<F, G>, std::enable_if_t<!std::is_void<F>::value && !std::is_void<G>::value>> {
+ static int push(lua_State* L, property_wrapper<F, G>&& pw) {
+ return stack::push(L, sol::overload(std::move(pw.read), std::move(pw.write)));
+ }
+ static int push(lua_State* L, const property_wrapper<F, G>& pw) {
+ return stack::push(L, sol::overload(pw.read, pw.write));
+ }
+ };
+
+ template <typename F>
+ struct pusher<property_wrapper<F, void>> {
+ static int push(lua_State* L, property_wrapper<F, void>&& pw) {
+ return stack::push(L, std::move(pw.read));
+ }
+ static int push(lua_State* L, const property_wrapper<F, void>& pw) {
+ return stack::push(L, pw.read);
+ }
+ };
+
+ template <typename F>
+ struct pusher<property_wrapper<void, F>> {
+ static int push(lua_State* L, property_wrapper<void, F>&& pw) {
+ return stack::push(L, std::move(pw.write));
+ }
+ static int push(lua_State* L, const property_wrapper<void, F>& pw) {
+ return stack::push(L, pw.write);
+ }
+ };
+
+ template <typename T>
+ struct pusher<var_wrapper<T>> {
+ static int push(lua_State* L, var_wrapper<T>&& vw) {
+ return stack::push(L, std::move(vw.value));
+ }
+ static int push(lua_State* L, const var_wrapper<T>& vw) {
+ return stack::push(L, vw.value);
+ }
+ };
+
+ template <typename... Functions>
+ struct pusher<factory_wrapper<Functions...>> {
+ static int push(lua_State* L, const factory_wrapper<Functions...>& fw) {
+ typedef function_detail::overloaded_function<Functions...> F;
+ pusher<function_sig<>>{}.set_fx<F>(L, fw.functions);
+ return 1;
+ }
+
+ static int push(lua_State* L, factory_wrapper<Functions...>&& fw) {
+ typedef function_detail::overloaded_function<Functions...> F;
+ pusher<function_sig<>>{}.set_fx<F>(L, std::move(fw.functions));
+ return 1;
+ }
+ };
+
+ template <typename T, typename... Lists>
+ struct pusher<detail::tagged<T, constructor_list<Lists...>>> {
+ static int push(lua_State* L, detail::tagged<T, constructor_list<Lists...>>) {
+ lua_CFunction cf = call_detail::construct<T, Lists...>;
+ return stack::push(L, cf);
+ }
+ };
+
+ template <typename T, typename... Fxs>
+ struct pusher<detail::tagged<T, constructor_wrapper<Fxs...>>> {
+ template <typename C>
+ static int push(lua_State* L, C&& c) {
+ lua_CFunction cf = call_detail::call_user<T, false, false, constructor_wrapper<Fxs...>>;
+ int closures = stack::push<user<constructor_wrapper<Fxs...>>>(L, std::forward<C>(c));
+ return stack::push(L, c_closure(cf, closures));
+ }
+ };
+
+ template <typename T>
+ struct pusher<detail::tagged<T, destructor_wrapper<void>>> {
+ static int push(lua_State* L, destructor_wrapper<void>) {
+ lua_CFunction cf = detail::usertype_alloc_destroy<T>;
+ return stack::push(L, cf);
+ }
+ };
+
+ template <typename T, typename Fx>
+ struct pusher<detail::tagged<T, destructor_wrapper<Fx>>> {
+ static int push(lua_State* L, destructor_wrapper<Fx> c) {
+ lua_CFunction cf = call_detail::call_user<T, false, false, destructor_wrapper<Fx>>;
+ int closures = stack::push<user<T>>(L, std::move(c));
+ return stack::push(L, c_closure(cf, closures));
+ }
+ };
+
+ } // stack
+} // sol
+
+#endif // SOL_FUNCTION_TYPES_HPP
diff --git a/3rdparty/sol2/sol/function_types_core.hpp b/3rdparty/sol2/sol/function_types_core.hpp
new file mode 100644
index 00000000000..24169ea7faf
--- /dev/null
+++ b/3rdparty/sol2/sol/function_types_core.hpp
@@ -0,0 +1,39 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_FUNCTION_TYPES_CORE_HPP
+#define SOL_FUNCTION_TYPES_CORE_HPP
+
+#include "stack.hpp"
+#include "wrapper.hpp"
+#include <memory>
+
+namespace sol {
+ namespace function_detail {
+ template <typename Fx>
+ inline int call(lua_State* L) {
+ Fx& fx = stack::get<user<Fx>>(L, upvalue_index(1));
+ return fx(L);
+ }
+ } // function_detail
+} // sol
+
+#endif // SOL_FUNCTION_TYPES_CORE_HPP
diff --git a/3rdparty/sol2/sol/function_types_overloaded.hpp b/3rdparty/sol2/sol/function_types_overloaded.hpp
new file mode 100644
index 00000000000..cfcfdebec68
--- /dev/null
+++ b/3rdparty/sol2/sol/function_types_overloaded.hpp
@@ -0,0 +1,59 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_FUNCTION_TYPES_OVERLOAD_HPP
+#define SOL_FUNCTION_TYPES_OVERLOAD_HPP
+
+#include "overload.hpp"
+#include "call.hpp"
+#include "function_types_core.hpp"
+
+namespace sol {
+ namespace function_detail {
+ template <typename... Functions>
+ struct overloaded_function {
+ typedef std::tuple<Functions...> overload_list;
+ typedef std::make_index_sequence<sizeof...(Functions)> indices;
+ overload_list overloads;
+
+ overloaded_function(overload_list set)
+ : overloads(std::move(set)) {}
+
+ overloaded_function(Functions... fxs)
+ : overloads(fxs...) {
+
+ }
+
+ template <typename Fx, std::size_t I, typename... R, typename... Args>
+ int call(types<Fx>, index_value<I>, types<R...>, types<Args...>, lua_State* L, int, int) {
+ auto& func = std::get<I>(overloads);
+ return call_detail::call_wrapped<void, true, false>(L, func);
+ }
+
+ int operator()(lua_State* L) {
+ auto mfx = [&](auto&&... args) { return this->call(std::forward<decltype(args)>(args)...); };
+ return call_detail::overload_match<Functions...>(mfx, L, 1);
+ }
+ };
+ } // function_detail
+} // sol
+
+#endif // SOL_FUNCTION_TYPES_OVERLOAD_HPP \ No newline at end of file
diff --git a/3rdparty/sol2/sol/function_types_stateful.hpp b/3rdparty/sol2/sol/function_types_stateful.hpp
new file mode 100644
index 00000000000..6846ed87474
--- /dev/null
+++ b/3rdparty/sol2/sol/function_types_stateful.hpp
@@ -0,0 +1,103 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_FUNCTION_TYPES_STATEFUL_HPP
+#define SOL_FUNCTION_TYPES_STATEFUL_HPP
+
+#include "function_types_core.hpp"
+
+namespace sol {
+ namespace function_detail {
+ template<typename Func>
+ struct functor_function {
+ typedef meta::unwrapped_t<meta::unqualified_t<Func>> Function;
+ typedef decltype(&Function::operator()) function_type;
+ typedef meta::function_return_t<function_type> return_type;
+ typedef meta::function_args_t<function_type> args_lists;
+ Function fx;
+
+ template<typename... Args>
+ functor_function(Function f, Args&&... args) : fx(std::move(f), std::forward<Args>(args)...) {}
+
+ int call(lua_State* L) {
+ return call_detail::call_wrapped<void, true, false>(L, fx);
+ }
+
+ int operator()(lua_State* L) {
+ auto f = [&](lua_State* L) -> int { return this->call(L); };
+ return detail::trampoline(L, f);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct member_function {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef meta::function_return_t<function_type> return_type;
+ typedef meta::function_args_t<function_type> args_lists;
+ function_type invocation;
+ T member;
+
+ template<typename... Args>
+ member_function(function_type f, Args&&... args) : invocation(std::move(f)), member(std::forward<Args>(args)...) {}
+
+ int call(lua_State* L) {
+ return call_detail::call_wrapped<T, true, false, -1>(L, invocation, detail::unwrap(detail::deref(member)));
+ }
+
+ int operator()(lua_State* L) {
+ auto f = [&](lua_State* L) -> int { return this->call(L); };
+ return detail::trampoline(L, f);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct member_variable {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef typename meta::bind_traits<function_type>::return_type return_type;
+ typedef typename meta::bind_traits<function_type>::args_list args_lists;
+ function_type var;
+ T member;
+ typedef std::add_lvalue_reference_t<meta::unwrapped_t<std::remove_reference_t<decltype(detail::deref(member))>>> M;
+
+ template<typename... Args>
+ member_variable(function_type v, Args&&... args) : var(std::move(v)), member(std::forward<Args>(args)...) {}
+
+ int call(lua_State* L) {
+ M mem = detail::unwrap(detail::deref(member));
+ switch (lua_gettop(L)) {
+ case 0:
+ return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
+ case 1:
+ return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
+ default:
+ return luaL_error(L, "sol: incorrect number of arguments to member variable function");
+ }
+ }
+
+ int operator()(lua_State* L) {
+ auto f = [&](lua_State* L) -> int { return this->call(L); };
+ return detail::trampoline(L, f);
+ }
+ };
+ } // function_detail
+} // sol
+
+#endif // SOL_FUNCTION_TYPES_STATEFUL_HPP
diff --git a/3rdparty/sol2/sol/function_types_stateless.hpp b/3rdparty/sol2/sol/function_types_stateless.hpp
new file mode 100644
index 00000000000..0b6e9072ddd
--- /dev/null
+++ b/3rdparty/sol2/sol/function_types_stateless.hpp
@@ -0,0 +1,163 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_FUNCTION_TYPES_STATELESS_HPP
+#define SOL_FUNCTION_TYPES_STATELESS_HPP
+
+#include "stack.hpp"
+
+namespace sol {
+ namespace function_detail {
+ template<typename Function>
+ struct upvalue_free_function {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef lua_bind_traits<function_type> traits_type;
+
+ static int real_call(lua_State* L) {
+ auto udata = stack::stack_detail::get_as_upvalues<function_type*>(L);
+ function_type* fx = udata.first;
+ return call_detail::call_wrapped<void, true, false>(L, fx);
+ }
+
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call)>(L);
+ }
+
+ int operator()(lua_State* L) {
+ return call(L);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct upvalue_member_function {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef lua_bind_traits<function_type> traits_type;
+
+ static int real_call(lua_State* L) {
+ // Layout:
+ // idx 1...n: verbatim data of member function pointer
+ // idx n + 1: is the object's void pointer
+ // We don't need to store the size, because the other side is templated
+ // with the same member function pointer type
+ auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
+ auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
+ function_type& memfx = memberdata.first;
+ auto& item = *objdata.first;
+ return call_detail::call_wrapped<T, true, false, -1>(L, memfx, item);
+ }
+
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call)>(L);
+ }
+
+ int operator()(lua_State* L) {
+ return call(L);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct upvalue_member_variable {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef lua_bind_traits<function_type> traits_type;
+
+ static int real_call(lua_State* L) {
+ // Layout:
+ // idx 1...n: verbatim data of member variable pointer
+ // idx n + 1: is the object's void pointer
+ // We don't need to store the size, because the other side is templated
+ // with the same member function pointer type
+ auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
+ auto objdata = stack::stack_detail::get_as_upvalues<T*>(L, memberdata.second);
+ auto& mem = *objdata.first;
+ function_type& var = memberdata.first;
+ switch (lua_gettop(L)) {
+ case 0:
+ return call_detail::call_wrapped<T, true, false, -1>(L, var, mem);
+ case 1:
+ return call_detail::call_wrapped<T, false, false, -1>(L, var, mem);
+ default:
+ return luaL_error(L, "sol: incorrect number of arguments to member variable function");
+ }
+ }
+
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call)>(L);
+ }
+
+ int operator()(lua_State* L) {
+ return call(L);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct upvalue_this_member_function {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef lua_bind_traits<function_type> traits_type;
+
+ static int real_call(lua_State* L) {
+ // Layout:
+ // idx 1...n: verbatim data of member variable pointer
+ auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
+ function_type& memfx = memberdata.first;
+ return call_detail::call_wrapped<T, false, false>(L, memfx);
+ }
+
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call)>(L);
+ }
+
+ int operator()(lua_State* L) {
+ return call(L);
+ }
+ };
+
+ template<typename T, typename Function>
+ struct upvalue_this_member_variable {
+ typedef std::remove_pointer_t<std::decay_t<Function>> function_type;
+ typedef lua_bind_traits<function_type> traits_type;
+
+ static int real_call(lua_State* L) {
+ // Layout:
+ // idx 1...n: verbatim data of member variable pointer
+ auto memberdata = stack::stack_detail::get_as_upvalues<function_type>(L, 1);
+ function_type& var = memberdata.first;
+ switch (lua_gettop(L)) {
+ case 1:
+ return call_detail::call_wrapped<T, true, false>(L, var);
+ case 2:
+ return call_detail::call_wrapped<T, false, false>(L, var);
+ default:
+ return luaL_error(L, "sol: incorrect number of arguments to member variable function");
+ }
+ }
+
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call)>(L);
+ }
+
+ int operator()(lua_State* L) {
+ return call(L);
+ }
+ };
+ } // function_detail
+} // sol
+
+#endif // SOL_FUNCTION_TYPES_STATELESS_HPP
diff --git a/3rdparty/sol2/sol/function_types_templated.hpp b/3rdparty/sol2/sol/function_types_templated.hpp
new file mode 100644
index 00000000000..80989408ad8
--- /dev/null
+++ b/3rdparty/sol2/sol/function_types_templated.hpp
@@ -0,0 +1,132 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_FUNCTION_TYPES_TEMPLATED_HPP
+#define SOL_FUNCTION_TYPES_TEMPLATED_HPP
+
+#include "call.hpp"
+
+namespace sol {
+ namespace function_detail {
+ template <typename F, F fx>
+ inline int call_wrapper_variable(std::false_type, lua_State* L) {
+ typedef meta::bind_traits<meta::unqualified_t<F>> traits_type;
+ typedef typename traits_type::args_list args_list;
+ typedef meta::tuple_types<typename traits_type::return_type> return_type;
+ return stack::call_into_lua(return_type(), args_list(), L, 1, fx);
+ }
+
+ template <typename R, typename V, V, typename T>
+ inline int call_set_assignable(std::false_type, T&&, lua_State* L) {
+ return luaL_error(L, "cannot write to this type: copy assignment/constructor not available");
+ }
+
+ template <typename R, typename V, V variable, typename T>
+ inline int call_set_assignable(std::true_type, lua_State* L, T&& mem) {
+ (mem.*variable) = stack::get<R>(L, 2);
+ return 0;
+ }
+
+ template <typename R, typename V, V, typename T>
+ inline int call_set_variable(std::false_type, lua_State* L, T&&) {
+ return luaL_error(L, "cannot write to a const variable");
+ }
+
+ template <typename R, typename V, V variable, typename T>
+ inline int call_set_variable(std::true_type, lua_State* L, T&& mem) {
+ return call_set_assignable<R, V, variable>(std::is_assignable<std::add_lvalue_reference_t<R>, R>(), L, std::forward<T>(mem));
+ }
+
+ template <typename V, V variable>
+ inline int call_wrapper_variable(std::true_type, lua_State* L) {
+ typedef meta::bind_traits<meta::unqualified_t<V>> traits_type;
+ typedef typename traits_type::object_type T;
+ typedef typename traits_type::return_type R;
+ auto& mem = stack::get<T>(L, 1);
+ switch (lua_gettop(L)) {
+ case 1: {
+ decltype(auto) r = (mem.*variable);
+ stack::push_reference(L, std::forward<decltype(r)>(r));
+ return 1; }
+ case 2:
+ return call_set_variable<R, V, variable>(meta::neg<std::is_const<R>>(), L, mem);
+ default:
+ return luaL_error(L, "incorrect number of arguments to member variable function call");
+ }
+ }
+
+ template <typename F, F fx>
+ inline int call_wrapper_function(std::false_type, lua_State* L) {
+ return call_wrapper_variable<F, fx>(std::is_member_object_pointer<F>(), L);
+ }
+
+ template <typename F, F fx>
+ inline int call_wrapper_function(std::true_type, lua_State* L) {
+ return call_detail::call_wrapped<void, false, false>(L, fx);
+ }
+
+ template <typename F, F fx>
+ int call_wrapper_entry(lua_State* L) {
+ return call_wrapper_function<F, fx>(std::is_member_function_pointer<meta::unqualified_t<F>>(), L);
+ }
+
+ template <typename... Fxs>
+ struct c_call_matcher {
+ template <typename Fx, std::size_t I, typename R, typename... Args>
+ int operator()(types<Fx>, index_value<I>, types<R>, types<Args...>, lua_State* L, int, int) const {
+ typedef meta::at_in_pack_t<I, Fxs...> target;
+ return target::call(L);
+ }
+ };
+
+ } // function_detail
+
+ template <typename F, F fx>
+ inline int c_call(lua_State* L) {
+#ifdef __clang__
+ return detail::trampoline(L, function_detail::call_wrapper_entry<F, fx>);
+#else
+ return detail::static_trampoline<(&function_detail::call_wrapper_entry<F, fx>)>(L);
+#endif // fuck you clang :c
+ }
+
+ template <typename F, F f>
+ struct wrap {
+ typedef F type;
+
+ static int call(lua_State* L) {
+ return c_call<type, f>(L);
+ }
+ };
+
+ template <typename... Fxs>
+ inline int c_call(lua_State* L) {
+ if (sizeof...(Fxs) < 2) {
+ return meta::at_in_pack_t<0, Fxs...>::call(L);
+ }
+ else {
+ return call_detail::overload_match_arity<typename Fxs::type...>(function_detail::c_call_matcher<Fxs...>(), L, lua_gettop(L), 1);
+ }
+ }
+
+} // sol
+
+#endif // SOL_FUNCTION_TYPES_TEMPLATED_HPP
diff --git a/3rdparty/sol2/sol/in_place.hpp b/3rdparty/sol2/sol/in_place.hpp
new file mode 100644
index 00000000000..2410fb96791
--- /dev/null
+++ b/3rdparty/sol2/sol/in_place.hpp
@@ -0,0 +1,50 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_IN_PLACE_HPP
+#define SOL_IN_PLACE_HPP
+
+namespace sol {
+
+ namespace detail {
+ struct in_place_of {};
+ template <std::size_t I>
+ struct in_place_of_i {};
+ template <typename T>
+ struct in_place_of_t {};
+ } // detail
+
+ struct in_place_tag { struct init {}; constexpr in_place_tag(init) {} in_place_tag() = delete; };
+ constexpr inline in_place_tag in_place(detail::in_place_of) { return in_place_tag(in_place_tag::init()); }
+ template <typename T>
+ constexpr inline in_place_tag in_place(detail::in_place_of_t<T>) { return in_place_tag(in_place_tag::init()); }
+ template <std::size_t I>
+ constexpr inline in_place_tag in_place(detail::in_place_of_i<I>) { return in_place_tag(in_place_tag::init()); }
+
+ using in_place_t = in_place_tag(&)(detail::in_place_of);
+ template <typename T>
+ using in_place_type_t = in_place_tag(&)(detail::in_place_of_t<T>);
+ template <std::size_t I>
+ using in_place_index_t = in_place_tag(&)(detail::in_place_of_i<I>);
+
+} // sol
+
+#endif // SOL_IN_PLACE_HPP
diff --git a/3rdparty/sol2/sol/inheritance.hpp b/3rdparty/sol2/sol/inheritance.hpp
new file mode 100644
index 00000000000..f2583495bc4
--- /dev/null
+++ b/3rdparty/sol2/sol/inheritance.hpp
@@ -0,0 +1,117 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_INHERITANCE_HPP
+#define SOL_INHERITANCE_HPP
+
+#include "types.hpp"
+#include <atomic>
+
+namespace sol {
+ template <typename... Args>
+ struct base_list { };
+ template <typename... Args>
+ using bases = base_list<Args...>;
+
+ typedef bases<> base_classes_tag;
+ const auto base_classes = base_classes_tag();
+
+ namespace detail {
+
+ template <typename T>
+ struct has_derived {
+ static bool value;
+ };
+
+ template <typename T>
+ bool has_derived<T>::value = false;
+
+ inline std::size_t unique_id() {
+ static std::atomic<std::size_t> x(0);
+ return ++x;
+ }
+
+ template <typename T>
+ struct id_for {
+ static const std::size_t value;
+ };
+
+ template <typename T>
+ const std::size_t id_for<T>::value = unique_id();
+
+ inline decltype(auto) base_class_check_key() {
+ static const auto& key = "class_check";
+ return key;
+ }
+
+ inline decltype(auto) base_class_cast_key() {
+ static const auto& key = "class_cast";
+ return key;
+ }
+
+ inline decltype(auto) base_class_index_propogation_key() {
+ static const auto& key = u8"\xF0\x9F\x8C\xB2.index";
+ return key;
+ }
+
+ inline decltype(auto) base_class_new_index_propogation_key() {
+ static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index";
+ return key;
+ }
+
+ template <typename T, typename... Bases>
+ struct inheritance {
+ static bool type_check_bases(types<>, std::size_t) {
+ return false;
+ }
+
+ template <typename Base, typename... Args>
+ static bool type_check_bases(types<Base, Args...>, std::size_t ti) {
+ return ti == id_for<Base>::value || type_check_bases(types<Args...>(), ti);
+ }
+
+ static bool type_check(std::size_t ti) {
+ return ti == id_for<T>::value || type_check_bases(types<Bases...>(), ti);
+ }
+
+ static void* type_cast_bases(types<>, T*, std::size_t) {
+ return nullptr;
+ }
+
+ template <typename Base, typename... Args>
+ static void* type_cast_bases(types<Base, Args...>, T* data, std::size_t ti) {
+ // Make sure to convert to T first, and then dynamic cast to the proper type
+ return ti != id_for<Base>::value ? type_cast_bases(types<Args...>(), data, ti) : static_cast<void*>(static_cast<Base*>(data));
+ }
+
+ static void* type_cast(void* voiddata, std::size_t ti) {
+ T* data = static_cast<T*>(voiddata);
+ return static_cast<void*>(ti != id_for<T>::value ? type_cast_bases(types<Bases...>(), data, ti) : data);
+ }
+ };
+
+ using inheritance_check_function = decltype(&inheritance<void>::type_check);
+ using inheritance_cast_function = decltype(&inheritance<void>::type_cast);
+
+ } // detail
+} // sol
+
+#endif // SOL_INHERITANCE_HPP
diff --git a/3rdparty/sol2/sol/load_result.hpp b/3rdparty/sol2/sol/load_result.hpp
new file mode 100644
index 00000000000..1a91cc6f3dc
--- /dev/null
+++ b/3rdparty/sol2/sol/load_result.hpp
@@ -0,0 +1,139 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_LOAD_RESULT_HPP
+#define SOL_LOAD_RESULT_HPP
+
+#include "stack.hpp"
+#include "function.hpp"
+#include "proxy_base.hpp"
+#include <cstdint>
+
+namespace sol {
+ struct load_result : public proxy_base<load_result> {
+ private:
+ lua_State* L;
+ int index;
+ int returncount;
+ int popcount;
+ load_status err;
+
+ template <typename T>
+ decltype(auto) tagged_get(types<sol::optional<T>>) const {
+ if (!valid()) {
+ return sol::optional<T>(nullopt);
+ }
+ return stack::get<sol::optional<T>>(L, index);
+ }
+
+ template <typename T>
+ decltype(auto) tagged_get(types<T>) const {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!valid()) {
+ type_panic(L, index, type_of(L, index), type::none);
+ }
+#endif // Check Argument Safety
+ return stack::get<T>(L, index);
+ }
+
+ sol::optional<sol::error> tagged_get(types<sol::optional<sol::error>>) const {
+ if (valid()) {
+ return nullopt;
+ }
+ return sol::error(detail::direct_error, stack::get<std::string>(L, index));
+ }
+
+ sol::error tagged_get(types<sol::error>) const {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (valid()) {
+ type_panic(L, index, type_of(L, index), type::none);
+ }
+#endif // Check Argument Safety
+ return sol::error(detail::direct_error, stack::get<std::string>(L, index));
+ }
+
+ public:
+ load_result() = default;
+ load_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, load_status err = load_status::ok) noexcept : L(L), index(index), returncount(returncount), popcount(popcount), err(err) {
+
+ }
+ load_result(const load_result&) = default;
+ load_result& operator=(const load_result&) = default;
+ load_result(load_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but we will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ o.popcount = 0;
+ o.err = load_status::syntax;
+ }
+ load_result& operator=(load_result&& o) noexcept {
+ L = o.L;
+ index = o.index;
+ returncount = o.returncount;
+ popcount = o.popcount;
+ err = o.err;
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but we will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ o.popcount = 0;
+ o.err = load_status::syntax;
+ return *this;
+ }
+
+ load_status status() const noexcept {
+ return err;
+ }
+
+ bool valid() const noexcept {
+ return status() == load_status::ok;
+ }
+
+ template<typename T>
+ T get() const {
+ return tagged_get(types<meta::unqualified_t<T>>());
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) {
+ return get<function>().template call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Args>
+ decltype(auto) operator()(Args&&... args) {
+ return call<>(std::forward<Args>(args)...);
+ }
+
+ lua_State* lua_state() const noexcept { return L; };
+ int stack_index() const noexcept { return index; };
+
+ ~load_result() {
+ stack::remove(L, index, popcount);
+ }
+ };
+} // sol
+
+#endif // SOL_LOAD_RESULT_HPP
diff --git a/3rdparty/sol2/sol/object.hpp b/3rdparty/sol2/sol/object.hpp
new file mode 100644
index 00000000000..42b46f9c41e
--- /dev/null
+++ b/3rdparty/sol2/sol/object.hpp
@@ -0,0 +1,152 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_OBJECT_HPP
+#define SOL_OBJECT_HPP
+
+#include "optional.hpp"
+#include "reference.hpp"
+#include "stack.hpp"
+#include "userdata.hpp"
+#include "variadic_args.hpp"
+
+namespace sol {
+
+ template <typename R = reference, bool should_pop = !std::is_base_of<stack_reference, R>::value, typename T>
+ R make_reference(lua_State* L, T&& value) {
+ int backpedal = stack::push(L, std::forward<T>(value));
+ R r = stack::get<R>(L, -backpedal);
+ if (should_pop) {
+ lua_pop(L, backpedal);
+ }
+ return r;
+ }
+
+ template <typename T, typename R = reference, bool should_pop = !std::is_base_of<stack_reference, R>::value, typename... Args>
+ R make_reference(lua_State* L, Args&&... args) {
+ int backpedal = stack::push<T>(L, std::forward<Args>(args)...);
+ R r = stack::get<R>(L, -backpedal);
+ if (should_pop) {
+ lua_pop(L, backpedal);
+ }
+ return r;
+ }
+
+ template <typename base_t>
+ class basic_object : public base_t {
+ private:
+ template<typename T>
+ decltype(auto) as_stack(std::true_type) const {
+ return stack::get<T>(base_t::lua_state(), base_t::stack_index());
+ }
+
+ template<typename T>
+ decltype(auto) as_stack(std::false_type) const {
+ base_t::push();
+ return stack::pop<T>(base_t::lua_state());
+ }
+
+ template<typename T>
+ bool is_stack(std::true_type) const {
+ return stack::check<T>(base_t::lua_state(), base_t::stack_index(), no_panic);
+ }
+
+ template<typename T>
+ bool is_stack(std::false_type) const {
+ auto pp = stack::push_pop(*this);
+ return stack::check<T>(base_t::lua_state(), -1, no_panic);
+ }
+
+ template <bool invert_and_pop = false>
+ basic_object(std::integral_constant<bool, invert_and_pop>, lua_State* L, int index = -1) noexcept : base_t(L, index) {
+ if (invert_and_pop) {
+ lua_pop(L, -index);
+ }
+ }
+
+ public:
+ basic_object() noexcept = default;
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_object>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_object(T&& r) : base_t(std::forward<T>(r)) {}
+ basic_object(nil_t r) : base_t(r) {}
+ basic_object(const basic_object&) = default;
+ basic_object(basic_object&&) = default;
+ basic_object& operator=(const basic_object&) = default;
+ basic_object& operator=(basic_object&&) = default;
+ basic_object& operator=(const base_t& b) { base_t::operator=(b); return *this; }
+ basic_object& operator=(base_t&& b) { base_t::operator=(std::move(b)); return *this; }
+ basic_object(const stack_reference& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {}
+ basic_object(stack_reference&& r) noexcept : basic_object(r.lua_state(), r.stack_index()) {}
+ template <typename Super>
+ basic_object(const proxy_base<Super>& r) noexcept : basic_object(r.operator basic_object()) {}
+ template <typename Super>
+ basic_object(proxy_base<Super>&& r) noexcept : basic_object(r.operator basic_object()) {}
+ template <typename Super>
+ basic_object& operator=(const proxy_base<Super>& r) { this->operator=(r.operator basic_object()); return *this; }
+ template <typename Super>
+ basic_object& operator=(proxy_base<Super>&& r) { this->operator=(r.operator basic_object()); return *this; }
+ basic_object(lua_State* L, int index = -1) noexcept : base_t(L, index) {}
+ template <typename T, typename... Args>
+ basic_object(lua_State* L, in_place_type_t<T>, Args&&... args) noexcept : basic_object(std::integral_constant<bool, !std::is_base_of<stack_reference, base_t>::value>(), L, -stack::push<T>(L, std::forward<Args>(args)...)) {}
+ template <typename T, typename... Args>
+ basic_object(lua_State* L, in_place_t, T&& arg, Args&&... args) noexcept : basic_object(L, in_place<T>, std::forward<T>(arg), std::forward<Args>(args)...) {}
+
+ template<typename T>
+ decltype(auto) as() const {
+ return as_stack<T>(std::is_same<base_t, stack_reference>());
+ }
+
+ template<typename T>
+ bool is() const {
+ if (!base_t::valid())
+ return false;
+ return is_stack<T>(std::is_same<base_t, stack_reference>());
+ }
+ };
+
+ template <typename T>
+ object make_object(lua_State* L, T&& value) {
+ return make_reference<object, true>(L, std::forward<T>(value));
+ }
+
+ template <typename T, typename... Args>
+ object make_object(lua_State* L, Args&&... args) {
+ return make_reference<T, object, true>(L, std::forward<Args>(args)...);
+ }
+
+ inline bool operator==(const object& lhs, const nil_t&) {
+ return !lhs.valid();
+ }
+
+ inline bool operator==(const nil_t&, const object& rhs) {
+ return !rhs.valid();
+ }
+
+ inline bool operator!=(const object& lhs, const nil_t&) {
+ return lhs.valid();
+ }
+
+ inline bool operator!=(const nil_t&, const object& rhs) {
+ return rhs.valid();
+ }
+} // sol
+
+#endif // SOL_OBJECT_HPP
diff --git a/3rdparty/sol2/sol/optional.hpp b/3rdparty/sol2/sol/optional.hpp
new file mode 100644
index 00000000000..823bdc3d5c3
--- /dev/null
+++ b/3rdparty/sol2/sol/optional.hpp
@@ -0,0 +1,43 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_OPTIONAL_HPP
+#define SOL_OPTIONAL_HPP
+
+#include "in_place.hpp"
+#if defined(SOL_USE_BOOST)
+#include <boost/optional.hpp>
+#else
+#include "../Optional/optional.hpp"
+#endif // Boost vs. Better optional
+
+namespace sol {
+
+#if defined(SOL_USE_BOOST)
+ template <typename T>
+ using optional = boost::optional<T>;
+ using nullopt_t = boost::none_t;
+ const nullopt_t nullopt = boost::none;
+#endif // Boost vs. Better optional
+
+} // sol
+
+#endif // SOL_OPTIONAL_HPP
diff --git a/3rdparty/sol2/sol/overload.hpp b/3rdparty/sol2/sol/overload.hpp
new file mode 100644
index 00000000000..316a3322ba3
--- /dev/null
+++ b/3rdparty/sol2/sol/overload.hpp
@@ -0,0 +1,45 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_OVERLOAD_HPP
+#define SOL_OVERLOAD_HPP
+
+#include <utility>
+
+namespace sol {
+ template <typename... Functions>
+ struct overload_set {
+ std::tuple<Functions...> functions;
+ template <typename Arg, typename... Args, meta::disable<std::is_same<overload_set, meta::unqualified_t<Arg>>> = meta::enabler>
+ overload_set (Arg&& arg, Args&&... args) : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+ overload_set(const overload_set&) = default;
+ overload_set(overload_set&&) = default;
+ overload_set& operator=(const overload_set&) = default;
+ overload_set& operator=(overload_set&&) = default;
+ };
+
+ template <typename... Args>
+ decltype(auto) overload(Args&&... args) {
+ return overload_set<std::decay_t<Args>...>(std::forward<Args>(args)...);
+ }
+}
+
+#endif // SOL_OVERLOAD_HPP \ No newline at end of file
diff --git a/3rdparty/sol2/sol/property.hpp b/3rdparty/sol2/sol/property.hpp
new file mode 100644
index 00000000000..703cac925d2
--- /dev/null
+++ b/3rdparty/sol2/sol/property.hpp
@@ -0,0 +1,105 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_PROPERTY_HPP
+#define SOL_PROPERTY_HPP
+
+namespace sol {
+
+ struct no_prop { };
+
+ template <typename R, typename W>
+ struct property_wrapper {
+ typedef std::integral_constant<bool, !std::is_void<R>::value> can_read;
+ typedef std::integral_constant<bool, !std::is_void<W>::value> can_write;
+ typedef std::conditional_t<can_read::value, R, no_prop> Read;
+ typedef std::conditional_t<can_write::value, W, no_prop> Write;
+ Read read;
+ Write write;
+
+ template <typename Rx, typename Wx>
+ property_wrapper(Rx&& r, Wx&& w) : read(std::forward<Rx>(r)), write(std::forward<Wx>(w)) {}
+ };
+
+ namespace property_detail {
+ template <typename R, typename W>
+ inline decltype(auto) property(std::true_type, R&& read, W&& write) {
+ return property_wrapper<std::decay_t<R>, std::decay_t<W>>(std::forward<R>(read), std::forward<W>(write));
+ }
+ template <typename W, typename R>
+ inline decltype(auto) property(std::false_type, W&& write, R&& read) {
+ return property_wrapper<std::decay_t<R>, std::decay_t<W>>(std::forward<R>(read), std::forward<W>(write));
+ }
+ template <typename R>
+ inline decltype(auto) property(std::true_type, R&& read) {
+ return property_wrapper<std::decay_t<R>, void>(std::forward<R>(read), no_prop());
+ }
+ template <typename W>
+ inline decltype(auto) property(std::false_type, W&& write) {
+ return property_wrapper<void, std::decay_t<W>>(no_prop(), std::forward<W>(write));
+ }
+ } // property_detail
+
+ template <typename F, typename G>
+ inline decltype(auto) property(F&& f, G&& g) {
+ typedef lua_bind_traits<meta::unqualified_t<F>> left_traits;
+ typedef lua_bind_traits<meta::unqualified_t<G>> right_traits;
+ return property_detail::property(meta::boolean<(left_traits::free_arity < right_traits::free_arity)>(), std::forward<F>(f), std::forward<G>(g));
+ }
+
+ template <typename F>
+ inline decltype(auto) property(F&& f) {
+ typedef lua_bind_traits<meta::unqualified_t<F>> left_traits;
+ return property_detail::property(meta::boolean<(left_traits::free_arity < 2)>(), std::forward<F>(f));
+ }
+
+ template <typename F>
+ inline decltype(auto) readonly_property(F&& f) {
+ return property_detail::property(std::true_type(), std::forward<F>(f));
+ }
+
+ // Allow someone to make a member variable readonly (const)
+ template <typename R, typename T>
+ inline auto readonly(R T::* v) {
+ typedef const R C;
+ return static_cast<C T::*>(v);
+ }
+
+ template <typename T>
+ struct var_wrapper {
+ T value;
+ template <typename... Args>
+ var_wrapper(Args&&... args) : value(std::forward<Args>(args)...) {}
+ var_wrapper(const var_wrapper&) = default;
+ var_wrapper(var_wrapper&&) = default;
+ var_wrapper& operator=(const var_wrapper&) = default;
+ var_wrapper& operator=(var_wrapper&&) = default;
+ };
+
+ template <typename V>
+ inline auto var(V&& v) {
+ typedef meta::unqualified_t<V> T;
+ return var_wrapper<T>(std::forward<V>(v));
+ }
+
+} // sol
+
+#endif // SOL_PROPERTY_HPP
diff --git a/3rdparty/sol2/sol/protect.hpp b/3rdparty/sol2/sol/protect.hpp
new file mode 100644
index 00000000000..42655c6b74b
--- /dev/null
+++ b/3rdparty/sol2/sol/protect.hpp
@@ -0,0 +1,51 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_PROTECT_HPP
+#define SOL_PROTECT_HPP
+
+#include "traits.hpp"
+#include <utility>
+
+namespace sol {
+
+ template <typename T>
+ struct protect_t {
+ T value;
+
+ template <typename Arg, typename... Args, meta::disable<std::is_same<protect_t, meta::unqualified_t<Arg>>> = meta::enabler>
+ protect_t(Arg&& arg, Args&&... args) : value(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+
+ protect_t(const protect_t&) = default;
+ protect_t(protect_t&&) = default;
+ protect_t& operator=(const protect_t&) = default;
+ protect_t& operator=(protect_t&&) = default;
+
+ };
+
+ template <typename T>
+ auto protect(T&& value) {
+ return protect_t<std::decay_t<T>>(std::forward<T>(value));
+ }
+
+} // sol
+
+#endif // SOL_PROTECT_HPP
diff --git a/3rdparty/sol2/sol/protected_function.hpp b/3rdparty/sol2/sol/protected_function.hpp
new file mode 100644
index 00000000000..583a8dd931f
--- /dev/null
+++ b/3rdparty/sol2/sol/protected_function.hpp
@@ -0,0 +1,190 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_PROTECTED_FUNCTION_HPP
+#define SOL_PROTECTED_FUNCTION_HPP
+
+#include "reference.hpp"
+#include "stack.hpp"
+#include "protected_function_result.hpp"
+#include <cstdint>
+#include <algorithm>
+
+namespace sol {
+ namespace detail {
+ inline reference& handler_storage() {
+ static sol::reference h;
+ return h;
+ }
+
+ struct handler {
+ const reference& target;
+ int stackindex;
+ handler(const reference& target) : target(target), stackindex(0) {
+ if (target.valid()) {
+ stackindex = lua_gettop(target.lua_state()) + 1;
+ target.push();
+ }
+ }
+ bool valid() const { return stackindex != 0; }
+ ~handler() {
+ if (valid()) {
+ lua_remove(target.lua_state(), stackindex);
+ }
+ }
+ };
+ }
+
+ template <typename base_t>
+ class basic_protected_function : public base_t {
+ public:
+ static reference& get_default_handler() {
+ return detail::handler_storage();
+ }
+
+ static void set_default_handler(const reference& ref) {
+ detail::handler_storage() = ref;
+ }
+
+ static void set_default_handler(reference&& ref) {
+ detail::handler_storage() = std::move(ref);
+ }
+
+ private:
+ call_status luacall(std::ptrdiff_t argcount, std::ptrdiff_t resultcount, detail::handler& h) const {
+ return static_cast<call_status>(lua_pcallk(base_t::lua_state(), static_cast<int>(argcount), static_cast<int>(resultcount), h.stackindex, 0, nullptr));
+ }
+
+ template<std::size_t... I, typename... Ret>
+ auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n, detail::handler& h) const {
+ luacall(n, sizeof...(Ret), h);
+ return stack::pop<std::tuple<Ret...>>(base_t::lua_state());
+ }
+
+ template<std::size_t I, typename Ret>
+ Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n, detail::handler& h) const {
+ luacall(n, 1, h);
+ return stack::pop<Ret>(base_t::lua_state());
+ }
+
+ template <std::size_t I>
+ void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n, detail::handler& h) const {
+ luacall(n, 0, h);
+ }
+
+ protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n, detail::handler& h) const {
+ int stacksize = lua_gettop(base_t::lua_state());
+ int poststacksize = stacksize;
+ int firstreturn = 1;
+ int returncount = 0;
+ call_status code = call_status::ok;
+#ifndef SOL_NO_EXCEPTIONS
+ auto onexcept = [&](const char* error) {
+ h.stackindex = 0;
+ if (h.target.valid()) {
+ h.target.push();
+ stack::push(base_t::lua_state(), error);
+ lua_call(base_t::lua_state(), 1, 1);
+ }
+ else {
+ stack::push(base_t::lua_state(), error);
+ }
+ };
+ try {
+#endif // No Exceptions
+ firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid())));
+ code = luacall(n, LUA_MULTRET, h);
+ poststacksize = lua_gettop(base_t::lua_state()) - static_cast<int>(h.valid());
+ returncount = poststacksize - (firstreturn - 1);
+#ifndef SOL_NO_EXCEPTIONS
+ }
+ // Handle C++ errors thrown from C++ functions bound inside of lua
+ catch (const char* error) {
+ onexcept(error);
+ firstreturn = lua_gettop(base_t::lua_state());
+ return protected_function_result(base_t::lua_state(), firstreturn, 0, 1, call_status::runtime);
+ }
+ catch (const std::exception& error) {
+ onexcept(error.what());
+ firstreturn = lua_gettop(base_t::lua_state());
+ return protected_function_result(base_t::lua_state(), firstreturn, 0, 1, call_status::runtime);
+ }
+ catch (...) {
+ onexcept("caught (...) unknown error during protected_function call");
+ firstreturn = lua_gettop(base_t::lua_state());
+ return protected_function_result(base_t::lua_state(), firstreturn, 0, 1, call_status::runtime);
+ }
+#endif // No Exceptions
+ return protected_function_result(base_t::lua_state(), firstreturn, returncount, returncount, code);
+ }
+
+ public:
+ reference error_handler;
+
+ basic_protected_function() = default;
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_protected_function>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_protected_function(T&& r) noexcept : base_t(std::forward<T>(r)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!is_function<meta::unqualified_t<T>>::value) {
+ auto pp = stack::push_pop(*this);
+ stack::check<basic_protected_function>(base_t::lua_state(), -1, type_panic);
+ }
+#endif // Safety
+ }
+ basic_protected_function(const basic_protected_function&) = default;
+ basic_protected_function& operator=(const basic_protected_function&) = default;
+ basic_protected_function(basic_protected_function&&) = default;
+ basic_protected_function& operator=(basic_protected_function&&) = default;
+ basic_protected_function(const basic_function<base_t>& b, reference eh = get_default_handler()) : base_t(b), error_handler(std::move(eh)) {}
+ basic_protected_function(basic_function<base_t>&& b, reference eh = get_default_handler()) : base_t(std::move(b)), error_handler(std::move(eh)) {}
+ basic_protected_function(const stack_reference& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {}
+ basic_protected_function(stack_reference&& r, reference eh = get_default_handler()) : basic_protected_function(r.lua_state(), r.stack_index(), std::move(eh)) {}
+ template <typename Super>
+ basic_protected_function(proxy_base<Super>&& p, reference eh = get_default_handler()) : basic_protected_function(p.operator basic_function<base_t>(), std::move(eh)) {}
+ template <typename Super>
+ basic_protected_function(const proxy_base<Super>& p, reference eh = get_default_handler()) : basic_protected_function(static_cast<basic_function<base_t>>(p), std::move(eh)) {}
+ basic_protected_function(lua_State* L, int index = -1, reference eh = get_default_handler()) : base_t(L, index), error_handler(std::move(eh)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ stack::check<basic_protected_function>(L, index, type_panic);
+#endif // Safety
+ }
+
+ template<typename... Args>
+ protected_function_result operator()(Args&&... args) const {
+ return call<>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) operator()(types<Ret...>, Args&&... args) const {
+ return call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) const {
+ detail::handler h(error_handler);
+ base_t::push();
+ int pushcount = stack::multi_push_reference(base_t::lua_state(), std::forward<Args>(args)...);
+ return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount, h);
+ }
+ };
+} // sol
+
+#endif // SOL_FUNCTION_HPP
diff --git a/3rdparty/sol2/sol/protected_function_result.hpp b/3rdparty/sol2/sol/protected_function_result.hpp
new file mode 100644
index 00000000000..bac0fc0fb62
--- /dev/null
+++ b/3rdparty/sol2/sol/protected_function_result.hpp
@@ -0,0 +1,130 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_PROTECTED_FUNCTION_RESULT_HPP
+#define SOL_PROTECTED_FUNCTION_RESULT_HPP
+
+#include "reference.hpp"
+#include "tuple.hpp"
+#include "stack.hpp"
+#include "proxy_base.hpp"
+#include <cstdint>
+
+namespace sol {
+ struct protected_function_result : public proxy_base<protected_function_result> {
+ private:
+ lua_State* L;
+ int index;
+ int returncount;
+ int popcount;
+ call_status err;
+
+ template <typename T>
+ decltype(auto) tagged_get(types<sol::optional<T>>) const {
+ if (!valid()) {
+ return sol::optional<T>(nullopt);
+ }
+ return stack::get<sol::optional<T>>(L, index);
+ }
+
+ template <typename T>
+ decltype(auto) tagged_get(types<T>) const {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!valid()) {
+ type_panic(L, index, type_of(L, index), type::none);
+ }
+#endif // Check Argument Safety
+ return stack::get<T>(L, index);
+ }
+
+ optional<error> tagged_get(types<optional<error>>) const {
+ if (valid()) {
+ return nullopt;
+ }
+ return error(detail::direct_error, stack::get<std::string>(L, index));
+ }
+
+ error tagged_get(types<error>) const {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (valid()) {
+ type_panic(L, index, type_of(L, index), type::none);
+ }
+#endif // Check Argument Safety
+ return error(detail::direct_error, stack::get<std::string>(L, index));
+ }
+
+ public:
+ protected_function_result() = default;
+ protected_function_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, call_status err = call_status::ok) noexcept : L(L), index(index), returncount(returncount), popcount(popcount), err(err) {
+
+ }
+ protected_function_result(const protected_function_result&) = default;
+ protected_function_result& operator=(const protected_function_result&) = default;
+ protected_function_result(protected_function_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but we will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ o.popcount = 0;
+ o.err = call_status::runtime;
+ }
+ protected_function_result& operator=(protected_function_result&& o) noexcept {
+ L = o.L;
+ index = o.index;
+ returncount = o.returncount;
+ popcount = o.popcount;
+ err = o.err;
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but we will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.returncount = 0;
+ o.popcount = 0;
+ o.err = call_status::runtime;
+ return *this;
+ }
+
+ call_status status() const noexcept {
+ return err;
+ }
+
+ bool valid() const noexcept {
+ return status() == call_status::ok || status() == call_status::yielded;
+ }
+
+ template<typename T>
+ decltype(auto) get() const {
+ return tagged_get(types<meta::unqualified_t<T>>());
+ }
+
+ lua_State* lua_state() const noexcept { return L; };
+ int stack_index() const noexcept { return index; };
+
+ ~protected_function_result() {
+ stack::remove(L, index, popcount);
+ }
+ };
+} // sol
+
+#endif // SOL_PROTECTED_FUNCTION_RESULT_HPP
diff --git a/3rdparty/sol2/sol/proxy.hpp b/3rdparty/sol2/sol/proxy.hpp
new file mode 100644
index 00000000000..22247a8d818
--- /dev/null
+++ b/3rdparty/sol2/sol/proxy.hpp
@@ -0,0 +1,175 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_PROXY_HPP
+#define SOL_PROXY_HPP
+
+#include "traits.hpp"
+#include "object.hpp"
+#include "function.hpp"
+#include "protected_function.hpp"
+#include "proxy_base.hpp"
+
+namespace sol {
+ template<typename Table, typename Key>
+ struct proxy : public proxy_base<proxy<Table, Key>> {
+ private:
+ typedef meta::condition<meta::is_specialization_of<std::tuple, Key>, Key, std::tuple<meta::condition<std::is_array<meta::unqualified_t<Key>>, Key&, meta::unqualified_t<Key>>>> key_type;
+
+ template<typename T, std::size_t... I>
+ decltype(auto) tuple_get(std::index_sequence<I...>) const {
+ return tbl.template traverse_get<T>(std::get<I>(key)...);
+ }
+
+ template<std::size_t... I, typename T>
+ void tuple_set(std::index_sequence<I...>, T&& value) {
+ tbl.traverse_set(std::get<I>(key)..., std::forward<T>(value));
+ }
+
+ public:
+ Table tbl;
+ key_type key;
+
+ template<typename T>
+ proxy(Table table, T&& key) : tbl(table), key(std::forward<T>(key)) {}
+
+ template<typename T>
+ proxy& set(T&& item) {
+ tuple_set(std::make_index_sequence<std::tuple_size<meta::unqualified_t<key_type>>::value>(), std::forward<T>(item));
+ return *this;
+ }
+
+ template<typename... Args>
+ proxy& set_function(Args&&... args) {
+ tbl.set_function(key, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename U, meta::enable<meta::neg<is_lua_reference<meta::unwrap_unqualified_t<U>>>, meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
+ proxy& operator=(U&& other) {
+ return set_function(std::forward<U>(other));
+ }
+
+ template<typename U, meta::disable<meta::neg<is_lua_reference<meta::unwrap_unqualified_t<U>>>, meta::is_callable<meta::unwrap_unqualified_t<U>>> = meta::enabler>
+ proxy& operator=(U&& other) {
+ return set(std::forward<U>(other));
+ }
+
+ template<typename T>
+ decltype(auto) get() const {
+ return tuple_get<T>(std::make_index_sequence<std::tuple_size<meta::unqualified_t<key_type>>::value>());
+ }
+
+ template<typename T>
+ decltype(auto) get_or(T&& otherwise) const {
+ typedef decltype(get<T>()) U;
+ sol::optional<U> option = get<sol::optional<U>>();
+ if (option) {
+ return static_cast<U>(option.value());
+ }
+ return static_cast<U>(std::forward<T>(otherwise));
+ }
+
+ template<typename T, typename D>
+ decltype(auto) get_or(D&& otherwise) const {
+ sol::optional<T> option = get<sol::optional<T>>();
+ if (option) {
+ return static_cast<T>(option.value());
+ }
+ return static_cast<T>(std::forward<D>(otherwise));
+ }
+
+ template <typename K>
+ decltype(auto) operator[](K&& k) const {
+ auto keys = meta::tuplefy(key, std::forward<K>(k));
+ return proxy<Table, decltype(keys)>(tbl, std::move(keys));
+ }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) {
+ return get<function>().template call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Args>
+ decltype(auto) operator()(Args&&... args) {
+ return call<>(std::forward<Args>(args)...);
+ }
+
+ bool valid() const {
+ stack::push_pop(tbl);
+ auto p = stack::probe_get_field<std::is_same<meta::unqualified_t<Table>, global_table>::value>(tbl.lua_state(), key, lua_gettop(tbl.lua_state()));
+ lua_pop(tbl.lua_state(), p.levels);
+ return p;
+ }
+ };
+
+ template<typename Table, typename Key, typename T>
+ inline bool operator==(T&& left, const proxy<Table, Key>& right) {
+ return left == right.template get<std::decay_t<T>>();
+ }
+
+ template<typename Table, typename Key, typename T>
+ inline bool operator==(const proxy<Table, Key>& right, T&& left) {
+ return right.template get<std::decay_t<T>>() == left;
+ }
+
+ template<typename Table, typename Key, typename T>
+ inline bool operator!=(T&& left, const proxy<Table, Key>& right) {
+ return right.template get<std::decay_t<T>>() != left;
+ }
+
+ template<typename Table, typename Key, typename T>
+ inline bool operator!=(const proxy<Table, Key>& right, T&& left) {
+ return right.template get<std::decay_t<T>>() != left;
+ }
+
+ template<typename Table, typename Key>
+ inline bool operator==(nil_t, const proxy<Table, Key>& right) {
+ return !right.valid();
+ }
+
+ template<typename Table, typename Key>
+ inline bool operator==(const proxy<Table, Key>& right, nil_t) {
+ return !right.valid();
+ }
+
+ template<typename Table, typename Key>
+ inline bool operator!=(nil_t, const proxy<Table, Key>& right) {
+ return right.valid();
+ }
+
+ template<typename Table, typename Key>
+ inline bool operator!=(const proxy<Table, Key>& right, nil_t) {
+ return right.valid();
+ }
+
+ namespace stack {
+ template <typename Table, typename Key>
+ struct pusher<proxy<Table, Key>> {
+ static int push(lua_State*, const proxy<Table, Key>& p) {
+ sol::reference r = p;
+ return r.push();
+ }
+ };
+ } // stack
+} // sol
+
+#endif // SOL_PROXY_HPP
diff --git a/3rdparty/sol2/sol/proxy_base.hpp b/3rdparty/sol2/sol/proxy_base.hpp
new file mode 100644
index 00000000000..959f6e6b281
--- /dev/null
+++ b/3rdparty/sol2/sol/proxy_base.hpp
@@ -0,0 +1,51 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_PROXY_BASE_HPP
+#define SOL_PROXY_BASE_HPP
+
+#include "reference.hpp"
+#include "tuple.hpp"
+#include "stack.hpp"
+
+namespace sol {
+ template <typename Super>
+ struct proxy_base {
+ operator std::string() const {
+ const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
+ return super.template get<std::string>();
+ }
+
+ template<typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, is_proxy_primitive<meta::unqualified_t<T>>> = meta::enabler>
+ operator T () const {
+ const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
+ return super.template get<T>();
+ }
+
+ template<typename T, meta::enable<meta::neg<meta::is_string_constructible<T>>, meta::neg<is_proxy_primitive<meta::unqualified_t<T>>>> = meta::enabler>
+ operator T& () const {
+ const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
+ return super.template get<T&>();
+ }
+ };
+} // sol
+
+#endif // SOL_PROXY_BASE_HPP
diff --git a/3rdparty/sol2/sol/raii.hpp b/3rdparty/sol2/sol/raii.hpp
new file mode 100644
index 00000000000..c7b20a69613
--- /dev/null
+++ b/3rdparty/sol2/sol/raii.hpp
@@ -0,0 +1,132 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_RAII_HPP
+#define SOL_RAII_HPP
+
+#include <memory>
+#include "traits.hpp"
+
+namespace sol {
+ namespace detail {
+ struct default_construct {
+ template<typename T, typename... Args>
+ static void construct(T&& obj, Args&&... args) {
+ std::allocator<meta::unqualified_t<T>> alloc{};
+ alloc.construct(obj, std::forward<Args>(args)...);
+ }
+
+ template<typename T, typename... Args>
+ void operator()(T&& obj, Args&&... args) const {
+ construct(std::forward<T>(obj), std::forward<Args>(args)...);
+ }
+ };
+
+ struct default_destruct {
+ template<typename T>
+ static void destroy(T&& obj) {
+ std::allocator<meta::unqualified_t<T>> alloc{};
+ alloc.destroy(obj);
+ }
+
+ template<typename T>
+ void operator()(T&& obj) const {
+ destroy(std::forward<T>(obj));
+ }
+ };
+
+ struct deleter {
+ template <typename T>
+ void operator()(T* p) const {
+ delete p;
+ }
+ };
+
+ template <typename T, typename Dx, typename... Args>
+ inline std::unique_ptr<T, Dx> make_unique_deleter(Args&&... args) {
+ return std::unique_ptr<T, Dx>(new T(std::forward<Args>(args)...));
+ }
+
+ template <typename Tag, typename T>
+ struct tagged {
+ T value;
+ template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, tagged>> = meta::enabler>
+ tagged(Arg&& arg, Args&&... args) : value(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+ };
+ } // detail
+
+ template <typename... Args>
+ struct constructor_list {};
+
+ template<typename... Args>
+ using constructors = constructor_list<Args...>;
+
+ const auto default_constructor = constructors<types<>>{};
+
+ struct no_construction {};
+ const auto no_constructor = no_construction{};
+
+ struct call_construction {};
+ const auto call_constructor = call_construction{};
+
+ template <typename... Functions>
+ struct constructor_wrapper {
+ std::tuple<Functions...> functions;
+ template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, constructor_wrapper>> = meta::enabler>
+ constructor_wrapper(Arg&& arg, Args&&... args) : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+ };
+
+ template <typename... Functions>
+ inline auto initializers(Functions&&... functions) {
+ return constructor_wrapper<std::decay_t<Functions>...>(std::forward<Functions>(functions)...);
+ }
+
+ template <typename... Functions>
+ struct factory_wrapper {
+ std::tuple<Functions...> functions;
+ template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, factory_wrapper>> = meta::enabler>
+ factory_wrapper(Arg&& arg, Args&&... args) : functions(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+ };
+
+ template <typename... Functions>
+ inline auto factories(Functions&&... functions) {
+ return factory_wrapper<std::decay_t<Functions>...>(std::forward<Functions>(functions)...);
+ }
+
+ template <typename Function>
+ struct destructor_wrapper {
+ Function fx;
+ destructor_wrapper(Function f) : fx(std::move(f)) {}
+ };
+
+ template <>
+ struct destructor_wrapper<void> {};
+
+ const destructor_wrapper<void> default_destructor{};
+
+ template <typename Fx>
+ inline auto destructor(Fx&& fx) {
+ return destructor_wrapper<std::decay_t<Fx>>(std::forward<Fx>(fx));
+ }
+
+} // sol
+
+#endif // SOL_RAII_HPP
diff --git a/3rdparty/sol2/sol/reference.hpp b/3rdparty/sol2/sol/reference.hpp
new file mode 100644
index 00000000000..c7c9d823d59
--- /dev/null
+++ b/3rdparty/sol2/sol/reference.hpp
@@ -0,0 +1,174 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_REFERENCE_HPP
+#define SOL_REFERENCE_HPP
+
+#include "types.hpp"
+#include "stack_reference.hpp"
+
+namespace sol {
+ namespace stack {
+ template <bool top_level>
+ struct push_popper_n {
+ lua_State* L;
+ int t;
+ push_popper_n(lua_State* L, int x) : L(L), t(x) { }
+ ~push_popper_n() { lua_pop(L, t); }
+ };
+ template <>
+ struct push_popper_n<true> {
+ push_popper_n(lua_State*, int) { }
+ };
+ template <bool top_level, typename T>
+ struct push_popper {
+ T t;
+ push_popper(T x) : t(x) { t.push(); }
+ ~push_popper() { t.pop(); }
+ };
+ template <typename T>
+ struct push_popper<true, T> {
+ push_popper(T) {}
+ ~push_popper() {}
+ };
+ template <bool top_level = false, typename T>
+ push_popper<top_level, T> push_pop(T&& x) {
+ return push_popper<top_level, T>(std::forward<T>(x));
+ }
+ template <bool top_level = false>
+ push_popper_n<top_level> pop_n(lua_State* L, int x) {
+ return push_popper_n<top_level>(L, x);
+ }
+ } // stack
+
+ namespace detail {
+ struct global_tag { } const global_{};
+ } // detail
+
+ class reference {
+ private:
+ lua_State* L = nullptr; // non-owning
+ int ref = LUA_NOREF;
+
+ int copy() const noexcept {
+ if (ref == LUA_NOREF)
+ return LUA_NOREF;
+ push();
+ return luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+
+ protected:
+ reference(lua_State* L, detail::global_tag) noexcept : L(L) {
+ lua_pushglobaltable(L);
+ ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+
+ int stack_index() const noexcept {
+ return -1;
+ }
+
+ public:
+ reference() noexcept = default;
+ reference(nil_t) noexcept : reference() {}
+ reference(const stack_reference& r) noexcept : reference(r.lua_state(), r.stack_index()) {}
+ reference(stack_reference&& r) noexcept : reference(r.lua_state(), r.stack_index()) {}
+ reference(lua_State* L, int index = -1) noexcept : L(L) {
+ lua_pushvalue(L, index);
+ ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ }
+
+ virtual ~reference() noexcept {
+ luaL_unref(L, LUA_REGISTRYINDEX, ref);
+ }
+
+ reference(reference&& o) noexcept {
+ L = o.L;
+ ref = o.ref;
+
+ o.L = nullptr;
+ o.ref = LUA_NOREF;
+ }
+
+ reference& operator=(reference&& o) noexcept {
+ L = o.L;
+ ref = o.ref;
+
+ o.L = nullptr;
+ o.ref = LUA_NOREF;
+
+ return *this;
+ }
+
+ reference(const reference& o) noexcept {
+ L = o.L;
+ ref = o.copy();
+ }
+
+ reference& operator=(const reference& o) noexcept {
+ L = o.L;
+ ref = o.copy();
+ return *this;
+ }
+
+ int push() const noexcept {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
+ return 1;
+ }
+
+ void pop(int n = 1) const noexcept {
+ lua_pop(lua_state(), n);
+ }
+
+ int registry_index() const noexcept {
+ return ref;
+ }
+
+ bool valid() const noexcept {
+ return !(ref == LUA_NOREF || ref == LUA_REFNIL);
+ }
+
+ explicit operator bool() const noexcept {
+ return valid();
+ }
+
+ type get_type() const noexcept {
+ auto pp = stack::push_pop(*this);
+ int result = lua_type(L, -1);
+ return static_cast<type>(result);
+ }
+
+ lua_State* lua_state() const noexcept {
+ return L;
+ }
+ };
+
+ inline bool operator== (const reference& l, const reference& r) {
+ auto ppl = stack::push_pop(l);
+ auto ppr = stack::push_pop(r);
+ return lua_compare(l.lua_state(), -1, -2, LUA_OPEQ) == 1;
+ }
+
+ inline bool operator!= (const reference& l, const reference& r) {
+ return !operator==(l, r);
+ }
+} // sol
+
+#endif // SOL_REFERENCE_HPP
diff --git a/3rdparty/sol2/sol/resolve.hpp b/3rdparty/sol2/sol/resolve.hpp
new file mode 100644
index 00000000000..7445a8150a9
--- /dev/null
+++ b/3rdparty/sol2/sol/resolve.hpp
@@ -0,0 +1,96 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_RESOLVE_HPP
+#define SOL_RESOLVE_HPP
+
+#include "traits.hpp"
+#include "tuple.hpp"
+
+namespace sol {
+ namespace detail {
+ template<typename R, typename... Args, typename F, typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
+ inline auto resolve_i(types<R(Args...)>, F&&)->R(meta::unqualified_t<F>::*)(Args...) {
+ using Sig = R(Args...);
+ typedef meta::unqualified_t<F> Fu;
+ return static_cast<Sig Fu::*>(&Fu::operator());
+ }
+
+ template<typename F, typename U = meta::unqualified_t<F>>
+ inline auto resolve_f(std::true_type, F&& f)
+ -> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f))) {
+ return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
+ }
+
+ template<typename F>
+ inline void resolve_f(std::false_type, F&&) {
+ static_assert(meta::has_deducible_signature<F>::value,
+ "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
+ }
+
+ template<typename F, typename U = meta::unqualified_t<F>>
+ inline auto resolve_i(types<>, F&& f) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f))) {
+ return resolve_f(meta::has_deducible_signature<U> {}, std::forward<F>(f));
+ }
+
+ template<typename... Args, typename F, typename R = std::result_of_t<F&(Args...)>>
+ inline auto resolve_i(types<Args...>, F&& f) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f))) {
+ return resolve_i(types<R(Args...)>(), std::forward<F>(f));
+ }
+
+ template<typename Sig, typename C>
+ inline Sig C::* resolve_v(std::false_type, Sig C::* mem_func_ptr) {
+ return mem_func_ptr;
+ }
+
+ template<typename Sig, typename C>
+ inline Sig C::* resolve_v(std::true_type, Sig C::* mem_variable_ptr) {
+ return mem_variable_ptr;
+ }
+ } // detail
+
+ template<typename... Args, typename R>
+ inline auto resolve(R fun_ptr(Args...))->R(*)(Args...) {
+ return fun_ptr;
+ }
+
+ template<typename Sig>
+ inline Sig* resolve(Sig* fun_ptr) {
+ return fun_ptr;
+ }
+
+ template<typename... Args, typename R, typename C>
+ inline auto resolve(R(C::*mem_ptr)(Args...))->R(C::*)(Args...) {
+ return mem_ptr;
+ }
+
+ template<typename Sig, typename C>
+ inline Sig C::* resolve(Sig C::* mem_ptr) {
+ return detail::resolve_v(std::is_member_object_pointer<Sig C::*>(), mem_ptr);
+ }
+
+ template<typename... Sig, typename F>
+ inline auto resolve(F&& f) -> decltype(detail::resolve_i(types<Sig...>(), std::forward<F>(f))) {
+ return detail::resolve_i(types<Sig...>(), std::forward<F>(f));
+ }
+} // sol
+
+#endif // SOL_RESOLVE_HPP
diff --git a/3rdparty/sol2/sol/simple_usertype_metatable.hpp b/3rdparty/sol2/sol/simple_usertype_metatable.hpp
new file mode 100644
index 00000000000..586e0d18527
--- /dev/null
+++ b/3rdparty/sol2/sol/simple_usertype_metatable.hpp
@@ -0,0 +1,494 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_SIMPLE_USERTYPE_METATABLE_HPP
+#define SOL_SIMPLE_USERTYPE_METATABLE_HPP
+
+#include "usertype_metatable.hpp"
+#include "object.hpp"
+#include <vector>
+#include <unordered_map>
+#include <utility>
+
+namespace sol {
+
+ namespace usertype_detail {
+ struct variable_wrapper {
+ virtual int index(lua_State* L) = 0;
+ virtual int new_index(lua_State* L) = 0;
+ virtual ~variable_wrapper() {};
+ };
+
+ template <typename T, typename F>
+ struct callable_binding : variable_wrapper {
+ F fx;
+
+ template <typename Arg>
+ callable_binding(Arg&& arg) : fx(std::forward<Arg>(arg)) {}
+
+ virtual int index(lua_State* L) override {
+ return call_detail::call_wrapped<T, true, true>(L, fx);
+ }
+
+ virtual int new_index(lua_State* L) override {
+ return call_detail::call_wrapped<T, false, true>(L, fx);
+ }
+ };
+
+ typedef std::unordered_map<std::string, std::unique_ptr<variable_wrapper>> variable_map;
+ typedef std::unordered_map<std::string, object> function_map;
+
+ struct simple_map {
+ const char* metakey;
+ variable_map variables;
+ function_map functions;
+ base_walk indexbaseclasspropogation;
+ base_walk newindexbaseclasspropogation;
+
+ simple_map(const char* mkey, base_walk index, base_walk newindex, variable_map&& vars, function_map&& funcs) : metakey(mkey), variables(std::move(vars)), functions(std::move(funcs)), indexbaseclasspropogation(index), newindexbaseclasspropogation(newindex) {}
+ };
+
+ template <typename T>
+ inline int simple_metatable_newindex(lua_State* L) {
+ if (stack::stack_detail::check_metatable<T, false>(L, 1)) {
+ stack::set_field<false, true>(L, stack_reference(L, 2), stack_reference(L, 3), 1);
+ lua_settop(L, 0);
+ return 0;
+ }
+ lua_pop(L, 1);
+ return indexing_fail<false>(L);
+ }
+
+ template <bool is_index, bool toplevel = false>
+ inline int simple_core_indexing_call(lua_State* L) {
+ simple_map& sm = toplevel ? stack::get<user<simple_map>>(L, upvalue_index(1)) : stack::pop<user<simple_map>>(L);
+ variable_map& variables = sm.variables;
+ function_map& functions = sm.functions;
+ static const int keyidx = -2 + static_cast<int>(is_index);
+ if (toplevel) {
+ if (stack::get<type>(L, keyidx) != type::string) {
+ lua_CFunction indexingfunc = is_index ? stack::get<lua_CFunction>(L, upvalue_index(2)) : stack::get<lua_CFunction>(L, upvalue_index(3));
+ return indexingfunc(L);
+ }
+ }
+ string_detail::string_shim accessor = stack::get<string_detail::string_shim>(L, keyidx);
+ std::string accessorkey = accessor.c_str();
+ auto vit = variables.find(accessorkey);
+ if (vit != variables.cend()) {
+ auto& varwrap = *(vit->second);
+ if (is_index) {
+ return varwrap.index(L);
+ }
+ return varwrap.new_index(L);
+ }
+ auto fit = functions.find(accessorkey);
+ if (fit != functions.cend()) {
+ auto& func = (fit->second);
+ return stack::push(L, func);
+ }
+ // Check table storage first for a method that works
+ luaL_getmetatable(L, sm.metakey);
+ if (type_of(L, -1) != type::nil) {
+ stack::get_field<false, true>(L, accessor.c_str(), lua_gettop(L));
+ if (type_of(L, -1) != type::nil) {
+ // Woo, we found it?
+ lua_remove(L, -2);
+ return 1;
+ }
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
+
+ int ret = 0;
+ bool found = false;
+ // Otherwise, we need to do propagating calls through the bases
+ if (is_index) {
+ sm.indexbaseclasspropogation(L, found, ret, accessor);
+ }
+ else {
+ sm.newindexbaseclasspropogation(L, found, ret, accessor);
+ }
+ if (found) {
+ return ret;
+ }
+ if (toplevel) {
+ lua_CFunction indexingfunc = is_index ? stack::get<lua_CFunction>(L, upvalue_index(2)) : stack::get<lua_CFunction>(L, upvalue_index(3));
+ return indexingfunc(L);
+ }
+ return -1;
+ }
+
+ inline int simple_real_index_call(lua_State* L) {
+ return simple_core_indexing_call<true, true>(L);
+ }
+
+ inline int simple_real_new_index_call(lua_State* L) {
+ return simple_core_indexing_call<false, true>(L);
+ }
+
+ inline int simple_index_call(lua_State* L) {
+ return detail::static_trampoline<(&simple_real_index_call)>(L);
+ }
+
+ inline int simple_new_index_call(lua_State* L) {
+ return detail::static_trampoline<(&simple_real_new_index_call)>(L);
+ }
+ }
+
+ struct simple_tag {} const simple{};
+
+ template <typename T>
+ struct simple_usertype_metatable : usertype_detail::registrar {
+ public:
+ usertype_detail::function_map registrations;
+ usertype_detail::variable_map varmap;
+ object callconstructfunc;
+ lua_CFunction indexfunc;
+ lua_CFunction newindexfunc;
+ lua_CFunction indexbase;
+ lua_CFunction newindexbase;
+ usertype_detail::base_walk indexbaseclasspropogation;
+ usertype_detail::base_walk newindexbaseclasspropogation;
+ void* baseclasscheck;
+ void* baseclasscast;
+ bool mustindex;
+ bool secondarymeta;
+
+ template <typename N>
+ void insert(N&& n, object&& o) {
+ std::string key = usertype_detail::make_string(std::forward<N>(n));
+ auto hint = registrations.find(key);
+ if (hint == registrations.cend()) {
+ registrations.emplace_hint(hint, std::move(key), std::move(o));
+ return;
+ }
+ hint->second = std::move(o);
+ }
+
+ template <typename N, typename F, meta::enable<meta::is_callable<meta::unwrap_unqualified_t<F>>> = meta::enabler>
+ void add_function(lua_State* L, N&& n, F&& f) {
+ insert(std::forward<N>(n), make_object(L, as_function_reference(std::forward<F>(f))));
+ }
+
+ template <typename N, typename F, meta::disable<meta::is_callable<meta::unwrap_unqualified_t<F>>> = meta::enabler>
+ void add_function(lua_State* L, N&& n, F&& f) {
+ object o = make_object(L, std::forward<F>(f));
+ if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
+ callconstructfunc = std::move(o);
+ return;
+ }
+ insert(std::forward<N>(n), std::move(o));
+ }
+
+ template <typename N, typename F, meta::disable<is_variable_binding<meta::unqualified_t<F>>> = meta::enabler>
+ void add(lua_State* L, N&& n, F&& f) {
+ add_function(L, std::forward<N>(n), std::forward<F>(f));
+ }
+
+ template <typename N, typename F, meta::enable<is_variable_binding<meta::unqualified_t<F>>> = meta::enabler>
+ void add(lua_State*, N&& n, F&& f) {
+ mustindex = true;
+ secondarymeta = true;
+ std::string key = usertype_detail::make_string(std::forward<N>(n));
+ auto o = std::make_unique<usertype_detail::callable_binding<T, std::decay_t<F>>>(std::forward<F>(f));
+ auto hint = varmap.find(key);
+ if (hint == varmap.cend()) {
+ varmap.emplace_hint(hint, std::move(key), std::move(o));
+ return;
+ }
+ hint->second = std::move(o);
+ }
+
+ template <typename N, typename... Fxs>
+ void add(lua_State* L, N&& n, constructor_wrapper<Fxs...> c) {
+ object o(L, in_place<detail::tagged<T, constructor_wrapper<Fxs...>>>, std::move(c));
+ if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
+ callconstructfunc = std::move(o);
+ return;
+ }
+ insert(std::forward<N>(n), std::move(o));
+ }
+
+ template <typename N, typename... Lists>
+ void add(lua_State* L, N&& n, constructor_list<Lists...> c) {
+ object o(L, in_place<detail::tagged<T, constructor_list<Lists...>>>, std::move(c));
+ if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
+ callconstructfunc = std::move(o);
+ return;
+ }
+ insert(std::forward<N>(n), std::move(o));
+ }
+
+ template <typename N>
+ void add(lua_State* L, N&& n, destructor_wrapper<void> c) {
+ object o(L, in_place<detail::tagged<T, destructor_wrapper<void>>>, std::move(c));
+ if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
+ callconstructfunc = std::move(o);
+ return;
+ }
+ insert(std::forward<N>(n), std::move(o));
+ }
+
+ template <typename N, typename Fx>
+ void add(lua_State* L, N&& n, destructor_wrapper<Fx> c) {
+ object o(L, in_place<detail::tagged<T, destructor_wrapper<Fx>>>, std::move(c));
+ if (std::is_same<meta::unqualified_t<N>, call_construction>::value) {
+ callconstructfunc = std::move(o);
+ return;
+ }
+ insert(std::forward<N>(n), std::move(o));
+ }
+
+ template <typename... Bases>
+ void add(lua_State*, base_classes_tag, bases<Bases...>) {
+ static_assert(sizeof(usertype_detail::base_walk) <= sizeof(void*), "size of function pointer is greater than sizeof(void*); cannot work on this platform");
+ if (sizeof...(Bases) < 1) {
+ return;
+ }
+ mustindex = true;
+ (void)detail::swallow{ 0, ((detail::has_derived<Bases>::value = true), 0)... };
+
+ static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
+ static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
+ baseclasscheck = (void*)&detail::inheritance<T, Bases...>::type_check;
+ baseclasscast = (void*)&detail::inheritance<T, Bases...>::type_cast;
+ indexbaseclasspropogation = usertype_detail::walk_all_bases<true, Bases...>;
+ newindexbaseclasspropogation = usertype_detail::walk_all_bases<false, Bases...>;
+ }
+
+ private:
+ template<std::size_t... I, typename Tuple>
+ simple_usertype_metatable(usertype_detail::verified_tag, std::index_sequence<I...>, lua_State* L, Tuple&& args)
+ : callconstructfunc(nil),
+ indexfunc(&usertype_detail::indexing_fail<true>), newindexfunc(&usertype_detail::simple_metatable_newindex<T>),
+ indexbase(&usertype_detail::simple_core_indexing_call<true>), newindexbase(&usertype_detail::simple_core_indexing_call<false>),
+ indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(&usertype_detail::walk_all_bases<false>),
+ baseclasscheck(nullptr), baseclasscast(nullptr),
+ mustindex(true), secondarymeta(true) {
+ (void)detail::swallow{ 0,
+ (add(L, detail::forward_get<I * 2>(args), detail::forward_get<I * 2 + 1>(args)),0)...
+ };
+ }
+
+ template<typename... Args>
+ simple_usertype_metatable(lua_State* L, usertype_detail::verified_tag v, Args&&... args) : simple_usertype_metatable(v, std::make_index_sequence<sizeof...(Args) / 2>(), L, std::forward_as_tuple(std::forward<Args>(args)...)) {}
+
+ template<typename... Args>
+ simple_usertype_metatable(lua_State* L, usertype_detail::add_destructor_tag, Args&&... args) : simple_usertype_metatable(L, usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}
+
+ template<typename... Args>
+ simple_usertype_metatable(lua_State* L, usertype_detail::check_destructor_tag, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_destructible<T>, meta::neg<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward<Args>(args)...) {}
+
+ public:
+ simple_usertype_metatable(lua_State* L) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_default_constructible<T>>, decltype(default_constructor), usertype_detail::check_destructor_tag>()) {}
+
+ template<typename Arg, typename... Args, meta::disable_any<
+ meta::any_same<meta::unqualified_t<Arg>,
+ usertype_detail::verified_tag,
+ usertype_detail::add_destructor_tag,
+ usertype_detail::check_destructor_tag
+ >,
+ meta::is_specialization_of<constructors, meta::unqualified_t<Arg>>,
+ meta::is_specialization_of<constructor_wrapper, meta::unqualified_t<Arg>>
+ > = meta::enabler>
+ simple_usertype_metatable(lua_State* L, Arg&& arg, Args&&... args) : simple_usertype_metatable(L, meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+
+ template<typename... Args, typename... CArgs>
+ simple_usertype_metatable(lua_State* L, constructors<CArgs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
+
+ template<typename... Args, typename... Fxs>
+ simple_usertype_metatable(lua_State* L, constructor_wrapper<Fxs...> constructorlist, Args&&... args) : simple_usertype_metatable(L, usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
+
+ virtual int push_um(lua_State* L) override {
+ return stack::push(L, std::move(*this));
+ }
+ };
+
+ namespace stack {
+ template <typename T>
+ struct pusher<simple_usertype_metatable<T>> {
+ typedef simple_usertype_metatable<T> umt_t;
+
+ static usertype_detail::simple_map& make_cleanup(lua_State* L, umt_t& umx) {
+ static int uniqueness = 0;
+ std::string uniquegcmetakey = usertype_traits<T>::user_gc_metatable;
+ // std::to_string doesn't exist in android still, with NDK, so this bullshit
+ // is necessary
+ // thanks, Android :v
+ int appended = snprintf(nullptr, 0, "%d", uniqueness);
+ std::size_t insertionpoint = uniquegcmetakey.length() - 1;
+ uniquegcmetakey.append(appended, '\0');
+ char* uniquetarget = &uniquegcmetakey[insertionpoint];
+ snprintf(uniquetarget, uniquegcmetakey.length(), "%d", uniqueness);
+ ++uniqueness;
+
+ const char* gcmetakey = &usertype_traits<T>::gc_table[0];
+ stack::push<user<usertype_detail::simple_map>>(L, metatable_key, uniquegcmetakey, &usertype_traits<T>::metatable[0], umx.indexbaseclasspropogation, umx.newindexbaseclasspropogation, std::move(umx.varmap), std::move(umx.registrations));
+ stack_reference stackvarmap(L, -1);
+ stack::set_field<true>(L, gcmetakey, stackvarmap);
+ stackvarmap.pop();
+
+ stack::get_field<true>(L, gcmetakey);
+ usertype_detail::simple_map& varmap = stack::pop<light<usertype_detail::simple_map>>(L);
+ return varmap;
+ }
+
+ static int push(lua_State* L, umt_t&& umx) {
+ auto& varmap = make_cleanup(L, umx);
+ bool hasequals = false;
+ bool hasless = false;
+ bool haslessequals = false;
+ for (std::size_t i = 0; i < 3; ++i) {
+ // Pointer types, AKA "references" from C++
+ const char* metakey = nullptr;
+ switch (i) {
+ case 0:
+ metakey = &usertype_traits<T*>::metatable[0];
+ break;
+ case 1:
+ metakey = &usertype_traits<detail::unique_usertype<T>>::metatable[0];
+ break;
+ case 2:
+ default:
+ metakey = &usertype_traits<T>::metatable[0];
+ break;
+ }
+ luaL_newmetatable(L, metakey);
+ stack_reference t(L, -1);
+ for (auto& kvp : varmap.functions) {
+ auto& first = std::get<0>(kvp);
+ auto& second = std::get<1>(kvp);
+ if (first == name_of(meta_function::equal_to)) {
+ hasequals = true;
+ }
+ else if (first == name_of(meta_function::less_than)) {
+ hasless = true;
+ }
+ else if (first == name_of(meta_function::less_than_or_equal_to)) {
+ haslessequals = true;
+ }
+ else if (first == name_of(meta_function::index)) {
+ umx.indexfunc = second.template as<lua_CFunction>();
+ }
+ else if (first == name_of(meta_function::new_index)) {
+ umx.newindexfunc = second.template as<lua_CFunction>();
+ }
+ switch (i) {
+ case 0:
+ if (first == name_of(meta_function::garbage_collect)) {
+ continue;
+ }
+ break;
+ case 1:
+ if (first == name_of(meta_function::garbage_collect)) {
+ stack::set_field(L, first, detail::unique_destruct<T>, t.stack_index());
+ continue;
+ }
+ break;
+ case 2:
+ default:
+ break;
+ }
+ stack::set_field(L, first, second, t.stack_index());
+ }
+ luaL_Reg opregs[4]{};
+ int opregsindex = 0;
+ if (!hasless) {
+ const char* name = name_of(meta_function::less_than).c_str();
+ usertype_detail::make_reg_op<T, std::less<>, meta::supports_op_less<T>>(opregs, opregsindex, name);
+ }
+ if (!haslessequals) {
+ const char* name = name_of(meta_function::less_than_or_equal_to).c_str();
+ usertype_detail::make_reg_op<T, std::less_equal<>, meta::supports_op_less_equal<T>>(opregs, opregsindex, name);
+ }
+ if (!hasequals) {
+ const char* name = name_of(meta_function::equal_to).c_str();
+ usertype_detail::make_reg_op<T, std::conditional_t<meta::supports_op_equal<T>::value, std::equal_to<>, usertype_detail::no_comp>, std::true_type>(opregs, opregsindex, name);
+ }
+ t.push();
+ luaL_setfuncs(L, opregs, 0);
+ t.pop();
+
+ if (umx.baseclasscheck != nullptr) {
+ stack::set_field(L, detail::base_class_check_key(), umx.baseclasscheck, t.stack_index());
+ }
+ if (umx.baseclasscast != nullptr) {
+ stack::set_field(L, detail::base_class_cast_key(), umx.baseclasscast, t.stack_index());
+ }
+
+ // Base class propagation features
+ stack::set_field(L, detail::base_class_index_propogation_key(), umx.indexbase, t.stack_index());
+ stack::set_field(L, detail::base_class_new_index_propogation_key(), umx.newindexbase, t.stack_index());
+
+ if (umx.mustindex) {
+ // use indexing function
+ static_assert(sizeof(usertype_detail::base_walk) <= sizeof(void*), "The size of this data pointer is too small to fit the base class index propagation key: file a bug report.");
+ stack::set_field(L, meta_function::index,
+ make_closure(&usertype_detail::simple_index_call,
+ make_light(varmap),
+ umx.indexfunc,
+ umx.newindexfunc
+ ), t.stack_index());
+ stack::set_field(L, meta_function::new_index,
+ make_closure(&usertype_detail::simple_new_index_call,
+ make_light(varmap),
+ umx.indexfunc,
+ umx.newindexfunc
+ ), t.stack_index());
+ }
+ else {
+ // Metatable indexes itself
+ stack::set_field(L, meta_function::index, t, t.stack_index());
+ }
+ // metatable on the metatable
+ // for call constructor purposes and such
+ lua_createtable(L, 0, 1);
+ stack_reference metabehind(L, -1);
+ if (umx.callconstructfunc.valid()) {
+ stack::set_field(L, sol::meta_function::call_function, umx.callconstructfunc, metabehind.stack_index());
+ }
+ if (umx.secondarymeta) {
+ stack::set_field(L, meta_function::index,
+ make_closure(&usertype_detail::simple_index_call,
+ make_light(varmap),
+ umx.indexfunc,
+ umx.newindexfunc
+ ), metabehind.stack_index());
+ stack::set_field(L, meta_function::new_index,
+ make_closure(&usertype_detail::simple_new_index_call,
+ make_light(varmap),
+ umx.indexfunc,
+ umx.newindexfunc
+ ), metabehind.stack_index());
+ }
+ stack::set_field(L, metatable_key, metabehind, t.stack_index());
+ metabehind.pop();
+
+ if (i < 2)
+ t.pop();
+ }
+ return 1;
+ }
+ };
+ } // stack
+} // sol
+
+#endif // SOL_SIMPLE_USERTYPE_METATABLE_HPP
diff --git a/3rdparty/sol2/sol/stack.hpp b/3rdparty/sol2/sol/stack.hpp
new file mode 100644
index 00000000000..f612d483f82
--- /dev/null
+++ b/3rdparty/sol2/sol/stack.hpp
@@ -0,0 +1,226 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_HPP
+#define SOL_STACK_HPP
+
+#include "stack_core.hpp"
+#include "stack_reference.hpp"
+#include "stack_check.hpp"
+#include "stack_get.hpp"
+#include "stack_check_get.hpp"
+#include "stack_push.hpp"
+#include "stack_pop.hpp"
+#include "stack_field.hpp"
+#include "stack_probe.hpp"
+#include <cstring>
+#include <array>
+
+namespace sol {
+ namespace stack {
+ namespace stack_detail {
+ template<typename T>
+ inline int push_as_upvalues(lua_State* L, T& item) {
+ typedef std::decay_t<T> TValue;
+ const static std::size_t itemsize = sizeof(TValue);
+ const static std::size_t voidsize = sizeof(void*);
+ const static std::size_t voidsizem1 = voidsize - 1;
+ const static std::size_t data_t_count = (sizeof(TValue) + voidsizem1) / voidsize;
+ typedef std::array<void*, data_t_count> data_t;
+
+ data_t data{ {} };
+ std::memcpy(&data[0], std::addressof(item), itemsize);
+ int pushcount = 0;
+ for (auto&& v : data) {
+ pushcount += push(L, lightuserdata_value(v));
+ }
+ return pushcount;
+ }
+
+ template<typename T>
+ inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 1) {
+ const static std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
+ typedef std::array<void*, data_t_count> data_t;
+ data_t voiddata{ {} };
+ for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) {
+ voiddata[i] = get<lightuserdata_value>(L, upvalue_index(index++));
+ }
+ return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
+ }
+
+ struct evaluator {
+ template <typename Fx, typename... Args>
+ static decltype(auto) eval(types<>, std::index_sequence<>, lua_State*, int, record&, Fx&& fx, Args&&... args) {
+ return std::forward<Fx>(fx)(std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename Arg, typename... Args, std::size_t I, std::size_t... Is, typename... FxArgs>
+ static decltype(auto) eval(types<Arg, Args...>, std::index_sequence<I, Is...>, lua_State* L, int start, record& tracking, Fx&& fx, FxArgs&&... fxargs) {
+ return eval(types<Args...>(), std::index_sequence<Is...>(), L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)..., stack_detail::unchecked_get<Arg>(L, start + tracking.used, tracking));
+ }
+ };
+
+ template <bool checkargs = default_check_arguments, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
+ inline decltype(auto) call(types<R>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
+#ifndef _MSC_VER
+ static_assert(meta::all<meta::is_not_move_only<Args>...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention.");
+#endif // This compiler make me so fucking sad
+ multi_check<checkargs, Args...>(L, start, type_panic);
+ record tracking{};
+ return evaluator{}.eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool checkargs = default_check_arguments, std::size_t... I, typename... Args, typename Fx, typename... FxArgs>
+ inline void call(types<void>, types<Args...> ta, std::index_sequence<I...> tai, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
+#ifndef _MSC_VER
+ static_assert(meta::all<meta::is_not_move_only<Args>...>::value, "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take a reference and std::move it manually if this was your intention.");
+#endif // This compiler make me so fucking sad
+ multi_check<checkargs, Args...>(L, start, type_panic);
+ record tracking{};
+ evaluator{}.eval(ta, tai, L, start, tracking, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+ } // stack_detail
+
+ template <typename T>
+ int set_ref(lua_State* L, T&& arg, int tableindex = -2) {
+ push(L, std::forward<T>(arg));
+ return luaL_ref(L, tableindex);
+ }
+
+ inline void remove(lua_State* L, int index, int count) {
+ if (count < 1)
+ return;
+ int top = lua_gettop(L);
+ if (index == -1 || top == index) {
+ // Slice them right off the top
+ lua_pop(L, static_cast<int>(count));
+ return;
+ }
+
+ // Remove each item one at a time using stack operations
+ // Probably slower, maybe, haven't benchmarked,
+ // but necessary
+ if (index < 0) {
+ index = lua_gettop(L) + (index + 1);
+ }
+ int last = index + count;
+ for (int i = index; i < last; ++i) {
+ lua_remove(L, i);
+ }
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
+ inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
+ typedef std::make_index_sequence<sizeof...(Args)> args_indices;
+ return stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
+ inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
+ return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
+ inline void call(types<void> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
+ typedef std::make_index_sequence<sizeof...(Args)> args_indices;
+ stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
+ inline void call(types<void> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
+ call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename R, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<!std::is_void<R>::value>>
+ inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
+ return call<check_args>(tr, ta, L, static_cast<int>(lua_gettop(L) - sizeof...(Args)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template <bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
+ inline void call_from_top(types<void> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
+ call<check_args>(tr, ta, L, static_cast<int>(lua_gettop(L) - sizeof...(Args)), std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
+ }
+
+ template<bool check_args = stack_detail::default_check_arguments, typename... Args, typename Fx, typename... FxArgs>
+ inline int call_into_lua(types<void> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
+ call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
+ lua_settop(L, 0);
+ return 0;
+ }
+
+ template<bool check_args = stack_detail::default_check_arguments, typename Ret0, typename... Ret, typename... Args, typename Fx, typename... FxArgs, typename = std::enable_if_t<meta::neg<std::is_void<Ret0>>::value>>
+ inline int call_into_lua(types<Ret0, Ret...>, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
+ decltype(auto) r = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
+ lua_settop(L, 0);
+ return push_reference(L, std::forward<decltype(r)>(r));
+ }
+
+ template<bool check_args = stack_detail::default_check_arguments, typename Fx, typename... FxArgs>
+ inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
+ typedef lua_bind_traits<meta::unqualified_t<Fx>> traits_type;
+ typedef typename traits_type::args_list args_list;
+ typedef typename traits_type::returns_list returns_list;
+ return call_into_lua(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
+ }
+
+ inline call_syntax get_call_syntax(lua_State* L, const std::string& key, int index = -2) {
+ luaL_getmetatable(L, key.c_str());
+ auto pn = pop_n(L, 1);
+ if (lua_compare(L, -1, index, LUA_OPEQ) == 1) {
+ return call_syntax::colon;
+ }
+ return call_syntax::dot;
+ }
+
+ inline void script(lua_State* L, const std::string& code) {
+ if (luaL_dostring(L, code.c_str())) {
+ lua_error(L);
+ }
+ }
+
+ inline void script_file(lua_State* L, const std::string& filename) {
+ if (luaL_dofile(L, filename.c_str())) {
+ lua_error(L);
+ }
+ }
+
+ inline void luajit_exception_handler(lua_State* L, int(*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) {
+#ifdef SOL_LUAJIT
+ lua_pushlightuserdata(L, (void*)handler);
+ auto pn = pop_n(L, 1);
+ luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
+#else
+ (void)L;
+ (void)handler;
+#endif
+ }
+
+ inline void luajit_exception_off(lua_State* L) {
+#ifdef SOL_LUAJIT
+ luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_OFF);
+#else
+ (void)L;
+#endif
+ }
+ } // stack
+} // sol
+
+#endif // SOL_STACK_HPP
diff --git a/3rdparty/sol2/sol/stack_check.hpp b/3rdparty/sol2/sol/stack_check.hpp
new file mode 100644
index 00000000000..bf9faa1ed52
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_check.hpp
@@ -0,0 +1,350 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_CHECK_HPP
+#define SOL_STACK_CHECK_HPP
+
+#include "stack_core.hpp"
+#include "usertype_traits.hpp"
+#include "inheritance.hpp"
+#include <memory>
+#include <functional>
+#include <utility>
+
+namespace sol {
+ namespace stack {
+ namespace stack_detail {
+ template <typename T, bool poptable = true>
+ inline bool check_metatable(lua_State* L, int index = -2) {
+ const auto& metakey = usertype_traits<T>::metatable;
+ luaL_getmetatable(L, &metakey[0]);
+ const type expectedmetatabletype = static_cast<type>(lua_type(L, -1));
+ if (expectedmetatabletype != type::nil) {
+ if (lua_rawequal(L, -1, index) == 1) {
+ lua_pop(L, 1 + static_cast<int>(poptable));
+ return true;
+ }
+ }
+ lua_pop(L, 1);
+ return false;
+ }
+
+ template <type expected, int(*check_func)(lua_State*, int)>
+ struct basic_check {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ bool success = check_func(L, index) == 1;
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, expected, type_of(L, index));
+ }
+ return success;
+ }
+ };
+ } // stack_detail
+
+ template <typename T, type expected, typename>
+ struct checker {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ const type indextype = type_of(L, index);
+ bool success = expected == indextype;
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, expected, indextype);
+ }
+ return success;
+ }
+ };
+
+ template <type expected, typename C>
+ struct checker<nil_t, expected, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ bool success = lua_isnil(L, index);
+ if (success) {
+ tracking.use(1);
+ return success;
+ }
+ tracking.use(0);
+ success = lua_isnone(L, index);
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, expected, type_of(L, index));
+ }
+ return success;
+ }
+ };
+
+ template <type expected, typename C>
+ struct checker<nullopt_t, expected, C> : checker<nil_t> {};
+
+ template <typename C>
+ struct checker<this_state, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State*, int, Handler&&, record& tracking) {
+ tracking.use(0);
+ return true;
+ }
+ };
+
+ template <typename C>
+ struct checker<variadic_args, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State*, int, Handler&&, record& tracking) {
+ tracking.use(0);
+ return true;
+ }
+ };
+
+ template <typename C>
+ struct checker<type, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State*, int, Handler&&, record& tracking) {
+ tracking.use(0);
+ return true;
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<T, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ bool success = !lua_isnone(L, index);
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, type::none, type_of(L, index));
+ }
+ return success;
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<T, type::lightuserdata, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ type t = type_of(L, index);
+ bool success = t == type::userdata || t == type::lightuserdata;
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, type::lightuserdata, t);
+ }
+ return success;
+ }
+ };
+
+ template <typename C>
+ struct checker<userdata_value, type::userdata, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ type t = type_of(L, index);
+ bool success = t == type::userdata;
+ if (!success) {
+ // expected type, actual type
+ handler(L, index, type::userdata, t);
+ }
+ return success;
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<user<T>, type::userdata, C> : checker<user<T>, type::lightuserdata, C> {};
+
+ template <typename T, typename C>
+ struct checker<non_null<T>, type::userdata, C> : checker<T, lua_type_of<T>::value, C> {};
+
+ template <typename C>
+ struct checker<lua_CFunction, type::function, C> : stack_detail::basic_check<type::function, lua_iscfunction> {};
+ template <typename C>
+ struct checker<std::remove_pointer_t<lua_CFunction>, type::function, C> : checker<lua_CFunction, type::function, C> {};
+ template <typename C>
+ struct checker<c_closure, type::function, C> : checker<lua_CFunction, type::function, C> {};
+
+ template <typename T, typename C>
+ struct checker<T, type::function, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ type t = type_of(L, index);
+ if (t == type::nil || t == type::none || t == type::function) {
+ // allow for nil to be returned
+ return true;
+ }
+ if (t != type::userdata && t != type::table) {
+ handler(L, index, type::function, t);
+ return false;
+ }
+ // Do advanced check for call-style userdata?
+ static const auto& callkey = name_of(meta_function::call);
+ if (lua_getmetatable(L, index) == 0) {
+ // No metatable, no __call key possible
+ handler(L, index, type::function, t);
+ return false;
+ }
+ if (lua_isnoneornil(L, -1)) {
+ lua_pop(L, 1);
+ handler(L, index, type::function, t);
+ return false;
+ }
+ lua_getfield(L, -1, &callkey[0]);
+ if (lua_isnoneornil(L, -1)) {
+ lua_pop(L, 2);
+ handler(L, index, type::function, t);
+ return false;
+ }
+ // has call, is definitely a function
+ lua_pop(L, 2);
+ return true;
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<T, type::table, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ type t = type_of(L, index);
+ if (t == type::table) {
+ return true;
+ }
+ if (t != type::userdata) {
+ handler(L, index, type::function, t);
+ return false;
+ }
+ return true;
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<T*, type::userdata, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ const type indextype = type_of(L, index);
+ // Allow nil to be transformed to nullptr
+ if (indextype == type::nil) {
+ tracking.use(1);
+ return true;
+ }
+ return checker<meta::unqualified_t<T>, type::userdata, C>{}.check(types<meta::unqualified_t<T>>(), L, indextype, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template <typename T, typename C>
+ struct checker<T, type::userdata, C> {
+ template <typename U, typename Handler>
+ static bool check(types<U>, lua_State* L, type indextype, int index, Handler&& handler, record& tracking) {
+ tracking.use(1);
+ if (indextype != type::userdata) {
+ handler(L, index, type::userdata, indextype);
+ return false;
+ }
+ if (meta::any<std::is_same<T, lightuserdata_value>, std::is_same<T, userdata_value>, std::is_same<T, userdata>, std::is_same<T, lightuserdata>>::value)
+ return true;
+ if (lua_getmetatable(L, index) == 0) {
+ return true;
+ }
+ int metatableindex = lua_gettop(L);
+ if (stack_detail::check_metatable<U>(L, metatableindex))
+ return true;
+ if (stack_detail::check_metatable<U*>(L, metatableindex))
+ return true;
+ if (stack_detail::check_metatable<detail::unique_usertype<U>>(L, metatableindex))
+ return true;
+ bool success = false;
+ if (detail::has_derived<T>::value) {
+ auto pn = stack::pop_n(L, 1);
+ lua_pushstring(L, &detail::base_class_check_key()[0]);
+ lua_rawget(L, metatableindex);
+ if (type_of(L, -1) != type::nil) {
+ void* basecastdata = lua_touserdata(L, -1);
+ detail::inheritance_check_function ic = (detail::inheritance_check_function)basecastdata;
+ success = ic(detail::id_for<T>::value);
+ }
+ }
+ if (!success) {
+ lua_pop(L, 1);
+ handler(L, index, type::userdata, indextype);
+ return false;
+ }
+ lua_pop(L, 1);
+ return true;
+ }
+
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ const type indextype = type_of(L, index);
+ return check(types<T>(), L, indextype, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template<typename T>
+ struct checker<T, type::userdata, std::enable_if_t<is_unique_usertype<T>::value>> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return checker<typename unique_usertype_traits<T>::type, type::userdata>{}.check(L, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template<typename T, typename C>
+ struct checker<std::reference_wrapper<T>, type::userdata, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return checker<T, type::userdata, C>{}.check(L, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template<typename... Args, typename C>
+ struct checker<std::tuple<Args...>, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return stack::multi_check<Args...>(L, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template<typename A, typename B, typename C>
+ struct checker<std::pair<A, B>, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return stack::multi_check<A, B>(L, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+
+ template<typename T, typename C>
+ struct checker<optional<T>, type::poly, C> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ type t = type_of(L, index);
+ if (t == type::none) {
+ tracking.use(0);
+ return true;
+ }
+ return t == type::nil || stack::check<T>(L, index, std::forward<Handler>(handler), tracking);
+ }
+ };
+ } // stack
+} // sol
+
+#endif // SOL_STACK_CHECK_HPP
diff --git a/3rdparty/sol2/sol/stack_check_get.hpp b/3rdparty/sol2/sol/stack_check_get.hpp
new file mode 100644
index 00000000000..728d7d9a448
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_check_get.hpp
@@ -0,0 +1,114 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_CHECK_GET_HPP
+#define SOL_STACK_CHECK_GET_HPP
+
+#include "stack_core.hpp"
+#include "stack_get.hpp"
+#include "stack_check.hpp"
+#include "optional.hpp"
+
+namespace sol {
+ namespace stack {
+ template <typename T, typename>
+ struct check_getter {
+ typedef decltype(stack_detail::unchecked_get<T>(nullptr, 0, std::declval<record&>())) R;
+
+ template <typename Handler>
+ static optional<R> get(lua_State* L, int index, Handler&& handler, record& tracking) {
+ if (!check<T>(L, index, std::forward<Handler>(handler))) {
+ tracking.use(static_cast<int>(!lua_isnone(L, index)));
+ return nullopt;
+ }
+ return stack_detail::unchecked_get<T>(L, index, tracking);
+ }
+ };
+
+ template <typename T>
+ struct check_getter<optional<T>> {
+ template <typename Handler>
+ static decltype(auto) get(lua_State* L, int index, Handler&&, record& tracking) {
+ return check_get<T>(L, index, no_panic, tracking);
+ }
+ };
+
+ template <typename T>
+ struct check_getter<T, std::enable_if_t<std::is_integral<T>::value && lua_type_of<T>::value == type::number>> {
+ template <typename Handler>
+ static optional<T> get(lua_State* L, int index, Handler&& handler, record& tracking) {
+ int isnum = 0;
+ lua_Integer value = lua_tointegerx(L, index, &isnum);
+ if (isnum == 0) {
+ type t = type_of(L, index);
+ tracking.use(static_cast<int>(t != type::none));
+ handler(L, index, type::number, t);
+ return nullopt;
+ }
+ tracking.use(1);
+ return static_cast<T>(value);
+ }
+ };
+
+ template <typename T>
+ struct check_getter<T, std::enable_if_t<std::is_enum<T>::value && !meta::any_same<T, meta_function, type>::value>> {
+ template <typename Handler>
+ static optional<T> get(lua_State* L, int index, Handler&& handler, record& tracking) {
+ int isnum = 0;
+ lua_Integer value = lua_tointegerx(L, index, &isnum);
+ if (isnum == 0) {
+ type t = type_of(L, index);
+ tracking.use(static_cast<int>(t != type::none));
+ handler(L, index, type::number, t);
+ return nullopt;
+ }
+ tracking.use(1);
+ return static_cast<T>(value);
+ }
+ };
+
+ template <typename T>
+ struct check_getter<T, std::enable_if_t<std::is_floating_point<T>::value>> {
+ template <typename Handler>
+ static optional<T> get(lua_State* L, int index, Handler&& handler, record& tracking) {
+ int isnum = 0;
+ lua_Number value = lua_tonumberx(L, index, &isnum);
+ if (isnum == 0) {
+ type t = type_of(L, index);
+ tracking.use(static_cast<int>(t != type::none));
+ handler(L, index, type::number, t);
+ return nullopt;
+ }
+ tracking.use(1);
+ return static_cast<T>(value);
+ }
+ };
+
+ template <typename T>
+ struct getter<optional<T>> {
+ static decltype(auto) get(lua_State* L, int index, record& tracking) {
+ return check_get<T>(L, index, no_panic, tracking);
+ }
+ };
+ } // stack
+} // sol
+
+#endif // SOL_STACK_CHECK_GET_HPP
diff --git a/3rdparty/sol2/sol/stack_core.hpp b/3rdparty/sol2/sol/stack_core.hpp
new file mode 100644
index 00000000000..910399f3793
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_core.hpp
@@ -0,0 +1,410 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_CORE_HPP
+#define SOL_STACK_CORE_HPP
+
+#include "types.hpp"
+#include "reference.hpp"
+#include "stack_reference.hpp"
+#include "userdata.hpp"
+#include "tuple.hpp"
+#include "traits.hpp"
+#include "tie.hpp"
+#include "stack_guard.hpp"
+#include <vector>
+#include <string>
+
+namespace sol {
+ namespace detail {
+ struct as_reference_tag {};
+ template <typename T>
+ struct as_pointer_tag {};
+ template <typename T>
+ struct as_value_tag {};
+
+ using special_destruct_func = void(*)(void*);
+
+ template <typename T, typename Real>
+ inline void special_destruct(void* memory) {
+ T** pointerpointer = static_cast<T**>(memory);
+ special_destruct_func* dx = static_cast<special_destruct_func*>(static_cast<void*>(pointerpointer + 1));
+ Real* target = static_cast<Real*>(static_cast<void*>(dx + 1));
+ target->~Real();
+ }
+
+ template <typename T>
+ inline int unique_destruct(lua_State* L) {
+ void* memory = lua_touserdata(L, 1);
+ T** pointerpointer = static_cast<T**>(memory);
+ special_destruct_func& dx = *static_cast<special_destruct_func*>(static_cast<void*>(pointerpointer + 1));
+ (dx)(memory);
+ return 0;
+ }
+
+ template <typename T>
+ inline int user_alloc_destroy(lua_State* L) {
+ void* rawdata = lua_touserdata(L, upvalue_index(1));
+ T* data = static_cast<T*>(rawdata);
+ std::allocator<T> alloc;
+ alloc.destroy(data);
+ return 0;
+ }
+
+ template <typename T>
+ inline int usertype_alloc_destroy(lua_State* L) {
+ void* rawdata = lua_touserdata(L, 1);
+ T** pdata = static_cast<T**>(rawdata);
+ T* data = *pdata;
+ std::allocator<T> alloc{};
+ alloc.destroy(data);
+ return 0;
+ }
+
+ template <typename T>
+ void reserve(T&, std::size_t) {}
+
+ template <typename T, typename Al>
+ void reserve(std::vector<T, Al>& arr, std::size_t hint) {
+ arr.reserve(hint);
+ }
+
+ template <typename T, typename Tr, typename Al>
+ void reserve(std::basic_string<T, Tr, Al>& arr, std::size_t hint) {
+ arr.reserve(hint);
+ }
+ } // detail
+
+ namespace stack {
+
+ template<typename T, bool global = false, bool raw = false, typename = void>
+ struct field_getter;
+ template <typename T, bool global = false, bool raw = false, typename = void>
+ struct probe_field_getter;
+ template<typename T, bool global = false, bool raw = false, typename = void>
+ struct field_setter;
+ template<typename T, typename = void>
+ struct getter;
+ template<typename T, typename = void>
+ struct popper;
+ template<typename T, typename = void>
+ struct pusher;
+ template<typename T, type = lua_type_of<T>::value, typename = void>
+ struct checker;
+ template<typename T, typename = void>
+ struct check_getter;
+
+ struct probe {
+ bool success;
+ int levels;
+
+ probe(bool s, int l) : success(s), levels(l) {}
+
+ operator bool() const { return success; };
+ };
+
+ struct record {
+ int last;
+ int used;
+
+ record() : last(), used() {}
+ void use(int count) {
+ last = count;
+ used += count;
+ }
+ };
+
+ namespace stack_detail {
+ template <typename T>
+ struct strip {
+ typedef T type;
+ };
+ template <typename T>
+ struct strip<std::reference_wrapper<T>> {
+ typedef T& type;
+ };
+ template <typename T>
+ struct strip<user<T>> {
+ typedef T& type;
+ };
+ template <typename T>
+ struct strip<non_null<T>> {
+ typedef T type;
+ };
+ template <typename T>
+ using strip_t = typename strip<T>::type;
+ const bool default_check_arguments =
+#ifdef SOL_CHECK_ARGUMENTS
+ true;
+#else
+ false;
+#endif
+ template<typename T>
+ inline decltype(auto) unchecked_get(lua_State* L, int index, record& tracking) {
+ return getter<meta::unqualified_t<T>>{}.get(L, index, tracking);
+ }
+ } // stack_detail
+
+ inline bool maybe_indexable(lua_State* L, int index = -1) {
+ type t = type_of(L, index);
+ return t == type::userdata || t == type::table;
+ }
+
+ template<typename T, typename... Args>
+ inline int push(lua_State* L, T&& t, Args&&... args) {
+ return pusher<meta::unqualified_t<T>>{}.push(L, std::forward<T>(t), std::forward<Args>(args)...);
+ }
+
+ // overload allows to use a pusher of a specific type, but pass in any kind of args
+ template<typename T, typename Arg, typename... Args, typename = std::enable_if_t<!std::is_same<T, Arg>::value>>
+ inline int push(lua_State* L, Arg&& arg, Args&&... args) {
+ return pusher<meta::unqualified_t<T>>{}.push(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
+ }
+
+ template<typename T, typename... Args>
+ inline int push_reference(lua_State* L, T&& t, Args&&... args) {
+ typedef meta::all<
+ std::is_lvalue_reference<T>,
+ meta::neg<std::is_const<T>>,
+ meta::neg<is_lua_primitive<meta::unqualified_t<T>>>,
+ meta::neg<is_unique_usertype<meta::unqualified_t<T>>>
+ > use_reference_tag;
+ return pusher<std::conditional_t<use_reference_tag::value, detail::as_reference_tag, meta::unqualified_t<T>>>{}.push(L, std::forward<T>(t), std::forward<Args>(args)...);
+ }
+
+ inline int multi_push(lua_State*) {
+ // do nothing
+ return 0;
+ }
+
+ template<typename T, typename... Args>
+ inline int multi_push(lua_State* L, T&& t, Args&&... args) {
+ int pushcount = push(L, std::forward<T>(t));
+ void(sol::detail::swallow{ (pushcount += sol::stack::push(L, std::forward<Args>(args)), 0)... });
+ return pushcount;
+ }
+
+ inline int multi_push_reference(lua_State*) {
+ // do nothing
+ return 0;
+ }
+
+ template<typename T, typename... Args>
+ inline int multi_push_reference(lua_State* L, T&& t, Args&&... args) {
+ int pushcount = push_reference(L, std::forward<T>(t));
+ void(sol::detail::swallow{ (pushcount += sol::stack::push_reference(L, std::forward<Args>(args)), 0)... });
+ return pushcount;
+ }
+
+ template <typename T, typename Handler>
+ bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ typedef meta::unqualified_t<T> Tu;
+ checker<Tu> c;
+ // VC++ has a bad warning here: shut it up
+ (void)c;
+ return c.check(L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template <typename T, typename Handler>
+ bool check(lua_State* L, int index, Handler&& handler) {
+ record tracking{};
+ return check<T>(L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template <typename T>
+ bool check(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
+ auto handler = no_panic;
+ return check<T>(L, index, handler);
+ }
+
+ template<typename T, typename Handler>
+ inline decltype(auto) check_get(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return check_getter<meta::unqualified_t<T>>{}.get(L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template<typename T, typename Handler>
+ inline decltype(auto) check_get(lua_State* L, int index, Handler&& handler) {
+ record tracking{};
+ return check_get<T>(L, index, handler, tracking);
+ }
+
+ template<typename T>
+ inline decltype(auto) check_get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
+ auto handler = no_panic;
+ return check_get<T>(L, index, handler);
+ }
+
+ namespace stack_detail {
+
+#ifdef SOL_CHECK_ARGUMENTS
+ template <typename T>
+ inline auto tagged_get(types<T>, lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) {
+ auto op = check_get<T>(L, index, type_panic, tracking);
+ return *op;
+ }
+#else
+ template <typename T>
+ inline decltype(auto) tagged_get(types<T>, lua_State* L, int index, record& tracking) {
+ return stack_detail::unchecked_get<T>(L, index, tracking);
+ }
+#endif
+
+ template <typename T>
+ inline decltype(auto) tagged_get(types<optional<T>>, lua_State* L, int index, record& tracking) {
+ return stack_detail::unchecked_get<optional<T>>(L, index, tracking);
+ }
+
+ template <bool b>
+ struct check_types {
+ template <typename T, typename... Args, typename Handler>
+ static bool check(types<T, Args...>, lua_State* L, int firstargument, Handler&& handler, record& tracking) {
+ if (!stack::check<T>(L, firstargument + tracking.used, handler, tracking))
+ return false;
+ return check(types<Args...>(), L, firstargument, std::forward<Handler>(handler), tracking);
+ }
+
+ template <typename Handler>
+ static bool check(types<>, lua_State*, int, Handler&&, record&) {
+ return true;
+ }
+ };
+
+ template <>
+ struct check_types<false> {
+ template <typename... Args, typename Handler>
+ static bool check(types<Args...>, lua_State*, int, Handler&&, record&) {
+ return true;
+ }
+ };
+
+ } // stack_detail
+
+ template <bool b, typename... Args, typename Handler>
+ bool multi_check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return stack_detail::check_types<b>{}.check(types<meta::unqualified_t<Args>...>(), L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template <bool b, typename... Args, typename Handler>
+ bool multi_check(lua_State* L, int index, Handler&& handler) {
+ record tracking{};
+ return multi_check<b, Args...>(L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template <bool b, typename... Args>
+ bool multi_check(lua_State* L, int index) {
+ auto handler = no_panic;
+ return multi_check<b, Args...>(L, index, handler);
+ }
+
+ template <typename... Args, typename Handler>
+ bool multi_check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ return multi_check<true, Args...>(L, index, std::forward<Handler>(handler), tracking);
+ }
+
+ template <typename... Args, typename Handler>
+ bool multi_check(lua_State* L, int index, Handler&& handler) {
+ return multi_check<true, Args...>(L, index, std::forward<Handler>(handler));
+ }
+
+ template <typename... Args>
+ bool multi_check(lua_State* L, int index) {
+ return multi_check<true, Args...>(L, index);
+ }
+
+ template<typename T>
+ inline decltype(auto) get(lua_State* L, int index, record& tracking) {
+ return stack_detail::tagged_get(types<T>(), L, index, tracking);
+ }
+
+ template<typename T>
+ inline decltype(auto) get(lua_State* L, int index = -lua_size<meta::unqualified_t<T>>::value) {
+ record tracking{};
+ return get<T>(L, index, tracking);
+ }
+
+ template<typename T>
+ inline decltype(auto) pop(lua_State* L) {
+ return popper<meta::unqualified_t<T>>{}.pop(L);
+ }
+
+ template <bool global = false, bool raw = false, typename Key>
+ void get_field(lua_State* L, Key&& key) {
+ field_getter<meta::unqualified_t<Key>, global, raw>{}.get(L, std::forward<Key>(key));
+ }
+
+ template <bool global = false, bool raw = false, typename Key>
+ void get_field(lua_State* L, Key&& key, int tableindex) {
+ field_getter<meta::unqualified_t<Key>, global, raw>{}.get(L, std::forward<Key>(key), tableindex);
+ }
+
+ template <bool global = false, typename Key>
+ void raw_get_field(lua_State* L, Key&& key) {
+ get_field<global, true>(L, std::forward<Key>(key));
+ }
+
+ template <bool global = false, typename Key>
+ void raw_get_field(lua_State* L, Key&& key, int tableindex) {
+ get_field<global, true>(L, std::forward<Key>(key), tableindex);
+ }
+
+ template <bool global = false, bool raw = false, typename Key>
+ probe probe_get_field(lua_State* L, Key&& key) {
+ return probe_field_getter<meta::unqualified_t<Key>, global, raw>{}.get(L, std::forward<Key>(key));
+ }
+
+ template <bool global = false, bool raw = false, typename Key>
+ probe probe_get_field(lua_State* L, Key&& key, int tableindex) {
+ return probe_field_getter<meta::unqualified_t<Key>, global, raw>{}.get(L, std::forward<Key>(key), tableindex);
+ }
+
+ template <bool global = false, typename Key>
+ probe probe_raw_get_field(lua_State* L, Key&& key) {
+ return probe_get_field<global, true>(L, std::forward<Key>(key));
+ }
+
+ template <bool global = false, typename Key>
+ probe probe_raw_get_field(lua_State* L, Key&& key, int tableindex) {
+ return probe_get_field<global, true>(L, std::forward<Key>(key), tableindex);
+ }
+
+ template <bool global = false, bool raw = false, typename Key, typename Value>
+ void set_field(lua_State* L, Key&& key, Value&& value) {
+ field_setter<meta::unqualified_t<Key>, global, raw>{}.set(L, std::forward<Key>(key), std::forward<Value>(value));
+ }
+
+ template <bool global = false, bool raw = false, typename Key, typename Value>
+ void set_field(lua_State* L, Key&& key, Value&& value, int tableindex) {
+ field_setter<meta::unqualified_t<Key>, global, raw>{}.set(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
+ }
+
+ template <bool global = false, typename Key, typename Value>
+ void raw_set_field(lua_State* L, Key&& key, Value&& value) {
+ set_field<global, true>(L, std::forward<Key>(key), std::forward<Value>(value));
+ }
+
+ template <bool global = false, typename Key, typename Value>
+ void raw_set_field(lua_State* L, Key&& key, Value&& value, int tableindex) {
+ set_field<global, true>(L, std::forward<Key>(key), std::forward<Value>(value), tableindex);
+ }
+ } // stack
+} // sol
+
+#endif // SOL_STACK_CORE_HPP
diff --git a/3rdparty/sol2/sol/stack_field.hpp b/3rdparty/sol2/sol/stack_field.hpp
new file mode 100644
index 00000000000..ca52f3dbdb7
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_field.hpp
@@ -0,0 +1,261 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_FIELD_HPP
+#define SOL_STACK_FIELD_HPP
+
+#include "stack_core.hpp"
+#include "stack_push.hpp"
+#include "stack_get.hpp"
+#include "stack_check_get.hpp"
+
+namespace sol {
+ namespace stack {
+ template <typename T, bool, bool, typename>
+ struct field_getter {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int tableindex = -2) {
+ push(L, std::forward<Key>(key));
+ lua_gettable(L, tableindex);
+ }
+ };
+
+ template <typename T, bool global, typename C>
+ struct field_getter<T, global, true, C> {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int tableindex = -2) {
+ push(L, std::forward<Key>(key));
+ lua_rawget(L, tableindex);
+ }
+ };
+
+ template <bool b, bool raw, typename C>
+ struct field_getter<metatable_key_t, b, raw, C> {
+ void get(lua_State* L, metatable_key_t, int tableindex = -1) {
+ if (lua_getmetatable(L, tableindex) == 0)
+ push(L, nil);
+ }
+ };
+
+ template <typename T, bool raw>
+ struct field_getter<T, true, raw, std::enable_if_t<meta::is_c_str<T>::value>> {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int = -1) {
+ lua_getglobal(L, &key[0]);
+ }
+ };
+
+ template <typename T>
+ struct field_getter<T, false, false, std::enable_if_t<meta::is_c_str<T>::value>> {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int tableindex = -1) {
+ lua_getfield(L, tableindex, &key[0]);
+ }
+ };
+
+#if SOL_LUA_VERSION >= 503
+ template <typename T>
+ struct field_getter<T, false, false, std::enable_if_t<std::is_integral<T>::value>> {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int tableindex = -1) {
+ lua_geti(L, tableindex, static_cast<lua_Integer>(key));
+ }
+ };
+#endif // Lua 5.3.x
+
+#if SOL_LUA_VERSION >= 502
+ template <typename C>
+ struct field_getter<void*, false, true, C> {
+ void get(lua_State* L, void* key, int tableindex = -1) {
+ lua_rawgetp(L, tableindex, key);
+ }
+ };
+#endif // Lua 5.3.x
+
+ template <typename T>
+ struct field_getter<T, false, true, std::enable_if_t<std::is_integral<T>::value>> {
+ template <typename Key>
+ void get(lua_State* L, Key&& key, int tableindex = -1) {
+ lua_rawgeti(L, tableindex, static_cast<lua_Integer>(key));
+ }
+ };
+
+ template <typename... Args, bool b, bool raw, typename C>
+ struct field_getter<std::tuple<Args...>, b, raw, C> {
+ template <std::size_t... I, typename Keys>
+ void apply(std::index_sequence<0, I...>, lua_State* L, Keys&& keys, int tableindex) {
+ get_field<b, raw>(L, detail::forward_get<0>(keys), tableindex);
+ void(detail::swallow{ (get_field<false, raw>(L, detail::forward_get<I>(keys)), 0)... });
+ reference saved(L, -1);
+ lua_pop(L, static_cast<int>(sizeof...(I)));
+ saved.push();
+ }
+
+ template <typename Keys>
+ void get(lua_State* L, Keys&& keys) {
+ apply(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), lua_absindex(L, -1));
+ }
+
+ template <typename Keys>
+ void get(lua_State* L, Keys&& keys, int tableindex) {
+ apply(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), tableindex);
+ }
+ };
+
+ template <typename A, typename B, bool b, bool raw, typename C>
+ struct field_getter<std::pair<A, B>, b, raw, C> {
+ template <typename Keys>
+ void get(lua_State* L, Keys&& keys, int tableindex) {
+ get_field<b, raw>(L, detail::forward_get<0>(keys), tableindex);
+ get_field<false, raw>(L, detail::forward_get<1>(keys));
+ reference saved(L, -1);
+ lua_pop(L, static_cast<int>(2));
+ saved.push();
+ }
+
+ template <typename Keys>
+ void get(lua_State* L, Keys&& keys) {
+ get_field<b, raw>(L, detail::forward_get<0>(keys));
+ get_field<false, raw>(L, detail::forward_get<1>(keys));
+ reference saved(L, -1);
+ lua_pop(L, static_cast<int>(2));
+ saved.push();
+ }
+ };
+
+ template <typename T, bool, bool, typename>
+ struct field_setter {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int tableindex = -3) {
+ push(L, std::forward<Key>(key));
+ push(L, std::forward<Value>(value));
+ lua_settable(L, tableindex);
+ }
+ };
+
+ template <typename T, bool b, typename C>
+ struct field_setter<T, b, true, C> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int tableindex = -3) {
+ push(L, std::forward<Key>(key));
+ push(L, std::forward<Value>(value));
+ lua_rawset(L, tableindex);
+ }
+ };
+
+ template <bool b, bool raw, typename C>
+ struct field_setter<metatable_key_t, b, raw, C> {
+ template <typename Value>
+ void set(lua_State* L, metatable_key_t, Value&& value, int tableindex = -2) {
+ push(L, std::forward<Value>(value));
+ lua_setmetatable(L, tableindex);
+ }
+ };
+
+ template <typename T, bool raw>
+ struct field_setter<T, true, raw, std::enable_if_t<meta::is_c_str<T>::value>> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int = -2) {
+ push(L, std::forward<Value>(value));
+ lua_setglobal(L, &key[0]);
+ }
+ };
+
+ template <typename T>
+ struct field_setter<T, false, false, std::enable_if_t<meta::is_c_str<T>::value>> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
+ push(L, std::forward<Value>(value));
+ lua_setfield(L, tableindex, &key[0]);
+ }
+ };
+
+#if SOL_LUA_VERSION >= 503
+ template <typename T>
+ struct field_setter<T, false, false, std::enable_if_t<std::is_integral<T>::value>> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
+ push(L, std::forward<Value>(value));
+ lua_seti(L, tableindex, static_cast<lua_Integer>(key));
+ }
+ };
+#endif // Lua 5.3.x
+
+ template <typename T>
+ struct field_setter<T, false, true, std::enable_if_t<std::is_integral<T>::value>> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
+ push(L, std::forward<Value>(value));
+ lua_rawseti(L, tableindex, static_cast<lua_Integer>(key));
+ }
+ };
+
+#if SOL_LUA_VERSION >= 502
+ template <typename C>
+ struct field_setter<void*, false, true, C> {
+ template <typename Key, typename Value>
+ void set(lua_State* L, void* key, Value&& value, int tableindex = -2) {
+ push(L, std::forward<Value>(value));
+ lua_rawsetp(L, tableindex, key);
+ }
+ };
+#endif // Lua 5.2.x
+
+ template <typename... Args, bool b, bool raw, typename C>
+ struct field_setter<std::tuple<Args...>, b, raw, C> {
+ template <bool g, std::size_t I, typename Key, typename Value>
+ void apply(std::index_sequence<I>, lua_State* L, Key&& keys, Value&& value, int tableindex) {
+ I < 1 ?
+ set_field<g, raw>(L, detail::forward_get<I>(keys), std::forward<Value>(value), tableindex) :
+ set_field<g, raw>(L, detail::forward_get<I>(keys), std::forward<Value>(value));
+ }
+
+ template <bool g, std::size_t I0, std::size_t I1, std::size_t... I, typename Keys, typename Value>
+ void apply(std::index_sequence<I0, I1, I...>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
+ I0 < 1 ? get_field<g, raw>(L, detail::forward_get<I0>(keys), tableindex) : get_field<g, raw>(L, detail::forward_get<I0>(keys), -1);
+ apply<false>(std::index_sequence<I1, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), -1);
+ }
+
+ template <bool g, std::size_t I0, std::size_t... I, typename Keys, typename Value>
+ void top_apply(std::index_sequence<I0, I...>, lua_State* L, Keys&& keys, Value&& value, int tableindex) {
+ apply<g>(std::index_sequence<I0, I...>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
+ lua_pop(L, static_cast<int>(sizeof...(I)));
+ }
+
+ template <typename Keys, typename Value>
+ void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -3) {
+ top_apply<b>(std::make_index_sequence<sizeof...(Args)>(), L, std::forward<Keys>(keys), std::forward<Value>(value), tableindex);
+ }
+ };
+
+ template <typename A, typename B, bool b, bool raw, typename C>
+ struct field_setter<std::pair<A, B>, b, raw, C> {
+ template <typename Keys, typename Value>
+ void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -1) {
+ get_field<b, raw>(L, detail::forward_get<0>(keys), tableindex);
+ set_field<false, raw>(L, detail::forward_get<1>(keys), std::forward<Value>(value));
+ lua_pop(L, 1);
+ }
+ };
+ } // stack
+} // sol
+
+#endif // SOL_STACK_FIELD_HPP
diff --git a/3rdparty/sol2/sol/stack_get.hpp b/3rdparty/sol2/sol/stack_get.hpp
new file mode 100644
index 00000000000..52c52efa10e
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_get.hpp
@@ -0,0 +1,537 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_GET_HPP
+#define SOL_STACK_GET_HPP
+
+#include "stack_core.hpp"
+#include "usertype_traits.hpp"
+#include "inheritance.hpp"
+#include "overload.hpp"
+#include "error.hpp"
+#include <memory>
+#include <functional>
+#include <utility>
+#ifdef SOL_CODECVT_SUPPORT
+#include <codecvt>
+#include <locale>
+#endif
+
+namespace sol {
+ namespace stack {
+
+ template<typename T, typename>
+ struct getter {
+ static T& get(lua_State* L, int index, record& tracking) {
+ return getter<T&>{}.get(L, index, tracking);
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<std::is_floating_point<T>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<T>(lua_tonumber(L, index));
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_signed<T>>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<T>(lua_tointeger(L, index));
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_unsigned<T>>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<T>(lua_tointeger(L, index));
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<std::is_enum<T>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<T>(lua_tointegerx(L, index, nullptr));
+ }
+ };
+
+ template<typename T>
+ struct getter<as_table_t<T>, std::enable_if_t<!meta::has_key_value_pair<meta::unqualified_t<T>>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ typedef typename T::value_type V;
+ tracking.use(1);
+
+ index = lua_absindex(L, index);
+ T arr;
+ get_field<false, true>(L, static_cast<lua_Integer>(-1), index);
+ int isnum;
+ std::size_t sizehint = static_cast<std::size_t>(lua_tointegerx(L, -1, &isnum));
+ if (isnum != 0) {
+ detail::reserve(arr, sizehint);
+ }
+ lua_pop(L, 1);
+#if SOL_LUA_VERSION >= 503
+ // This method is HIGHLY performant over regular table iteration thanks to the Lua API changes in 5.3
+ for (lua_Integer i = 0; ; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
+ for (int vi = 0; vi < lua_size<V>::value; ++vi) {
+ type t = static_cast<type>(lua_geti(L, index, i + vi));
+ if (t == type::nil) {
+ if (i == 0) {
+ continue;
+ }
+ else {
+ lua_pop(L, (vi + 1));
+ return arr;
+ }
+ }
+ }
+ arr.push_back(stack::get<V>(L, -lua_size<V>::value));
+ }
+#else
+ // Zzzz slower but necessary thanks to the lower version API and missing functions qq
+ for (lua_Integer i = 0; ; i += lua_size<V>::value, lua_pop(L, lua_size<V>::value)) {
+ for (int vi = 0; vi < lua_size<V>::value; ++vi) {
+ lua_pushinteger(L, i);
+ lua_gettable(L, index);
+ type t = type_of(L, -1);
+ if (t == type::nil) {
+ if (i == 0) {
+ continue;
+ }
+ else {
+ lua_pop(L, (vi + 1));
+ return arr;
+ }
+ }
+ }
+ arr.push_back(stack::get<V>(L, -1));
+ }
+#endif
+ return arr;
+ }
+ };
+
+ template<typename T>
+ struct getter<as_table_t<T>, std::enable_if_t<meta::has_key_value_pair<meta::unqualified_t<T>>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ typedef typename T::value_type P;
+ typedef typename P::first_type K;
+ typedef typename P::second_type V;
+ tracking.use(1);
+
+ T associative;
+ index = lua_absindex(L, index);
+ lua_pushnil(L);
+ while (lua_next(L, index) != 0) {
+ decltype(auto) key = stack::check_get<K>(L, -2);
+ if (!key) {
+ lua_pop(L, 1);
+ continue;
+ }
+ associative.emplace(std::forward<decltype(*key)>(*key), stack::get<V>(L, -1));
+ lua_pop(L, 1);
+ }
+ return associative;
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<std::is_base_of<reference, T>::value || std::is_base_of<stack_reference, T>::value>> {
+ static T get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return T(L, index);
+ }
+ };
+
+ template<>
+ struct getter<userdata_value> {
+ static userdata_value get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return userdata_value(lua_touserdata(L, index));
+ }
+ };
+
+ template<>
+ struct getter<lightuserdata_value> {
+ static lightuserdata_value get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return lightuserdata_value(lua_touserdata(L, index));
+ }
+ };
+
+ template<typename T>
+ struct getter<light<T>> {
+ static light<T> get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return light<T>(static_cast<T*>(lua_touserdata(L, index)));
+ }
+ };
+
+ template<typename T>
+ struct getter<user<T>> {
+ static T& get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return *static_cast<T*>(lua_touserdata(L, index));
+ }
+ };
+
+ template<typename T>
+ struct getter<user<T*>> {
+ static T* get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<T*>(lua_touserdata(L, index));
+ }
+ };
+
+ template<>
+ struct getter<type> {
+ static type get(lua_State *L, int index, record& tracking) {
+ tracking.use(1);
+ return static_cast<type>(lua_type(L, index));
+ }
+ };
+
+ template<>
+ struct getter<bool> {
+ static bool get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return lua_toboolean(L, index) != 0;
+ }
+ };
+
+ template<>
+ struct getter<std::string> {
+ static std::string get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ std::size_t len;
+ auto str = lua_tolstring(L, index, &len);
+ return std::string( str, len );
+ }
+ };
+
+ template <>
+ struct getter<string_detail::string_shim> {
+ string_detail::string_shim get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t len;
+ const char* p = lua_tolstring(L, index, &len);
+ return string_detail::string_shim(p, len);
+ }
+ };
+
+ template<>
+ struct getter<const char*> {
+ static const char* get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return lua_tostring(L, index);
+ }
+ };
+
+ template<>
+ struct getter<char> {
+ static char get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t len;
+ auto str = lua_tolstring(L, index, &len);
+ return len > 0 ? str[0] : '\0';
+ }
+ };
+
+#ifdef SOL_CODECVT_SUPPORT
+ template<>
+ struct getter<std::wstring> {
+ static std::wstring get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t len;
+ auto str = lua_tolstring(L, index, &len);
+ if (len < 1)
+ return std::wstring();
+ if (sizeof(wchar_t) == 2) {
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
+ std::wstring r = convert.from_bytes(str, str + len);
+#ifdef __MINGW32__
+ // Fuck you, MinGW, and fuck you libstdc++ for introducing this absolutely asinine bug
+ // https://sourceforge.net/p/mingw-w64/bugs/538/
+ // http://chat.stackoverflow.com/transcript/message/32271369#32271369
+ for (auto& c : r) {
+ uint8_t* b = reinterpret_cast<uint8_t*>(&c);
+ std::swap(b[0], b[1]);
+ }
+#endif
+ return r;
+ }
+ std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
+ std::wstring r = convert.from_bytes(str, str + len);
+ return r;
+ }
+ };
+
+ template<>
+ struct getter<std::u16string> {
+ static std::u16string get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t len;
+ auto str = lua_tolstring(L, index, &len);
+ if (len < 1)
+ return std::u16string();
+#ifdef _MSC_VER
+ std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert;
+ auto intd = convert.from_bytes(str, str + len);
+ std::u16string r(intd.size(), '\0');
+ std::memcpy(&r[0], intd.data(), intd.size() * sizeof(char16_t));
+#else
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+ std::u16string r = convert.from_bytes(str, str + len);
+#endif // VC++ is a shit
+ return r;
+ }
+ };
+
+ template<>
+ struct getter<std::u32string> {
+ static std::u32string get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t len;
+ auto str = lua_tolstring(L, index, &len);
+ if (len < 1)
+ return std::u32string();
+#ifdef _MSC_VER
+ std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> convert;
+ auto intd = convert.from_bytes(str, str + len);
+ std::u32string r(intd.size(), '\0');
+ std::memcpy(&r[0], intd.data(), r.size() * sizeof(char32_t));
+#else
+ std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
+ std::u32string r = convert.from_bytes(str, str + len);
+#endif // VC++ is a shit
+ return r;
+ }
+ };
+
+ template<>
+ struct getter<wchar_t> {
+ static wchar_t get(lua_State* L, int index, record& tracking) {
+ auto str = getter<std::wstring>{}.get(L, index, tracking);
+ return str.size() > 0 ? str[0] : wchar_t(0);
+ }
+ };
+
+ template<>
+ struct getter<char16_t> {
+ static char16_t get(lua_State* L, int index, record& tracking) {
+ auto str = getter<std::u16string>{}.get(L, index, tracking);
+ return str.size() > 0 ? str[0] : char16_t(0);
+ }
+ };
+
+ template<>
+ struct getter<char32_t> {
+ static char32_t get(lua_State* L, int index, record& tracking) {
+ auto str = getter<std::u32string>{}.get(L, index, tracking);
+ return str.size() > 0 ? str[0] : char32_t(0);
+ }
+ };
+#endif // codecvt header support
+
+ template<>
+ struct getter<meta_function> {
+ static meta_function get(lua_State *L, int index, record& tracking) {
+ tracking.use(1);
+ const char* name = getter<const char*>{}.get(L, index, tracking);
+ for (std::size_t i = 0; i < meta_function_names.size(); ++i)
+ if (meta_function_names[i] == name)
+ return static_cast<meta_function>(i);
+ return meta_function::construct;
+ }
+ };
+
+ template<>
+ struct getter<nil_t> {
+ static nil_t get(lua_State*, int, record& tracking) {
+ tracking.use(1);
+ return nil;
+ }
+ };
+
+ template<>
+ struct getter<std::nullptr_t> {
+ static std::nullptr_t get(lua_State*, int, record& tracking) {
+ tracking.use(1);
+ return nullptr;
+ }
+ };
+
+ template<>
+ struct getter<nullopt_t> {
+ static nullopt_t get(lua_State*, int, record& tracking) {
+ tracking.use(1);
+ return nullopt;
+ }
+ };
+
+ template<>
+ struct getter<this_state> {
+ static this_state get(lua_State* L, int, record& tracking) {
+ tracking.use(0);
+ return this_state{ L };
+ }
+ };
+
+ template<>
+ struct getter<lua_CFunction> {
+ static lua_CFunction get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return lua_tocfunction(L, index);
+ }
+ };
+
+ template<>
+ struct getter<c_closure> {
+ static c_closure get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return c_closure(lua_tocfunction(L, index), -1);
+ }
+ };
+
+ template<>
+ struct getter<error> {
+ static error get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ size_t sz = 0;
+ const char* err = lua_tolstring(L, index, &sz);
+ if (err == nullptr) {
+ return error(detail::direct_error, "");
+ }
+ return error(detail::direct_error, std::string(err, sz));
+ }
+ };
+
+ template<>
+ struct getter<void*> {
+ static void* get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ return lua_touserdata(L, index);
+ }
+ };
+
+ template<typename T>
+ struct getter<T*> {
+ static T* get_no_nil(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ void** pudata = static_cast<void**>(lua_touserdata(L, index));
+ void* udata = *pudata;
+ return get_no_nil_from(L, udata, index, tracking);
+ }
+
+ static T* get_no_nil_from(lua_State* L, void* udata, int index, record&) {
+ if (detail::has_derived<T>::value && luaL_getmetafield(L, index, &detail::base_class_cast_key()[0]) != 0) {
+ void* basecastdata = lua_touserdata(L, -1);
+ detail::inheritance_cast_function ic = (detail::inheritance_cast_function)basecastdata;
+ // use the casting function to properly adjust the pointer for the desired T
+ udata = ic(udata, detail::id_for<T>::value);
+ lua_pop(L, 1);
+ }
+ T* obj = static_cast<T*>(udata);
+ return obj;
+ }
+
+ static T* get(lua_State* L, int index, record& tracking) {
+ type t = type_of(L, index);
+ if (t == type::nil) {
+ tracking.use(1);
+ return nullptr;
+ }
+ return get_no_nil(L, index, tracking);
+ }
+ };
+
+ template<typename T>
+ struct getter<non_null<T*>> {
+ static T* get(lua_State* L, int index, record& tracking) {
+ return getter<T*>::get_no_nil(L, index, tracking);
+ }
+ };
+
+ template<typename T>
+ struct getter<T&> {
+ static T& get(lua_State* L, int index, record& tracking) {
+ return *getter<T*>::get_no_nil(L, index, tracking);
+ }
+ };
+
+ template<typename T>
+ struct getter<T, std::enable_if_t<is_unique_usertype<T>::value>> {
+ typedef typename unique_usertype_traits<T>::type P;
+ typedef typename unique_usertype_traits<T>::actual_type Real;
+
+ static Real& get(lua_State* L, int index, record& tracking) {
+ tracking.use(1);
+ P** pref = static_cast<P**>(lua_touserdata(L, index));
+ detail::special_destruct_func* fx = static_cast<detail::special_destruct_func*>(static_cast<void*>(pref + 1));
+ Real* mem = static_cast<Real*>(static_cast<void*>(fx + 1));
+ return *mem;
+ }
+ };
+
+ template<typename T>
+ struct getter<std::reference_wrapper<T>> {
+ static T& get(lua_State* L, int index, record& tracking) {
+ return getter<T&>{}.get(L, index, tracking);
+ }
+ };
+
+ template<typename... Args>
+ struct getter<std::tuple<Args...>> {
+ typedef std::tuple<decltype(stack::get<Args>(nullptr, 0))...> R;
+
+ template <typename... TArgs>
+ static R apply(std::index_sequence<>, lua_State*, int, record&, TArgs&&... args) {
+ // Fuck you too, VC++
+ return R{std::forward<TArgs>(args)...};
+ }
+
+ template <std::size_t I, std::size_t... Ix, typename... TArgs>
+ static R apply(std::index_sequence<I, Ix...>, lua_State* L, int index, record& tracking, TArgs&&... args) {
+ // Fuck you too, VC++
+ typedef std::tuple_element_t<I, std::tuple<Args...>> T;
+ return apply(std::index_sequence<Ix...>(), L, index, tracking, std::forward<TArgs>(args)..., stack::get<T>(L, index + tracking.used, tracking));
+ }
+
+ static R get(lua_State* L, int index, record& tracking) {
+ return apply(std::make_index_sequence<sizeof...(Args)>(), L, index, tracking);
+ }
+ };
+
+ template<typename A, typename B>
+ struct getter<std::pair<A, B>> {
+ static decltype(auto) get(lua_State* L, int index, record& tracking) {
+ return std::pair<decltype(stack::get<A>(L, index)), decltype(stack::get<B>(L, index))>{stack::get<A>(L, index, tracking), stack::get<B>(L, index + tracking.used, tracking)};
+ }
+ };
+
+ } // stack
+} // sol
+
+#endif // SOL_STACK_GET_HPP
diff --git a/3rdparty/sol2/sol/stack_guard.hpp b/3rdparty/sol2/sol/stack_guard.hpp
new file mode 100644
index 00000000000..54e359fecb8
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_guard.hpp
@@ -0,0 +1,63 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_GUARD_HPP
+#define SOL_STACK_GUARD_HPP
+
+#include "compatibility/version.hpp"
+#include "error.hpp"
+#include <functional>
+
+namespace sol {
+ namespace detail {
+ inline void stack_fail(int, int) {
+#ifndef SOL_NO_EXCEPTIONS
+ throw error(detail::direct_error, "imbalanced stack after operation finish");
+#else
+ // Lol, what do you want, an error printout? :3c
+ // There's no sane default here. The right way would be C-style abort(), and that's not acceptable, so
+ // hopefully someone will register their own stack_fail thing for the `fx` parameter of stack_guard.
+#endif // No Exceptions
+ }
+ } // detail
+
+ struct stack_guard {
+ lua_State* L;
+ int top;
+ std::function<void(int, int)> on_mismatch;
+
+ stack_guard(lua_State* L) : stack_guard(L, lua_gettop(L)) {}
+ stack_guard(lua_State* L, int top, std::function<void(int, int)> fx = detail::stack_fail) : L(L), top(top), on_mismatch(std::move(fx)) {}
+ bool check_stack(int modification = 0) const {
+ int bottom = lua_gettop(L) + modification;
+ if (top == bottom) {
+ return true;
+ }
+ on_mismatch(top, bottom);
+ return false;
+ }
+ ~stack_guard() {
+ check_stack();
+ }
+ };
+} // sol
+
+#endif // SOL_STACK_GUARD_HPP
diff --git a/3rdparty/sol2/sol/stack_pop.hpp b/3rdparty/sol2/sol/stack_pop.hpp
new file mode 100644
index 00000000000..f69701311e5
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_pop.hpp
@@ -0,0 +1,49 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_POP_HPP
+#define SOL_STACK_POP_HPP
+
+#include "stack_core.hpp"
+#include "stack_get.hpp"
+#include <utility>
+#include <tuple>
+
+namespace sol {
+ namespace stack {
+ template <typename T, typename>
+ struct popper {
+ inline static decltype(auto) pop(lua_State* L) {
+ record tracking{};
+ decltype(auto) r = get<T>(L, -lua_size<T>::value, tracking);
+ lua_pop(L, tracking.used);
+ return r;
+ }
+ };
+
+ template <typename T>
+ struct popper<T, std::enable_if_t<std::is_base_of<stack_reference, meta::unqualified_t<T>>::value>> {
+ static_assert(meta::neg<std::is_base_of<stack_reference, meta::unqualified_t<T>>>::value, "You cannot pop something that derives from stack_reference: it will not remain on the stack and thusly will go out of scope!");
+ };
+ } // stack
+} // sol
+
+#endif // SOL_STACK_POP_HPP
diff --git a/3rdparty/sol2/sol/stack_probe.hpp b/3rdparty/sol2/sol/stack_probe.hpp
new file mode 100644
index 00000000000..05836da4ad2
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_probe.hpp
@@ -0,0 +1,87 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_PROBE_HPP
+#define SOL_STACK_PROBE_HPP
+
+#include "stack_core.hpp"
+#include "stack_field.hpp"
+#include "stack_check.hpp"
+
+namespace sol {
+ namespace stack {
+ template <typename T, bool b, bool raw, typename>
+ struct probe_field_getter {
+ template <typename Key>
+ probe get(lua_State* L, Key&& key, int tableindex = -2) {
+ if (!b && !maybe_indexable(L, tableindex)) {
+ return probe(false, 0);
+ }
+ get_field<b, raw>(L, std::forward<Key>(key), tableindex);
+ return probe(!check<nil_t>(L), 1);
+ }
+ };
+
+ template <typename A, typename B, bool b, bool raw, typename C>
+ struct probe_field_getter<std::pair<A, B>, b, raw, C> {
+ template <typename Keys>
+ probe get(lua_State* L, Keys&& keys, int tableindex = -2) {
+ if (!b && !maybe_indexable(L, tableindex)) {
+ return probe(false, 0);
+ }
+ get_field<b, raw>(L, std::get<0>(keys), tableindex);
+ if (!maybe_indexable(L)) {
+ return probe(false, 1);
+ }
+ get_field<false, raw>(L, std::get<1>(keys), tableindex);
+ return probe(!check<nil_t>(L), 2);
+ }
+ };
+
+ template <typename... Args, bool b, bool raw, typename C>
+ struct probe_field_getter<std::tuple<Args...>, b, raw, C> {
+ template <std::size_t I, typename Keys>
+ probe apply(std::index_sequence<I>, int sofar, lua_State* L, Keys&& keys, int tableindex) {
+ get_field < I < 1 && b, raw>(L, std::get<I>(keys), tableindex);
+ return probe(!check<nil_t>(L), sofar);
+ }
+
+ template <std::size_t I, std::size_t I1, std::size_t... In, typename Keys>
+ probe apply(std::index_sequence<I, I1, In...>, int sofar, lua_State* L, Keys&& keys, int tableindex) {
+ get_field < I < 1 && b, raw>(L, std::get<I>(keys), tableindex);
+ if (!maybe_indexable(L)) {
+ return probe(false, sofar);
+ }
+ return apply(std::index_sequence<I1, In...>(), sofar + 1, L, std::forward<Keys>(keys), -1);
+ }
+
+ template <typename Keys>
+ probe get(lua_State* L, Keys&& keys, int tableindex = -2) {
+ if (!b && !maybe_indexable(L, tableindex)) {
+ return probe(false, 0);
+ }
+ return apply(std::index_sequence_for<Args...>(), 1, L, std::forward<Keys>(keys), tableindex);
+ }
+ };
+ } // stack
+} // sol
+
+#endif // SOL_STACK_PROBE_HPP \ No newline at end of file
diff --git a/3rdparty/sol2/sol/stack_proxy.hpp b/3rdparty/sol2/sol/stack_proxy.hpp
new file mode 100644
index 00000000000..c1959233b63
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_proxy.hpp
@@ -0,0 +1,124 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_PROXY_HPP
+#define SOL_STACK_PROXY_HPP
+
+#include "stack.hpp"
+#include "function.hpp"
+#include "protected_function.hpp"
+#include "proxy_base.hpp"
+
+namespace sol {
+ struct stack_proxy : public proxy_base<stack_proxy> {
+ private:
+ lua_State* L;
+ int index;
+
+ public:
+ stack_proxy() : L(nullptr), index(0) {}
+ stack_proxy(lua_State* L, int index) : L(L), index(index) {}
+
+ template<typename T>
+ decltype(auto) get() const {
+ return stack::get<T>(L, stack_index());
+ }
+
+ int push() const {
+ lua_pushvalue(L, index);
+ return 1;
+ }
+
+ lua_State* lua_state() const { return L; }
+ int stack_index() const { return index; }
+
+ template<typename... Ret, typename... Args>
+ decltype(auto) call(Args&&... args) {
+ return get<function>().template call<Ret...>(std::forward<Args>(args)...);
+ }
+
+ template<typename... Args>
+ decltype(auto) operator()(Args&&... args) {
+ return call<>(std::forward<Args>(args)...);
+ }
+ };
+
+ namespace stack {
+ template <>
+ struct getter<stack_proxy> {
+ static stack_proxy get(lua_State* L, int index = -1) {
+ return stack_proxy(L, index);
+ }
+ };
+
+ template <>
+ struct pusher<stack_proxy> {
+ static int push(lua_State*, const stack_proxy& ref) {
+ return ref.push();
+ }
+ };
+ } // stack
+
+ namespace detail {
+ template <>
+ struct is_speshul<function_result> : std::true_type {};
+ template <>
+ struct is_speshul<protected_function_result> : std::true_type {};
+
+ template <std::size_t I, typename... Args, typename T>
+ stack_proxy get(types<Args...>, index_value<0>, index_value<I>, const T& fr) {
+ return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
+ }
+
+ template <std::size_t I, std::size_t N, typename Arg, typename... Args, typename T, meta::enable<meta::boolean<(N > 0)>> = meta::enabler>
+ stack_proxy get(types<Arg, Args...>, index_value<N>, index_value<I>, const T& fr) {
+ return get(types<Args...>(), index_value<N - 1>(), index_value<I + lua_size<Arg>::value>(), fr);
+ }
+ }
+
+ template <>
+ struct tie_size<function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
+
+ template <std::size_t I>
+ stack_proxy get(const function_result& fr) {
+ return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
+ }
+
+ template <std::size_t I, typename... Args>
+ stack_proxy get(types<Args...> t, const function_result& fr) {
+ return detail::get(t, index_value<I>(), index_value<0>(), fr);
+ }
+
+ template <>
+ struct tie_size<protected_function_result> : std::integral_constant<std::size_t, SIZE_MAX> {};
+
+ template <std::size_t I>
+ stack_proxy get(const protected_function_result& fr) {
+ return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
+ }
+
+ template <std::size_t I, typename... Args>
+ stack_proxy get(types<Args...> t, const protected_function_result& fr) {
+ return detail::get(t, index_value<I>(), index_value<0>(), fr);
+ }
+} // sol
+
+#endif // SOL_STACK_PROXY_HPP
diff --git a/3rdparty/sol2/sol/stack_push.hpp b/3rdparty/sol2/sol/stack_push.hpp
new file mode 100644
index 00000000000..27d28fc081e
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_push.hpp
@@ -0,0 +1,693 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_PUSH_HPP
+#define SOL_STACK_PUSH_HPP
+
+#include "stack_core.hpp"
+#include "raii.hpp"
+#include "optional.hpp"
+#include <memory>
+#ifdef SOL_CODECVT_SUPPORT
+#include <codecvt>
+#include <locale>
+#endif
+
+namespace sol {
+ namespace stack {
+ template <typename T>
+ struct pusher<detail::as_value_tag<T>> {
+ template <typename F, typename... Args>
+ static int push_fx(lua_State* L, F&& f, Args&&... args) {
+ // Basically, we store all user-data like this:
+ // If it's a movable/copyable value (no std::ref(x)), then we store the pointer to the new
+ // data in the first sizeof(T*) bytes, and then however many bytes it takes to
+ // do the actual object. Things that are std::ref or plain T* are stored as
+ // just the sizeof(T*), and nothing else.
+ T** pointerpointer = static_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
+ T*& referencereference = *pointerpointer;
+ T* allocationtarget = reinterpret_cast<T*>(pointerpointer + 1);
+ referencereference = allocationtarget;
+ std::allocator<T> alloc{};
+ alloc.construct(allocationtarget, std::forward<Args>(args)...);
+ f();
+ return 1;
+ }
+
+ template <typename K, typename... Args>
+ static int push_keyed(lua_State* L, K&& k, Args&&... args) {
+ return push_fx(L, [&L, &k]() {
+ luaL_newmetatable(L, &k[0]);
+ lua_setmetatable(L, -2);
+ }, std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static int push(lua_State* L, Args&&... args) {
+ return push_keyed(L, usertype_traits<T>::metatable, std::forward<Args>(args)...);
+ }
+ };
+
+ template <typename T>
+ struct pusher<detail::as_pointer_tag<T>> {
+ template <typename F>
+ static int push_fx(lua_State* L, F&& f, T* obj) {
+ if (obj == nullptr)
+ return stack::push(L, nil);
+ T** pref = static_cast<T**>(lua_newuserdata(L, sizeof(T*)));
+ *pref = obj;
+ f();
+ return 1;
+ }
+
+ template <typename K>
+ static int push_keyed(lua_State* L, K&& k, T* obj) {
+ return push_fx(L, [&L, &k]() {
+ luaL_newmetatable(L, &k[0]);
+ lua_setmetatable(L, -2);
+ }, obj);
+ }
+
+ static int push(lua_State* L, T* obj) {
+ return push_keyed(L, usertype_traits<meta::unqualified_t<T>*>::metatable, obj);
+ }
+ };
+
+ template <>
+ struct pusher<detail::as_reference_tag> {
+ template <typename T>
+ static int push(lua_State* L, T&& obj) {
+ return stack::push(L, detail::ptr(obj));
+ }
+ };
+
+ template<typename T, typename>
+ struct pusher {
+ template <typename... Args>
+ static int push(lua_State* L, Args&&... args) {
+ return pusher<detail::as_value_tag<T>>{}.push(L, std::forward<Args>(args)...);
+ }
+ };
+
+ template<typename T>
+ struct pusher<T*, meta::disable_if_t<meta::all<meta::has_begin_end<meta::unqualified_t<T>>, meta::neg<meta::any<std::is_base_of<reference, meta::unqualified_t<T>>, std::is_base_of<stack_reference, meta::unqualified_t<T>>>>>::value>> {
+ template <typename... Args>
+ static int push(lua_State* L, Args&&... args) {
+ return pusher<detail::as_pointer_tag<T>>{}.push(L, std::forward<Args>(args)...);
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<is_unique_usertype<T>::value>> {
+ typedef typename unique_usertype_traits<T>::type P;
+ typedef typename unique_usertype_traits<T>::actual_type Real;
+
+ template <typename Arg, meta::enable<std::is_base_of<Real, meta::unqualified_t<Arg>>> = meta::enabler>
+ static int push(lua_State* L, Arg&& arg) {
+ if (unique_usertype_traits<T>::is_null(arg))
+ return stack::push(L, nil);
+ return push_deep(L, std::forward<Arg>(arg));
+ }
+
+ template <typename Arg0, typename Arg1, typename... Args>
+ static int push(lua_State* L, Arg0&& arg0, Arg0&& arg1, Args&&... args) {
+ return push_deep(L, std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static int push_deep(lua_State* L, Args&&... args) {
+ P** pref = static_cast<P**>(lua_newuserdata(L, sizeof(P*) + sizeof(detail::special_destruct_func) + sizeof(Real)));
+ detail::special_destruct_func* fx = static_cast<detail::special_destruct_func*>(static_cast<void*>(pref + 1));
+ Real* mem = static_cast<Real*>(static_cast<void*>(fx + 1));
+ *fx = detail::special_destruct<P, Real>;
+ detail::default_construct::construct(mem, std::forward<Args>(args)...);
+ *pref = unique_usertype_traits<T>::get(*mem);
+ if (luaL_newmetatable(L, &usertype_traits<detail::unique_usertype<P>>::metatable[0]) == 1) {
+ set_field(L, "__gc", detail::unique_destruct<P>);
+ }
+ lua_setmetatable(L, -2);
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<std::reference_wrapper<T>> {
+ static int push(lua_State* L, const std::reference_wrapper<T>& t) {
+ return stack::push(L, std::addressof(detail::deref(t.get())));
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<std::is_floating_point<T>::value>> {
+ static int push(lua_State* L, const T& value) {
+ lua_pushnumber(L, value);
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_signed<T>>::value>> {
+ static int push(lua_State* L, const T& value) {
+ lua_pushinteger(L, static_cast<lua_Integer>(value));
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<std::is_enum<T>::value>> {
+ static int push(lua_State* L, const T& value) {
+ if (std::is_same<char, T>::value) {
+ return stack::push(L, static_cast<int>(value));
+ }
+ return stack::push(L, static_cast<std::underlying_type_t<T>>(value));
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<meta::all<std::is_integral<T>, std::is_unsigned<T>>::value>> {
+ static int push(lua_State* L, const T& value) {
+ lua_pushinteger(L, static_cast<lua_Integer>(value));
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<as_table_t<T>, std::enable_if_t<!meta::has_key_value_pair<meta::unqualified_t<std::remove_pointer_t<T>>>::value>> {
+ static int push(lua_State* L, const as_table_t<T>& tablecont) {
+ auto& cont = detail::deref(detail::unwrap(tablecont.source));
+ lua_createtable(L, static_cast<int>(cont.size()), 0);
+ int tableindex = lua_gettop(L);
+ std::size_t index = 1;
+ for (const auto& i : cont) {
+#if SOL_LUA_VERSION >= 503
+ int p = stack::push(L, i);
+ for (int pi = 0; pi < p; ++pi) {
+ lua_seti(L, tableindex, static_cast<lua_Integer>(index++));
+ }
+#else
+ lua_pushinteger(L, static_cast<lua_Integer>(index));
+ int p = stack::push(L, i);
+ if (p == 1) {
+ ++index;
+ lua_settable(L, tableindex);
+ }
+ else {
+ int firstindex = tableindex + 1 + 1;
+ for (int pi = 0; pi < p; ++pi) {
+ stack::push(L, index);
+ lua_pushvalue(L, firstindex);
+ lua_settable(L, tableindex);
+ ++index;
+ ++firstindex;
+ }
+ lua_pop(L, 1 + p);
+ }
+#endif
+ }
+ // TODO: figure out a better way to do this...?
+ //set_field(L, -1, cont.size());
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<as_table_t<T>, std::enable_if_t<meta::has_key_value_pair<meta::unqualified_t<std::remove_pointer_t<T>>>::value>> {
+ static int push(lua_State* L, const as_table_t<T>& tablecont) {
+ auto& cont = detail::deref(detail::unwrap(tablecont.source));
+ lua_createtable(L, static_cast<int>(cont.size()), 0);
+ int tableindex = lua_gettop(L);
+ for (const auto& pair : cont) {
+ set_field(L, pair.first, pair.second, tableindex);
+ }
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<T, std::enable_if_t<std::is_base_of<reference, T>::value || std::is_base_of<stack_reference, T>::value>> {
+ static int push(lua_State*, const T& ref) {
+ return ref.push();
+ }
+
+ static int push(lua_State*, T&& ref) {
+ return ref.push();
+ }
+ };
+
+ template<>
+ struct pusher<bool> {
+ static int push(lua_State* L, bool b) {
+ lua_pushboolean(L, b);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<nil_t> {
+ static int push(lua_State* L, nil_t) {
+ lua_pushnil(L);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<metatable_key_t> {
+ static int push(lua_State* L, metatable_key_t) {
+ lua_pushlstring(L, "__mt", 4);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<std::remove_pointer_t<lua_CFunction>> {
+ static int push(lua_State* L, lua_CFunction func, int n = 0) {
+ lua_pushcclosure(L, func, n);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<lua_CFunction> {
+ static int push(lua_State* L, lua_CFunction func, int n = 0) {
+ lua_pushcclosure(L, func, n);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<c_closure> {
+ static int push(lua_State* L, c_closure cc) {
+ lua_pushcclosure(L, cc.c_function, cc.upvalues);
+ return 1;
+ }
+ };
+
+ template<typename Arg, typename... Args>
+ struct pusher<closure<Arg, Args...>> {
+ template <std::size_t... I, typename T>
+ static int push(std::index_sequence<I...>, lua_State* L, T&& c) {
+ int pushcount = multi_push(L, detail::forward_get<I>(c.upvalues)...);
+ return stack::push(L, c_closure(c.c_function, pushcount));
+ }
+
+ template <typename T>
+ static int push(lua_State* L, T&& c) {
+ return push(std::make_index_sequence<1 + sizeof...(Args)>(), L, std::forward<T>(c));
+ }
+ };
+
+ template<>
+ struct pusher<void*> {
+ static int push(lua_State* L, void* userdata) {
+ lua_pushlightuserdata(L, userdata);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<lightuserdata_value> {
+ static int push(lua_State* L, lightuserdata_value userdata) {
+ lua_pushlightuserdata(L, userdata);
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<light<T>> {
+ static int push(lua_State* L, light<T> l) {
+ lua_pushlightuserdata(L, static_cast<void*>(l.value));
+ return 1;
+ }
+ };
+
+ template<typename T>
+ struct pusher<user<T>> {
+ template <bool with_meta = true, typename Key, typename... Args>
+ static int push_with(lua_State* L, Key&& name, Args&&... args) {
+ // A dumb pusher
+ void* rawdata = lua_newuserdata(L, sizeof(T));
+ T* data = static_cast<T*>(rawdata);
+ std::allocator<T> alloc;
+ alloc.construct(data, std::forward<Args>(args)...);
+ if (with_meta) {
+ lua_CFunction cdel = detail::user_alloc_destroy<T>;
+ // Make sure we have a plain GC set for this data
+ if (luaL_newmetatable(L, name) != 0) {
+ lua_pushlightuserdata(L, rawdata);
+ lua_pushcclosure(L, cdel, 1);
+ lua_setfield(L, -2, "__gc");
+ }
+ lua_setmetatable(L, -2);
+ }
+ return 1;
+ }
+
+ template <typename Arg, typename... Args, meta::disable<meta::any_same<meta::unqualified_t<Arg>, no_metatable_t, metatable_key_t>> = meta::enabler>
+ static int push(lua_State* L, Arg&& arg, Args&&... args) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with(L, name, std::forward<Arg>(arg), std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static int push(lua_State* L, no_metatable_t, Args&&... args) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with<false>(L, name, std::forward<Args>(args)...);
+ }
+
+ template <typename Key, typename... Args>
+ static int push(lua_State* L, metatable_key_t, Key&& key, Args&&... args) {
+ const auto name = &key[0];
+ return push_with<true>(L, name, std::forward<Args>(args)...);
+ }
+
+ static int push(lua_State* L, const user<T>& u) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with(L, name, u.value);
+ }
+
+ static int push(lua_State* L, user<T>&& u) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with(L, name, std::move(u.value));
+ }
+
+ static int push(lua_State* L, no_metatable_t, const user<T>& u) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with<false>(L, name, u.value);
+ }
+
+ static int push(lua_State* L, no_metatable_t, user<T>&& u) {
+ const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable[0];
+ return push_with<false>(L, name, std::move(u.value));
+ }
+ };
+
+ template<>
+ struct pusher<userdata_value> {
+ static int push(lua_State* L, userdata_value data) {
+ void** ud = static_cast<void**>(lua_newuserdata(L, sizeof(void*)));
+ *ud = data.value;
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<const char*> {
+ static int push_sized(lua_State* L, const char* str, std::size_t len) {
+ lua_pushlstring(L, str, len);
+ return 1;
+ }
+
+ static int push(lua_State* L, const char* str) {
+ return push_sized(L, str, std::char_traits<char>::length(str));
+ }
+
+ static int push(lua_State* L, const char* strb, const char* stre) {
+ return push_sized(L, strb, stre - strb);
+ }
+
+ static int push(lua_State* L, const char* str, std::size_t len) {
+ return push_sized(L, str, len);
+ }
+ };
+
+ template<size_t N>
+ struct pusher<char[N]> {
+ static int push(lua_State* L, const char(&str)[N]) {
+ lua_pushlstring(L, str, N - 1);
+ return 1;
+ }
+
+ static int push(lua_State* L, const char(&str)[N], std::size_t sz) {
+ lua_pushlstring(L, str, sz);
+ return 1;
+ }
+ };
+
+ template <>
+ struct pusher<char> {
+ static int push(lua_State* L, char c) {
+ const char str[2] = { c, '\0' };
+ return stack::push(L, str, 1);
+ }
+ };
+
+ template<>
+ struct pusher<std::string> {
+ static int push(lua_State* L, const std::string& str) {
+ lua_pushlstring(L, str.c_str(), str.size());
+ return 1;
+ }
+
+ static int push(lua_State* L, const std::string& str, std::size_t sz) {
+ lua_pushlstring(L, str.c_str(), sz);
+ return 1;
+ }
+ };
+
+ template<>
+ struct pusher<meta_function> {
+ static int push(lua_State* L, meta_function m) {
+ const std::string& str = name_of(m);
+ lua_pushlstring(L, str.c_str(), str.size());
+ return 1;
+ }
+ };
+
+#ifdef SOL_CODECVT_SUPPORT
+ template<>
+ struct pusher<const wchar_t*> {
+ static int push(lua_State* L, const wchar_t* wstr) {
+ return push(L, wstr, std::char_traits<wchar_t>::length(wstr));
+ }
+
+ static int push(lua_State* L, const wchar_t* wstr, std::size_t sz) {
+ return push(L, wstr, wstr + sz);
+ }
+
+ static int push(lua_State* L, const wchar_t* strb, const wchar_t* stre) {
+ if (sizeof(wchar_t) == 2) {
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;
+ std::string u8str = convert.to_bytes(strb, stre);
+ return stack::push(L, u8str);
+ }
+ std::wstring_convert<std::codecvt_utf8<wchar_t>> convert;
+ std::string u8str = convert.to_bytes(strb, stre);
+ return stack::push(L, u8str);
+ }
+ };
+
+ template<>
+ struct pusher<const char16_t*> {
+ static int push(lua_State* L, const char16_t* u16str) {
+ return push(L, u16str, std::char_traits<char16_t>::length(u16str));
+ }
+
+ static int push(lua_State* L, const char16_t* u16str, std::size_t sz) {
+ return push(L, u16str, u16str + sz);
+ }
+
+ static int push(lua_State* L, const char16_t* strb, const char16_t* stre) {
+#ifdef _MSC_VER
+ std::wstring_convert<std::codecvt_utf8_utf16<int16_t>, int16_t> convert;
+ std::string u8str = convert.to_bytes(reinterpret_cast<const int16_t*>(strb), reinterpret_cast<const int16_t*>(stre));
+#else
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
+ std::string u8str = convert.to_bytes(strb, stre);
+#endif // VC++ is a shit
+ return stack::push(L, u8str);
+ }
+ };
+
+ template<>
+ struct pusher<const char32_t*> {
+ static int push(lua_State* L, const char32_t* u32str) {
+ return push(L, u32str, u32str + std::char_traits<char32_t>::length(u32str));
+ }
+
+ static int push(lua_State* L, const char32_t* u32str, std::size_t sz) {
+ return push(L, u32str, u32str + sz);
+ }
+
+ static int push(lua_State* L, const char32_t* strb, const char32_t* stre) {
+#ifdef _MSC_VER
+ std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> convert;
+ std::string u8str = convert.to_bytes(reinterpret_cast<const int32_t*>(strb), reinterpret_cast<const int32_t*>(stre));
+#else
+ std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
+ std::string u8str = convert.to_bytes(strb, stre);
+#endif // VC++ is a shit
+ return stack::push(L, u8str);
+ }
+ };
+
+ template<size_t N>
+ struct pusher<wchar_t[N]> {
+ static int push(lua_State* L, const wchar_t(&str)[N]) {
+ return push(L, str, N - 1);
+ }
+
+ static int push(lua_State* L, const wchar_t(&str)[N], std::size_t sz) {
+ return stack::push<const wchar_t*>(L, str, str + sz);
+ }
+ };
+
+ template<size_t N>
+ struct pusher<char16_t[N]> {
+ static int push(lua_State* L, const char16_t(&str)[N]) {
+ return push(L, str, N - 1);
+ }
+
+ static int push(lua_State* L, const char16_t(&str)[N], std::size_t sz) {
+ return stack::push<const char16_t*>(L, str, str + sz);
+ }
+ };
+
+ template<size_t N>
+ struct pusher<char32_t[N]> {
+ static int push(lua_State* L, const char32_t(&str)[N]) {
+ return push(L, str, N - 1);
+ }
+
+ static int push(lua_State* L, const char32_t(&str)[N], std::size_t sz) {
+ return stack::push<const char32_t*>(L, str, str + sz);
+ }
+ };
+
+ template <>
+ struct pusher<wchar_t> {
+ static int push(lua_State* L, wchar_t c) {
+ const wchar_t str[2] = { c, '\0' };
+ return stack::push(L, str, 1);
+ }
+ };
+
+ template <>
+ struct pusher<char16_t> {
+ static int push(lua_State* L, char16_t c) {
+ const char16_t str[2] = { c, '\0' };
+ return stack::push(L, str, 1);
+ }
+ };
+
+ template <>
+ struct pusher<char32_t> {
+ static int push(lua_State* L, char32_t c) {
+ const char32_t str[2] = { c, '\0' };
+ return stack::push(L, str, 1);
+ }
+ };
+
+ template<>
+ struct pusher<std::wstring> {
+ static int push(lua_State* L, const std::wstring& wstr) {
+ return push(L, wstr.data(), wstr.size());
+ }
+
+ static int push(lua_State* L, const std::wstring& wstr, std::size_t sz) {
+ return stack::push(L, wstr.data(), wstr.data() + sz);
+ }
+ };
+
+ template<>
+ struct pusher<std::u16string> {
+ static int push(lua_State* L, const std::u16string& u16str) {
+ return push(L, u16str, u16str.size());
+ }
+
+ static int push(lua_State* L, const std::u16string& u16str, std::size_t sz) {
+ return stack::push(L, u16str.data(), u16str.data() + sz);
+ }
+ };
+
+ template<>
+ struct pusher<std::u32string> {
+ static int push(lua_State* L, const std::u32string& u32str) {
+ return push(L, u32str, u32str.size());
+ }
+
+ static int push(lua_State* L, const std::u32string& u32str, std::size_t sz) {
+ return stack::push(L, u32str.data(), u32str.data() + sz);
+ }
+ };
+#endif // codecvt Header Support
+
+ template<typename... Args>
+ struct pusher<std::tuple<Args...>> {
+ template <std::size_t... I, typename T>
+ static int push(std::index_sequence<I...>, lua_State* L, T&& t) {
+ int pushcount = 0;
+ (void)detail::swallow{ 0, (pushcount += stack::push(L,
+ detail::forward_get<I>(t)
+ ), 0)... };
+ return pushcount;
+ }
+
+ template <typename T>
+ static int push(lua_State* L, T&& t) {
+ return push(std::index_sequence_for<Args...>(), L, std::forward<T>(t));
+ }
+ };
+
+ template<typename A, typename B>
+ struct pusher<std::pair<A, B>> {
+ template <typename T>
+ static int push(lua_State* L, T&& t) {
+ int pushcount = stack::push(L, detail::forward_get<0>(t));
+ pushcount += stack::push(L, detail::forward_get<1>(t));
+ return pushcount;
+ }
+ };
+
+ template<typename O>
+ struct pusher<optional<O>> {
+ template <typename T>
+ static int push(lua_State* L, T&& t) {
+ if (t == nullopt) {
+ return stack::push(L, nullopt);
+ }
+ return stack::push(L, t.value());
+ }
+ };
+
+ template<>
+ struct pusher<nullopt_t> {
+ static int push(lua_State* L, nullopt_t) {
+ return stack::push(L, nil);
+ }
+ };
+
+ template<>
+ struct pusher<std::nullptr_t> {
+ static int push(lua_State* L, std::nullptr_t) {
+ return stack::push(L, nil);
+ }
+ };
+
+ template<>
+ struct pusher<this_state> {
+ static int push(lua_State*, const this_state&) {
+ return 0;
+ }
+ };
+ } // stack
+} // sol
+
+#endif // SOL_STACK_PUSH_HPP
diff --git a/3rdparty/sol2/sol/stack_reference.hpp b/3rdparty/sol2/sol/stack_reference.hpp
new file mode 100644
index 00000000000..1b3403dedd9
--- /dev/null
+++ b/3rdparty/sol2/sol/stack_reference.hpp
@@ -0,0 +1,84 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STACK_REFERENCE_HPP
+#define SOL_STACK_REFERENCE_HPP
+
+namespace sol {
+ class stack_reference {
+ private:
+ lua_State* L = nullptr;
+ int index = 0;
+
+ protected:
+ int registry_index() const noexcept {
+ return LUA_NOREF;
+ }
+
+ public:
+ stack_reference() noexcept = default;
+ stack_reference(nil_t) noexcept : stack_reference() {};
+ stack_reference(lua_State* L, int i) noexcept : L(L), index(lua_absindex(L, i)) {}
+ stack_reference(lua_State* L, absolute_index i) noexcept : L(L), index(i) {}
+ stack_reference(lua_State* L, raw_index i) noexcept : L(L), index(i) {}
+ stack_reference(stack_reference&& o) noexcept = default;
+ stack_reference& operator=(stack_reference&&) noexcept = default;
+ stack_reference(const stack_reference&) noexcept = default;
+ stack_reference& operator=(const stack_reference&) noexcept = default;
+
+ int push() const noexcept {
+ lua_pushvalue(L, index);
+ return 1;
+ }
+
+ void pop(int n = 1) const noexcept {
+ lua_pop(lua_state(), n);
+ }
+
+ int stack_index() const noexcept {
+ return index;
+ }
+
+ type get_type() const noexcept {
+ int result = lua_type(L, index);
+ return static_cast<type>(result);
+ }
+
+ lua_State* lua_state() const noexcept {
+ return L;
+ }
+
+ bool valid() const noexcept {
+ type t = get_type();
+ return t != type::nil && t != type::none;
+ }
+ };
+
+ inline bool operator== (const stack_reference& l, const stack_reference& r) {
+ return lua_compare(l.lua_state(), l.stack_index(), r.stack_index(), LUA_OPEQ) == 0;
+ }
+
+ inline bool operator!= (const stack_reference& l, const stack_reference& r) {
+ return !operator==(l, r);
+ }
+} // sol
+
+#endif // SOL_STACK_REFERENCE_HPP
diff --git a/3rdparty/sol2/sol/state.hpp b/3rdparty/sol2/sol/state.hpp
new file mode 100644
index 00000000000..18c32db5010
--- /dev/null
+++ b/3rdparty/sol2/sol/state.hpp
@@ -0,0 +1,59 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STATE_HPP
+#define SOL_STATE_HPP
+
+#include "state_view.hpp"
+
+namespace sol {
+ inline int default_at_panic(lua_State* L) {
+#ifdef SOL_NO_EXCEPTIONS
+ (void)L;
+ return -1;
+#else
+ const char* message = lua_tostring(L, -1);
+ std::string err = message ? message : "An unexpected error occurred and forced the lua state to call atpanic";
+ throw error(err);
+#endif
+ }
+
+ class state : private std::unique_ptr<lua_State, void(*)(lua_State*)>, public state_view {
+ private:
+ typedef std::unique_ptr<lua_State, void(*)(lua_State*)> unique_base;
+ public:
+ state(lua_CFunction panic = default_at_panic) : unique_base(luaL_newstate(), lua_close),
+ state_view(unique_base::get()) {
+ set_panic(panic);
+ stack::luajit_exception_handler(unique_base::get());
+ }
+
+ state(lua_CFunction panic, lua_Alloc alfunc, void* alpointer = nullptr) : unique_base(lua_newstate(alfunc, alpointer), lua_close),
+ state_view(unique_base::get()) {
+ set_panic(panic);
+ stack::luajit_exception_handler(unique_base::get());
+ }
+
+ using state_view::get;
+ };
+} // sol
+
+#endif // SOL_STATE_HPP
diff --git a/3rdparty/sol2/sol/state_view.hpp b/3rdparty/sol2/sol/state_view.hpp
new file mode 100644
index 00000000000..3efb3674d25
--- /dev/null
+++ b/3rdparty/sol2/sol/state_view.hpp
@@ -0,0 +1,460 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_STATE_VIEW_HPP
+#define SOL_STATE_VIEW_HPP
+
+#include "error.hpp"
+#include "table.hpp"
+#include "load_result.hpp"
+#include <memory>
+
+namespace sol {
+ enum class lib : char {
+ base,
+ package,
+ coroutine,
+ string,
+ os,
+ math,
+ table,
+ debug,
+ bit32,
+ io,
+ ffi,
+ jit,
+ utf8,
+ count
+ };
+
+ class state_view {
+ private:
+ lua_State* L;
+ table reg;
+ global_table global;
+
+ optional<object> is_loaded_package(const std::string& key) {
+ auto loaded = reg.traverse_get<optional<object>>("_LOADED", key);
+ bool is53mod = loaded && !(loaded->is<bool>() && !loaded->as<bool>());
+ if (is53mod)
+ return loaded;
+#if SOL_LUA_VERSION <= 501
+ auto loaded51 = global.traverse_get<optional<object>>("package", "loaded", key);
+ bool is51mod = loaded51 && !(loaded51->is<bool>() && !loaded51->as<bool>());
+ if (is51mod)
+ return loaded51;
+#endif
+ return nullopt;
+ }
+
+ template <typename T>
+ void ensure_package(const std::string& key, T&& sr) {
+#if SOL_LUA_VERSION <= 501
+ auto pkg = global["package"];
+ if (!pkg.valid()) {
+ pkg = create_table_with("loaded", create_table_with(key, sr));
+ }
+ else {
+ auto ld = pkg["loaded"];
+ if (!ld.valid()) {
+ ld = create_table_with(key, sr);
+ }
+ else {
+ ld[key] = sr;
+ }
+ }
+#endif
+ auto loaded = reg["_LOADED"];
+ if (!loaded.valid()) {
+ loaded = create_table_with(key, sr);
+ }
+ else {
+ loaded[key] = sr;
+ }
+ }
+
+ template <typename Fx>
+ object require_core(const std::string& key, Fx&& action, bool create_global = true) {
+ optional<object> loaded = is_loaded_package(key);
+ if (loaded && loaded->valid())
+ return std::move(*loaded);
+ action();
+ auto sr = stack::get<stack_reference>(L);
+ if (create_global)
+ set(key, sr);
+ ensure_package(key, sr);
+ return stack::pop<object>(L);
+ }
+
+ public:
+ typedef global_table::iterator iterator;
+ typedef global_table::const_iterator const_iterator;
+
+ state_view(lua_State* L) :
+ L(L),
+ reg(L, LUA_REGISTRYINDEX),
+ global(L, detail::global_) {
+
+ }
+
+ lua_State* lua_state() const {
+ return L;
+ }
+
+ template<typename... Args>
+ void open_libraries(Args&&... args) {
+ static_assert(meta::all_same<lib, Args...>::value, "all types must be libraries");
+ if (sizeof...(args) == 0) {
+ luaL_openlibs(L);
+ return;
+ }
+
+ lib libraries[1 + sizeof...(args)] = { lib::count, std::forward<Args>(args)... };
+
+ for (auto&& library : libraries) {
+ switch (library) {
+#if SOL_LUA_VERSION <= 501 && defined(SOL_LUAJIT)
+ case lib::coroutine:
+#endif // luajit opens coroutine base stuff
+ case lib::base:
+ luaL_requiref(L, "base", luaopen_base, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::package:
+ luaL_requiref(L, "package", luaopen_package, 1);
+ lua_pop(L, 1);
+ break;
+#if !defined(SOL_LUAJIT)
+ case lib::coroutine:
+#if SOL_LUA_VERSION > 501
+ luaL_requiref(L, "coroutine", luaopen_coroutine, 1);
+ lua_pop(L, 1);
+#endif // Lua 5.2+ only
+ break;
+#endif // Not LuaJIT
+ case lib::string:
+ luaL_requiref(L, "string", luaopen_string, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::table:
+ luaL_requiref(L, "table", luaopen_table, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::math:
+ luaL_requiref(L, "math", luaopen_math, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::bit32:
+#ifdef SOL_LUAJIT
+ luaL_requiref(L, "bit32", luaopen_bit, 1);
+ lua_pop(L, 1);
+#elif SOL_LUA_VERSION == 502
+ luaL_requiref(L, "bit32", luaopen_bit32, 1);
+ lua_pop(L, 1);
+#else
+#endif // Lua 5.2 only (deprecated in 5.3 (503))
+ break;
+ case lib::io:
+ luaL_requiref(L, "io", luaopen_io, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::os:
+ luaL_requiref(L, "os", luaopen_os, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::debug:
+ luaL_requiref(L, "debug", luaopen_debug, 1);
+ lua_pop(L, 1);
+ break;
+ case lib::utf8:
+#if SOL_LUA_VERSION > 502 && !defined(SOL_LUAJIT)
+ luaL_requiref(L, "utf8", luaopen_utf8, 1);
+ lua_pop(L, 1);
+#endif // Lua 5.3+ only
+ break;
+ case lib::ffi:
+#ifdef SOL_LUAJIT
+ luaL_requiref(L, "ffi", luaopen_ffi, 1);
+ lua_pop(L, 1);
+#endif
+ break;
+ case lib::jit:
+#ifdef SOL_LUAJIT
+ luaL_requiref(L, "jit", luaopen_jit, 1);
+ lua_pop(L, 1);
+#endif
+ break;
+ case lib::count:
+ default:
+ break;
+ }
+ }
+ }
+
+ object require(const std::string& key, lua_CFunction open_function, bool create_global = true) {
+ luaL_requiref(L, key.c_str(), open_function, create_global ? 1 : 0);
+ return stack::pop<object>(L);
+ }
+
+ object require_script(const std::string& key, const std::string& code, bool create_global = true) {
+ return require_core(key, [this, &code]() {stack::script(L, code); }, create_global);
+ }
+
+ object require_file(const std::string& key, const std::string& filename, bool create_global = true) {
+ return require_core(key, [this, &filename]() {stack::script_file(L, filename); }, create_global);
+ }
+
+ function_result script(const std::string& code) {
+ int index = (::std::max)(lua_gettop(L), 1);
+ stack::script(L, code);
+ int returns = lua_gettop(L) - (index - 1);
+ return function_result(L, index, returns);
+ }
+
+ function_result script_file(const std::string& filename) {
+ int index = (::std::max)(lua_gettop(L), 1);
+ stack::script_file(L, filename);
+ int returns = lua_gettop(L) - (index - 1);
+ return function_result(L, index, returns);
+ }
+
+ load_result load(const std::string& code) {
+ load_status x = static_cast<load_status>(luaL_loadstring(L, code.c_str()));
+ return load_result(L, lua_absindex(L, -1), 1, 1, x);
+ }
+
+ load_result load_file(const std::string& filename) {
+ load_status x = static_cast<load_status>(luaL_loadfile(L, filename.c_str()));
+ return load_result(L, lua_absindex(L, -1), 1, 1, x);
+ }
+
+ load_result load_buffer(const char *buff, size_t size, const char *name, const char* mode = nullptr) {
+ load_status x = static_cast<load_status>(luaL_loadbufferx(L, buff, size, name, mode));
+ return load_result(L, lua_absindex(L, -1), 1, 1, x);
+ }
+
+ iterator begin() const {
+ return global.begin();
+ }
+
+ iterator end() const {
+ return global.end();
+ }
+
+ const_iterator cbegin() const {
+ return global.cbegin();
+ }
+
+ const_iterator cend() const {
+ return global.cend();
+ }
+
+ global_table globals() const {
+ return global;
+ }
+
+ table registry() const {
+ return reg;
+ }
+
+ operator lua_State* () const {
+ return lua_state();
+ }
+
+ void set_panic(lua_CFunction panic) {
+ lua_atpanic(L, panic);
+ }
+
+ template<typename... Args, typename... Keys>
+ decltype(auto) get(Keys&&... keys) const {
+ return global.get<Args...>(std::forward<Keys>(keys)...);
+ }
+
+ template<typename T, typename Key>
+ decltype(auto) get_or(Key&& key, T&& otherwise) const {
+ return global.get_or(std::forward<Key>(key), std::forward<T>(otherwise));
+ }
+
+ template<typename T, typename Key, typename D>
+ decltype(auto) get_or(Key&& key, D&& otherwise) const {
+ return global.get_or<T>(std::forward<Key>(key), std::forward<D>(otherwise));
+ }
+
+ template<typename... Args>
+ state_view& set(Args&&... args) {
+ global.set(std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename T, typename... Keys>
+ decltype(auto) traverse_get(Keys&&... keys) const {
+ return global.traverse_get<T>(std::forward<Keys>(keys)...);
+ }
+
+ template<typename... Args>
+ state_view& traverse_set(Args&&... args) {
+ global.traverse_set(std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename T>
+ state_view& set_usertype(usertype<T>& user) {
+ return set_usertype(usertype_traits<T>::name, user);
+ }
+
+ template<typename Key, typename T>
+ state_view& set_usertype(Key&& key, usertype<T>& user) {
+ global.set_usertype(std::forward<Key>(key), user);
+ return *this;
+ }
+
+ template<typename Class, typename... Args>
+ state_view& new_usertype(const std::string& name, Args&&... args) {
+ global.new_usertype<Class>(name, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ state_view& new_usertype(const std::string& name, Args&&... args) {
+ global.new_usertype<Class, CTor0, CTor...>(name, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ state_view& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
+ global.new_usertype<Class>(name, ctor, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename... Args>
+ state_view& new_simple_usertype(const std::string& name, Args&&... args) {
+ global.new_simple_usertype<Class>(name, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ state_view& new_simple_usertype(const std::string& name, Args&&... args) {
+ global.new_simple_usertype<Class, CTor0, CTor...>(name, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ state_view& new_simple_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
+ global.new_simple_usertype<Class>(name, ctor, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Class, typename... Args>
+ simple_usertype<Class> create_simple_usertype(Args&&... args) {
+ return global.create_simple_usertype<Class>(std::forward<Args>(args)...);
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ simple_usertype<Class> create_simple_usertype(Args&&... args) {
+ return global.create_simple_usertype<Class, CTor0, CTor...>(std::forward<Args>(args)...);
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ simple_usertype<Class> create_simple_usertype(constructors<CArgs...> ctor, Args&&... args) {
+ return global.create_simple_usertype<Class>(ctor, std::forward<Args>(args)...);
+ }
+
+ template<bool read_only = true, typename... Args>
+ state_view& new_enum(const std::string& name, Args&&... args) {
+ global.new_enum<read_only>(name, std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template <typename Fx>
+ void for_each(Fx&& fx) {
+ global.for_each(std::forward<Fx>(fx));
+ }
+
+ template<typename T>
+ proxy<global_table&, T> operator[](T&& key) {
+ return global[std::forward<T>(key)];
+ }
+
+ template<typename T>
+ proxy<const global_table&, T> operator[](T&& key) const {
+ return global[std::forward<T>(key)];
+ }
+
+ template<typename Sig, typename... Args, typename Key>
+ state_view& set_function(Key&& key, Args&&... args) {
+ global.set_function<Sig>(std::forward<Key>(key), std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename... Args, typename Key>
+ state_view& set_function(Key&& key, Args&&... args) {
+ global.set_function(std::forward<Key>(key), std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template <typename Name>
+ table create_table(Name&& name, int narr = 0, int nrec = 0) {
+ return global.create(std::forward<Name>(name), narr, nrec);
+ }
+
+ template <typename Name, typename Key, typename Value, typename... Args>
+ table create_table(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ return global.create(std::forward<Name>(name), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ }
+
+ template <typename Name, typename... Args>
+ table create_named_table(Name&& name, Args&&... args) {
+ table x = global.create_with(std::forward<Args>(args)...);
+ global.set(std::forward<Name>(name), x);
+ return x;
+ }
+
+ table create_table(int narr = 0, int nrec = 0) {
+ return create_table(lua_state(), narr, nrec);
+ }
+
+ template <typename Key, typename Value, typename... Args>
+ table create_table(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ return create_table(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ table create_table_with(Args&&... args) {
+ return create_table_with(lua_state(), std::forward<Args>(args)...);
+ }
+
+ static inline table create_table(lua_State* L, int narr = 0, int nrec = 0) {
+ return global_table::create(L, narr, nrec);
+ }
+
+ template <typename Key, typename Value, typename... Args>
+ static inline table create_table(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ return global_table::create(L, narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static inline table create_table_with(lua_State* L, Args&&... args) {
+ return global_table::create_with(L, std::forward<Args>(args)...);
+ }
+ };
+} // sol
+
+#endif // SOL_STATE_VIEW_HPP
diff --git a/3rdparty/sol2/sol/string_shim.hpp b/3rdparty/sol2/sol/string_shim.hpp
new file mode 100644
index 00000000000..b1e685bddc8
--- /dev/null
+++ b/3rdparty/sol2/sol/string_shim.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#include <cstddef>
+#include <string>
+
+namespace sol {
+ namespace string_detail {
+ struct string_shim {
+ std::size_t s;
+ const char* p;
+
+ string_shim(const std::string& r) : string_shim(r.data(), r.size()) {}
+ string_shim(const char* p) : string_shim(p, std::char_traits<char>::length(p)) {}
+ string_shim(const char* p, std::size_t s) : s(s), p(p) {}
+
+ static int compare(const char* lhs_p, std::size_t lhs_sz, const char* rhs_p, std::size_t rhs_sz) {
+ int result = std::char_traits<char>::compare(lhs_p, rhs_p, lhs_sz < rhs_sz ? lhs_sz : rhs_sz);
+ if (result != 0)
+ return result;
+ if (lhs_sz < rhs_sz)
+ return -1;
+ if (lhs_sz > rhs_sz)
+ return 1;
+ return 0;
+ }
+
+ const char* c_str() const {
+ return p;
+ }
+
+ const char* data() const {
+ return p;
+ }
+
+ std::size_t size() const {
+ return s;
+ }
+
+ bool operator==(const string_shim& r) const {
+ return compare(p, s, r.data(), r.size()) == 0;
+ }
+
+ bool operator==(const char* r) const {
+ return compare(r, std::char_traits<char>::length(r), p, s) == 0;
+ }
+
+ bool operator==(const std::string& r) const {
+ return compare(r.data(), r.size(), p, s) == 0;
+ }
+
+ bool operator!=(const string_shim& r) const {
+ return !(*this == r);
+ }
+
+ bool operator!=(const char* r) const {
+ return !(*this == r);
+ }
+
+ bool operator!=(const std::string& r) const {
+ return !(*this == r);
+ }
+ };
+ }
+} \ No newline at end of file
diff --git a/3rdparty/sol2/sol/table.hpp b/3rdparty/sol2/sol/table.hpp
new file mode 100644
index 00000000000..fd556a6117d
--- /dev/null
+++ b/3rdparty/sol2/sol/table.hpp
@@ -0,0 +1,31 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_TABLE_HPP
+#define SOL_TABLE_HPP
+
+#include "table_core.hpp"
+
+namespace sol {
+ typedef table_core<false> table;
+} // sol
+
+#endif // SOL_TABLE_HPP
diff --git a/3rdparty/sol2/sol/table_core.hpp b/3rdparty/sol2/sol/table_core.hpp
new file mode 100644
index 00000000000..918f3d4ad76
--- /dev/null
+++ b/3rdparty/sol2/sol/table_core.hpp
@@ -0,0 +1,462 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_TABLE_CORE_HPP
+#define SOL_TABLE_CORE_HPP
+
+#include "proxy.hpp"
+#include "stack.hpp"
+#include "function_types.hpp"
+#include "usertype.hpp"
+#include "table_iterator.hpp"
+
+namespace sol {
+ namespace detail {
+ template <std::size_t n>
+ struct clean { lua_State* L; clean(lua_State* L) : L(L) {} ~clean() { lua_pop(L, static_cast<int>(n)); } };
+ struct ref_clean { lua_State* L; int& n; ref_clean(lua_State* L, int& n) : L(L), n(n) {} ~ref_clean() { lua_pop(L, static_cast<int>(n)); } };
+ inline int fail_on_newindex(lua_State* L) {
+ return luaL_error(L, "sol: cannot modify the elements of an enumeration table");
+ }
+ }
+
+ template <bool top_level, typename base_t>
+ class basic_table_core : public base_t {
+ friend class state;
+ friend class state_view;
+
+ template <typename... Args>
+ using is_global = meta::all<meta::boolean<top_level>, meta::is_c_str<Args>...>;
+
+ template<typename Fx>
+ void for_each(std::true_type, Fx&& fx) const {
+ auto pp = stack::push_pop(*this);
+ stack::push(base_t::lua_state(), nil);
+ while (lua_next(base_t::lua_state(), -2)) {
+ sol::object key(base_t::lua_state(), -2);
+ sol::object value(base_t::lua_state(), -1);
+ std::pair<sol::object&, sol::object&> keyvalue(key, value);
+ auto pn = stack::pop_n(base_t::lua_state(), 1);
+ fx(keyvalue);
+ }
+ }
+
+ template<typename Fx>
+ void for_each(std::false_type, Fx&& fx) const {
+ auto pp = stack::push_pop(*this);
+ stack::push(base_t::lua_state(), nil);
+ while (lua_next(base_t::lua_state(), -2)) {
+ sol::object key(base_t::lua_state(), -2);
+ sol::object value(base_t::lua_state(), -1);
+ auto pn = stack::pop_n(base_t::lua_state(), 1);
+ fx(key, value);
+ }
+ }
+
+ template<typename Ret0, typename Ret1, typename... Ret, std::size_t... I, typename Keys>
+ auto tuple_get(types<Ret0, Ret1, Ret...>, std::index_sequence<0, 1, I...>, Keys&& keys) const
+ -> decltype(stack::pop<std::tuple<Ret0, Ret1, Ret...>>(nullptr)) {
+ typedef decltype(stack::pop<std::tuple<Ret0, Ret1, Ret...>>(nullptr)) Tup;
+ return Tup(
+ traverse_get_optional<top_level, Ret0>(meta::is_specialization_of<sol::optional, meta::unqualified_t<Ret0>>(), detail::forward_get<0>(keys)),
+ traverse_get_optional<top_level, Ret1>(meta::is_specialization_of<sol::optional, meta::unqualified_t<Ret1>>(), detail::forward_get<1>(keys)),
+ traverse_get_optional<top_level, Ret>(meta::is_specialization_of<sol::optional, meta::unqualified_t<Ret>>(), detail::forward_get<I>(keys))...
+ );
+ }
+
+ template<typename Ret, std::size_t I, typename Keys>
+ decltype(auto) tuple_get(types<Ret>, std::index_sequence<I>, Keys&& keys) const {
+ return traverse_get_optional<top_level, Ret>(meta::is_specialization_of<sol::optional, meta::unqualified_t<Ret>>(), detail::forward_get<I>(keys));
+ }
+
+ template<typename Pairs, std::size_t... I>
+ void tuple_set(std::index_sequence<I...>, Pairs&& pairs) {
+ auto pp = stack::push_pop<top_level && (is_global<decltype(detail::forward_get<I * 2>(pairs))...>::value)>(*this);
+ void(detail::swallow{ (stack::set_field<top_level>(base_t::lua_state(),
+ detail::forward_get<I * 2>(pairs),
+ detail::forward_get<I * 2 + 1>(pairs),
+ lua_gettop(base_t::lua_state())
+ ), 0)... });
+ }
+
+ template <bool global, typename T, typename Key>
+ decltype(auto) traverse_get_deep(Key&& key) const {
+ stack::get_field<global>(base_t::lua_state(), std::forward<Key>(key));
+ return stack::get<T>(base_t::lua_state());
+ }
+
+ template <bool global, typename T, typename Key, typename... Keys>
+ decltype(auto) traverse_get_deep(Key&& key, Keys&&... keys) const {
+ stack::get_field<global>(base_t::lua_state(), std::forward<Key>(key));
+ return traverse_get_deep<false, T>(std::forward<Keys>(keys)...);
+ }
+
+ template <bool global, typename T, std::size_t I, typename Key>
+ decltype(auto) traverse_get_deep_optional(int& popcount, Key&& key) const {
+ typedef decltype(stack::get<T>(base_t::lua_state())) R;
+ auto p = stack::probe_get_field<global>(base_t::lua_state(), std::forward<Key>(key), lua_gettop(base_t::lua_state()));
+ popcount += p.levels;
+ if (!p.success)
+ return R(nullopt);
+ return stack::get<T>(base_t::lua_state());
+ }
+
+ template <bool global, typename T, std::size_t I, typename Key, typename... Keys>
+ decltype(auto) traverse_get_deep_optional(int& popcount, Key&& key, Keys&&... keys) const {
+ auto p = I > 0 ? stack::probe_get_field<global>(base_t::lua_state(), std::forward<Key>(key), -1) : stack::probe_get_field<global>(base_t::lua_state(), std::forward<Key>(key), lua_gettop(base_t::lua_state()));
+ popcount += p.levels;
+ if (!p.success)
+ return T(nullopt);
+ return traverse_get_deep_optional<false, T, I + 1>(popcount, std::forward<Keys>(keys)...);
+ }
+
+ template <bool global, typename T, typename... Keys>
+ decltype(auto) traverse_get_optional(std::false_type, Keys&&... keys) const {
+ detail::clean<sizeof...(Keys)> c(base_t::lua_state());
+ return traverse_get_deep<top_level, T>(std::forward<Keys>(keys)...);
+ }
+
+ template <bool global, typename T, typename... Keys>
+ decltype(auto) traverse_get_optional(std::true_type, Keys&&... keys) const {
+ int popcount = 0;
+ detail::ref_clean c(base_t::lua_state(), popcount);
+ return traverse_get_deep_optional<top_level, T, 0>(popcount, std::forward<Keys>(keys)...);
+ }
+
+ template <bool global, typename Key, typename Value>
+ void traverse_set_deep(Key&& key, Value&& value) const {
+ stack::set_field<global>(base_t::lua_state(), std::forward<Key>(key), std::forward<Value>(value));
+ }
+
+ template <bool global, typename Key, typename... Keys>
+ void traverse_set_deep(Key&& key, Keys&&... keys) const {
+ stack::get_field<global>(base_t::lua_state(), std::forward<Key>(key));
+ traverse_set_deep<false>(std::forward<Keys>(keys)...);
+ }
+
+ basic_table_core(lua_State* L, detail::global_tag t) noexcept : reference(L, t) { }
+
+ public:
+ typedef basic_table_iterator<base_t> iterator;
+ typedef iterator const_iterator;
+
+ basic_table_core() noexcept : base_t() { }
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_table_core(T&& r) noexcept : base_t(std::forward<T>(r)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!is_table<meta::unqualified_t<T>>::value) {
+ auto pp = stack::push_pop(*this);
+ stack::check<basic_table_core>(base_t::lua_state(), -1, type_panic);
+ }
+#endif // Safety
+ }
+ basic_table_core(const basic_table_core&) = default;
+ basic_table_core(basic_table_core&&) = default;
+ basic_table_core& operator=(const basic_table_core&) = default;
+ basic_table_core& operator=(basic_table_core&&) = default;
+ basic_table_core(const stack_reference& r) : basic_table_core(r.lua_state(), r.stack_index()) {}
+ basic_table_core(stack_reference&& r) : basic_table_core(r.lua_state(), r.stack_index()) {}
+ basic_table_core(lua_State* L, int index = -1) : base_t(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ stack::check<basic_table_core>(L, index, type_panic);
+#endif // Safety
+ }
+
+ iterator begin() const {
+ return iterator(*this);
+ }
+
+ iterator end() const {
+ return iterator();
+ }
+
+ const_iterator cbegin() const {
+ return begin();
+ }
+
+ const_iterator cend() const {
+ return end();
+ }
+
+ template<typename... Ret, typename... Keys>
+ decltype(auto) get(Keys&&... keys) const {
+ static_assert(sizeof...(Keys) == sizeof...(Ret), "number of keys and number of return types do not match");
+ auto pp = stack::push_pop<is_global<Keys...>::value>(*this);
+ return tuple_get(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), std::forward_as_tuple(std::forward<Keys>(keys)...));
+ }
+
+ template<typename T, typename Key>
+ decltype(auto) get_or(Key&& key, T&& otherwise) const {
+ typedef decltype(get<T>("")) U;
+ sol::optional<U> option = get<sol::optional<U>>(std::forward<Key>(key));
+ if (option) {
+ return static_cast<U>(option.value());
+ }
+ return static_cast<U>(std::forward<T>(otherwise));
+ }
+
+ template<typename T, typename Key, typename D>
+ decltype(auto) get_or(Key&& key, D&& otherwise) const {
+ sol::optional<T> option = get<sol::optional<T>>(std::forward<Key>(key));
+ if (option) {
+ return static_cast<T>(option.value());
+ }
+ return static_cast<T>(std::forward<D>(otherwise));
+ }
+
+ template <typename T, typename... Keys>
+ decltype(auto) traverse_get(Keys&&... keys) const {
+ auto pp = stack::push_pop<is_global<Keys...>::value>(*this);
+ return traverse_get_optional<top_level, T>(meta::is_specialization_of<sol::optional, meta::unqualified_t<T>>(), std::forward<Keys>(keys)...);
+ }
+
+ template <typename... Keys>
+ basic_table_core& traverse_set(Keys&&... keys) {
+ auto pp = stack::push_pop<is_global<Keys...>::value>(*this);
+ auto pn = stack::pop_n(base_t::lua_state(), static_cast<int>(sizeof...(Keys)-2));
+ traverse_set_deep<top_level>(std::forward<Keys>(keys)...);
+ return *this;
+ }
+
+ template<typename... Args>
+ basic_table_core& set(Args&&... args) {
+ tuple_set(std::make_index_sequence<sizeof...(Args) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...));
+ return *this;
+ }
+
+ template<typename T>
+ basic_table_core& set_usertype(usertype<T>& user) {
+ return set_usertype(usertype_traits<T>::name, user);
+ }
+
+ template<typename Key, typename T>
+ basic_table_core& set_usertype(Key&& key, usertype<T>& user) {
+ return set(std::forward<Key>(key), user);
+ }
+
+ template<typename Class, typename... Args>
+ basic_table_core& new_usertype(const std::string& name, Args&&... args) {
+ usertype<Class> utype(std::forward<Args>(args)...);
+ set_usertype(name, utype);
+ return *this;
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ basic_table_core& new_usertype(const std::string& name, Args&&... args) {
+ constructors<types<CTor0, CTor...>> ctor{};
+ return new_usertype<Class>(name, ctor, std::forward<Args>(args)...);
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ basic_table_core& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
+ usertype<Class> utype(ctor, std::forward<Args>(args)...);
+ set_usertype(name, utype);
+ return *this;
+ }
+
+ template<typename Class, typename... Args>
+ basic_table_core& new_simple_usertype(const std::string& name, Args&&... args) {
+ simple_usertype<Class> utype(base_t::lua_state(), std::forward<Args>(args)...);
+ set_usertype(name, utype);
+ return *this;
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ basic_table_core& new_simple_usertype(const std::string& name, Args&&... args) {
+ constructors<types<CTor0, CTor...>> ctor{};
+ return new_simple_usertype<Class>(name, ctor, std::forward<Args>(args)...);
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ basic_table_core& new_simple_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
+ simple_usertype<Class> utype(base_t::lua_state(), ctor, std::forward<Args>(args)...);
+ set_usertype(name, utype);
+ return *this;
+ }
+
+ template<typename Class, typename... Args>
+ simple_usertype<Class> create_simple_usertype(Args&&... args) {
+ simple_usertype<Class> utype(base_t::lua_state(), std::forward<Args>(args)...);
+ return utype;
+ }
+
+ template<typename Class, typename CTor0, typename... CTor, typename... Args>
+ simple_usertype<Class> create_simple_usertype(Args&&... args) {
+ constructors<types<CTor0, CTor...>> ctor{};
+ return create_simple_usertype<Class>(ctor, std::forward<Args>(args)...);
+ }
+
+ template<typename Class, typename... CArgs, typename... Args>
+ simple_usertype<Class> create_simple_usertype(constructors<CArgs...> ctor, Args&&... args) {
+ simple_usertype<Class> utype(base_t::lua_state(), ctor, std::forward<Args>(args)...);
+ return utype;
+ }
+
+ template<bool read_only = true, typename... Args>
+ basic_table_core& new_enum(const std::string& name, Args&&... args) {
+ if (read_only) {
+ table idx = create_with(std::forward<Args>(args)...);
+ table x = create_with(
+ meta_function::new_index, detail::fail_on_newindex,
+ meta_function::index, idx
+ );
+ table target = create_named(name);
+ target[metatable_key] = x;
+ }
+ else {
+ create_named(name, std::forward<Args>(args)...);
+ }
+ return *this;
+ }
+
+ template<typename Fx>
+ void for_each(Fx&& fx) const {
+ typedef meta::is_invokable<Fx(std::pair<sol::object, sol::object>)> is_paired;
+ for_each(is_paired(), std::forward<Fx>(fx));
+ }
+
+ size_t size() const {
+ auto pp = stack::push_pop(*this);
+ lua_len(base_t::lua_state(), -1);
+ return stack::pop<size_t>(base_t::lua_state());
+ }
+
+ bool empty() const {
+ return cbegin() == cend();
+ }
+
+ template<typename T>
+ proxy<basic_table_core&, T> operator[](T&& key) & {
+ return proxy<basic_table_core&, T>(*this, std::forward<T>(key));
+ }
+
+ template<typename T>
+ proxy<const basic_table_core&, T> operator[](T&& key) const & {
+ return proxy<const basic_table_core&, T>(*this, std::forward<T>(key));
+ }
+
+ template<typename T>
+ proxy<basic_table_core, T> operator[](T&& key) && {
+ return proxy<basic_table_core, T>(*this, std::forward<T>(key));
+ }
+
+ template<typename Sig, typename Key, typename... Args>
+ basic_table_core& set_function(Key&& key, Args&&... args) {
+ set_fx(types<Sig>(), std::forward<Key>(key), std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template<typename Key, typename... Args>
+ basic_table_core& set_function(Key&& key, Args&&... args) {
+ set_fx(types<>(), std::forward<Key>(key), std::forward<Args>(args)...);
+ return *this;
+ }
+
+ template <typename... Args>
+ basic_table_core& add(Args&&... args) {
+ auto pp = stack::push_pop(*this);
+ (void)detail::swallow{0,
+ (stack::set_ref(base_t::lua_state(), std::forward<Args>(args)), 0)...
+ };
+ return *this;
+ }
+
+ private:
+ template<typename R, typename... Args, typename Fx, typename Key, typename = std::result_of_t<Fx(Args...)>>
+ void set_fx(types<R(Args...)>, Key&& key, Fx&& fx) {
+ set_resolved_function<R(Args...)>(std::forward<Key>(key), std::forward<Fx>(fx));
+ }
+
+ template<typename Fx, typename Key, meta::enable<meta::is_specialization_of<overload_set, meta::unqualified_t<Fx>>> = meta::enabler>
+ void set_fx(types<>, Key&& key, Fx&& fx) {
+ set(std::forward<Key>(key), std::forward<Fx>(fx));
+ }
+
+ template<typename Fx, typename Key, typename... Args, meta::disable<meta::is_specialization_of<overload_set, meta::unqualified_t<Fx>>> = meta::enabler>
+ void set_fx(types<>, Key&& key, Fx&& fx, Args&&... args) {
+ set(std::forward<Key>(key), as_function_reference(std::forward<Fx>(fx), std::forward<Args>(args)...));
+ }
+
+ template<typename... Sig, typename... Args, typename Key>
+ void set_resolved_function(Key&& key, Args&&... args) {
+ set(std::forward<Key>(key), as_function_reference<function_sig<Sig...>>(std::forward<Args>(args)...));
+ }
+
+ public:
+ static inline table create(lua_State* L, int narr = 0, int nrec = 0) {
+ lua_createtable(L, narr, nrec);
+ table result(L);
+ lua_pop(L, 1);
+ return result;
+ }
+
+ template <typename Key, typename Value, typename... Args>
+ static inline table create(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ lua_createtable(L, narr, nrec);
+ table result(L);
+ result.set(std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ lua_pop(L, 1);
+ return result;
+ }
+
+ template <typename... Args>
+ static inline table create_with(lua_State* L, Args&&... args) {
+ static const int narr = static_cast<int>(meta::count_2_for_pack<std::is_integral, Args...>::value);
+ return create(L, narr, static_cast<int>((sizeof...(Args) / 2) - narr), std::forward<Args>(args)...);
+ }
+
+ table create(int narr = 0, int nrec = 0) {
+ return create(base_t::lua_state(), narr, nrec);
+ }
+
+ template <typename Key, typename Value, typename... Args>
+ table create(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ return create(base_t::lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ }
+
+ template <typename Name>
+ table create(Name&& name, int narr = 0, int nrec = 0) {
+ table x = create(base_t::lua_state(), narr, nrec);
+ this->set(std::forward<Name>(name), x);
+ return x;
+ }
+
+ template <typename Name, typename Key, typename Value, typename... Args>
+ table create(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
+ table x = create(base_t::lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
+ this->set(std::forward<Name>(name), x);
+ return x;
+ }
+
+ template <typename... Args>
+ table create_with(Args&&... args) {
+ return create_with(base_t::lua_state(), std::forward<Args>(args)...);
+ }
+
+ template <typename Name, typename... Args>
+ table create_named(Name&& name, Args&&... args) {
+ static const int narr = static_cast<int>(meta::count_2_for_pack<std::is_integral, Args...>::value);
+ return create(std::forward<Name>(name), narr, sizeof...(Args) / 2 - narr, std::forward<Args>(args)...);
+ }
+ };
+} // sol
+
+#endif // SOL_TABLE_CORE_HPP
diff --git a/3rdparty/sol2/sol/table_iterator.hpp b/3rdparty/sol2/sol/table_iterator.hpp
new file mode 100644
index 00000000000..7d81a6515bb
--- /dev/null
+++ b/3rdparty/sol2/sol/table_iterator.hpp
@@ -0,0 +1,120 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_TABLE_ITERATOR_HPP
+#define SOL_TABLE_ITERATOR_HPP
+
+#include "object.hpp"
+#include <iterator>
+
+namespace sol {
+
+ template <typename reference_type>
+ class basic_table_iterator : public std::iterator<std::input_iterator_tag, std::pair<object, object>> {
+ private:
+ typedef std::iterator<std::input_iterator_tag, std::pair<object, object>> base_t;
+ public:
+ typedef object key_type;
+ typedef object mapped_type;
+ typedef base_t::value_type value_type;
+ typedef base_t::iterator_category iterator_category;
+ typedef base_t::difference_type difference_type;
+ typedef base_t::pointer pointer;
+ typedef base_t::reference reference;
+ typedef const value_type& const_reference;
+
+ private:
+ std::pair<object, object> kvp;
+ reference_type ref;
+ int tableidx = 0;
+ int keyidx = 0;
+ std::ptrdiff_t idx = 0;
+
+ public:
+
+ basic_table_iterator() : keyidx(-1), idx(-1) {
+
+ }
+
+ basic_table_iterator(reference_type x) : ref(std::move(x)) {
+ ref.push();
+ tableidx = lua_gettop(ref.lua_state());
+ stack::push(ref.lua_state(), nil);
+ this->operator++();
+ if (idx == -1) {
+ return;
+ }
+ --idx;
+ }
+
+ basic_table_iterator& operator++() {
+ if (idx == -1)
+ return *this;
+
+ if (lua_next(ref.lua_state(), tableidx) == 0) {
+ idx = -1;
+ keyidx = -1;
+ return *this;
+ }
+ ++idx;
+ kvp.first = object(ref.lua_state(), -2);
+ kvp.second = object(ref.lua_state(), -1);
+ lua_pop(ref.lua_state(), 1);
+ // leave key on the stack
+ keyidx = lua_gettop(ref.lua_state());
+ return *this;
+ }
+
+ basic_table_iterator operator++(int) {
+ auto saved = *this;
+ this->operator++();
+ return saved;
+ }
+
+ reference operator*() {
+ return kvp;
+ }
+
+ const_reference operator*() const {
+ return kvp;
+ }
+
+ bool operator== (const basic_table_iterator& right) const {
+ return idx == right.idx;
+ }
+
+ bool operator!= (const basic_table_iterator& right) const {
+ return idx != right.idx;
+ }
+
+ ~basic_table_iterator() {
+ if (keyidx != -1) {
+ stack::remove(ref.lua_state(), keyidx, 1);
+ }
+ if (ref.valid()) {
+ stack::remove(ref.lua_state(), tableidx, 1);
+ }
+ }
+ };
+
+} // sol
+
+#endif // SOL_TABLE_ITERATOR_HPP
diff --git a/3rdparty/sol2/sol/thread.hpp b/3rdparty/sol2/sol/thread.hpp
new file mode 100644
index 00000000000..d4834dee4f2
--- /dev/null
+++ b/3rdparty/sol2/sol/thread.hpp
@@ -0,0 +1,77 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_THREAD_HPP
+#define SOL_THREAD_HPP
+
+#include "reference.hpp"
+#include "stack.hpp"
+
+namespace sol {
+ class thread : public reference {
+ public:
+ thread() noexcept = default;
+ thread(const thread&) = default;
+ thread(thread&&) = default;
+ thread(const stack_reference& r) : thread(r.lua_state(), r.stack_index()) {};
+ thread(stack_reference&& r) : thread(r.lua_state(), r.stack_index()) {};
+ thread& operator=(const thread&) = default;
+ thread& operator=(thread&&) = default;
+ thread(lua_State* L, int index = -1) : reference(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ type_assert(L, index, type::thread);
+#endif // Safety
+ }
+
+ state_view state() const {
+ return state_view(this->thread_state());
+ }
+
+ lua_State* thread_state() const {
+ auto pp = stack::push_pop(*this);
+ lua_State* lthread = lua_tothread(lua_state(), -1);
+ return lthread;
+ }
+
+ thread_status status() const {
+ lua_State* lthread = thread_state();
+ thread_status lstat = static_cast<thread_status>(lua_status(lthread));
+ if (lstat != thread_status::ok && lua_gettop(lthread) == 0) {
+ // No thing on the thread's stack means its dead
+ return thread_status::dead;
+ }
+ return lstat;
+ }
+
+ thread create() {
+ return create(lua_state());
+ }
+
+ static thread create(lua_State* L) {
+ lua_newthread(L);
+ thread result(L);
+ lua_pop(L, 1);
+ return result;
+ }
+ };
+} // sol
+
+#endif // SOL_THREAD_HPP
diff --git a/3rdparty/sol2/sol/tie.hpp b/3rdparty/sol2/sol/tie.hpp
new file mode 100644
index 00000000000..fc3ec155044
--- /dev/null
+++ b/3rdparty/sol2/sol/tie.hpp
@@ -0,0 +1,101 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_TIE_HPP
+#define SOL_TIE_HPP
+
+#include "traits.hpp"
+
+namespace sol {
+
+ namespace detail {
+ template <typename T>
+ struct is_speshul : std::false_type {};
+ }
+
+ template <typename T>
+ struct tie_size : std::tuple_size<T> {};
+
+ template <typename T>
+ struct is_tieable : std::integral_constant<bool, (::sol::tie_size<T>::value > 0)> {};
+
+ template <typename... Tn>
+ struct tie_t : public std::tuple<std::add_lvalue_reference_t<Tn>...> {
+ private:
+ typedef std::tuple<std::add_lvalue_reference_t<Tn>...> base_t;
+
+ template <typename T>
+ void set(std::false_type, T&& target) {
+ std::get<0>(*this) = std::forward<T>(target);
+ }
+
+ template <typename T>
+ void set(std::true_type, T&& target) {
+ typedef tie_size<meta::unqualified_t<T>> value_size;
+ typedef tie_size<std::tuple<Tn...>> tie_size;
+ typedef std::conditional_t<(value_size::value < tie_size::value), value_size, tie_size> indices_size;
+ typedef std::make_index_sequence<indices_size::value> indices;
+ set_extra(detail::is_speshul<meta::unqualified_t<T>>(), indices(), std::forward<T>(target));
+ }
+
+ template <std::size_t... I, typename T>
+ void set_extra(std::true_type, std::index_sequence<I...>, T&& target) {
+ using std::get;
+ (void)detail::swallow{ 0,
+ (get<I>(*this) = get<I>(types<Tn...>(), target), 0)...
+ , 0 };
+ }
+
+ template <std::size_t... I, typename T>
+ void set_extra(std::false_type, std::index_sequence<I...>, T&& target) {
+ using std::get;
+ (void)detail::swallow{ 0,
+ (get<I>(*this) = get<I>(target), 0)...
+ , 0 };
+ }
+
+ public:
+ using base_t::base_t;
+
+ template <typename T>
+ tie_t& operator= (T&& value) {
+ typedef is_tieable<meta::unqualified_t<T>> tieable;
+ set(tieable(), std::forward<T>(value));
+ return *this;
+ }
+
+ };
+
+ template <typename... Tn>
+ struct tie_size< tie_t<Tn...> > : std::tuple_size< std::tuple<Tn...> > { };
+
+ namespace adl_barrier_detail {
+ template <typename... Tn>
+ inline tie_t<std::remove_reference_t<Tn>...> tie(Tn&&... argn) {
+ return tie_t<std::remove_reference_t<Tn>...>(std::forward<Tn>(argn)...);
+ }
+ }
+
+ using namespace adl_barrier_detail;
+
+} // sol
+
+#endif // SOL_TIE_HPP
diff --git a/3rdparty/sol2/sol/traits.hpp b/3rdparty/sol2/sol/traits.hpp
new file mode 100644
index 00000000000..1721b90e866
--- /dev/null
+++ b/3rdparty/sol2/sol/traits.hpp
@@ -0,0 +1,425 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_TRAITS_HPP
+#define SOL_TRAITS_HPP
+
+#include "tuple.hpp"
+#include "bind_traits.hpp"
+#include <type_traits>
+#include <memory>
+#include <functional>
+
+namespace sol {
+ template<std::size_t I>
+ using index_value = std::integral_constant<std::size_t, I>;
+
+ namespace meta {
+ template<typename T>
+ struct identity { typedef T type; };
+
+ template<typename T>
+ using identity_t = typename identity<T>::type;
+
+ template<typename... Args>
+ struct is_tuple : std::false_type { };
+
+ template<typename... Args>
+ struct is_tuple<std::tuple<Args...>> : std::true_type { };
+
+ template<typename T>
+ struct unwrapped {
+ typedef T type;
+ };
+
+ template<typename T>
+ struct unwrapped<std::reference_wrapper<T>> {
+ typedef T type;
+ };
+
+ template<typename T>
+ using unwrapped_t = typename unwrapped<T>::type;
+
+ template <typename T>
+ struct unwrap_unqualified : unwrapped<unqualified_t<T>> {};
+
+ template <typename T>
+ using unwrap_unqualified_t = typename unwrap_unqualified<T>::type;
+
+ template<typename T>
+ struct remove_member_pointer;
+
+ template<typename R, typename T>
+ struct remove_member_pointer<R T::*> {
+ typedef R type;
+ };
+
+ template<typename R, typename T>
+ struct remove_member_pointer<R T::* const> {
+ typedef R type;
+ };
+
+ template<typename T>
+ using remove_member_pointer_t = remove_member_pointer<T>;
+
+ template<template<typename...> class Templ, typename T>
+ struct is_specialization_of : std::false_type { };
+ template<typename... T, template<typename...> class Templ>
+ struct is_specialization_of<Templ, Templ<T...>> : std::true_type { };
+
+ template<class T, class...>
+ struct all_same : std::true_type { };
+
+ template<class T, class U, class... Args>
+ struct all_same<T, U, Args...> : std::integral_constant <bool, std::is_same<T, U>::value && all_same<T, Args...>::value> { };
+
+ template<class T, class...>
+ struct any_same : std::false_type { };
+
+ template<class T, class U, class... Args>
+ struct any_same<T, U, Args...> : std::integral_constant <bool, std::is_same<T, U>::value || any_same<T, Args...>::value> { };
+
+ template<typename T>
+ using invoke_t = typename T::type;
+
+ template<bool B>
+ using boolean = std::integral_constant<bool, B>;
+
+ template<typename T>
+ using neg = boolean<!T::value>;
+
+ template<typename Condition, typename Then, typename Else>
+ using condition = std::conditional_t<Condition::value, Then, Else>;
+
+ template<typename... Args>
+ struct all : boolean<true> {};
+
+ template<typename T, typename... Args>
+ struct all<T, Args...> : condition<T, all<Args...>, boolean<false>> {};
+
+ template<typename... Args>
+ struct any : boolean<false> {};
+
+ template<typename T, typename... Args>
+ struct any<T, Args...> : condition<T, boolean<true>, any<Args...>> {};
+
+ enum class enable_t {
+ _
+ };
+
+ constexpr const auto enabler = enable_t::_;
+
+ template<bool value, typename T = void>
+ using disable_if_t = std::enable_if_t<!value, T>;
+
+ template<typename... Args>
+ using enable = std::enable_if_t<all<Args...>::value, enable_t>;
+
+ template<typename... Args>
+ using disable = std::enable_if_t<neg<all<Args...>>::value, enable_t>;
+
+ template<typename... Args>
+ using disable_any = std::enable_if_t<neg<any<Args...>>::value, enable_t>;
+
+ template<typename V, typename... Vs>
+ struct find_in_pack_v : boolean<false> { };
+
+ template<typename V, typename Vs1, typename... Vs>
+ struct find_in_pack_v<V, Vs1, Vs...> : any<boolean<(V::value == Vs1::value)>, find_in_pack_v<V, Vs...>> { };
+
+ namespace meta_detail {
+ template<std::size_t I, typename T, typename... Args>
+ struct index_in_pack : std::integral_constant<std::size_t, SIZE_MAX> { };
+
+ template<std::size_t I, typename T, typename T1, typename... Args>
+ struct index_in_pack<I, T, T1, Args...> : std::conditional_t<std::is_same<T, T1>::value, std::integral_constant<std::ptrdiff_t, I>, index_in_pack<I + 1, T, Args...>> { };
+ }
+
+ template<typename T, typename... Args>
+ struct index_in_pack : meta_detail::index_in_pack<0, T, Args...> { };
+
+ template<typename T, typename List>
+ struct index_in : meta_detail::index_in_pack<0, T, List> { };
+
+ template<typename T, typename... Args>
+ struct index_in<T, types<Args...>> : meta_detail::index_in_pack<0, T, Args...> { };
+
+ template<std::size_t I, typename... Args>
+ struct at_in_pack {};
+
+ template<std::size_t I, typename... Args>
+ using at_in_pack_t = typename at_in_pack<I, Args...>::type;
+
+ template<std::size_t I, typename Arg, typename... Args>
+ struct at_in_pack<I, Arg, Args...> : std::conditional<I == 0, Arg, at_in_pack_t<I - 1, Args...>> {};
+
+ template<typename Arg, typename... Args>
+ struct at_in_pack<0, Arg, Args...> { typedef Arg type; };
+
+ namespace meta_detail {
+ template<std::size_t Limit, std::size_t I, template<typename...> class Pred, typename... Ts>
+ struct count_for_pack : std::integral_constant<std::size_t, 0> {};
+ template<std::size_t Limit, std::size_t I, template<typename...> class Pred, typename T, typename... Ts>
+ struct count_for_pack<Limit, I, Pred, T, Ts...> : std::conditional_t < sizeof...(Ts) == 0 || Limit < 2,
+ std::integral_constant<std::size_t, I + static_cast<std::size_t>(Limit != 0 && Pred<T>::value)>,
+ count_for_pack<Limit - 1, I + static_cast<std::size_t>(Pred<T>::value), Pred, Ts...>
+ > { };
+ template<std::size_t I, template<typename...> class Pred, typename... Ts>
+ struct count_2_for_pack : std::integral_constant<std::size_t, 0> {};
+ template<std::size_t I, template<typename...> class Pred, typename T, typename U, typename... Ts>
+ struct count_2_for_pack<I, Pred, T, U, Ts...> : std::conditional_t<sizeof...(Ts) == 0,
+ std::integral_constant<std::size_t, I + static_cast<std::size_t>(Pred<T>::value)>,
+ count_2_for_pack<I + static_cast<std::size_t>(Pred<T>::value), Pred, Ts...>
+ > { };
+ } // meta_detail
+
+ template<template<typename...> class Pred, typename... Ts>
+ struct count_for_pack : meta_detail::count_for_pack<sizeof...(Ts), 0, Pred, Ts...> { };
+
+ template<template<typename...> class Pred, typename List>
+ struct count_for;
+
+ template<template<typename...> class Pred, typename... Args>
+ struct count_for<Pred, types<Args...>> : count_for_pack<Pred, Args...> {};
+
+ template<std::size_t Limit, template<typename...> class Pred, typename... Ts>
+ struct count_for_to_pack : meta_detail::count_for_pack<Limit, 0, Pred, Ts...> { };
+
+ template<template<typename...> class Pred, typename... Ts>
+ struct count_2_for_pack : meta_detail::count_2_for_pack<0, Pred, Ts...> { };
+
+ template<typename... Args>
+ struct return_type {
+ typedef std::tuple<Args...> type;
+ };
+
+ template<typename T>
+ struct return_type<T> {
+ typedef T type;
+ };
+
+ template<>
+ struct return_type<> {
+ typedef void type;
+ };
+
+ template <typename... Args>
+ using return_type_t = typename return_type<Args...>::type;
+
+ namespace meta_detail {
+ template <typename> struct always_true : std::true_type {};
+ struct is_invokable_tester {
+ template <typename Fun, typename... Args>
+ always_true<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);
+ template <typename...>
+ std::false_type static test(...);
+ };
+ } // meta_detail
+
+ template <typename T>
+ struct is_invokable;
+ template <typename Fun, typename... Args>
+ struct is_invokable<Fun(Args...)> : decltype(meta_detail::is_invokable_tester::test<Fun, Args...>(0)) {};
+
+ namespace meta_detail {
+
+ template<typename T, bool isclass = std::is_class<unqualified_t<T>>::value>
+ struct is_callable : std::is_function<std::remove_pointer_t<T>> {};
+
+ template<typename T>
+ struct is_callable<T, true> {
+ using yes = char;
+ using no = struct { char s[2]; };
+
+ struct F { void operator()(); };
+ struct Derived : T, F {};
+ template<typename U, U> struct Check;
+
+ template<typename V>
+ static no test(Check<void (F::*)(), &V::operator()>*);
+
+ template<typename>
+ static yes test(...);
+
+ static const bool value = sizeof(test<Derived>(0)) == sizeof(yes);
+ };
+
+ struct has_begin_end_impl {
+ template<typename T, typename U = unqualified_t<T>,
+ typename B = decltype(std::declval<U&>().begin()),
+ typename E = decltype(std::declval<U&>().end())>
+ static std::true_type test(int);
+
+ template<typename...>
+ static std::false_type test(...);
+ };
+
+ struct has_key_value_pair_impl {
+ template<typename T, typename U = unqualified_t<T>,
+ typename V = typename U::value_type,
+ typename F = decltype(std::declval<V&>().first),
+ typename S = decltype(std::declval<V&>().second)>
+ static std::true_type test(int);
+
+ template<typename...>
+ static std::false_type test(...);
+ };
+
+ template <typename T, typename U = T, typename = decltype(std::declval<T&>() < std::declval<U&>())>
+ std::true_type supports_op_less_test(const T&);
+ std::false_type supports_op_less_test(...);
+ template <typename T, typename U = T, typename = decltype(std::declval<T&>() == std::declval<U&>())>
+ std::true_type supports_op_equal_test(const T&);
+ std::false_type supports_op_equal_test(...);
+ template <typename T, typename U = T, typename = decltype(std::declval<T&>() <= std::declval<U&>())>
+ std::true_type supports_op_less_equal_test(const T&);
+ std::false_type supports_op_less_equal_test(...);
+
+ } // meta_detail
+
+ template <typename T>
+ using supports_op_less = decltype(meta_detail::supports_op_less_test(std::declval<T&>()));
+ template <typename T>
+ using supports_op_equal = decltype(meta_detail::supports_op_equal_test(std::declval<T&>()));
+ template <typename T>
+ using supports_op_less_equal = decltype(meta_detail::supports_op_less_equal_test(std::declval<T&>()));
+
+ template<typename T>
+ struct is_callable : boolean<meta_detail::is_callable<T>::value> {};
+
+ template<typename T>
+ struct has_begin_end : decltype(meta_detail::has_begin_end_impl::test<T>(0)) {};
+
+ template<typename T>
+ struct has_key_value_pair : decltype(meta_detail::has_key_value_pair_impl::test<T>(0)) {};
+
+ template <typename T>
+ using is_string_constructible = any<std::is_same<unqualified_t<T>, const char*>, std::is_same<unqualified_t<T>, char>, std::is_same<unqualified_t<T>, std::string>, std::is_same<unqualified_t<T>, std::initializer_list<char>>>;
+
+ template <typename T>
+ using is_c_str = any<
+ std::is_same<std::decay_t<unqualified_t<T>>, const char*>,
+ std::is_same<std::decay_t<unqualified_t<T>>, char*>,
+ std::is_same<unqualified_t<T>, std::string>
+ >;
+
+ template <typename T>
+ struct is_move_only : all<
+ neg<std::is_reference<T>>,
+ neg<std::is_copy_constructible<unqualified_t<T>>>,
+ std::is_move_constructible<unqualified_t<T>>
+ > {};
+
+ template <typename T>
+ using is_not_move_only = neg<is_move_only<T>>;
+
+ namespace meta_detail {
+ template <typename T, meta::disable<meta::is_specialization_of<std::tuple, meta::unqualified_t<T>>> = meta::enabler>
+ decltype(auto) force_tuple(T&& x) {
+ return std::forward_as_tuple(std::forward<T>(x));
+ }
+
+ template <typename T, meta::enable<meta::is_specialization_of<std::tuple, meta::unqualified_t<T>>> = meta::enabler>
+ decltype(auto) force_tuple(T&& x) {
+ return std::forward<T>(x);
+ }
+ } // meta_detail
+
+ template <typename... X>
+ decltype(auto) tuplefy(X&&... x) {
+ return std::tuple_cat(meta_detail::force_tuple(std::forward<X>(x))...);
+ }
+ } // meta
+ namespace detail {
+ template <std::size_t I, typename Tuple>
+ decltype(auto) forward_get(Tuple&& tuple) {
+ return std::forward<meta::tuple_element_t<I, Tuple>>(std::get<I>(tuple));
+ }
+
+ template <std::size_t... I, typename Tuple>
+ auto forward_tuple_impl(std::index_sequence<I...>, Tuple&& tuple) -> decltype(std::tuple<decltype(forward_get<I>(tuple))...>(forward_get<I>(tuple)...)) {
+ return std::tuple<decltype(forward_get<I>(tuple))...>(std::move(std::get<I>(tuple))...);
+ }
+
+ template <typename Tuple>
+ auto forward_tuple(Tuple&& tuple) {
+ auto x = forward_tuple_impl(std::make_index_sequence<std::tuple_size<meta::unqualified_t<Tuple>>::value>(), std::forward<Tuple>(tuple));
+ return x;
+ }
+
+ template<typename T>
+ auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
+ return std::forward<T>(item);
+ }
+
+ template<typename T>
+ T& unwrap(std::reference_wrapper<T> arg) {
+ return arg.get();
+ }
+
+ template<typename T>
+ auto deref(T&& item) -> decltype(std::forward<T>(item)) {
+ return std::forward<T>(item);
+ }
+
+ template<typename T>
+ inline T& deref(T* item) {
+ return *item;
+ }
+
+ template<typename T, typename Dx>
+ inline std::add_lvalue_reference_t<T> deref(std::unique_ptr<T, Dx>& item) {
+ return *item;
+ }
+
+ template<typename T>
+ inline std::add_lvalue_reference_t<T> deref(std::shared_ptr<T>& item) {
+ return *item;
+ }
+
+ template<typename T, typename Dx>
+ inline std::add_lvalue_reference_t<T> deref(const std::unique_ptr<T, Dx>& item) {
+ return *item;
+ }
+
+ template<typename T>
+ inline std::add_lvalue_reference_t<T> deref(const std::shared_ptr<T>& item) {
+ return *item;
+ }
+
+ template<typename T>
+ inline T* ptr(T& val) {
+ return std::addressof(val);
+ }
+
+ template<typename T>
+ inline T* ptr(std::reference_wrapper<T> val) {
+ return std::addressof(val.get());
+ }
+
+ template<typename T>
+ inline T* ptr(T* val) {
+ return val;
+ }
+ } // detail
+} // sol
+
+#endif // SOL_TRAITS_HPP
diff --git a/3rdparty/sol2/sol/tuple.hpp b/3rdparty/sol2/sol/tuple.hpp
new file mode 100644
index 00000000000..07a6d493de1
--- /dev/null
+++ b/3rdparty/sol2/sol/tuple.hpp
@@ -0,0 +1,80 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_TUPLE_HPP
+#define SOL_TUPLE_HPP
+
+#include <tuple>
+#include <cstddef>
+
+namespace sol {
+ namespace detail {
+ using swallow = std::initializer_list<int>;
+ } // detail
+
+ template<typename... Args>
+ struct types { typedef std::make_index_sequence<sizeof...(Args)> indices; static constexpr std::size_t size() { return sizeof...(Args); } };
+ namespace meta {
+ namespace detail {
+ template<typename... Args>
+ struct tuple_types_ { typedef types<Args...> type; };
+
+ template<typename... Args>
+ struct tuple_types_<std::tuple<Args...>> { typedef types<Args...> type; };
+ } // detail
+
+ template<typename T>
+ using unqualified = std::remove_cv<std::remove_reference_t<T>>;
+
+ template<typename T>
+ using unqualified_t = typename unqualified<T>::type;
+
+ template<typename... Args>
+ using tuple_types = typename detail::tuple_types_<Args...>::type;
+
+ template<typename Arg>
+ struct pop_front_type;
+
+ template<typename Arg>
+ using pop_front_type_t = typename pop_front_type<Arg>::type;
+
+ template<typename... Args>
+ struct pop_front_type<types<Args...>> { typedef void front_type; typedef types<Args...> type; };
+
+ template<typename Arg, typename... Args>
+ struct pop_front_type<types<Arg, Args...>> { typedef Arg front_type; typedef types<Args...> type; };
+
+ template <std::size_t N, typename Tuple>
+ using tuple_element = std::tuple_element<N, unqualified_t<Tuple>>;
+
+ template <std::size_t N, typename Tuple>
+ using tuple_element_t = std::tuple_element_t<N, unqualified_t<Tuple>>;
+
+ template <std::size_t N, typename Tuple>
+ using unqualified_tuple_element = unqualified<tuple_element_t<N, Tuple>>;
+
+ template <std::size_t N, typename Tuple>
+ using unqualified_tuple_element_t = unqualified_t<tuple_element_t<N, Tuple>>;
+
+ } // meta
+} // sol
+
+#endif // SOL_TUPLE_HPP
diff --git a/3rdparty/sol2/sol/types.hpp b/3rdparty/sol2/sol/types.hpp
new file mode 100644
index 00000000000..86ac4806532
--- /dev/null
+++ b/3rdparty/sol2/sol/types.hpp
@@ -0,0 +1,756 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_TYPES_HPP
+#define SOL_TYPES_HPP
+
+#include "optional.hpp"
+#include "compatibility.hpp"
+#include "traits.hpp"
+#include "string_shim.hpp"
+#include <array>
+#include <string>
+
+namespace sol {
+ namespace detail {
+#ifdef SOL_NO_EXCEPTIONS
+ template <lua_CFunction f>
+ int static_trampoline(lua_State* L) {
+ return f(L);
+ }
+
+ template <typename Fx, typename... Args>
+ int trampoline(lua_State* L, Fx&& f, Args&&... args) {
+ return f(L, std::forward<Args>(args)...);
+ }
+
+ inline int c_trampoline(lua_State* L, lua_CFunction f) {
+ return trampoline(L, f);
+ }
+#else
+ template <lua_CFunction f>
+ int static_trampoline(lua_State* L) {
+ try {
+ return f(L);
+ }
+ catch (const char *s) {
+ lua_pushstring(L, s);
+ }
+ catch (const std::exception& e) {
+ lua_pushstring(L, e.what());
+ }
+ catch (...) {
+ lua_pushstring(L, "caught (...) exception");
+ }
+ return lua_error(L);
+ }
+
+ template <typename Fx, typename... Args>
+ int trampoline(lua_State* L, Fx&& f, Args&&... args) {
+ try {
+ return f(L, std::forward<Args>(args)...);
+ }
+ catch (const char *s) {
+ lua_pushstring(L, s);
+ }
+ catch (const std::exception& e) {
+ lua_pushstring(L, e.what());
+ }
+ catch (...) {
+ lua_pushstring(L, "caught (...) exception");
+ }
+ return lua_error(L);
+ }
+
+ inline int c_trampoline(lua_State* L, lua_CFunction f) {
+ return trampoline(L, f);
+ }
+#endif // Exceptions vs. No Exceptions
+
+ template <typename T>
+ struct unique_usertype {};
+
+ template <typename T>
+ struct implicit_wrapper {
+ T& item;
+ implicit_wrapper(T* item) : item(*item) {}
+ implicit_wrapper(T& item) : item(item) {}
+ operator T& () {
+ return item;
+ }
+ operator T* () {
+ return std::addressof(item);
+ }
+ };
+ } // detail
+
+ struct nil_t {};
+ const nil_t nil{};
+ inline bool operator==(nil_t, nil_t) { return true; }
+ inline bool operator!=(nil_t, nil_t) { return false; }
+
+ struct metatable_key_t {};
+ const metatable_key_t metatable_key = {};
+
+ struct no_metatable_t {};
+ const no_metatable_t no_metatable = {};
+
+ typedef std::remove_pointer_t<lua_CFunction> lua_r_CFunction;
+
+ template <typename T>
+ struct unique_usertype_traits {
+ typedef T type;
+ typedef T actual_type;
+ static const bool value = false;
+
+ template <typename U>
+ static bool is_null(U&&) {
+ return false;
+ }
+
+ template <typename U>
+ static auto get(U&& value) {
+ return std::addressof(detail::deref(value));
+ }
+ };
+
+ template <typename T>
+ struct unique_usertype_traits<std::shared_ptr<T>> {
+ typedef T type;
+ typedef std::shared_ptr<T> actual_type;
+ static const bool value = true;
+
+ static bool is_null(const actual_type& p) {
+ return p == nullptr;
+ }
+
+ static type* get(const actual_type& p) {
+ return p.get();
+ }
+ };
+
+ template <typename T, typename D>
+ struct unique_usertype_traits<std::unique_ptr<T, D>> {
+ typedef T type;
+ typedef std::unique_ptr<T, D> actual_type;
+ static const bool value = true;
+
+ static bool is_null(const actual_type& p) {
+ return p == nullptr;
+ }
+
+ static type* get(const actual_type& p) {
+ return p.get();
+ }
+ };
+
+ template <typename T>
+ struct non_null {};
+
+ template <typename... Args>
+ struct function_sig {};
+
+ struct upvalue_index {
+ int index;
+ upvalue_index(int idx) : index(lua_upvalueindex(idx)) {}
+ operator int() const { return index; }
+ };
+
+ struct raw_index {
+ int index;
+ raw_index(int i) : index(i) {}
+ operator int() const { return index; }
+ };
+
+ struct absolute_index {
+ int index;
+ absolute_index(lua_State* L, int idx) : index(lua_absindex(L, idx)) {}
+ operator int() const { return index; }
+ };
+
+ struct lightuserdata_value {
+ void* value;
+ lightuserdata_value(void* data) : value(data) {}
+ operator void*() const { return value; }
+ };
+
+ struct userdata_value {
+ void* value;
+ userdata_value(void* data) : value(data) {}
+ operator void*() const { return value; }
+ };
+
+ template <typename L>
+ struct light {
+ L* value;
+
+ light(L& x) : value(std::addressof(x)) {}
+ light(L* x) : value(x) {}
+ light(void* x) : value(static_cast<L*>(x)) {}
+ operator L* () const { return value; }
+ operator L& () const { return *value; }
+ };
+
+ template <typename T>
+ auto make_light(T& l) {
+ typedef meta::unwrapped_t<std::remove_pointer_t<std::remove_pointer_t<T>>> L;
+ return light<L>(l);
+ }
+
+ template <typename U>
+ struct user {
+ U value;
+
+ user(U x) : value(std::move(x)) {}
+ operator U* () { return std::addressof(value); }
+ operator U& () { return value; }
+ operator const U& () const { return value; }
+ };
+
+ template <typename T>
+ auto make_user(T&& u) {
+ typedef meta::unwrapped_t<meta::unqualified_t<T>> U;
+ return user<U>(std::forward<T>(u));
+ }
+
+ template <typename T>
+ struct metatable_registry_key {
+ T key;
+
+ metatable_registry_key(T key) : key(std::forward<T>(key)) {}
+ };
+
+ template <typename T>
+ auto meta_registry_key(T&& key) {
+ typedef meta::unqualified_t<T> K;
+ return metatable_registry_key<K>(std::forward<T>(key));
+ }
+
+ template <typename... Upvalues>
+ struct closure {
+ lua_CFunction c_function;
+ std::tuple<Upvalues...> upvalues;
+ closure(lua_CFunction f, Upvalues... upvalues) : c_function(f), upvalues(std::forward<Upvalues>(upvalues)...) {}
+ };
+
+ template <>
+ struct closure<> {
+ lua_CFunction c_function;
+ int upvalues;
+ closure(lua_CFunction f, int upvalues = 0) : c_function(f), upvalues(upvalues) {}
+ };
+
+ typedef closure<> c_closure;
+
+ template <typename... Args>
+ closure<Args...> make_closure(lua_CFunction f, Args&&... args) {
+ return closure<Args...>(f, std::forward<Args>(args)...);
+ }
+
+ template <typename Sig, typename... Ps>
+ struct function_arguments {
+ std::tuple<Ps...> arguments;
+ template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, function_arguments>> = meta::enabler>
+ function_arguments(Arg&& arg, Args&&... args) : arguments(std::forward<Arg>(arg), std::forward<Args>(args)...) {}
+ };
+
+ template <typename Sig = function_sig<>, typename... Args>
+ auto as_function(Args&&... args) {
+ return function_arguments<Sig, std::decay_t<Args>...>(std::forward<Args>(args)...);
+ }
+
+ template <typename Sig = function_sig<>, typename... Args>
+ auto as_function_reference(Args&&... args) {
+ return function_arguments<Sig, Args...>(std::forward<Args>(args)...);
+ }
+
+ template <typename T>
+ struct as_table_t {
+ T source;
+ template <typename... Args>
+ as_table_t(Args&&... args) : source(std::forward<Args>(args)...) {}
+
+ operator std::add_lvalue_reference_t<T> () {
+ return source;
+ }
+ };
+
+ template <typename T>
+ as_table_t<T> as_table(T&& container) {
+ return as_table_t<T>(std::forward<T>(container));
+ }
+
+ struct this_state {
+ lua_State* L;
+ operator lua_State* () const {
+ return L;
+ }
+ lua_State* operator-> () const {
+ return L;
+ }
+ };
+
+ enum class call_syntax {
+ dot = 0,
+ colon = 1
+ };
+
+ enum class call_status : int {
+ ok = LUA_OK,
+ yielded = LUA_YIELD,
+ runtime = LUA_ERRRUN,
+ memory = LUA_ERRMEM,
+ handler = LUA_ERRERR,
+ gc = LUA_ERRGCMM
+ };
+
+ enum class thread_status : int {
+ ok = LUA_OK,
+ yielded = LUA_YIELD,
+ runtime = LUA_ERRRUN,
+ memory = LUA_ERRMEM,
+ gc = LUA_ERRGCMM,
+ handler = LUA_ERRERR,
+ dead,
+ };
+
+ enum class load_status : int {
+ ok = LUA_OK,
+ syntax = LUA_ERRSYNTAX,
+ memory = LUA_ERRMEM,
+ gc = LUA_ERRGCMM,
+ file = LUA_ERRFILE,
+ };
+
+ enum class type : int {
+ none = LUA_TNONE,
+ nil = LUA_TNIL,
+ string = LUA_TSTRING,
+ number = LUA_TNUMBER,
+ thread = LUA_TTHREAD,
+ boolean = LUA_TBOOLEAN,
+ function = LUA_TFUNCTION,
+ userdata = LUA_TUSERDATA,
+ lightuserdata = LUA_TLIGHTUSERDATA,
+ table = LUA_TTABLE,
+ poly = none | nil | string | number | thread |
+ table | boolean | function | userdata | lightuserdata
+ };
+
+ enum class meta_function {
+ construct,
+ index,
+ new_index,
+ mode,
+ call,
+ metatable,
+ to_string,
+ length,
+ unary_minus,
+ addition,
+ subtraction,
+ multiplication,
+ division,
+ modulus,
+ power_of,
+ involution = power_of,
+ concatenation,
+ equal_to,
+ less_than,
+ less_than_or_equal_to,
+ garbage_collect,
+ call_function = call,
+ };
+
+ typedef meta_function meta_method;
+
+ const std::array<std::string, 2> meta_variable_names = { {
+ "__index",
+ "__newindex",
+ } };
+
+ const std::array<std::string, 21> meta_function_names = { {
+ "new",
+ "__index",
+ "__newindex",
+ "__mode",
+ "__call",
+ "__metatable",
+ "__tostring",
+ "__len",
+ "__unm",
+ "__add",
+ "__sub",
+ "__mul",
+ "__div",
+ "__mod",
+ "__pow",
+ "__concat",
+ "__eq",
+ "__lt",
+ "__le",
+ "__gc",
+ } };
+
+ inline const std::string& name_of(meta_function mf) {
+ return meta_function_names[static_cast<int>(mf)];
+ }
+
+ inline type type_of(lua_State* L, int index) {
+ return static_cast<type>(lua_type(L, index));
+ }
+
+ inline int type_panic(lua_State* L, int index, type expected, type actual) {
+ return luaL_error(L, "stack index %d, expected %s, received %s", index,
+ expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)),
+ expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(actual))
+ );
+ }
+
+ // Specify this function as the handler for lua::check if you know there's nothing wrong
+ inline int no_panic(lua_State*, int, type, type) noexcept {
+ return 0;
+ }
+
+ inline void type_error(lua_State* L, int expected, int actual) {
+ luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
+ }
+
+ inline void type_error(lua_State* L, type expected, type actual) {
+ type_error(L, static_cast<int>(expected), static_cast<int>(actual));
+ }
+
+ inline void type_assert(lua_State* L, int index, type expected, type actual) {
+ if (expected != type::poly && expected != actual) {
+ type_panic(L, index, expected, actual);
+ }
+ }
+
+ inline void type_assert(lua_State* L, int index, type expected) {
+ type actual = type_of(L, index);
+ type_assert(L, index, expected, actual);
+ }
+
+ inline std::string type_name(lua_State* L, type t) {
+ return lua_typename(L, static_cast<int>(t));
+ }
+
+ class reference;
+ class stack_reference;
+ template <typename Table, typename Key>
+ struct proxy;
+ template<typename T>
+ class usertype;
+ template <bool, typename T>
+ class basic_table_core;
+ template <bool b>
+ using table_core = basic_table_core<b, reference>;
+ template <bool b>
+ using stack_table_core = basic_table_core<b, stack_reference>;
+ typedef table_core<false> table;
+ typedef table_core<true> global_table;
+ typedef stack_table_core<false> stack_table;
+ typedef stack_table_core<true> stack_global_table;
+ template <typename T>
+ class basic_function;
+ template <typename T>
+ class basic_protected_function;
+ using function = basic_function<reference>;
+ using protected_function = basic_protected_function<reference>;
+ using stack_function = basic_function<stack_reference>;
+ using stack_protected_function = basic_protected_function<stack_reference>;
+ template <typename base_t>
+ class basic_object;
+ template <typename base_t>
+ class basic_userdata;
+ template <typename base_t>
+ class basic_lightuserdata;
+ struct variadic_args;
+ using object = basic_object<reference>;
+ using stack_object = basic_object<stack_reference>;
+ using userdata = basic_userdata<reference>;
+ using stack_userdata = basic_userdata<stack_reference>;
+ using lightuserdata = basic_lightuserdata<reference>;
+ using stack_lightuserdata = basic_lightuserdata<stack_reference>;
+ class coroutine;
+ class thread;
+ struct variadic_args;
+ struct this_state;
+
+ namespace detail {
+ template <typename T, typename = void>
+ struct lua_type_of : std::integral_constant<type, type::userdata> {};
+
+ template <>
+ struct lua_type_of<std::string> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<std::wstring> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<std::u16string> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<std::u32string> : std::integral_constant<type, type::string> {};
+
+ template <std::size_t N>
+ struct lua_type_of<char[N]> : std::integral_constant<type, type::string> {};
+
+ template <std::size_t N>
+ struct lua_type_of<wchar_t[N]> : std::integral_constant<type, type::string> {};
+
+ template <std::size_t N>
+ struct lua_type_of<char16_t[N]> : std::integral_constant<type, type::string> {};
+
+ template <std::size_t N>
+ struct lua_type_of<char32_t[N]> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<char> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<wchar_t> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<char16_t> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<char32_t> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<const char*> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<const char16_t*> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<const char32_t*> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<string_detail::string_shim> : std::integral_constant<type, type::string> {};
+
+ template <>
+ struct lua_type_of<bool> : std::integral_constant<type, type::boolean> {};
+
+ template <>
+ struct lua_type_of<nil_t> : std::integral_constant<type, type::nil> { };
+
+ template <>
+ struct lua_type_of<nullopt_t> : std::integral_constant<type, type::nil> { };
+
+ template <>
+ struct lua_type_of<std::nullptr_t> : std::integral_constant<type, type::nil> { };
+
+ template <>
+ struct lua_type_of<sol::error> : std::integral_constant<type, type::string> { };
+
+ template <bool b, typename Base>
+ struct lua_type_of<basic_table_core<b, Base>> : std::integral_constant<type, type::table> { };
+
+ template <>
+ struct lua_type_of<reference> : std::integral_constant<type, type::poly> {};
+
+ template <>
+ struct lua_type_of<stack_reference> : std::integral_constant<type, type::poly> {};
+
+ template <typename Base>
+ struct lua_type_of<basic_object<Base>> : std::integral_constant<type, type::poly> {};
+
+ template <typename... Args>
+ struct lua_type_of<std::tuple<Args...>> : std::integral_constant<type, type::poly> {};
+
+ template <typename A, typename B>
+ struct lua_type_of<std::pair<A, B>> : std::integral_constant<type, type::poly> {};
+
+ template <>
+ struct lua_type_of<void*> : std::integral_constant<type, type::lightuserdata> {};
+
+ template <>
+ struct lua_type_of<lightuserdata_value> : std::integral_constant<type, type::lightuserdata> {};
+
+ template <>
+ struct lua_type_of<userdata_value> : std::integral_constant<type, type::userdata> {};
+
+ template <typename T>
+ struct lua_type_of<light<T>> : std::integral_constant<type, type::lightuserdata> {};
+
+ template <typename T>
+ struct lua_type_of<user<T>> : std::integral_constant<type, type::userdata> {};
+
+ template <typename Base>
+ struct lua_type_of<basic_lightuserdata<Base>> : std::integral_constant<type, type::lightuserdata> {};
+
+ template <typename Base>
+ struct lua_type_of<basic_userdata<Base>> : std::integral_constant<type, type::userdata> {};
+
+ template <>
+ struct lua_type_of<lua_CFunction> : std::integral_constant<type, type::function> {};
+
+ template <>
+ struct lua_type_of<std::remove_pointer_t<lua_CFunction>> : std::integral_constant<type, type::function> {};
+
+ template <typename Base>
+ struct lua_type_of<basic_function<Base>> : std::integral_constant<type, type::function> {};
+
+ template <typename Base>
+ struct lua_type_of<basic_protected_function<Base>> : std::integral_constant<type, type::function> {};
+
+ template <>
+ struct lua_type_of<coroutine> : std::integral_constant<type, type::function> {};
+
+ template <>
+ struct lua_type_of<thread> : std::integral_constant<type, type::thread> {};
+
+ template <typename Signature>
+ struct lua_type_of<std::function<Signature>> : std::integral_constant<type, type::function> {};
+
+ template <typename T>
+ struct lua_type_of<optional<T>> : std::integral_constant<type, type::poly> {};
+
+ template <>
+ struct lua_type_of<variadic_args> : std::integral_constant<type, type::poly> {};
+
+ template <>
+ struct lua_type_of<this_state> : std::integral_constant<type, type::poly> {};
+
+ template <>
+ struct lua_type_of<type> : std::integral_constant<type, type::poly> {};
+
+ template <typename T>
+ struct lua_type_of<T*> : std::integral_constant<type, type::userdata> {};
+
+ template <typename T>
+ struct lua_type_of<T, std::enable_if_t<std::is_arithmetic<T>::value>> : std::integral_constant<type, type::number> {};
+
+ template <typename T>
+ struct lua_type_of<T, std::enable_if_t<std::is_enum<T>::value>> : std::integral_constant<type, type::number> {};
+
+ template <>
+ struct lua_type_of<meta_function> : std::integral_constant<type, type::string> {};
+
+ template <typename C, C v, template <typename...> class V, typename... Args>
+ struct accumulate : std::integral_constant<C, v> {};
+
+ template <typename C, C v, template <typename...> class V, typename T, typename... Args>
+ struct accumulate<C, v, V, T, Args...> : accumulate<C, v + V<T>::value, V, Args...> {};
+ } // detail
+
+ template <typename T>
+ struct is_unique_usertype : std::integral_constant<bool, unique_usertype_traits<T>::value> {};
+
+ template <typename T>
+ struct lua_type_of : detail::lua_type_of<T> {};
+
+ template <typename T>
+ struct lua_size : std::integral_constant<int, 1> { };
+
+ template <typename A, typename B>
+ struct lua_size<std::pair<A, B>> : std::integral_constant<int, lua_size<A>::value + lua_size<B>::value> { };
+
+ template <typename... Args>
+ struct lua_size<std::tuple<Args...>> : std::integral_constant<int, detail::accumulate<int, 0, lua_size, Args...>::value> { };
+
+ template <typename T>
+ struct is_lua_primitive : std::integral_constant<bool,
+ type::userdata != lua_type_of<meta::unqualified_t<T>>::value
+ || (lua_size<T>::value > 1)
+ || std::is_base_of<reference, meta::unqualified_t<T>>::value
+ || std::is_base_of<stack_reference, meta::unqualified_t<T>>::value
+ || meta::is_specialization_of<std::tuple, meta::unqualified_t<T>>::value
+ || meta::is_specialization_of<std::pair, meta::unqualified_t<T>>::value
+ > { };
+
+ template <typename T>
+ struct is_lua_reference : std::integral_constant<bool,
+ std::is_base_of<reference, meta::unqualified_t<T>>::value
+ || std::is_base_of<stack_reference, meta::unqualified_t<T>>::value
+ || meta::is_specialization_of<proxy, meta::unqualified_t<T>>::value
+ > { };
+
+ template <typename T>
+ struct is_lua_primitive<T*> : std::true_type {};
+ template <typename T>
+ struct is_lua_primitive<std::reference_wrapper<T>> : std::true_type { };
+ template <typename T>
+ struct is_lua_primitive<user<T>> : std::true_type { };
+ template <typename T>
+ struct is_lua_primitive<light<T>> : is_lua_primitive<T*> { };
+ template <typename T>
+ struct is_lua_primitive<optional<T>> : std::true_type {};
+ template <>
+ struct is_lua_primitive<userdata_value> : std::true_type {};
+ template <>
+ struct is_lua_primitive<lightuserdata_value> : std::true_type {};
+ template <typename T>
+ struct is_lua_primitive<non_null<T>> : is_lua_primitive<T*> {};
+
+ template <typename T>
+ struct is_proxy_primitive : is_lua_primitive<T> { };
+
+ template <typename T>
+ struct is_transparent_argument : std::false_type {};
+
+ template <>
+ struct is_transparent_argument<this_state> : std::true_type {};
+
+ template <>
+ struct is_transparent_argument<variadic_args> : std::true_type {};
+
+ template <typename Signature>
+ struct lua_bind_traits : meta::bind_traits<Signature> {
+ private:
+ typedef meta::bind_traits<Signature> base_t;
+ public:
+ static const std::size_t true_arity = base_t::arity;
+ static const std::size_t arity = base_t::arity - meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
+ static const std::size_t true_free_arity = base_t::free_arity;
+ static const std::size_t free_arity = base_t::free_arity - meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
+ };
+
+ template <typename T>
+ struct is_table : std::false_type {};
+ template <bool x, typename T>
+ struct is_table<basic_table_core<x, T>> : std::true_type {};
+
+ template <typename T>
+ struct is_function : std::false_type {};
+ template <typename T>
+ struct is_function<basic_function<T>> : std::true_type {};
+ template <typename T>
+ struct is_function<basic_protected_function<T>> : std::true_type {};
+
+ template <typename T>
+ struct is_lightuserdata : std::false_type {};
+ template <typename T>
+ struct is_lightuserdata<basic_lightuserdata<T>> : std::true_type {};
+
+ template <typename T>
+ struct is_userdata : std::false_type {};
+ template <typename T>
+ struct is_userdata<basic_userdata<T>> : std::true_type {};
+
+ template<typename T>
+ inline type type_of() {
+ return lua_type_of<meta::unqualified_t<T>>::value;
+ }
+} // sol
+
+#endif // SOL_TYPES_HPP
diff --git a/3rdparty/sol2/sol/userdata.hpp b/3rdparty/sol2/sol/userdata.hpp
new file mode 100644
index 00000000000..6a4098f1a0a
--- /dev/null
+++ b/3rdparty/sol2/sol/userdata.hpp
@@ -0,0 +1,82 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_USERDATA_HPP
+#define SOL_USERDATA_HPP
+
+#include "reference.hpp"
+
+namespace sol {
+ template <typename base_t>
+ class basic_userdata : public base_t {
+ public:
+ basic_userdata() noexcept = default;
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_userdata>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_userdata(T&& r) noexcept : base_t(std::forward<T>(r)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!is_userdata<meta::unqualified_t<T>>::value) {
+ auto pp = stack::push_pop(*this);
+ type_assert(base_t::lua_state(), -1, type::userdata);
+ }
+#endif // Safety
+ }
+ basic_userdata(const basic_userdata&) = default;
+ basic_userdata(basic_userdata&&) = default;
+ basic_userdata& operator=(const basic_userdata&) = default;
+ basic_userdata& operator=(basic_userdata&&) = default;
+ basic_userdata(const stack_reference& r) : basic_userdata(r.lua_state(), r.stack_index()) {}
+ basic_userdata(stack_reference&& r) : basic_userdata(r.lua_state(), r.stack_index()) {}
+ basic_userdata(lua_State* L, int index = -1) : base_t(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ type_assert(L, index, type::userdata);
+#endif // Safety
+ }
+ };
+
+ template <typename base_t>
+ class basic_lightuserdata : public base_t {
+ public:
+ basic_lightuserdata() noexcept = default;
+ template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_lightuserdata>>, meta::neg<std::is_same<base_t, stack_reference>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
+ basic_lightuserdata(T&& r) noexcept : base_t(std::forward<T>(r)) {
+#ifdef SOL_CHECK_ARGUMENTS
+ if (!is_userdata<meta::unqualified_t<T>>::value) {
+ auto pp = stack::push_pop(*this);
+ type_assert(base_t::lua_state(), -1, type::lightuserdata);
+ }
+#endif // Safety
+ }
+ basic_lightuserdata(const basic_lightuserdata&) = default;
+ basic_lightuserdata(basic_lightuserdata&&) = default;
+ basic_lightuserdata& operator=(const basic_lightuserdata&) = default;
+ basic_lightuserdata& operator=(basic_lightuserdata&&) = default;
+ basic_lightuserdata(const stack_reference& r) : basic_lightuserdata(r.lua_state(), r.stack_index()) {}
+ basic_lightuserdata(stack_reference&& r) : basic_lightuserdata(r.lua_state(), r.stack_index()) {}
+ basic_lightuserdata(lua_State* L, int index = -1) : base_t(L, index) {
+#ifdef SOL_CHECK_ARGUMENTS
+ type_assert(L, index, type::lightuserdata);
+#endif // Safety
+ }
+ };
+
+} // sol
+
+#endif // SOL_USERDATA_HPP
diff --git a/3rdparty/sol2/sol/usertype.hpp b/3rdparty/sol2/sol/usertype.hpp
new file mode 100644
index 00000000000..7fae5119c6d
--- /dev/null
+++ b/3rdparty/sol2/sol/usertype.hpp
@@ -0,0 +1,97 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_USERTYPE_HPP
+#define SOL_USERTYPE_HPP
+
+#include "stack.hpp"
+#include "usertype_metatable.hpp"
+#include "simple_usertype_metatable.hpp"
+#include "container_usertype_metatable.hpp"
+#include <memory>
+
+namespace sol {
+
+ template<typename T>
+ class usertype {
+ private:
+ std::unique_ptr<usertype_detail::registrar, detail::deleter> metatableregister;
+
+ template<typename... Args>
+ usertype(usertype_detail::verified_tag, Args&&... args) : metatableregister(detail::make_unique_deleter<usertype_metatable<T, std::make_index_sequence<sizeof...(Args) / 2>, Args...>, detail::deleter>(std::forward<Args>(args)...)) {}
+
+ template<typename... Args>
+ usertype(usertype_detail::add_destructor_tag, Args&&... args) : usertype(usertype_detail::verified, std::forward<Args>(args)..., "__gc", default_destructor) {}
+
+ template<typename... Args>
+ usertype(usertype_detail::check_destructor_tag, Args&&... args) : usertype(meta::condition<meta::all<std::is_destructible<T>, meta::neg<usertype_detail::has_destructor<Args...>>>, usertype_detail::add_destructor_tag, usertype_detail::verified_tag>(), std::forward<Args>(args)...) {}
+
+ public:
+
+ template<typename... Args>
+ usertype(Args&&... args) : usertype(meta::condition<meta::all<std::is_default_constructible<T>, meta::neg<usertype_detail::has_constructor<Args...>>>, decltype(default_constructor), usertype_detail::check_destructor_tag>(), std::forward<Args>(args)...) {}
+
+ template<typename... Args, typename... CArgs>
+ usertype(constructors<CArgs...> constructorlist, Args&&... args) : usertype(usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
+
+ template<typename... Args, typename... Fxs>
+ usertype(constructor_wrapper<Fxs...> constructorlist, Args&&... args) : usertype(usertype_detail::check_destructor_tag(), std::forward<Args>(args)..., "new", constructorlist) {}
+
+ template<typename... Args>
+ usertype(simple_tag, lua_State* L, Args&&... args) : metatableregister(detail::make_unique_deleter<simple_usertype_metatable<T>, detail::deleter>(L, std::forward<Args>(args)...)) {}
+
+ usertype_detail::registrar* registrar_data() {
+ return metatableregister.get();
+ }
+
+ int push(lua_State* L) {
+ return metatableregister->push_um(L);
+ }
+ };
+
+ template<typename T>
+ class simple_usertype : public usertype<T> {
+ private:
+ typedef usertype<T> base_t;
+ lua_State* state;
+
+ public:
+ template<typename... Args>
+ simple_usertype(lua_State* L, Args&&... args) : base_t(simple, L, std::forward<Args>(args)...), state(L) {}
+
+ template <typename N, typename F>
+ void set(N&& n, F&& f) {
+ auto meta = static_cast<simple_usertype_metatable<T>*>(base_t::registrar_data());
+ meta->add(state, n, f);
+ }
+ };
+
+ namespace stack {
+ template<typename T>
+ struct pusher<usertype<T>> {
+ static int push(lua_State* L, usertype<T>& user) {
+ return user.push(L);
+ }
+ };
+ } // stack
+} // sol
+
+#endif // SOL_USERTYPE_HPP
diff --git a/3rdparty/sol2/sol/usertype_metatable.hpp b/3rdparty/sol2/sol/usertype_metatable.hpp
new file mode 100644
index 00000000000..cd57f2679b9
--- /dev/null
+++ b/3rdparty/sol2/sol/usertype_metatable.hpp
@@ -0,0 +1,583 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_USERTYPE_METATABLE_HPP
+#define SOL_USERTYPE_METATABLE_HPP
+
+#include "wrapper.hpp"
+#include "call.hpp"
+#include "stack.hpp"
+#include "types.hpp"
+#include "stack_reference.hpp"
+#include "usertype_traits.hpp"
+#include "inheritance.hpp"
+#include "raii.hpp"
+#include "deprecate.hpp"
+#include <unordered_map>
+#include <cstdio>
+
+namespace sol {
+ namespace usertype_detail {
+ struct no_comp {
+ template <typename A, typename B>
+ bool operator()(A&&, B&&) const {
+ return false;
+ }
+ };
+
+ typedef void(*base_walk)(lua_State*, bool&, int&, string_detail::string_shim&);
+ typedef int(*member_search)(lua_State*, void*);
+
+ struct find_call_pair {
+ member_search first;
+ member_search second;
+
+ find_call_pair(member_search first, member_search second) : first(first), second(second) {}
+ };
+
+ inline bool is_indexer(string_detail::string_shim s) {
+ return s == name_of(meta_function::index) || s == name_of(meta_function::new_index);
+ }
+
+ inline bool is_indexer(meta_function mf) {
+ return mf == meta_function::index || mf == meta_function::new_index;
+ }
+
+ inline bool is_indexer(call_construction) {
+ return false;
+ }
+
+ inline bool is_indexer(base_classes_tag) {
+ return false;
+ }
+
+ inline auto make_shim(string_detail::string_shim s) {
+ return s;
+ }
+
+ inline auto make_shim(call_construction) {
+ return string_detail::string_shim(name_of(meta_function::call_function));
+ }
+
+ inline auto make_shim(meta_function mf) {
+ return string_detail::string_shim(name_of(mf));
+ }
+
+ inline auto make_shim(base_classes_tag) {
+ return string_detail::string_shim(detail::base_class_cast_key());
+ }
+
+ template <typename Arg>
+ inline std::string make_string(Arg&& arg) {
+ string_detail::string_shim s = make_shim(arg);
+ return std::string(s.c_str(), s.size());
+ }
+
+ template <typename N>
+ inline luaL_Reg make_reg(N&& n, lua_CFunction f) {
+ luaL_Reg l{ make_shim(std::forward<N>(n)).c_str(), f };
+ return l;
+ }
+
+ struct registrar {
+ virtual int push_um(lua_State* L) = 0;
+ virtual ~registrar() {}
+ };
+
+ template <bool is_index>
+ inline int indexing_fail(lua_State* L) {
+ auto maybeaccessor = stack::get<optional<string_detail::string_shim>>(L, is_index ? -1 : -2);
+ string_detail::string_shim accessor = maybeaccessor.value_or(string_detail::string_shim("(unknown)"));
+ if (is_index)
+ return luaL_error(L, "sol: attempt to index (get) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str());
+ else
+ return luaL_error(L, "sol: attempt to index (set) nil value \"%s\" on userdata (bad (misspelled?) key name or does not exist)", accessor.c_str());
+ }
+
+ template <bool is_index, typename Base>
+ static void walk_single_base(lua_State* L, bool& found, int& ret, string_detail::string_shim&) {
+ if (found)
+ return;
+ const char* metakey = &usertype_traits<Base>::metatable[0];
+ const char* gcmetakey = &usertype_traits<Base>::gc_table[0];
+ const char* basewalkkey = is_index ? detail::base_class_index_propogation_key() : detail::base_class_new_index_propogation_key();
+
+ luaL_getmetatable(L, metakey);
+ if (type_of(L, -1) == type::nil) {
+ lua_pop(L, 1);
+ return;
+ }
+
+ stack::get_field(L, basewalkkey);
+ if (type_of(L, -1) == type::nil) {
+ lua_pop(L, 2);
+ return;
+ }
+ lua_CFunction basewalkfunc = stack::pop<lua_CFunction>(L);
+ lua_pop(L, 1);
+
+ stack::get_field<true>(L, gcmetakey);
+ int value = basewalkfunc(L);
+ if (value > -1) {
+ found = true;
+ ret = value;
+ }
+ }
+
+ template <bool is_index, typename... Bases>
+ static void walk_all_bases(lua_State* L, bool& found, int& ret, string_detail::string_shim& accessor) {
+ (void)L;
+ (void)found;
+ (void)ret;
+ (void)accessor;
+ (void)detail::swallow{ 0, (walk_single_base<is_index, Bases>(L, found, ret, accessor), 0)... };
+ }
+
+ template <typename T, typename Op>
+ inline int operator_wrap(lua_State* L) {
+ auto maybel = stack::check_get<T>(L, 1);
+ if (maybel) {
+ auto mayber = stack::check_get<T>(L, 2);
+ if (mayber) {
+ auto& l = *maybel;
+ auto& r = *mayber;
+ if (std::is_same<no_comp, Op>::value) {
+ return stack::push(L, detail::ptr(l) == detail::ptr(r));
+ }
+ else {
+ Op op;
+ return stack::push(L, (detail::ptr(l) == detail::ptr(r)) || op(detail::deref(l), detail::deref(r)));
+ }
+ }
+ }
+ return stack::push(L, false);
+ }
+
+ template <typename T, typename Op, typename Supports, typename Regs, meta::enable<Supports> = meta::enabler>
+ inline void make_reg_op(Regs& l, int& index, const char* name) {
+ l[index] = { name, &operator_wrap<T, Op> };
+ ++index;
+ }
+
+ template <typename T, typename Op, typename Supports, typename Regs, meta::disable<Supports> = meta::enabler>
+ inline void make_reg_op(Regs&, int&, const char*) {
+ // Do nothing if there's no support
+ }
+
+ struct add_destructor_tag {};
+ struct check_destructor_tag {};
+ struct verified_tag {} const verified{};
+
+ template <typename T>
+ struct is_constructor : std::false_type {};
+
+ template <typename... Args>
+ struct is_constructor<constructors<Args...>> : std::true_type {};
+
+ template <typename... Args>
+ struct is_constructor<constructor_wrapper<Args...>> : std::true_type {};
+
+ template <typename... Args>
+ struct is_constructor<factory_wrapper<Args...>> : std::true_type {};
+
+ template <>
+ struct is_constructor<no_construction> : std::true_type {};
+
+ template <typename... Args>
+ using has_constructor = meta::any<is_constructor<meta::unqualified_t<Args>>...>;
+
+ template <typename T>
+ struct is_destructor : std::false_type {};
+
+ template <typename Fx>
+ struct is_destructor<destructor_wrapper<Fx>> : std::true_type {};
+
+ template <typename... Args>
+ using has_destructor = meta::any<is_destructor<meta::unqualified_t<Args>>...>;
+
+ } // usertype_detail
+
+ template <typename T>
+ struct clean_type {
+ typedef std::conditional_t<std::is_array<meta::unqualified_t<T>>::value, T&, std::decay_t<T>> type;
+ };
+
+ template <typename T>
+ using clean_type_t = typename clean_type<T>::type;
+
+ template <typename T, typename IndexSequence, typename... Tn>
+ struct usertype_metatable : usertype_detail::registrar {};
+
+ template <typename T, std::size_t... I, typename... Tn>
+ struct usertype_metatable<T, std::index_sequence<I...>, Tn...> : usertype_detail::registrar {
+ typedef std::make_index_sequence<sizeof...(I) * 2> indices;
+ typedef std::index_sequence<I...> half_indices;
+ typedef std::array<luaL_Reg, sizeof...(Tn) / 2 + 1 + 3> regs_t;
+ typedef std::tuple<Tn...> RawTuple;
+ typedef std::tuple<clean_type_t<Tn> ...> Tuple;
+ template <std::size_t Idx>
+ struct check_binding : is_variable_binding<meta::unqualified_tuple_element_t<Idx, Tuple>> {};
+ typedef std::unordered_map<std::string, usertype_detail::find_call_pair> mapping_t;
+ Tuple functions;
+ mapping_t mapping;
+ lua_CFunction indexfunc;
+ lua_CFunction newindexfunc;
+ lua_CFunction destructfunc;
+ lua_CFunction callconstructfunc;
+ lua_CFunction indexbase;
+ lua_CFunction newindexbase;
+ usertype_detail::base_walk indexbaseclasspropogation;
+ usertype_detail::base_walk newindexbaseclasspropogation;
+ void* baseclasscheck;
+ void* baseclasscast;
+ bool mustindex;
+ bool secondarymeta;
+ bool hasequals;
+ bool hasless;
+ bool haslessequals;
+
+ template <std::size_t Idx, meta::enable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
+ inline lua_CFunction make_func() {
+ return std::get<Idx + 1>(functions);
+ }
+
+ template <std::size_t Idx, meta::disable<std::is_same<lua_CFunction, meta::unqualified_tuple_element<Idx + 1, RawTuple>>> = meta::enabler>
+ inline lua_CFunction make_func() {
+ return call<Idx + 1>;
+ }
+
+ static bool contains_variable() {
+ typedef meta::any<check_binding<(I * 2 + 1)>...> has_variables;
+ return has_variables::value;
+ }
+
+ bool contains_index() const {
+ bool idx = false;
+ (void)detail::swallow{ 0, ((idx |= usertype_detail::is_indexer(std::get<I * 2>(functions))), 0) ... };
+ return idx;
+ }
+
+ int finish_regs(regs_t& l, int& index) {
+ if (!hasless) {
+ const char* name = name_of(meta_function::less_than).c_str();
+ usertype_detail::make_reg_op<T, std::less<>, meta::supports_op_less<T>>(l, index, name);
+ }
+ if (!haslessequals) {
+ const char* name = name_of(meta_function::less_than_or_equal_to).c_str();
+ usertype_detail::make_reg_op<T, std::less_equal<>, meta::supports_op_less_equal<T>>(l, index, name);
+ }
+ if (!hasequals) {
+ const char* name = name_of(meta_function::equal_to).c_str();
+ usertype_detail::make_reg_op<T, std::conditional_t<meta::supports_op_equal<T>::value, std::equal_to<>, usertype_detail::no_comp>, std::true_type>(l, index, name);
+ }
+ if (destructfunc != nullptr) {
+ l[index] = { name_of(meta_function::garbage_collect).c_str(), destructfunc };
+ ++index;
+ }
+ return index;
+ }
+
+ template <std::size_t Idx, typename F>
+ void make_regs(regs_t&, int&, call_construction, F&&) {
+ callconstructfunc = call<Idx + 1>;
+ secondarymeta = true;
+ }
+
+ template <std::size_t, typename... Bases>
+ void make_regs(regs_t&, int&, base_classes_tag, bases<Bases...>) {
+ if (sizeof...(Bases) < 1) {
+ return;
+ }
+ mustindex = true;
+ (void)detail::swallow{ 0, ((detail::has_derived<Bases>::value = true), 0)... };
+
+ static_assert(sizeof(void*) <= sizeof(detail::inheritance_check_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
+ static_assert(sizeof(void*) <= sizeof(detail::inheritance_cast_function), "The size of this data pointer is too small to fit the inheritance checking function: file a bug report.");
+ baseclasscheck = (void*)&detail::inheritance<T, Bases...>::type_check;
+ baseclasscast = (void*)&detail::inheritance<T, Bases...>::type_cast;
+ indexbaseclasspropogation = usertype_detail::walk_all_bases<true, Bases...>;
+ newindexbaseclasspropogation = usertype_detail::walk_all_bases<false, Bases...>;
+ }
+
+ template <std::size_t Idx, typename N, typename F, typename = std::enable_if_t<!meta::any_same<meta::unqualified_t<N>, base_classes_tag, call_construction>::value>>
+ void make_regs(regs_t& l, int& index, N&& n, F&&) {
+ if (is_variable_binding<meta::unqualified_t<F>>::value) {
+ return;
+ }
+ luaL_Reg reg = usertype_detail::make_reg(std::forward<N>(n), make_func<Idx>());
+ // Returnable scope
+ // That would be a neat keyword for C++
+ // returnable { ... };
+ if (reg.name == name_of(meta_function::equal_to)) {
+ hasequals = true;
+ }
+ if (reg.name == name_of(meta_function::less_than)) {
+ hasless = true;
+ }
+ if (reg.name == name_of(meta_function::less_than_or_equal_to)) {
+ haslessequals = true;
+ }
+ if (reg.name == name_of(meta_function::garbage_collect)) {
+ destructfunc = reg.func;
+ return;
+ }
+ else if (reg.name == name_of(meta_function::index)) {
+ indexfunc = reg.func;
+ mustindex = true;
+ return;
+ }
+ else if (reg.name == name_of(meta_function::new_index)) {
+ newindexfunc = reg.func;
+ mustindex = true;
+ return;
+ }
+ l[index] = reg;
+ ++index;
+ }
+
+ template <typename... Args, typename = std::enable_if_t<sizeof...(Args) == sizeof...(Tn)>>
+ usertype_metatable(Args&&... args) : functions(std::forward<Args>(args)...),
+ mapping(),
+ indexfunc(usertype_detail::indexing_fail<true>), newindexfunc(usertype_detail::indexing_fail<false>),
+ destructfunc(nullptr), callconstructfunc(nullptr),
+ indexbase(&core_indexing_call<true>), newindexbase(&core_indexing_call<false>),
+ indexbaseclasspropogation(usertype_detail::walk_all_bases<true>), newindexbaseclasspropogation(usertype_detail::walk_all_bases<false>),
+ baseclasscheck(nullptr), baseclasscast(nullptr),
+ mustindex(contains_variable() || contains_index()), secondarymeta(contains_variable()),
+ hasequals(false), hasless(false), haslessequals(false) {
+ std::initializer_list<typename mapping_t::value_type> ilist{ {
+ std::pair<std::string, usertype_detail::find_call_pair>(
+ usertype_detail::make_string(std::get<I * 2>(functions)),
+ usertype_detail::find_call_pair(&usertype_metatable::real_find_call<I * 2, I * 2 + 1, false>,
+ &usertype_metatable::real_find_call<I * 2, I * 2 + 1, true>)
+ )
+ }... };
+ mapping.insert(ilist);
+ }
+
+ template <std::size_t I0, std::size_t I1, bool is_index>
+ static int real_find_call(lua_State* L, void* um) {
+ auto& f = *static_cast<usertype_metatable*>(um);
+ if (is_variable_binding<decltype(std::get<I1>(f.functions))>::value) {
+ return real_call_with<I1, is_index, true>(L, f);
+ }
+ return stack::push(L, c_closure(call<I1, is_index>, stack::push(L, light<usertype_metatable>(f))));
+ }
+
+ template <bool is_index, bool toplevel = false>
+ static int core_indexing_call(lua_State* L) {
+ usertype_metatable& f = toplevel ? stack::get<light<usertype_metatable>>(L, upvalue_index(1)) : stack::pop<light<usertype_metatable>>(L);
+ static const int keyidx = -2 + static_cast<int>(is_index);
+ if (toplevel && stack::get<type>(L, keyidx) != type::string) {
+ return is_index ? f.indexfunc(L) : f.newindexfunc(L);
+ }
+ std::string name = stack::get<std::string>(L, keyidx);
+ auto memberit = f.mapping.find(name);
+ if (memberit != f.mapping.cend()) {
+ auto& member = is_index ? memberit->second.second : memberit->second.first;
+ return (member)(L, static_cast<void*>(&f));
+ }
+ string_detail::string_shim accessor = name;
+ int ret = 0;
+ bool found = false;
+ // Otherwise, we need to do propagating calls through the bases
+ if (is_index)
+ f.indexbaseclasspropogation(L, found, ret, accessor);
+ else
+ f.newindexbaseclasspropogation(L, found, ret, accessor);
+ if (found) {
+ return ret;
+ }
+ return toplevel ? (is_index ? f.indexfunc(L) : f.newindexfunc(L)) : -1;
+ }
+
+ static int real_index_call(lua_State* L) {
+ return core_indexing_call<true, true>(L);
+ }
+
+ static int real_new_index_call(lua_State* L) {
+ return core_indexing_call<false, true>(L);
+ }
+
+ template <std::size_t Idx, bool is_index = true, bool is_variable = false>
+ static int real_call(lua_State* L) {
+ usertype_metatable& f = stack::get<light<usertype_metatable>>(L, upvalue_index(1));
+ return real_call_with<Idx, is_index, is_variable>(L, f);
+ }
+
+ template <std::size_t Idx, bool is_index = true, bool is_variable = false>
+ static int real_call_with(lua_State* L, usertype_metatable& um) {
+ auto& f = std::get<Idx>(um.functions);
+ return call_detail::call_wrapped<T, is_index, is_variable>(L, f);
+ }
+
+ template <std::size_t Idx, bool is_index = true, bool is_variable = false>
+ static int call(lua_State* L) {
+ return detail::static_trampoline<(&real_call<Idx, is_index, is_variable>)>(L);
+ }
+
+ template <std::size_t Idx, bool is_index = true, bool is_variable = false>
+ static int call_with(lua_State* L) {
+ return detail::static_trampoline<(&real_call_with<Idx, is_index, is_variable>)>(L);
+ }
+
+ static int index_call(lua_State* L) {
+ return detail::static_trampoline<(&real_index_call)>(L);
+ }
+
+ static int new_index_call(lua_State* L) {
+ return detail::static_trampoline<(&real_new_index_call)>(L);
+ }
+
+ virtual int push_um(lua_State* L) override {
+ return stack::push(L, std::move(*this));
+ }
+
+ ~usertype_metatable() override {
+
+ }
+ };
+
+ namespace stack {
+
+ template <typename T, std::size_t... I, typename... Args>
+ struct pusher<usertype_metatable<T, std::index_sequence<I...>, Args...>> {
+ typedef usertype_metatable<T, std::index_sequence<I...>, Args...> umt_t;
+ typedef typename umt_t::regs_t regs_t;
+
+ static umt_t& make_cleanup(lua_State* L, umt_t&& umx) {
+ // ensure some sort of uniqueness
+ static int uniqueness = 0;
+ std::string uniquegcmetakey = usertype_traits<T>::user_gc_metatable;
+ // std::to_string doesn't exist in android still, with NDK, so this bullshit
+ // is necessary
+ // thanks, Android :v
+ int appended = snprintf(nullptr, 0, "%d", uniqueness);
+ std::size_t insertionpoint = uniquegcmetakey.length() - 1;
+ uniquegcmetakey.append(appended, '\0');
+ char* uniquetarget = &uniquegcmetakey[insertionpoint];
+ snprintf(uniquetarget, uniquegcmetakey.length(), "%d", uniqueness);
+ ++uniqueness;
+
+ const char* gcmetakey = &usertype_traits<T>::gc_table[0];
+ // Make sure userdata's memory is properly in lua first,
+ // otherwise all the light userdata we make later will become invalid
+ stack::push<user<umt_t>>(L, metatable_key, uniquegcmetakey, std::move(umx));
+ // Create the top level thing that will act as our deleter later on
+ stack_reference umt(L, -1);
+ stack::set_field<true>(L, gcmetakey, umt);
+ umt.pop();
+
+ stack::get_field<true>(L, gcmetakey);
+ return stack::pop<light<umt_t>>(L);
+ }
+
+ static int push(lua_State* L, umt_t&& umx) {
+
+ umt_t& um = make_cleanup(L, std::move(umx));
+ regs_t value_table{ {} };
+ int lastreg = 0;
+ (void)detail::swallow{ 0, (um.template make_regs<(I * 2)>(value_table, lastreg, std::get<(I * 2)>(um.functions), std::get<(I * 2 + 1)>(um.functions)), 0)... };
+ um.finish_regs(value_table, lastreg);
+ value_table[lastreg] = { nullptr, nullptr };
+ regs_t ref_table = value_table;
+ regs_t unique_table = value_table;
+ bool hasdestructor = !value_table.empty() && name_of(meta_function::garbage_collect) == value_table[lastreg - 1].name;
+ if (hasdestructor) {
+ ref_table[lastreg - 1] = { nullptr, nullptr };
+ unique_table[lastreg - 1] = { value_table[lastreg - 1].name, detail::unique_destruct<T> };
+ }
+
+ // Now use um
+ const bool& mustindex = um.mustindex;
+ for (std::size_t i = 0; i < 3; ++i) {
+ // Pointer types, AKA "references" from C++
+ const char* metakey = nullptr;
+ luaL_Reg* metaregs = nullptr;
+ switch (i) {
+ case 0:
+ metakey = &usertype_traits<T*>::metatable[0];
+ metaregs = ref_table.data();
+ break;
+ case 1:
+ metakey = &usertype_traits<detail::unique_usertype<T>>::metatable[0];
+ metaregs = unique_table.data();
+ break;
+ case 2:
+ default:
+ metakey = &usertype_traits<T>::metatable[0];
+ metaregs = value_table.data();
+ break;
+ }
+ luaL_newmetatable(L, metakey);
+ stack_reference t(L, -1);
+ stack::push(L, make_light(um));
+ luaL_setfuncs(L, metaregs, 1);
+
+ if (um.baseclasscheck != nullptr) {
+ stack::set_field(L, detail::base_class_check_key(), um.baseclasscheck, t.stack_index());
+ }
+ if (um.baseclasscast != nullptr) {
+ stack::set_field(L, detail::base_class_cast_key(), um.baseclasscast, t.stack_index());
+ }
+
+ stack::set_field(L, detail::base_class_index_propogation_key(), make_closure(um.indexbase, make_light(um)), t.stack_index());
+ stack::set_field(L, detail::base_class_new_index_propogation_key(), make_closure(um.newindexbase, make_light(um)), t.stack_index());
+
+ if (mustindex) {
+ // Basic index pushing: specialize
+ // index and newindex to give variables and stuff
+ stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um)), t.stack_index());
+ stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um)), t.stack_index());
+ }
+ else {
+ // If there's only functions, we can use the fast index version
+ stack::set_field(L, meta_function::index, t, t.stack_index());
+ }
+ // metatable on the metatable
+ // for call constructor purposes and such
+ lua_createtable(L, 0, 1);
+ stack_reference metabehind(L, -1);
+ if (um.callconstructfunc != nullptr) {
+ stack::set_field(L, meta_function::call_function, make_closure(um.callconstructfunc, make_light(um)), metabehind.stack_index());
+ }
+ if (um.secondarymeta) {
+ stack::set_field(L, meta_function::index, make_closure(umt_t::index_call, make_light(um)), metabehind.stack_index());
+ stack::set_field(L, meta_function::new_index, make_closure(umt_t::new_index_call, make_light(um)), metabehind.stack_index());
+ }
+ stack::set_field(L, metatable_key, metabehind, t.stack_index());
+ metabehind.pop();
+ // We want to just leave the table
+ // in the registry only, otherwise we return it
+ if (i < 2) {
+ t.pop();
+ }
+ }
+
+ return 1;
+ }
+ };
+
+ } // stack
+
+} // sol
+
+#endif // SOL_USERTYPE_METATABLE_HPP
diff --git a/3rdparty/sol2/sol/usertype_traits.hpp b/3rdparty/sol2/sol/usertype_traits.hpp
new file mode 100644
index 00000000000..2dd3d62cbaf
--- /dev/null
+++ b/3rdparty/sol2/sol/usertype_traits.hpp
@@ -0,0 +1,55 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_USERTYPE_TRAITS_HPP
+#define SOL_USERTYPE_TRAITS_HPP
+
+#include "demangle.hpp"
+
+namespace sol {
+
+ template<typename T>
+ struct usertype_traits {
+ static const std::string name;
+ static const std::string qualified_name;
+ static const std::string metatable;
+ static const std::string user_gc_metatable;
+ static const std::string gc_table;
+ };
+
+ template<typename T>
+ const std::string usertype_traits<T>::name = detail::short_demangle<T>();
+
+ template<typename T>
+ const std::string usertype_traits<T>::qualified_name = detail::demangle<T>();
+
+ template<typename T>
+ const std::string usertype_traits<T>::metatable = std::string("sol.").append(detail::demangle<T>());
+
+ template<typename T>
+ const std::string usertype_traits<T>::user_gc_metatable = std::string("sol.").append(detail::demangle<T>()).append(".user\xE2\x99\xBB");
+
+ template<typename T>
+ const std::string usertype_traits<T>::gc_table = std::string("sol.").append(detail::demangle<T>().append(".\xE2\x99\xBB"));
+
+}
+
+#endif // SOL_USERTYPE_TRAITS_HPP
diff --git a/3rdparty/sol2/sol/variadic_args.hpp b/3rdparty/sol2/sol/variadic_args.hpp
new file mode 100644
index 00000000000..36fa3cda7e2
--- /dev/null
+++ b/3rdparty/sol2/sol/variadic_args.hpp
@@ -0,0 +1,236 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_VARIADIC_ARGS_HPP
+#define SOL_VARIADIC_ARGS_HPP
+
+#include "stack.hpp"
+#include "stack_proxy.hpp"
+#include <limits>
+#include <iterator>
+
+namespace sol {
+ template <bool is_const>
+ struct va_iterator : std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const stack_proxy, stack_proxy>, std::ptrdiff_t, std::conditional_t<is_const, const stack_proxy*, stack_proxy*>, std::conditional_t<is_const, const stack_proxy, stack_proxy>> {
+ typedef std::iterator<std::random_access_iterator_tag, std::conditional_t<is_const, const stack_proxy, stack_proxy>, std::ptrdiff_t, std::conditional_t<is_const, const stack_proxy*, stack_proxy*>, std::conditional_t<is_const, const stack_proxy, stack_proxy>> base_t;
+ typedef typename base_t::reference reference;
+ typedef typename base_t::pointer pointer;
+ typedef typename base_t::value_type value_type;
+ typedef typename base_t::difference_type difference_type;
+ typedef typename base_t::iterator_category iterator_category;
+ lua_State* L;
+ int index;
+ int stacktop;
+ stack_proxy sp;
+
+ va_iterator() : L(nullptr), index((std::numeric_limits<int>::max)()), stacktop((std::numeric_limits<int>::max)()) {}
+ va_iterator(lua_State* L, int index, int stacktop) : L(L), index(index), stacktop(stacktop), sp(L, index) {}
+
+ reference operator*() {
+ return stack_proxy(L, index);
+ }
+
+ pointer operator->() {
+ sp = stack_proxy(L, index);
+ return &sp;
+ }
+
+ va_iterator& operator++ () {
+ ++index;
+ return *this;
+ }
+
+ va_iterator operator++ (int) {
+ auto r = *this;
+ this->operator ++();
+ return r;
+ }
+
+ va_iterator& operator-- () {
+ --index;
+ return *this;
+ }
+
+ va_iterator operator-- (int) {
+ auto r = *this;
+ this->operator --();
+ return r;
+ }
+
+ va_iterator& operator+= (difference_type idx) {
+ index += static_cast<int>(idx);
+ return *this;
+ }
+
+ va_iterator& operator-= (difference_type idx) {
+ index -= static_cast<int>(idx);
+ return *this;
+ }
+
+ difference_type operator- (const va_iterator& r) const {
+ return index - r.index;
+ }
+
+ va_iterator operator+ (difference_type idx) const {
+ va_iterator r = *this;
+ r += idx;
+ return r;
+ }
+
+ reference operator[](difference_type idx) {
+ return stack_proxy(L, index + static_cast<int>(idx));
+ }
+
+ bool operator==(const va_iterator& r) const {
+ if (stacktop == (std::numeric_limits<int>::max)()) {
+ return r.index == r.stacktop;
+ }
+ else if (r.stacktop == (std::numeric_limits<int>::max)()) {
+ return index == stacktop;
+ }
+ return index == r.index;
+ }
+
+ bool operator != (const va_iterator& r) const {
+ return !(this->operator==(r));
+ }
+
+ bool operator < (const va_iterator& r) const {
+ return index < r.index;
+ }
+
+ bool operator > (const va_iterator& r) const {
+ return index > r.index;
+ }
+
+ bool operator <= (const va_iterator& r) const {
+ return index <= r.index;
+ }
+
+ bool operator >= (const va_iterator& r) const {
+ return index >= r.index;
+ }
+ };
+
+ template <bool is_const>
+ inline va_iterator<is_const> operator+(typename va_iterator<is_const>::difference_type n, const va_iterator<is_const>& r) {
+ return r + n;
+ }
+
+ struct variadic_args {
+ private:
+ lua_State* L;
+ int index;
+ int stacktop;
+
+ public:
+ typedef stack_proxy reference_type;
+ typedef stack_proxy value_type;
+ typedef stack_proxy* pointer;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::size_t size_type;
+ typedef va_iterator<false> iterator;
+ typedef va_iterator<true> const_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ variadic_args() = default;
+ variadic_args(lua_State* L, int index = -1) : L(L), index(lua_absindex(L, index)), stacktop(lua_gettop(L)) {}
+ variadic_args(const variadic_args&) = default;
+ variadic_args& operator=(const variadic_args&) = default;
+ variadic_args(variadic_args&& o) : L(o.L), index(o.index), stacktop(o.stacktop) {
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.stacktop = 0;
+ }
+ variadic_args& operator=(variadic_args&& o) {
+ L = o.L;
+ index = o.index;
+ stacktop = o.stacktop;
+ // Must be manual, otherwise destructor will screw us
+ // return count being 0 is enough to keep things clean
+ // but will be thorough
+ o.L = nullptr;
+ o.index = 0;
+ o.stacktop = 0;
+ return *this;
+ }
+
+ iterator begin() { return iterator(L, index, stacktop + 1); }
+ iterator end() { return iterator(L, stacktop + 1, stacktop + 1); }
+ const_iterator begin() const { return const_iterator(L, index, stacktop + 1); }
+ const_iterator end() const { return const_iterator(L, stacktop + 1, stacktop + 1); }
+ const_iterator cbegin() const { return begin(); }
+ const_iterator cend() const { return end(); }
+
+ reverse_iterator rbegin() { return std::reverse_iterator<iterator>(begin()); }
+ reverse_iterator rend() { return std::reverse_iterator<iterator>(end()); }
+ const_reverse_iterator rbegin() const { return std::reverse_iterator<const_iterator>(begin()); }
+ const_reverse_iterator rend() const { return std::reverse_iterator<const_iterator>(end()); }
+ const_reverse_iterator crbegin() const { return std::reverse_iterator<const_iterator>(cbegin()); }
+ const_reverse_iterator crend() const { return std::reverse_iterator<const_iterator>(cend()); }
+
+ int push() const {
+ int pushcount = 0;
+ for (int i = index; i <= stacktop; ++i) {
+ lua_pushvalue(L, i);
+ pushcount += 1;
+ }
+ return pushcount;
+ }
+
+ template<typename T>
+ decltype(auto) get(difference_type start = 0) const {
+ return stack::get<T>(L, index + static_cast<int>(start));
+ }
+
+ stack_proxy operator[](difference_type start) const {
+ return stack_proxy(L, index + static_cast<int>(start));
+ }
+
+ lua_State* lua_state() const { return L; };
+ int stack_index() const { return index; };
+ int leftover_count() const { return stacktop - (index - 1); }
+ int top() const { return stacktop; }
+ };
+
+ namespace stack {
+ template <>
+ struct getter<variadic_args> {
+ static variadic_args get(lua_State* L, int index, record& tracking) {
+ tracking.last = 0;
+ return variadic_args(L, index);
+ }
+ };
+
+ template <>
+ struct pusher<variadic_args> {
+ static int push(lua_State*, const variadic_args& ref) {
+ return ref.push();
+ }
+ };
+ } // stack
+} // sol
+
+#endif // SOL_VARIADIC_ARGS_HPP
diff --git a/3rdparty/sol2/sol/wrapper.hpp b/3rdparty/sol2/sol/wrapper.hpp
new file mode 100644
index 00000000000..7e38d39f3fe
--- /dev/null
+++ b/3rdparty/sol2/sol/wrapper.hpp
@@ -0,0 +1,233 @@
+// The MIT License (MIT)
+
+// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
+
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#ifndef SOL_WRAPPER_HPP
+#define SOL_WRAPPER_HPP
+
+#include "types.hpp"
+
+namespace sol {
+
+ template <typename F, typename = void>
+ struct wrapper {
+ typedef lua_bind_traits<F> traits_type;
+ typedef typename traits_type::args_list args_list;
+ typedef typename traits_type::args_list free_args_list;
+ typedef typename traits_type::returns_list returns_list;
+
+ template <typename... Args>
+ static decltype(auto) call(F& f, Args&&... args) {
+ return f(std::forward<Args>(args)...);
+ }
+
+ struct caller {
+ template <typename... Args>
+ decltype(auto) operator()(F& fx, Args&&... args) const {
+ return call(fx, std::forward<Args>(args)...);
+ }
+ };
+ };
+
+ template <typename F>
+ struct wrapper<F, std::enable_if_t<std::is_function<meta::unqualified_t<std::remove_pointer_t<F>>>::value>> {
+ typedef lua_bind_traits<F> traits_type;
+ typedef typename traits_type::args_list args_list;
+ typedef typename traits_type::args_list free_args_list;
+ typedef typename traits_type::returns_list returns_list;
+
+ template <F fx, typename... Args>
+ static decltype(auto) invoke(Args&&... args) {
+ return fx(std::forward<Args>(args)...);
+ }
+
+ template <typename... Args>
+ static decltype(auto) call(F& fx, Args&&... args) {
+ return fx(std::forward<Args>(args)...);
+ }
+
+ struct caller {
+ template <typename... Args>
+ decltype(auto) operator()(F& fx, Args&&... args) const {
+ return call(fx, std::forward<Args>(args)...);
+ }
+ };
+
+ template <F fx>
+ struct invoker {
+ template <typename... Args>
+ decltype(auto) operator()(Args&&... args) const {
+ return invoke<fx>(std::forward<Args>(args)...);
+ }
+ };
+ };
+
+ template <typename F>
+ struct wrapper<F, std::enable_if_t<std::is_member_object_pointer<meta::unqualified_t<F>>::value>> {
+ typedef lua_bind_traits<F> traits_type;
+ typedef typename traits_type::object_type object_type;
+ typedef typename traits_type::return_type return_type;
+ typedef typename traits_type::args_list args_list;
+ typedef types<object_type&, return_type> free_args_list;
+ typedef typename traits_type::returns_list returns_list;
+
+ template <F fx, typename... Args>
+ static decltype(auto) invoke(object_type& mem, Args&&... args) {
+ return (mem.*fx)(std::forward<Args>(args)...);
+ }
+
+ template <typename Fx>
+ static decltype(auto) call(Fx&& fx, object_type& mem) {
+ return (mem.*fx);
+ }
+
+ template <typename Fx, typename Arg, typename... Args>
+ static void call(Fx&& fx, object_type& mem, Arg&& arg, Args&&...) {
+ (mem.*fx) = std::forward<Arg>(arg);
+ }
+
+ struct caller {
+ template <typename Fx, typename... Args>
+ decltype(auto) operator()(Fx&& fx, object_type& mem, Args&&... args) const {
+ return call(std::forward<Fx>(fx), mem, std::forward<Args>(args)...);
+ }
+ };
+
+ template <F fx>
+ struct invoker {
+ template <typename... Args>
+ decltype(auto) operator()(Args&&... args) const {
+ return invoke<fx>(std::forward<Args>(args)...);
+ }
+ };
+ };
+
+ template <typename F, typename R, typename O, typename... FArgs>
+ struct member_function_wrapper {
+ typedef O object_type;
+ typedef lua_bind_traits<F> traits_type;
+ typedef typename traits_type::args_list args_list;
+ typedef types<object_type&, FArgs...> free_args_list;
+ typedef meta::tuple_types<R> returns_list;
+
+ template <F fx, typename... Args>
+ static R invoke(O& mem, Args&&... args) {
+ return (mem.*fx)(std::forward<Args>(args)...);
+ }
+
+ template <typename Fx, typename... Args>
+ static R call(Fx&& fx, O& mem, Args&&... args) {
+ return (mem.*fx)(std::forward<Args>(args)...);
+ }
+
+ struct caller {
+ template <typename Fx, typename... Args>
+ decltype(auto) operator()(Fx&& fx, O& mem, Args&&... args) const {
+ return call(std::forward<Fx>(fx), mem, std::forward<Args>(args)...);
+ }
+ };
+
+ template <F fx>
+ struct invoker {
+ template <typename... Args>
+ decltype(auto) operator()(O& mem, Args&&... args) const {
+ return invoke<fx>(mem, std::forward<Args>(args)...);
+ }
+ };
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...)> : public member_function_wrapper<R(O:: *)(Args...), R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const> : public member_function_wrapper<R(O:: *)(Args...) const, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const volatile> : public member_function_wrapper<R(O:: *)(Args...) const volatile, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) &> : public member_function_wrapper<R(O:: *)(Args...) &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const &> : public member_function_wrapper<R(O:: *)(Args...) const &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const volatile &> : public member_function_wrapper<R(O:: *)(Args...) const volatile &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) &> : public member_function_wrapper<R(O:: *)(Args..., ...) &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) const &> : public member_function_wrapper<R(O:: *)(Args..., ...) const &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) const volatile &> : public member_function_wrapper<R(O:: *)(Args..., ...) const volatile &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) && > : public member_function_wrapper<R(O:: *)(Args...) &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const &&> : public member_function_wrapper<R(O:: *)(Args...) const &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args...) const volatile &&> : public member_function_wrapper<R(O:: *)(Args...) const volatile &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) && > : public member_function_wrapper<R(O:: *)(Args..., ...) &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) const &&> : public member_function_wrapper<R(O:: *)(Args..., ...) const &, R, O, Args...> {
+
+ };
+
+ template <typename R, typename O, typename... Args>
+ struct wrapper<R(O:: *)(Args..., ...) const volatile &&> : public member_function_wrapper<R(O:: *)(Args..., ...) const volatile &, R, O, Args...> {
+
+ };
+
+} // sol
+
+#endif // SOL_WRAPPER_HPP
diff --git a/3rdparty/sol2/test_containers.cpp b/3rdparty/sol2/test_containers.cpp
new file mode 100644
index 00000000000..015fbd20db0
--- /dev/null
+++ b/3rdparty/sol2/test_containers.cpp
@@ -0,0 +1,310 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <sol.hpp>
+#include <catch.hpp>
+
+#include <iterator>
+#include <vector>
+#include <list>
+#include <map>
+#include <unordered_map>
+#include <set>
+#include <unordered_set>
+
+std::vector<int> test_table_return_one() {
+ return{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+}
+
+std::vector<std::pair<std::string, int>> test_table_return_two() {
+ return{ { "one", 1 },{ "two", 2 },{ "three", 3 } };
+}
+
+std::map<std::string, std::string> test_table_return_three() {
+ return{ { "name", "Rapptz" },{ "friend", "ThePhD" },{ "project", "sol" } };
+}
+
+TEST_CASE("containers/returns", "make sure that even references to vectors are being serialized as tables") {
+ sol::state lua;
+ std::vector<int> v{ 1, 2, 3 };
+ lua.set_function("f", [&]() -> std::vector<int>& {
+ return v;
+ });
+ lua.script("x = f()");
+ sol::object x = lua["x"];
+ sol::type xt = x.get_type();
+ REQUIRE(xt == sol::type::userdata);
+ sol::table t = x;
+ bool matching;
+ matching = t[1] == 1;
+ REQUIRE(matching);
+ matching = t[2] == 2;
+ REQUIRE(matching);
+ matching = t[3] == 3;
+ REQUIRE(matching);
+}
+
+TEST_CASE("containers/vector_roundtrip", "make sure vectors can be round-tripped") {
+ sol::state lua;
+ std::vector<int> v{ 1, 2, 3 };
+ lua.set_function("f", [&]() -> std::vector<int>& {
+ return v;
+ });
+ lua.script("x = f()");
+ std::vector<int> x = lua["x"];
+ bool areequal = x == v;
+ REQUIRE(areequal);
+}
+
+TEST_CASE("containers/list_roundtrip", "make sure lists can be round-tripped") {
+ sol::state lua;
+ std::list<int> v{ 1, 2, 3 };
+ lua.set_function("f", [&]() -> std::list<int>& {
+ return v;
+ });
+ lua.script("x = f()");
+ std::list <int> x = lua["x"];
+ bool areequal = x == v;
+ REQUIRE(areequal);
+}
+
+TEST_CASE("containers/map_roundtrip", "make sure maps can be round-tripped") {
+ sol::state lua;
+ std::map<std::string, int> v{ { "a", 1 },{ "b", 2 },{ "c", 3 } };
+ lua.set_function("f", [&]() -> std::map<std::string, int>& {
+ return v;
+ });
+ lua.script("x = f()");
+ std::map<std::string, int> x = lua["x"];
+ bool areequal = x == v;
+ REQUIRE(areequal);
+}
+
+TEST_CASE("containers/unordered_map_roundtrip", "make sure unordered_maps can be round-tripped") {
+ sol::state lua;
+ std::unordered_map<std::string, int> v{ { "a", 1 },{ "b", 2 },{ "c", 3 } };
+ lua.set_function("f", [&]() -> std::unordered_map<std::string, int>& {
+ return v;
+ });
+ lua.script("x = f()");
+ std::unordered_map<std::string, int> x = lua["x"];
+ bool areequal = x == v;
+ REQUIRE(areequal);
+}
+
+TEST_CASE("containers/unordered_set_roundtrip", "make sure unordered_sets can be round-tripped") {
+ sol::state lua;
+ std::unordered_set<int> v{ 1, 2, 3 };
+ lua.set_function("f", [&]() -> std::unordered_set<int>& {
+ return v;
+ });
+ lua.script("x = f()");
+ std::unordered_set<int> x = lua["x"];
+ bool areequal = x == v;
+ REQUIRE(areequal);
+}
+
+TEST_CASE("containers/set_roundtrip", "make sure sets can be round-tripped") {
+ sol::state lua;
+ std::set<int> v{ 1, 2, 3 };
+ lua.set_function("f", [&]() -> std::set<int>& {
+ return v;
+ });
+ lua.script("x = f()");
+ std::set<int> x = lua["x"];
+ bool areequal = x == v;
+ REQUIRE(areequal);
+}
+
+TEST_CASE("containers/custom-usertype", "make sure container usertype metatables can be overridden") {
+ typedef std::unordered_map<int, int> bark;
+
+ sol::state lua;
+ lua.open_libraries();
+ lua.new_usertype<bark>("bark",
+ "something", [](const bark& b) {
+ INFO("It works: " << b.at(24));
+ },
+ "size", &bark::size,
+ "at", sol::resolve<const int&>(&bark::at),
+ "clear", &bark::clear
+ );
+ bark obj{ { 24, 50 } };
+ lua.set("a", &obj);
+ REQUIRE_NOTHROW(lua.script("assert(a:at(24) == 50)"));
+ REQUIRE_NOTHROW(lua.script("a:something()"));
+ lua.set("a", obj);
+ REQUIRE_NOTHROW(lua.script("assert(a:at(24) == 50)"));
+ REQUIRE_NOTHROW(lua.script("a:something()"));
+}
+
+TEST_CASE("containers/const-serialization-kvp", "make sure const keys / values are respected") {
+ typedef std::map<int, const int> bark;
+
+ sol::state lua;
+ lua.open_libraries();
+ bark obj{ { 24, 50 } };
+ lua.set("a", &obj);
+ REQUIRE_NOTHROW(lua.script("assert(a[24] == 50)"));
+ REQUIRE_THROWS(lua.script("a[24] = 51"));
+ REQUIRE_NOTHROW(lua.script("assert(a[24] == 50)"));
+}
+
+TEST_CASE("containers/basic-serialization", "make sure containers are turned into proper userdata and have basic hooks established") {
+ typedef std::vector<int> woof;
+ sol::state lua;
+ lua.open_libraries();
+ lua.set("b", woof{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 });
+ REQUIRE_NOTHROW(
+ lua.script("for k = 1, #b do assert(k == b[k]) end");
+ );
+ woof w{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
+ lua.set("b", w);
+ REQUIRE_NOTHROW(
+ lua.script("for k = 1, #b do assert(k == b[k]) end");
+ );
+ lua.set("b", &w);
+ REQUIRE_NOTHROW(
+ lua.script("for k = 1, #b do assert(k == b[k]) end");
+ );
+ lua.set("b", std::ref(w));
+ REQUIRE_NOTHROW(
+ lua.script("for k = 1, #b do assert(k == b[k]) end");
+ );
+}
+
+#if 0 // glibc is a fuccboi
+TEST_CASE("containers/const-serialization", "make sure containers are turned into proper userdata and the basic hooks respect const-ness") {
+ typedef std::vector<const int> woof;
+ sol::state lua;
+ lua.open_libraries();
+ lua.set("b", woof{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 });
+ REQUIRE_NOTHROW(
+ lua.script("for k, v in pairs(b) do assert(k == v) end");
+ );
+ REQUIRE_THROWS(lua.script("b[1] = 20"));
+}
+#endif // Fuck you, glibc
+
+TEST_CASE("containers/table-serialization", "ensure types can be serialized as tables still") {
+ typedef std::vector<int> woof;
+ sol::state lua;
+ lua.open_libraries();
+ lua.set("b", sol::as_table(woof{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }));
+ REQUIRE_NOTHROW(
+ lua.script("for k, v in ipairs(b) do assert(k == v) end");
+ );
+ woof w{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
+ lua.set("b", sol::as_table(w));
+ REQUIRE_NOTHROW(
+ lua.script("for k, v in ipairs(b) do assert(k == v) end");
+ );
+ lua.set("b", sol::as_table(&w));
+ REQUIRE_NOTHROW(
+ lua.script("for k, v in ipairs(b) do assert(k == v) end");
+ );
+ lua.set("b", sol::as_table(std::ref(w)));
+ REQUIRE_NOTHROW(
+ lua.script("for k, v in ipairs(b) do assert(k == v) end");
+ );
+}
+
+TEST_CASE("containers/const-correctness", "usertype metatable names should reasonably ignore const attributes") {
+ struct Vec {
+ int x, y, z;
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.new_usertype<Vec>("Vec", "x", &Vec::x, "y", &Vec::y, "z", &Vec::z);
+
+ Vec vec;
+ vec.x = 1;
+ vec.y = 2;
+ vec.z = -3;
+
+ std::vector<Vec> foo;
+ foo.push_back(vec);
+
+ std::vector<Vec const *> bar;
+ bar.push_back(&vec);
+
+ lua.script(R"(
+func = function(vecs)
+ for i = 1, #vecs do
+ vec = vecs[i]
+ print(i, ":", vec.x, vec.y, vec.z)
+ end
+end
+)");
+
+ REQUIRE_NOTHROW({
+ lua["func"](foo);
+ lua["func"](bar);
+ });
+}
+
+TEST_CASE("containers/arbitrary-creation", "userdata and tables should be usable from standard containers") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.set_function("test_one", test_table_return_one);
+ lua.set_function("test_two", test_table_return_two);
+ lua.set_function("test_three", test_table_return_three);
+
+ REQUIRE_NOTHROW(lua.script("a = test_one()"));
+ REQUIRE_NOTHROW(lua.script("b = test_two()"));
+ REQUIRE_NOTHROW(lua.script("c = test_three()"));
+
+ REQUIRE_NOTHROW(lua.script("assert(#a == 10, 'error')"));
+ REQUIRE_NOTHROW(lua.script("assert(a[3] == 3, 'error')"));
+ REQUIRE_NOTHROW(lua.script("assert(b.one == 1, 'error')"));
+ REQUIRE_NOTHROW(lua.script("assert(b.three == 3, 'error')"));
+ REQUIRE_NOTHROW(lua.script("assert(c.name == 'Rapptz', 'error')"));
+ REQUIRE_NOTHROW(lua.script("assert(c.project == 'sol', 'error')"));
+
+ sol::table a = lua.get<sol::table>("a");
+ sol::table b = lua.get<sol::table>("b");
+ sol::table c = lua.get<sol::table>("c");
+
+ REQUIRE(a.size() == 10ULL);
+ REQUIRE(a.get<int>(3) == 3);
+ REQUIRE(b.get<int>("one") == 1);
+ REQUIRE(b.get<int>("three") == 3);
+ REQUIRE(c.get<std::string>("name") == "Rapptz");
+ REQUIRE(c.get<std::string>("project") == "sol");
+}
+
+TEST_CASE("containers/usertype-transparency", "Make sure containers pass their arguments through transparently and push the results as references, not new values") {
+ class A {
+ public:
+ int a;
+ A(int b = 2) : a(b) {};
+
+ void func() { }
+ };
+
+ struct B {
+
+ B() {
+ for (std::size_t i = 0; i < 20; ++i) {
+ a_list.emplace_back(static_cast<int>(i));
+ }
+ }
+
+ std::vector<A> a_list;
+ };
+
+ sol::state lua;
+ lua.new_usertype<B>("B",
+ "a_list", &B::a_list
+ );
+
+ lua.script(R"(
+b = B.new()
+a_ref = b.a_list[2]
+)");
+
+ B& b = lua["b"];
+ A& a_ref = lua["a_ref"];
+ REQUIRE(&b.a_list[1] == &a_ref);
+ REQUIRE(b.a_list[1].a == a_ref.a);
+}
diff --git a/3rdparty/sol2/test_coroutines.cpp b/3rdparty/sol2/test_coroutines.cpp
new file mode 100644
index 00000000000..1581dc3d5a8
--- /dev/null
+++ b/3rdparty/sol2/test_coroutines.cpp
@@ -0,0 +1,64 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <catch.hpp>
+#include <sol.hpp>
+
+TEST_CASE("threading/coroutines", "ensure calling a coroutine works") {
+ const auto& script = R"(counter = 20
+
+function loop()
+ while counter ~= 30
+ do
+ coroutine.yield(counter);
+ counter = counter + 1;
+ end
+ return counter
+end
+)";
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::coroutine);
+ lua.script(script);
+ sol::coroutine cr = lua["loop"];
+
+ int counter;
+ for (counter = 20; counter < 31 && cr; ++counter) {
+ int value = cr();
+ if (counter != value) {
+ throw std::logic_error("fuck");
+ }
+ }
+ counter -= 1;
+ REQUIRE(counter == 30);
+}
+
+TEST_CASE("threading/new-thread-coroutines", "ensure calling a coroutine works when the work is put on a different thread") {
+ const auto& script = R"(counter = 20
+
+function loop()
+ while counter ~= 30
+ do
+ coroutine.yield(counter);
+ counter = counter + 1;
+ end
+ return counter
+end
+)";
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::coroutine);
+ lua.script(script);
+ sol::thread runner = sol::thread::create(lua.lua_state());
+ sol::state_view runnerstate = runner.state();
+ sol::coroutine cr = runnerstate["loop"];
+
+ int counter;
+ for (counter = 20; counter < 31 && cr; ++counter) {
+ int value = cr();
+ if (counter != value) {
+ throw std::logic_error("fuck");
+ }
+ }
+ counter -= 1;
+ REQUIRE(counter == 30);
+} \ No newline at end of file
diff --git a/3rdparty/sol2/test_customizations.cpp b/3rdparty/sol2/test_customizations.cpp
new file mode 100644
index 00000000000..dc15a92027c
--- /dev/null
+++ b/3rdparty/sol2/test_customizations.cpp
@@ -0,0 +1,86 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <catch.hpp>
+#include <sol.hpp>
+
+#include <unordered_map>
+#include <vector>
+
+struct two_things {
+ int a;
+ bool b;
+};
+
+namespace sol {
+
+ // First, the expected size
+ // Specialization of a struct
+ template <>
+ struct lua_size<two_things> : std::integral_constant<int, 2> {};
+
+ // Now, specialize various stack structures
+ namespace stack {
+
+ template <>
+ struct checker<two_things> {
+ template <typename Handler>
+ static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
+ // Check first and second second index for being the proper types
+ bool success = stack::check<int>(L, index, handler)
+ && stack::check<bool>(L, index + 1, handler);
+ tracking.use(2);
+ return success;
+ }
+ };
+
+ template <>
+ struct getter<two_things> {
+ static two_things get(lua_State* L, int index, record& tracking) {
+ // Get the first element
+ int a = stack::get<int>(L, index);
+ // Get the second element,
+ // in the +1 position from the first
+ bool b = stack::get<bool>(L, index + 1);
+ // we use 2 slots, each of the previous takes 1
+ tracking.use(2);
+ return two_things{ a, b };
+ }
+ };
+
+ template <>
+ struct pusher<two_things> {
+ static int push(lua_State* L, const two_things& things) {
+ int amount = stack::push(L, things.a);
+ amount += stack::push(L, things.b);
+ // Return 2 things
+ return amount;
+ }
+ };
+
+ }
+}
+
+TEST_CASE("customization/split-struct", "using the newly documented customization points to handle different kinds of classes") {
+ sol::state lua;
+
+ // Create a pass-through style of function
+ lua.script("function f ( a, b, c ) return a + c, b end");
+ lua.set_function("g", [](int a, bool b, int c, double d) {
+ return std::make_tuple(a + c, b, d + 2.5);
+ });
+
+ // get the function out of Lua
+ sol::function f = lua["f"];
+ sol::function g = lua["g"];
+
+ two_things thingsf = f(two_things{ 24, true }, 1);
+ two_things thingsg;
+ double d;
+ sol::tie( thingsg, d ) = g(two_things{ 25, false }, 2, 34.0);
+ REQUIRE(thingsf.a == 25);
+ REQUIRE(thingsf.b);
+
+ REQUIRE(thingsg.a == 27);
+ REQUIRE_FALSE(thingsg.b);
+ REQUIRE(d == 36.5);
+}
diff --git a/3rdparty/sol2/test_functions.cpp b/3rdparty/sol2/test_functions.cpp
new file mode 100644
index 00000000000..60a3c7020ef
--- /dev/null
+++ b/3rdparty/sol2/test_functions.cpp
@@ -0,0 +1,949 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <catch.hpp>
+#include <sol.hpp>
+#include <iostream>
+#include "test_stack_guard.hpp"
+
+std::function<int()> makefn() {
+ auto fx = []() -> int {
+ return 0x1456789;
+ };
+ return fx;
+}
+
+void takefn(std::function<int()> purr) {
+ if (purr() != 0x1456789)
+ throw 0;
+}
+
+struct A {
+ int a = 0xA; int bark() { return 1; }
+};
+
+std::tuple<int, int> bark(int num_value, A* a) {
+ return std::tuple<int, int>(num_value * 2, a->bark());
+}
+
+void test_free_func(std::function<void()> f) {
+ f();
+}
+
+void test_free_func2(std::function<int(int)> f, int arg1) {
+ int val = f(arg1);
+ if (val != arg1)
+ throw sol::error("failed function call!");
+}
+
+int overloaded(int x) {
+ INFO(x);
+ return 3;
+}
+
+int overloaded(int x, int y) {
+ INFO(x << " " << y);
+ return 7;
+}
+
+int overloaded(int x, int y, int z) {
+ INFO(x << " " << y << " " << z);
+ return 11;
+}
+
+int non_overloaded(int x, int y, int z) {
+ INFO(x << " " << y << " " << z);
+ return 13;
+}
+
+namespace sep {
+ int plop_xyz(int x, int y, std::string z) {
+ INFO(x << " " << y << " " << z);
+ return 11;
+ }
+}
+
+int func_1(int) {
+ return 1;
+}
+
+std::string func_1s(std::string a) {
+ return "string: " + a;
+}
+
+int func_2(int, int) {
+ return 2;
+}
+
+void func_3(int, int, int) {
+
+}
+
+int f1(int) { return 32; }
+int f2(int, int) { return 1; }
+struct fer {
+ double f3(int, int) {
+ return 2.5;
+ }
+};
+
+TEST_CASE("functions/tuple-returns", "Make sure tuple returns are ordered properly") {
+ sol::state lua;
+ lua.script("function f() return '3', 4 end");
+
+ std::tuple<std::string, int> result = lua["f"]();
+ auto s = std::get<0>(result);
+ auto v = std::get<1>(result);
+ REQUIRE(s == "3");
+ REQUIRE(v == 4);
+}
+
+TEST_CASE("functions/overload-resolution", "Check if overloaded function resolution templates compile/work") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.set_function("non_overloaded", non_overloaded);
+ REQUIRE_NOTHROW(lua.script("x = non_overloaded(1, 2, 3)\nprint(x)"));
+
+ /*
+ // Cannot reasonably support: clang++ refuses to try enough
+ // deductions to make this work
+ lua.set_function<int>("overloaded", overloaded);
+ REQUIRE_NOTHROW(lua.script("print(overloaded(1))"));
+
+ lua.set_function<int, int>("overloaded", overloaded);
+ REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2))"));
+
+ lua.set_function<int, int, int>("overloaded", overloaded);
+ REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2, 3))"));
+ */
+ lua.set_function("overloaded", sol::resolve<int(int)>(overloaded));
+ REQUIRE_NOTHROW(lua.script("print(overloaded(1))"));
+
+ lua.set_function("overloaded", sol::resolve<int(int, int)>(overloaded));
+ REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2))"));
+
+ lua.set_function("overloaded", sol::resolve<int(int, int, int)>(overloaded));
+ REQUIRE_NOTHROW(lua.script("print(overloaded(1, 2, 3))"));
+}
+
+TEST_CASE("functions/return-order-and-multi-get", "Check if return order is in the same reading order specified in Lua") {
+ const static std::tuple<int, int, int> triple = std::make_tuple(10, 11, 12);
+ const static std::tuple<int, float> paired = std::make_tuple(10, 10.f);
+ sol::state lua;
+ lua.set_function("f", [] {
+ return std::make_tuple(10, 11, 12);
+ });
+ int a = 0;
+ lua.set_function("h", []() {
+ return std::make_tuple(10, 10.0f);
+ });
+ lua.script("function g() return 10, 11, 12 end\nx,y,z = g()");
+ auto tcpp = lua.get<sol::function>("f").call<int, int, int>();
+ auto tlua = lua.get<sol::function>("g").call<int, int, int>();
+ auto tcpp2 = lua.get<sol::function>("h").call<int, float>();
+ auto tluaget = lua.get<int, int, int>("x", "y", "z");
+ REQUIRE(tcpp == triple);
+ REQUIRE(tlua == triple);
+ REQUIRE(tluaget == triple);
+ REQUIRE(tcpp2 == paired);
+}
+
+TEST_CASE("functions/deducing-return-order-and-multi-get", "Check if return order is in the same reading order specified in Lua, with regular deducing calls") {
+ const static std::tuple<int, int, int> triple = std::make_tuple(10, 11, 12);
+ sol::state lua;
+ lua.set_function("f_string", []() { return "this is a string!"; });
+ sol::function f_string = lua["f_string"];
+
+ // Make sure there are no overload collisions / compiler errors for automatic string conversions
+ std::string f_string_result = f_string();
+ REQUIRE(f_string_result == "this is a string!");
+ f_string_result = f_string();
+ REQUIRE(f_string_result == "this is a string!");
+
+ lua.set_function("f", [] {
+ return std::make_tuple(10, 11, 12);
+ });
+ lua.script("function g() return 10, 11, 12 end\nx,y,z = g()");
+ std::tuple<int, int, int> tcpp = lua.get<sol::function>("f")();
+ std::tuple<int, int, int> tlua = lua.get<sol::function>("g")();
+ std::tuple<int, int, int> tluaget = lua.get<int, int, int>("x", "y", "z");
+ INFO("cpp: " << std::get<0>(tcpp) << ',' << std::get<1>(tcpp) << ',' << std::get<2>(tcpp));
+ INFO("lua: " << std::get<0>(tlua) << ',' << std::get<1>(tlua) << ',' << std::get<2>(tlua));
+ INFO("lua xyz: " << lua.get<int>("x") << ',' << lua.get<int>("y") << ',' << lua.get<int>("z"));
+ REQUIRE(tcpp == triple);
+ REQUIRE(tlua == triple);
+ REQUIRE(tluaget == triple);
+}
+
+TEST_CASE("functions/optional-values", "check if optionals can be passed in to be nil or otherwise") {
+ struct thing {
+ int v;
+ };
+ sol::state lua;
+ lua.script(R"( function f (a)
+ return a
+end )");
+
+ sol::function lua_bark = lua["f"];
+
+ sol::optional<int> testv = lua_bark(sol::optional<int>(29));
+ sol::optional<int> testn = lua_bark(sol::nullopt);
+ REQUIRE((bool)testv);
+ REQUIRE_FALSE((bool)testn);
+ REQUIRE(testv.value() == 29);
+ sol::optional<thing> v = lua_bark(sol::optional<thing>(thing{ 29 }));
+ REQUIRE_NOTHROW(sol::nil_t n = lua_bark(sol::nullopt));
+ REQUIRE(v->v == 29);
+}
+
+TEST_CASE("functions/pair-and-tuple-and-proxy-tests", "Check if sol::reference and sol::proxy can be passed to functions as arguments") {
+ sol::state lua;
+ lua.new_usertype<A>("A",
+ "bark", &A::bark);
+ lua.script(R"( function f (num_value, a)
+ return num_value * 2, a:bark()
+end
+function h (num_value, a, b)
+ return num_value * 2, a:bark(), b * 3
+end
+nested = { variables = { no = { problem = 10 } } } )");
+ lua.set_function("g", bark);
+
+ sol::function cpp_bark = lua["g"];
+ sol::function lua_bark = lua["f"];
+ sol::function lua_bark2 = lua["h"];
+
+ sol::reference lua_variable_x = lua["nested"]["variables"]["no"]["problem"];
+ A cpp_variable_y;
+
+ static const std::tuple<int, int> abdesired(20, 1);
+ static const std::pair<int, int> cddesired = { 20, 1 };
+ static const std::tuple<int, int, int> abcdesired(20, 1, 3);
+
+ std::tuple<int, int> ab = cpp_bark(lua_variable_x, cpp_variable_y);
+ std::pair<int, int> cd = lua_bark(lua["nested"]["variables"]["no"]["problem"], cpp_variable_y);
+
+ REQUIRE(ab == abdesired);
+ REQUIRE(cd == cddesired);
+
+ ab = cpp_bark(std::make_pair(lua_variable_x, cpp_variable_y));
+ cd = lua_bark(std::make_pair(lua["nested"]["variables"]["no"]["problem"], cpp_variable_y));
+
+ REQUIRE(ab == abdesired);
+ REQUIRE(cd == cddesired);
+
+ std::tuple<int, int, int> abc = lua_bark2(std::make_tuple(10, cpp_variable_y), sol::optional<int>(1));
+ REQUIRE(abc == abcdesired);
+}
+
+TEST_CASE("functions/sol::function-to-std::function", "check if conversion to std::function works properly and calls with correct arguments") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.set_function("testFunc", test_free_func);
+ lua.set_function("testFunc2", test_free_func2);
+ lua.script(
+ "testFunc(function() print(\"hello std::function\") end)"
+ );
+ REQUIRE_NOTHROW(lua.script(
+ "function m(a)\n"
+ " print(\"hello std::function with arg \", a)\n"
+ " return a\n"
+ "end\n"
+ "\n"
+ "testFunc2(m, 1)"
+ ));
+}
+
+TEST_CASE("functions/returning-functions-from-C++-and-gettin-in-lua", "check to see if returning a functor and getting a functor from lua is possible") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.set_function("makefn", makefn);
+ lua.set_function("takefn", takefn);
+ lua.script("afx = makefn()\n"
+ "print(afx())\n"
+ "takefn(afx)\n");
+}
+
+TEST_CASE("functions/function_result-protected_function_result", "Function result should be the beefy return type for sol::function that allows for error checking and error handlers") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::debug);
+ static const char unhandlederrormessage[] = "true error message";
+ static const char handlederrormessage[] = "doodle";
+ static const std::string handlederrormessage_s = handlederrormessage;
+
+ // Some function; just using a lambda to be cheap
+ auto doomfx = []() {
+ INFO("doomfx called");
+ throw std::runtime_error(unhandlederrormessage);
+ };
+ auto luadoomfx = [&lua]() {
+ INFO("luadoomfx called");
+ // Does not bypass error function, will call it
+ luaL_error(lua.lua_state(), unhandlederrormessage);
+ };
+ lua.set_function("doom", doomfx);
+ lua.set_function("luadoom", luadoomfx);
+
+ auto cpphandlerfx = [](std::string x) {
+ INFO("c++ handler called with: " << x);
+ return handlederrormessage;
+ };
+ lua.set_function("cpphandler", cpphandlerfx);
+ lua.script(
+ std::string("function luahandler ( message )")
+ + " print('lua handler called with: ' .. message)"
+ + " return '" + handlederrormessage + "'"
+ + "end"
+ );
+ auto nontrampolinefx = [](lua_State*) -> int { throw "x"; };
+ lua_CFunction c_nontrampolinefx = nontrampolinefx;
+ lua.set("nontrampoline", c_nontrampolinefx);
+ lua.set_function("bark", []() -> int {return 100; });
+
+ sol::function luahandler = lua["luahandler"];
+ sol::function cpphandler = lua["cpphandler"];
+ sol::protected_function doom(lua["doom"], luahandler);
+ sol::protected_function luadoom(lua["luadoom"]);
+ sol::protected_function nontrampoline = lua["nontrampoline"];
+ sol::protected_function justfine = lua["bark"];
+ sol::protected_function justfinewithhandler = lua["bark"];
+ luadoom.error_handler = cpphandler;
+ nontrampoline.error_handler = cpphandler;
+ justfinewithhandler.error_handler = luahandler;
+ bool present = true;
+ {
+ sol::protected_function_result result = doom();
+ REQUIRE_FALSE(result.valid());
+ sol::optional<sol::error> operr = result;
+ sol::optional<int> opvalue = result;
+ present = (bool)operr;
+ REQUIRE(present);
+ present = (bool)opvalue;
+ REQUIRE_FALSE(present);
+ sol::error err = result;
+ REQUIRE(err.what() == handlederrormessage_s);
+ }
+ {
+ sol::protected_function_result result = luadoom();
+ REQUIRE_FALSE(result.valid());
+ sol::optional<sol::error> operr = result;
+ sol::optional<int> opvalue = result;
+ present = (bool)operr;
+ REQUIRE(present);
+ present = (bool)opvalue;
+ REQUIRE_FALSE(present);
+ sol::error err = result;
+ REQUIRE(err.what() == handlederrormessage_s);
+ }
+ {
+ sol::protected_function_result result = nontrampoline();
+ REQUIRE_FALSE(result.valid());
+ sol::optional<sol::error> operr = result;
+ sol::optional<int> opvalue = result;
+ present = (bool)operr;
+ REQUIRE(present);
+ present = (bool)opvalue;
+ REQUIRE_FALSE(present);
+ sol::error err = result;
+ REQUIRE(err.what() == handlederrormessage_s);
+ }
+ {
+ sol::protected_function_result result = justfine();
+ REQUIRE(result.valid());
+ sol::optional<sol::error> operr = result;
+ sol::optional<int> opvalue = result;
+ present = (bool)operr;
+ REQUIRE_FALSE(present);
+ present = (bool)opvalue;
+ REQUIRE(present);
+ int value = result;
+ REQUIRE(value == 100);
+ }
+ {
+ sol::protected_function_result result = justfinewithhandler();
+ REQUIRE(result.valid());
+ sol::optional<sol::error> operr = result;
+ sol::optional<int> opvalue = result;
+ present = (bool)operr;
+ REQUIRE_FALSE(present);
+ present = (bool)opvalue;
+ REQUIRE(present);
+ int value = result;
+ REQUIRE(value == 100);
+ }
+}
+
+TEST_CASE("functions/destructor-tests", "Show that proper copies / destruction happens") {
+ static int created = 0;
+ static int destroyed = 0;
+ static void* last_call = nullptr;
+ static void* static_call = reinterpret_cast<void*>(0x01);
+ typedef void(*fptr)();
+ struct x {
+ x() { ++created; }
+ x(const x&) { ++created; }
+ x(x&&) { ++created; }
+ x& operator=(const x&) { return *this; }
+ x& operator=(x&&) { return *this; }
+ void func() { last_call = static_cast<void*>(this); };
+ ~x() { ++destroyed; }
+ };
+ struct y {
+ y() { ++created; }
+ y(const x&) { ++created; }
+ y(x&&) { ++created; }
+ y& operator=(const x&) { return *this; }
+ y& operator=(x&&) { return *this; }
+ static void func() { last_call = static_call; };
+ void operator()() { func(); }
+ operator fptr () { return func; }
+ ~y() { ++destroyed; }
+ };
+
+ // stateful functors/member functions should always copy unless specified
+ {
+ created = 0;
+ destroyed = 0;
+ last_call = nullptr;
+ {
+ sol::state lua;
+ x x1;
+ lua.set_function("x1copy", &x::func, x1);
+ lua.script("x1copy()");
+ REQUIRE(created == 2);
+ REQUIRE(destroyed == 0);
+ REQUIRE_FALSE(last_call == &x1);
+
+ lua.set_function("x1ref", &x::func, std::ref(x1));
+ lua.script("x1ref()");
+ REQUIRE(created == 2);
+ REQUIRE(destroyed == 0);
+ REQUIRE(last_call == &x1);
+ }
+ REQUIRE(created == 2);
+ REQUIRE(destroyed == 2);
+ }
+
+ // things convertible to a static function should _never_ be forced to make copies
+ // therefore, pass through untouched
+ {
+ created = 0;
+ destroyed = 0;
+ last_call = nullptr;
+ {
+ sol::state lua;
+ y y1;
+ lua.set_function("y1copy", y1);
+ lua.script("y1copy()");
+ REQUIRE(created == 1);
+ REQUIRE(destroyed == 0);
+ REQUIRE(last_call == static_call);
+
+ last_call = nullptr;
+ lua.set_function("y1ref", std::ref(y1));
+ lua.script("y1ref()");
+ REQUIRE(created == 1);
+ REQUIRE(destroyed == 0);
+ REQUIRE(last_call == static_call);
+ }
+ REQUIRE(created == 1);
+ REQUIRE(destroyed == 1);
+ }
+}
+
+
+TEST_CASE("functions/all-kinds", "Register all kinds of functions, make sure they all compile and work") {
+ sol::state lua;
+
+ struct test_1 {
+ int a = 0xA;
+ virtual int bark() {
+ return a;
+ }
+
+ int bark_mem() {
+ return a;
+ }
+
+ static std::tuple<int, int> x_bark(int num_value, test_1* a) {
+ return std::tuple<int, int>(num_value * 2, a->a);
+ }
+ };
+
+ struct test_2 {
+ int a = 0xC;
+ int bark() {
+ return 20;
+ }
+ };
+
+ struct inner {
+ const int z = 5653;
+ };
+
+ struct nested {
+ inner i;
+ };
+
+ auto a = []() { return 500; };
+ auto b = [&]() { return 501; };
+ auto c = [&]() { return 502; };
+ auto d = []() { return 503; };
+
+ lua.new_usertype<test_1>("test_1",
+ "bark", sol::c_call<decltype(&test_1::bark_mem), &test_1::bark_mem>
+ );
+ lua.new_usertype<test_2>("test_2",
+ "bark", sol::c_call<decltype(&test_2::bark), &test_2::bark>
+ );
+ test_2 t2;
+
+ lua.set_function("a", a);
+ lua.set_function("b", b);
+ lua.set_function("c", std::ref(c));
+ lua.set_function("d", std::ref(d));
+ lua.set_function("f", &test_1::bark);
+ lua.set_function("g", test_1::x_bark);
+ lua.set_function("h", sol::c_call<decltype(&test_1::bark_mem), &test_1::bark_mem>);
+ lua.set_function("i", &test_2::bark, test_2());
+ lua.set_function("j", &test_2::a, test_2());
+ lua.set_function("k", &test_2::a);
+ lua.set_function("l", sol::c_call<decltype(&test_1::a), &test_1::a>);
+ lua.set_function("m", &test_2::a, &t2);
+ lua.set_function("n", sol::c_call<decltype(&non_overloaded), &non_overloaded>);
+
+ lua.script(R"(
+o1 = test_1.new()
+o2 = test_2.new()
+)");
+
+ lua.script(R"(
+ob = o1:bark()
+
+A = a()
+B = b()
+C = c()
+D = d()
+F = f(o1)
+G0, G1 = g(2, o1)
+H = h(o1)
+I = i(o1)
+I = i(o1)
+)");
+
+
+ lua.script(R"(
+J0 = j()
+j(24)
+J1 = j()
+ )");
+
+ lua.script(R"(
+K0 = k(o2)
+k(o2, 1024)
+K1 = k(o2)
+ )");
+
+ lua.script(R"(
+L0 = l(o1)
+l(o1, 678)
+L1 = l(o1)
+ )");
+
+
+ lua.script(R"(
+M0 = m()
+m(256)
+M1 = m()
+ )");
+
+ lua.script(R"(
+N = n(1, 2, 3)
+ )");
+ int ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N;
+ std::tie(ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N)
+ = lua.get<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(
+ "ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N"
+ );
+
+ REQUIRE(ob == 0xA);
+
+ REQUIRE(A == 500);
+ REQUIRE(B == 501);
+ REQUIRE(C == 502);
+ REQUIRE(D == 503);
+
+ REQUIRE(F == 0xA);
+ REQUIRE(G0 == 4);
+ REQUIRE(G1 == 0xA);
+ REQUIRE(H == 0xA);
+ REQUIRE(I == 20);
+
+ REQUIRE(J0 == 0xC);
+ REQUIRE(J1 == 24);
+
+ REQUIRE(K0 == 0xC);
+ REQUIRE(K1 == 1024);
+
+ REQUIRE(L0 == 0xA);
+ REQUIRE(L1 == 678);
+
+ REQUIRE(M0 == 0xC);
+ REQUIRE(M1 == 256);
+
+ REQUIRE(N == 13);
+
+ sol::tie(ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N)
+ = lua.get<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(
+ "ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N"
+ );
+
+ REQUIRE(ob == 0xA);
+
+ REQUIRE(A == 500);
+ REQUIRE(B == 501);
+ REQUIRE(C == 502);
+ REQUIRE(D == 503);
+
+ REQUIRE(F == 0xA);
+ REQUIRE(G0 == 4);
+ REQUIRE(G1 == 0xA);
+ REQUIRE(H == 0xA);
+ REQUIRE(I == 20);
+
+ REQUIRE(J0 == 0xC);
+ REQUIRE(J1 == 24);
+
+ REQUIRE(K0 == 0xC);
+ REQUIRE(K1 == 1024);
+
+ REQUIRE(L0 == 0xA);
+ REQUIRE(L1 == 678);
+
+ REQUIRE(M0 == 0xC);
+ REQUIRE(M1 == 256);
+
+ REQUIRE(N == 13);
+
+ // Work that compiler, WORK IT!
+ lua.set("o", &test_1::bark);
+ lua.set("p", test_1::x_bark);
+ lua.set("q", sol::c_call<decltype(&test_1::bark_mem), &test_1::bark_mem>);
+ lua.set("r", &test_2::a);
+ lua.set("s", sol::readonly(&test_2::a));
+ lua.set_function("t", sol::readonly(&test_2::a), test_2());
+ lua.set_function("u", &nested::i, nested());
+ lua.set("v", &nested::i);
+ lua.set("nested", nested());
+ lua.set("inner", inner());
+ REQUIRE_THROWS(lua.script("s(o2, 2)"));
+ REQUIRE_THROWS(lua.script("t(2)"));
+ REQUIRE_THROWS(lua.script("u(inner)"));
+ REQUIRE_THROWS(lua.script("v(nested, inner)"));
+}
+
+TEST_CASE("simple/call-with-parameters", "Lua function is called with a few parameters from C++") {
+ sol::state lua;
+
+ REQUIRE_NOTHROW(lua.script("function my_add(i, j, k) return i + j + k end"));
+ auto f = lua.get<sol::function>("my_add");
+ REQUIRE_NOTHROW(lua.script("function my_nothing(i, j, k) end"));
+ auto fvoid = lua.get<sol::function>("my_nothing");
+ int a;
+ REQUIRE_NOTHROW(fvoid(1, 2, 3));
+ REQUIRE_NOTHROW(a = f.call<int>(1, 2, 3));
+ REQUIRE(a == 6);
+ REQUIRE_THROWS(a = f(1, 2, "arf"));
+}
+
+TEST_CASE("simple/call-c++-function", "C++ function is called from lua") {
+ sol::state lua;
+
+ lua.set_function("plop_xyz", sep::plop_xyz);
+ lua.script("x = plop_xyz(2, 6, 'hello')");
+
+ REQUIRE(lua.get<int>("x") == 11);
+}
+
+TEST_CASE("simple/call-lambda", "A C++ lambda is exposed to lua and called") {
+ sol::state lua;
+
+ int a = 0;
+
+ lua.set_function("foo", [&a] { a = 1; });
+
+ lua.script("foo()");
+
+ REQUIRE(a == 1);
+}
+
+TEST_CASE("advanced/get-and-call", "Checks for lambdas returning values after a get operation") {
+ const static std::string lol = "lol", str = "str";
+ const static std::tuple<int, float, double, std::string> heh_tuple = std::make_tuple(1, 6.28f, 3.14, std::string("heh"));
+ sol::state lua;
+
+ REQUIRE_NOTHROW(lua.set_function("a", [] { return 42; }));
+ REQUIRE(lua.get<sol::function>("a").call<int>() == 42);
+
+ REQUIRE_NOTHROW(lua.set_function("b", [] { return 42u; }));
+ REQUIRE(lua.get<sol::function>("b").call<unsigned int>() == 42u);
+
+ REQUIRE_NOTHROW(lua.set_function("c", [] { return 3.14; }));
+ REQUIRE(lua.get<sol::function>("c").call<double>() == 3.14);
+
+ REQUIRE_NOTHROW(lua.set_function("d", [] { return 6.28f; }));
+ REQUIRE(lua.get<sol::function>("d").call<float>() == 6.28f);
+
+ REQUIRE_NOTHROW(lua.set_function("e", [] { return "lol"; }));
+ REQUIRE(lua.get<sol::function>("e").call<std::string>() == lol);
+
+ REQUIRE_NOTHROW(lua.set_function("f", [] { return true; }));
+ REQUIRE(lua.get<sol::function>("f").call<bool>());
+
+ REQUIRE_NOTHROW(lua.set_function("g", [] { return std::string("str"); }));
+ REQUIRE(lua.get<sol::function>("g").call<std::string>() == str);
+
+ REQUIRE_NOTHROW(lua.set_function("h", [] {}));
+ REQUIRE_NOTHROW(lua.get<sol::function>("h").call());
+
+ REQUIRE_NOTHROW(lua.set_function("i", [] { return sol::nil; }));
+ REQUIRE(lua.get<sol::function>("i").call<sol::nil_t>() == sol::nil);
+ REQUIRE_NOTHROW(lua.set_function("j", [] { return std::make_tuple(1, 6.28f, 3.14, std::string("heh")); }));
+ REQUIRE((lua.get<sol::function>("j").call<int, float, double, std::string>() == heh_tuple));
+}
+
+TEST_CASE("advanced/operator[]-call", "Checks for lambdas returning values using operator[]") {
+ const static std::string lol = "lol", str = "str";
+ const static std::tuple<int, float, double, std::string> heh_tuple = std::make_tuple(1, 6.28f, 3.14, std::string("heh"));
+ sol::state lua;
+
+ REQUIRE_NOTHROW(lua.set_function("a", [] { return 42; }));
+ REQUIRE(lua["a"].call<int>() == 42);
+
+ REQUIRE_NOTHROW(lua.set_function("b", [] { return 42u; }));
+ REQUIRE(lua["b"].call<unsigned int>() == 42u);
+
+ REQUIRE_NOTHROW(lua.set_function("c", [] { return 3.14; }));
+ REQUIRE(lua["c"].call<double>() == 3.14);
+
+ REQUIRE_NOTHROW(lua.set_function("d", [] { return 6.28f; }));
+ REQUIRE(lua["d"].call<float>() == 6.28f);
+
+ REQUIRE_NOTHROW(lua.set_function("e", [] { return "lol"; }));
+ REQUIRE(lua["e"].call<std::string>() == lol);
+
+ REQUIRE_NOTHROW(lua.set_function("f", [] { return true; }));
+ REQUIRE(lua["f"].call<bool>());
+
+ REQUIRE_NOTHROW(lua.set_function("g", [] { return std::string("str"); }));
+ REQUIRE(lua["g"].call<std::string>() == str);
+
+ REQUIRE_NOTHROW(lua.set_function("h", [] {}));
+ REQUIRE_NOTHROW(lua["h"].call());
+
+ REQUIRE_NOTHROW(lua.set_function("i", [] { return sol::nil; }));
+ REQUIRE(lua["i"].call<sol::nil_t>() == sol::nil);
+ REQUIRE_NOTHROW(lua.set_function("j", [] { return std::make_tuple(1, 6.28f, 3.14, std::string("heh")); }));
+ REQUIRE((lua["j"].call<int, float, double, std::string>() == heh_tuple));
+}
+
+TEST_CASE("advanced/call-lambdas", "A C++ lambda is exposed to lua and called") {
+ sol::state lua;
+
+ int x = 0;
+ lua.set_function("set_x", [&](int new_x) {
+ x = new_x;
+ return 0;
+ });
+
+ lua.script("set_x(9)");
+ REQUIRE(x == 9);
+}
+
+TEST_CASE("advanced/call-referenced_obj", "A C++ object is passed by pointer/reference_wrapper to lua and invoked") {
+ sol::state lua;
+
+ int x = 0;
+ auto objx = [&](int new_x) {
+ x = new_x;
+ return 0;
+ };
+ lua.set_function("set_x", std::ref(objx));
+
+ int y = 0;
+ auto objy = [&](int new_y) {
+ y = new_y;
+ return std::tuple<int, int>(0, 0);
+ };
+ lua.set_function("set_y", &decltype(objy)::operator(), std::ref(objy));
+
+ lua.script("set_x(9)");
+ lua.script("set_y(9)");
+ REQUIRE(x == 9);
+ REQUIRE(y == 9);
+}
+
+TEST_CASE("functions/tie", "make sure advanced syntax with 'tie' works") {
+ sol::state lua;
+
+ lua.script(R"(function f ()
+ return 1, 2, 3
+end)");
+ sol::function f = lua["f"];
+
+ int a, b, c;
+ sol::tie(a, b, c) = f();
+ REQUIRE(a == 1);
+ REQUIRE(b == 2);
+ REQUIRE(c == 3);
+}
+
+TEST_CASE("functions/variadic_args", "Check to see we can receive multiple arguments through a variadic") {
+ struct structure {
+ int x;
+ bool b;
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.set_function("v", [](sol::this_state, sol::variadic_args va) -> structure {
+ int r = 0;
+ for (auto v : va) {
+ int value = v;
+ r += value;
+ }
+ return{ r, r > 200 };
+ });
+
+ lua.script("x = v(25, 25)");
+ lua.script("x2 = v(25, 25, 100, 50, 250, 150)");
+ lua.script("x3 = v(1, 2, 3, 4, 5, 6)");
+
+ structure& lx = lua["x"];
+ structure& lx2 = lua["x2"];
+ structure& lx3 = lua["x3"];
+ REQUIRE(lx.x == 50);
+ REQUIRE(lx2.x == 600);
+ REQUIRE(lx3.x == 21);
+ REQUIRE_FALSE(lx.b);
+ REQUIRE(lx2.b);
+ REQUIRE_FALSE(lx3.b);
+}
+
+TEST_CASE("functions/required_and_variadic_args", "Check if a certain number of arguments can still be required even when using variadic_args") {
+ sol::state lua;
+ lua.set_function("v",
+ [](sol::this_state, sol::variadic_args, int, int) {
+ }
+ );
+ REQUIRE_NOTHROW(lua.script("v(20, 25, 30)"));
+ REQUIRE_NOTHROW(lua.script("v(20, 25)"));
+#ifndef SOL_LUAJIT
+ REQUIRE_THROWS(lua.script("v(20)"));
+#endif // LuaJIT has problems with exceptions, as fucking usual
+}
+
+TEST_CASE("functions/overloading", "Check if overloading works properly for regular set function syntax") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.set_function("func_1", func_1);
+ lua.set_function("func", sol::overload(func_2, func_3, func_1, func_1s));
+
+ const std::string string_bark = "string: bark";
+
+ REQUIRE_NOTHROW(lua.script(
+ "a = func(1)\n"
+ "b = func('bark')\n"
+ "c = func(1,2)\n"
+ "func(1,2,3)\n"
+ ));
+
+ REQUIRE((lua["a"] == 1));
+ REQUIRE((lua["b"] == string_bark));
+ REQUIRE((lua["c"] == 2));
+
+ REQUIRE_THROWS(lua.script("func(1,2,'meow')"));
+}
+
+TEST_CASE("overloading/c_call", "Make sure that overloading works with c_call functionality") {
+ sol::state lua;
+ lua.set("f", sol::c_call<sol::wrap<decltype(&f1), &f1>, sol::wrap<decltype(&f2), &f2>, sol::wrap<decltype(&fer::f3), &fer::f3>>);
+ lua.set("g", sol::c_call<sol::wrap<decltype(&f1), &f1>>);
+ lua.set("h", sol::c_call<decltype(&f2), &f2>);
+ lua.set("obj", fer());
+
+ lua.script("r1 = f(1)");
+ lua.script("r2 = f(1, 2)");
+ lua.script("r3 = f(obj, 1, 2)");
+ lua.script("r4 = g(1)");
+ lua.script("r5 = h(1, 2)");
+
+ int r1 = lua["r1"];
+ int r2 = lua["r2"];
+ double r3 = lua["r3"];
+ int r4 = lua["r4"];
+ int r5 = lua["r5"];
+
+ REQUIRE(r1 == 32);
+ REQUIRE(r2 == 1);
+ REQUIRE(r3 == 2.5);
+ REQUIRE(r4 == 32);
+ REQUIRE(r5 == 1);
+}
+
+TEST_CASE("functions/stack-protect", "make sure functions don't impede on the stack") {
+ //setup sol/lua
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::string);
+
+ lua.script("function ErrorHandler(msg) print('Lua created error msg : ' .. msg) return msg end");
+ lua.script("function stringtest(a) if a == nil then error('fuck') end print('Lua recieved content : ' .. a) return a end");
+
+ // test normal function
+ {
+ sol::stack_guard normalsg(lua);
+ std::string str = lua["stringtest"]("normal test");
+ INFO("Back in C++, direct call result is : " << str);
+ }
+
+ //test protected_function
+ sol::protected_function Stringtest(lua["stringtest"]);
+ Stringtest.error_handler = lua["ErrorHandler"];
+ sol::stack_guard sg(lua);
+ {
+ sol::protected_function_result stringresult = Stringtest("protected test");
+ REQUIRE(stringresult.valid());
+ std::string s = stringresult;
+ INFO("Back in C++, protected result is : " << s);
+ }
+ REQUIRE(sg.check_stack());
+
+ //test optional
+ {
+ sol::stack_guard opsg(lua);
+ sol::optional<std::string> opt_result = Stringtest("optional test");
+ REQUIRE(opsg.check_stack());
+ if (opt_result)
+ {
+ std::string s = opt_result.value();
+ INFO("Back in C++, opt_result is : " << s);
+ }
+ else
+ {
+ INFO("opt_result failed");
+ }
+ }
+ REQUIRE(sg.check_stack());
+
+ {
+ sol::protected_function_result errresult = Stringtest(sol::nil);
+ REQUIRE_FALSE(errresult.valid());
+ sol::error err = errresult;
+ std::string msg = err.what();
+ INFO("error :" << msg);
+ }
+ REQUIRE(sg.check_stack());
+}
diff --git a/3rdparty/sol2/test_inheritance.cpp b/3rdparty/sol2/test_inheritance.cpp
new file mode 100644
index 00000000000..5afb363b8e7
--- /dev/null
+++ b/3rdparty/sol2/test_inheritance.cpp
@@ -0,0 +1,247 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <sol.hpp>
+#include <catch.hpp>
+
+#include <iostream>
+
+TEST_CASE("inheritance/basic", "test that metatables are properly inherited") {
+ struct A {
+ int a = 5;
+ };
+
+ struct B {
+ int b() {
+ return 10;
+ }
+ };
+
+ struct C : B, A {
+ double c = 2.4;
+ };
+
+ struct D : C {
+ bool d() const {
+ return true;
+ }
+ };
+
+ sol::state lua;
+ lua.new_usertype<A>("A",
+ "a", &A::a
+ );
+ lua.new_usertype<B>("B",
+ "b", &B::b
+ );
+ lua.new_usertype<C>("C",
+ "c", &C::c,
+ sol::base_classes, sol::bases<B, A>()
+ );
+ lua.new_usertype<D>("D",
+ "d", &D::d,
+ sol::base_classes, sol::bases<C, B, A>()
+ );
+
+ lua.script("obj = D.new()");
+ lua.script("d = obj:d()");
+ bool d = lua["d"];
+ lua.script("c = obj.c");
+ double c = lua["c"];
+ lua.script("b = obj:b()");
+ int b = lua["b"];
+ lua.script("a = obj.a");
+ int a = lua["a"];
+
+ REQUIRE(d);
+ REQUIRE(c == 2.4);
+ REQUIRE(b == 10);
+ REQUIRE(a == 5);
+}
+
+TEST_CASE("inheritance/multi-base", "test that multiple bases all work and overloading for constructors works with them") {
+ class TestClass00 {
+ public:
+ int Thing() const { return 123; }
+ };
+
+ class TestClass01 : public TestClass00 {
+ public:
+ TestClass01() : a(1) {}
+ TestClass01(const TestClass00& other) : a(other.Thing()) {}
+
+ int a;
+ };
+
+ class TestClass02 : public TestClass01 {
+ public:
+ TestClass02() : b(2) {}
+ TestClass02(const TestClass01& other) : b(other.a) {}
+ TestClass02(const TestClass00& other) : b(other.Thing()) {}
+
+ int b;
+ };
+
+ class TestClass03 : public TestClass02 {
+ public:
+ TestClass03() : c(2) {}
+ TestClass03(const TestClass02& other) : c(other.b) {}
+ TestClass03(const TestClass01& other) : c(other.a) {}
+ TestClass03(const TestClass00& other) : c(other.Thing()) {}
+
+ int c;
+ };
+
+ sol::state lua;
+
+ sol::usertype<TestClass00> s_TestUsertype00(
+ sol::call_constructor, sol::constructors<sol::types<>>(),
+ "Thing", &TestClass00::Thing
+ );
+
+ lua.set_usertype("TestClass00", s_TestUsertype00);
+
+ sol::usertype<TestClass01> s_TestUsertype01(
+ sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass00&>>(),
+ sol::base_classes, sol::bases<TestClass00>(),
+ "a", &TestClass01::a
+ );
+
+ lua.set_usertype("TestClass01", s_TestUsertype01);
+
+ sol::usertype<TestClass02> s_TestUsertype02(
+ sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass01&>, sol::types<const TestClass00&>>(),
+ sol::base_classes, sol::bases<TestClass01, TestClass00>(),
+ "b", &TestClass02::b
+ );
+
+ lua.set_usertype("TestClass02", s_TestUsertype02);
+
+ sol::usertype<TestClass03> s_TestUsertype03(
+ sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass02&>, sol::types<const TestClass01&>, sol::types<const TestClass00&>>(),
+ sol::base_classes, sol::bases<TestClass02, TestClass01, TestClass00>(),
+ "c", &TestClass03::c
+ );
+
+ lua.set_usertype("TestClass03", s_TestUsertype03);
+
+ lua.script(R"(
+tc0 = TestClass00()
+)");
+
+ lua.script(R"(
+tc2 = TestClass02(tc0)
+)");
+
+ lua.script(R"(
+tc1 = TestClass01()
+)");
+
+ lua.script(R"(
+tc3 = TestClass03(tc1)
+)");
+
+ TestClass00& tc0 = lua["tc0"];
+ TestClass01& tc1 = lua["tc1"];
+ TestClass02& tc2 = lua["tc2"];
+ TestClass03& tc3 = lua["tc3"];
+ REQUIRE(tc1.a == 1);
+ REQUIRE(tc2.a == 1);
+ REQUIRE(tc2.b == 123);
+ REQUIRE(tc3.a == 1);
+ REQUIRE(tc3.b == 2);
+ REQUIRE(tc3.c == 1);
+}
+
+TEST_CASE("inheritance/simple-multi-base", "test that multiple bases all work and overloading for constructors works with them") {
+ class TestClass00 {
+ public:
+ int Thing() const { return 123; }
+ };
+
+ class TestClass01 : public TestClass00 {
+ public:
+ TestClass01() : a(1) {}
+ TestClass01(const TestClass00& other) : a(other.Thing()) {}
+
+ int a;
+ };
+
+ class TestClass02 : public TestClass01 {
+ public:
+ TestClass02() : b(2) {}
+ TestClass02(const TestClass01& other) : b(other.a) {}
+ TestClass02(const TestClass00& other) : b(other.Thing()) {}
+
+ int b;
+ };
+
+ class TestClass03 : public TestClass02 {
+ public:
+ TestClass03() : c(2) {}
+ TestClass03(const TestClass02& other) : c(other.b) {}
+ TestClass03(const TestClass01& other) : c(other.a) {}
+ TestClass03(const TestClass00& other) : c(other.Thing()) {}
+
+ int c;
+ };
+
+ sol::state lua;
+
+ sol::simple_usertype<TestClass00> s_TestUsertype00( lua,
+ sol::call_constructor, sol::constructors<sol::types<>>(),
+ "Thing", &TestClass00::Thing
+ );
+
+ lua.set_usertype("TestClass00", s_TestUsertype00);
+
+ sol::simple_usertype<TestClass01> s_TestUsertype01( lua,
+ sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass00&>>(),
+ sol::base_classes, sol::bases<TestClass00>(),
+ "a", &TestClass01::a
+ );
+
+ lua.set_usertype("TestClass01", s_TestUsertype01);
+
+ sol::simple_usertype<TestClass02> s_TestUsertype02( lua,
+ sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass01&>, sol::types<const TestClass00&>>(),
+ sol::base_classes, sol::bases<TestClass01, TestClass00>(),
+ "b", &TestClass02::b
+ );
+
+ lua.set_usertype("TestClass02", s_TestUsertype02);
+
+ sol::simple_usertype<TestClass03> s_TestUsertype03( lua,
+ sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass02&>, sol::types<const TestClass01&>, sol::types<const TestClass00&>>(),
+ sol::base_classes, sol::bases<TestClass02, TestClass01, TestClass00>(),
+ "c", &TestClass03::c
+ );
+
+ lua.set_usertype("TestClass03", s_TestUsertype03);
+
+ lua.script(R"(
+tc0 = TestClass00()
+)");
+
+ lua.script(R"(
+tc2 = TestClass02(tc0)
+)");
+
+ lua.script(R"(
+tc1 = TestClass01()
+)");
+
+ lua.script(R"(
+tc3 = TestClass03(tc1)
+)");
+
+ TestClass00& tc0 = lua["tc0"];
+ TestClass01& tc1 = lua["tc1"];
+ TestClass02& tc2 = lua["tc2"];
+ TestClass03& tc3 = lua["tc3"];
+ REQUIRE(tc1.a == 1);
+ REQUIRE(tc2.a == 1);
+ REQUIRE(tc2.b == 123);
+ REQUIRE(tc3.a == 1);
+ REQUIRE(tc3.b == 2);
+ REQUIRE(tc3.c == 1);
+}
diff --git a/3rdparty/sol2/test_operators.cpp b/3rdparty/sol2/test_operators.cpp
new file mode 100644
index 00000000000..b8e48e783ee
--- /dev/null
+++ b/3rdparty/sol2/test_operators.cpp
@@ -0,0 +1,83 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <sol.hpp>
+#include <catch.hpp>
+
+TEST_CASE("operators/default", "test that generic equality operators and all sorts of equality tests can be used") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ struct T {};
+ struct U {
+ int a;
+ U(int x = 20) : a(x) {}
+ bool operator==(const U& r) {
+ return a == r.a;
+ }
+ };
+ struct V {
+ int a;
+ V(int x = 20) : a(x) {}
+ bool operator==(const V& r) const {
+ return a == r.a;
+ }
+ };
+ lua.new_usertype<T>("T");
+ lua.new_usertype<U>("U");
+ lua.new_usertype<V>("V");
+
+ T t1;
+ T& t2 = t1;
+ T t3;
+ U u1;
+ U u2{ 30 };
+ U u3;
+ U v1;
+ U v2{ 30 };
+ U v3;
+ lua["t1"] = &t1;
+ lua["t2"] = &t2;
+ lua["t3"] = &t3;
+ lua["u1"] = &u1;
+ lua["u2"] = &u2;
+ lua["u3"] = &u3;
+ lua["v1"] = &v1;
+ lua["v2"] = &v2;
+ lua["v3"] = &v3;
+
+ // Can only compare identity here
+ REQUIRE_NOTHROW({
+ lua.script("assert(t1 == t1)");
+ lua.script("assert(t2 == t2)");
+ lua.script("assert(t3 == t3)");
+ });
+ REQUIRE_NOTHROW({
+ lua.script("assert(t1 == t2)");
+ lua.script("assert(not (t1 == t3))");
+ lua.script("assert(not (t2 == t3))");
+ });
+ // Object should compare equal to themselves
+ // (and not invoke operator==; pointer test should be sufficient)
+ REQUIRE_NOTHROW({
+ lua.script("assert(u1 == u1)");
+ lua.script("assert(u2 == u2)");
+ lua.script("assert(u3 == u3)");
+ });
+ REQUIRE_NOTHROW({
+ lua.script("assert(not (u1 == u2))");
+ lua.script("assert(u1 == u3)");
+ lua.script("assert(not (u2 == u3))");
+ });
+ // Object should compare equal to themselves
+ // (and not invoke operator==; pointer test should be sufficient)
+ REQUIRE_NOTHROW({
+ lua.script("assert(v1 == v1)");
+ lua.script("assert(v2 == v2)");
+ lua.script("assert(v3 == v3)");
+ });
+ REQUIRE_NOTHROW({
+ lua.script("assert(not (v1 == v2))");
+ lua.script("assert(v1 == v3)");
+ lua.script("assert(not (v2 == v3))");
+ });
+} \ No newline at end of file
diff --git a/3rdparty/sol2/test_overflow.cpp b/3rdparty/sol2/test_overflow.cpp
new file mode 100644
index 00000000000..68c11811a97
--- /dev/null
+++ b/3rdparty/sol2/test_overflow.cpp
@@ -0,0 +1,47 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <catch.hpp>
+#include <sol.hpp>
+
+
+TEST_CASE("issues/stack-overflow", "make sure various operations repeated don't trigger stack overflow") {
+ sol::state lua;
+ lua.script("t = {};t[0]=20");
+ lua.script("lua_function=function(i)return i;end");
+
+ sol::function f = lua["lua_function"];
+ std::string teststring = "testtext";
+ REQUIRE_NOTHROW(
+ for (int i = 0; i < 1000000; ++i) {
+ std::string result = f(teststring);
+ if (result != teststring) throw std::logic_error("RIP");
+ }
+ );
+ sol::table t = lua["t"];
+ int expected = 20;
+ REQUIRE_NOTHROW(
+ for (int i = 0; i < 1000000; ++i) {
+ int result = t[0];
+ t.size();
+ if (result != expected)
+ throw std::logic_error("RIP");
+ }
+ );
+}
+
+
+TEST_CASE("issues/stack-overflow-2", "make sure basic iterators clean up properly when they're not iterated through (e.g., with empty())") {
+ sol::state lua;
+ sol::table t = lua.create_table_with(1, "wut");
+ int MAX = 50000;
+ auto fx = [&]() {
+ int a = 50;
+ for (int i = 0; i < MAX; ++i) {
+ if (t.empty()) {
+ a += 4;
+ }
+ a += 2;
+ }
+ };
+ REQUIRE_NOTHROW(fx());
+}
diff --git a/3rdparty/sol2/test_simple_usertypes.cpp b/3rdparty/sol2/test_simple_usertypes.cpp
new file mode 100644
index 00000000000..4683aa3b631
--- /dev/null
+++ b/3rdparty/sol2/test_simple_usertypes.cpp
@@ -0,0 +1,459 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <sol.hpp>
+#include <catch.hpp>
+
+#include <iostream>
+#include <list>
+#include <memory>
+#include <mutex>
+
+TEST_CASE("usertype/simple-usertypes", "Ensure that simple usertypes properly work here") {
+ struct marker {
+ bool value = false;
+ };
+ struct bark {
+ int var = 50;
+ marker mark;
+
+ void fun() {
+ var = 51;
+ }
+
+ int get() const {
+ return var;
+ }
+
+ int set(int x) {
+ var = x;
+ return var;
+ }
+
+ std::string special() const {
+ return mark.value ? "woof" : "pantpant";
+ }
+
+ const marker& the_marker() const {
+ return mark;
+ }
+ };
+
+ sol::state lua;
+ lua.new_simple_usertype<bark>("bark",
+ "fun", &bark::fun,
+ "get", &bark::get,
+ "var", sol::as_function( &bark::var ),
+ "the_marker", sol::as_function(&bark::the_marker),
+ "x", sol::overload(&bark::get),
+ "y", sol::overload(&bark::set),
+ "z", sol::overload(&bark::get, &bark::set)
+ );
+
+ lua.script("b = bark.new()");
+ bark& b = lua["b"];
+
+ lua.script("b:fun()");
+ int var = b.var;
+ REQUIRE(var == 51);
+
+ lua.script("b:var(20)");
+ lua.script("v = b:var()");
+ int v = lua["v"];
+ REQUIRE(v == 20);
+ REQUIRE(b.var == 20);
+
+ lua.script("m = b:the_marker()");
+ marker& m = lua["m"];
+ REQUIRE_FALSE(b.mark.value);
+ REQUIRE_FALSE(m.value);
+ m.value = true;
+ REQUIRE(&b.mark == &m);
+ REQUIRE(b.mark.value);
+
+ sol::table barktable = lua["bark"];
+ barktable["special"] = &bark::special;
+
+ lua.script("s = b:special()");
+ std::string s = lua["s"];
+ REQUIRE(s == "woof");
+
+ lua.script("b:y(24)");
+ lua.script("x = b:x()");
+ int x = lua["x"];
+ REQUIRE(x == 24);
+
+ lua.script("z = b:z(b:z() + 5)");
+ int z = lua["z"];
+ REQUIRE(z == 29);
+}
+
+TEST_CASE("usertype/simple-usertypes-constructors", "Ensure that calls with specific arguments work") {
+ struct marker {
+ bool value = false;
+ };
+ struct bark {
+ int var = 50;
+ marker mark;
+
+ bark() {}
+ bark(int v) : var(v) {}
+
+ void fun() {
+ var = 51;
+ }
+
+ int get() const {
+ return var;
+ }
+
+ int set(int x) {
+ var = x;
+ return var;
+ }
+
+ std::string special() const {
+ return mark.value ? "woof" : "pantpant";
+ }
+
+ const marker& the_marker() const {
+ return mark;
+ }
+ };
+
+ sol::state lua;
+ lua.new_simple_usertype<bark>("bark",
+ sol::constructors<sol::types<>, sol::types<int>>(),
+ "fun", sol::protect( &bark::fun ),
+ "get", &bark::get,
+ "var", sol::as_function( &bark::var ),
+ "the_marker", &bark::the_marker,
+ "x", sol::overload(&bark::get),
+ "y", sol::overload(&bark::set),
+ "z", sol::overload(&bark::get, &bark::set)
+ );
+
+ lua.script("bx = bark.new(760)");
+ bark& bx = lua["bx"];
+ REQUIRE(bx.var == 760);
+
+ lua.script("b = bark.new()");
+ bark& b = lua["b"];
+
+ lua.script("b:fun()");
+ int var = b.var;
+ REQUIRE(var == 51);
+
+ lua.script("b:var(20)");
+ lua.script("v = b:var()");
+ int v = lua["v"];
+ REQUIRE(v == 20);
+
+ lua.script("m = b:the_marker()");
+ marker& m = lua["m"];
+ REQUIRE_FALSE(b.mark.value);
+ REQUIRE_FALSE(m.value);
+ m.value = true;
+ REQUIRE(&b.mark == &m);
+ REQUIRE(b.mark.value);
+
+ sol::table barktable = lua["bark"];
+ barktable["special"] = &bark::special;
+
+ lua.script("s = b:special()");
+ std::string s = lua["s"];
+ REQUIRE(s == "woof");
+
+ lua.script("b:y(24)");
+ lua.script("x = b:x()");
+ int x = lua["x"];
+ REQUIRE(x == 24);
+
+ lua.script("z = b:z(b:z() + 5)");
+ int z = lua["z"];
+ REQUIRE(z == 29);
+}
+
+TEST_CASE("usertype/simple-shared-ptr-regression", "simple usertype metatables should not screw over unique usertype metatables") {
+ static int created = 0;
+ static int destroyed = 0;
+ struct test {
+ test() {
+ ++created;
+ }
+
+ ~test() {
+ ++destroyed;
+ }
+ };
+ {
+ std::list<std::shared_ptr<test>> tests;
+ sol::state lua;
+ lua.open_libraries();
+
+ lua.new_simple_usertype<test>("test",
+ "create", [&]() -> std::shared_ptr<test> {
+ tests.push_back(std::make_shared<test>());
+ return tests.back();
+ }
+ );
+ REQUIRE(created == 0);
+ REQUIRE(destroyed == 0);
+ lua.script("x = test.create()");
+ REQUIRE(created == 1);
+ REQUIRE(destroyed == 0);
+ REQUIRE_FALSE(tests.empty());
+ std::shared_ptr<test>& x = lua["x"];
+ std::size_t xuse = x.use_count();
+ std::size_t tuse = tests.back().use_count();
+ REQUIRE(xuse == tuse);
+ }
+ REQUIRE(created == 1);
+ REQUIRE(destroyed == 1);
+}
+
+TEST_CASE("usertype/simple-vars", "simple usertype vars can bind various values (no ref)") {
+ int muh_variable = 10;
+ int through_variable = 25;
+
+ sol::state lua;
+ lua.open_libraries();
+
+ struct test {};
+ lua.new_simple_usertype<test>("test",
+ "straight", sol::var(2),
+ "global", sol::var(muh_variable),
+ "global2", sol::var(through_variable),
+ "global3", sol::var(std::ref(through_variable))
+ );
+
+ through_variable = 20;
+
+ lua.script(R"(
+print(test.straight)
+s = test.straight
+print(test.global)
+g = test.global
+print(test.global2)
+g2 = test.global2
+print(test.global3)
+g3 = test.global3
+)");
+
+ int s = lua["s"];
+ int g = lua["g"];
+ int g2 = lua["g2"];
+ int g3 = lua["g3"];
+ REQUIRE(s == 2);
+ REQUIRE(g == 10);
+ REQUIRE(g2 == 25);
+ REQUIRE(g3 == 20);
+}
+
+TEST_CASE("usertypes/simple-variable-control", "test to see if usertypes respond to inheritance and variable controls") {
+ class A {
+ public:
+ virtual void a() { throw std::runtime_error("entered base pure virtual implementation"); };
+ };
+
+ class B : public A {
+ public:
+ virtual void a() override { }
+ };
+
+ class sA {
+ public:
+ virtual void a() { throw std::runtime_error("entered base pure virtual implementation"); };
+ };
+
+ class sB : public sA {
+ public:
+ virtual void a() override { }
+ };
+
+ struct sV {
+ int a = 10;
+ int b = 20;
+
+ int get_b() const {
+ return b + 2;
+ }
+
+ void set_b(int value) {
+ b = value;
+ }
+ };
+
+ struct sW : sV {};
+
+ sol::state lua;
+ lua.open_libraries();
+
+ lua.new_usertype<A>("A", "a", &A::a);
+ lua.new_usertype<B>("B", sol::base_classes, sol::bases<A>());
+ lua.new_simple_usertype<sA>("sA", "a", &sA::a);
+ lua.new_simple_usertype<sB>("sB", sol::base_classes, sol::bases<sA>());
+ lua.new_simple_usertype<sV>("sV", "a", &sV::a, "b", &sV::b, "pb", sol::property(&sV::get_b, &sV::set_b));
+ lua.new_simple_usertype<sW>("sW", sol::base_classes, sol::bases<sV>());
+
+ B b;
+ lua.set("b", &b);
+ lua.script("b:a()");
+
+ sB sb;
+ lua.set("sb", &sb);
+ lua.script("sb:a()");
+
+ sV sv;
+ lua.set("sv", &sv);
+ lua.script("print(sv.b)assert(sv.b == 20)");
+
+ sW sw;
+ lua.set("sw", &sw);
+ lua.script("print(sw.a)assert(sw.a == 10)");
+ lua.script("print(sw.b)assert(sw.b == 20)");
+ lua.script("print(sw.pb)assert(sw.pb == 22)");
+ lua.script("sw.a = 11");
+ lua.script("sw.b = 21");
+ lua.script("print(sw.a)assert(sw.a == 11)");
+ lua.script("print(sw.b)assert(sw.b == 21)");
+ lua.script("print(sw.pb)assert(sw.pb == 23)");
+ lua.script("sw.pb = 25");
+ lua.script("print(sw.b)assert(sw.b == 25)");
+ lua.script("print(sw.pb)assert(sw.pb == 27)");
+}
+
+TEST_CASE("usertype/simple-factory-constructor-overload-usage", "simple usertypes should probably invoke types") {
+ class A {
+ public:
+ virtual void a() { throw std::runtime_error("entered base pure virtual implementation"); };
+ };
+
+ class B : public A {
+ public:
+ int bvar = 24;
+ virtual void a() override { }
+ void f() {}
+ };
+
+ sol::state lua;
+ lua.open_libraries();
+ sol::constructors<sol::types<>, sol::types<const B&>> c;
+ lua.new_simple_usertype<B>("B",
+ sol::call_constructor, c,
+ "new", sol::factories([]() { return B(); }),
+ "new2", sol::initializers([](B& mem) { new(&mem)B(); }, [](B& mem, int v) { new(&mem)B(); mem.bvar = v; }),
+ "f", sol::as_function(&B::bvar),
+ "g", sol::overload([](B&) { return 2; }, [](B&, int v) { return v; })
+ );
+
+ lua.script("b = B()");
+ lua.script("b2 = B.new()");
+ lua.script("b3 = B.new2()");
+ lua.script("b4 = B.new2(11)");
+
+ lua.script("x = b:f()");
+ lua.script("x2 = b2:f()");
+ lua.script("x3 = b3:f()");
+ lua.script("x4 = b4:f()");
+ int x = lua["x"];
+ int x2 = lua["x2"];
+ int x3 = lua["x3"];
+ int x4 = lua["x4"];
+ REQUIRE(x == 24);
+ REQUIRE(x2 == 24);
+ REQUIRE(x3 == 24);
+ REQUIRE(x4 == 11);
+
+ lua.script("y = b:g()");
+ lua.script("y2 = b2:g(3)");
+ lua.script("y3 = b3:g()");
+ lua.script("y4 = b4:g(3)");
+ int y = lua["y"];
+ int y2 = lua["y2"];
+ int y3 = lua["y3"];
+ int y4 = lua["y4"];
+ REQUIRE(y == 2);
+ REQUIRE(y2 == 3);
+ REQUIRE(y3 == 2);
+ REQUIRE(y4 == 3);
+}
+
+TEST_CASE("usertype/simple-runtime-append", "allow extra functions to be appended at runtime directly to the metatable itself") {
+ class A {
+ };
+
+ class B : public A {
+ };
+
+ sol::state lua;
+ lua.new_simple_usertype<A>("A");
+ lua.new_simple_usertype<B>("B", sol::base_classes, sol::bases<A>());
+ lua.set("b", std::make_unique<B>());
+ lua["A"]["method"] = []() { return 200; };
+ lua["B"]["method2"] = [](B&) { return 100; };
+ lua.script("x = b.method()");
+ lua.script("y = b:method()");
+
+ int x = lua["x"];
+ int y = lua["y"];
+ REQUIRE(x == 200);
+ REQUIRE(y == 200);
+
+ lua.script("z = b.method2(b)");
+ lua.script("w = b:method2()");
+ int z = lua["z"];
+ int w = lua["w"];
+ REQUIRE(z == 100);
+ REQUIRE(w == 100);
+}
+
+TEST_CASE("usertype/simple-destruction-test", "make sure usertypes are properly destructed and don't double-delete memory or segfault") {
+ sol::state lua;
+
+ class CrashClass {
+ public:
+ CrashClass() {
+ }
+
+ ~CrashClass() {
+ a = 10; // This will cause a crash.
+ }
+
+ private:
+ int a;
+ };
+
+ lua.new_simple_usertype<CrashClass>("CrashClass",
+ sol::call_constructor, sol::constructors<sol::types<>>()
+ );
+
+ lua.script(R"(
+ function testCrash()
+ local x = CrashClass()
+ end
+ )");
+
+ for (int i = 0; i < 1000; ++i) {
+ lua["testCrash"]();
+ }
+}
+
+TEST_CASE("usertype/simple-table-append", "Ensure that appending to the meta table also affects the internal function table for pointers as well") {
+ struct A {
+ int func() {
+ return 5000;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries();
+
+ lua.new_simple_usertype<A>("A");
+ sol::table table = lua["A"];
+ table["func"] = &A::func;
+ A a;
+ lua.set("a", &a);
+ REQUIRE_NOTHROW(
+ lua.script("assert(a:func() == 5000)")
+ );
+}
diff --git a/3rdparty/sol2/test_stack_guard.hpp b/3rdparty/sol2/test_stack_guard.hpp
new file mode 100644
index 00000000000..d77ffb8b682
--- /dev/null
+++ b/3rdparty/sol2/test_stack_guard.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+struct test_stack_guard {
+ lua_State* L;
+ int& begintop;
+ int& endtop;
+ test_stack_guard(lua_State* L, int& begintop, int& endtop) : L(L), begintop(begintop), endtop(endtop) {
+ begintop = lua_gettop(L);
+ }
+ ~test_stack_guard() { endtop = lua_gettop(L); }
+};
diff --git a/3rdparty/sol2/test_strings.cpp b/3rdparty/sol2/test_strings.cpp
new file mode 100644
index 00000000000..98396e204bd
--- /dev/null
+++ b/3rdparty/sol2/test_strings.cpp
@@ -0,0 +1,122 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <catch.hpp>
+#include <sol.hpp>
+
+#include <iostream>
+
+struct test {};
+template <typename T>
+struct test_t {};
+
+namespace muh_namespace {
+ struct ns_test {};
+
+ namespace {
+ struct ns_anon_test {};
+ }
+}
+
+// There isn't a single library roundtripping which codecvt works on. We'll do the nitty-gritty of it later...
+TEST_CASE("stack/strings", "test that strings can be roundtripped") {
+ sol::state lua;
+
+ static const char utf8str[] = "\xF0\x9F\x8D\x8C\x20\xE6\x99\xA5\x20\x46\x6F\x6F\x20\xC2\xA9\x20\x62\x61\x72\x20\xF0\x9D\x8C\x86\x20\x62\x61\x7A\x20\xE2\x98\x83\x20\x71\x75\x78";
+ static const char16_t utf16str[] = { 0xD83C, 0xDF4C, 0x20, 0x6665, 0x20, 0x46, 0x6F, 0x6F, 0x20, 0xA9, 0x20, 0x62, 0x61, 0x72, 0x20, 0xD834, 0xDF06, 0x20, 0x62, 0x61, 0x7A, 0x20, 0x2603, 0x20, 0x71, 0x75, 0x78, 0x00 };
+ static const char32_t utf32str[] = { 0x1F34C, 0x0020, 0x6665, 0x0020, 0x0046, 0x006F, 0x006F, 0x0020, 0x00A9, 0x0020, 0x0062, 0x0061, 0x0072, 0x0020, 0x1D306, 0x0020, 0x0062, 0x0061, 0x007A, 0x0020, 0x2603, 0x0020, 0x0071, 0x0075, 0x0078, 0x00 };
+#ifdef _WIN32
+ INFO("win32 widestr");
+ static const wchar_t widestr[] = { 0xD83C, 0xDF4C, 0x20, 0x6665, 0x20, 0x46, 0x6F, 0x6F, 0x20, 0xA9, 0x20, 0x62, 0x61, 0x72, 0x20, 0xD834, 0xDF06, 0x20, 0x62, 0x61, 0x7A, 0x20, 0x2603, 0x20, 0x71, 0x75, 0x78, 0x00 };
+#else
+ INFO("non-windows widestr");
+ static const wchar_t widestr[] = { 0x1F34C, 0x0020, 0x6665, 0x0020, 0x0046, 0x006F, 0x006F, 0x0020, 0x00A9, 0x0020, 0x0062, 0x0061, 0x0072, 0x0020, 0x1D306, 0x0020, 0x0062, 0x0061, 0x007A, 0x0020, 0x2603, 0x0020, 0x0071, 0x0075, 0x0078, 0x00 };
+#endif
+ static const std::string utf8str_s = utf8str;
+ static const std::u16string utf16str_s = utf16str;
+ static const std::u32string utf32str_s = utf32str;
+ static const std::wstring widestr_s = widestr;
+
+#ifdef SOL_CODECVT_SUPPORT
+ INFO("sizeof(wchar_t): " << sizeof(wchar_t));
+ INFO("sizeof(char16_t): " << sizeof(char16_t));
+ INFO("sizeof(char32_t): " << sizeof(char32_t));
+ INFO("utf8str: " << utf8str);
+ INFO("utf8str_s: " << utf8str_s);
+
+ lua["utf8"] = utf8str;
+ lua["utf16"] = utf16str;
+ lua["utf32"] = utf32str;
+ lua["wide"] = widestr;
+
+ std::string utf8_to_utf8 = lua["utf8"];
+ std::string utf16_to_utf8 = lua["utf16"];
+ std::string utf32_to_utf8 = lua["utf32"];
+ std::string wide_to_utf8 = lua["wide"];
+
+ REQUIRE(utf8_to_utf8 == utf8str_s);
+ REQUIRE(utf16_to_utf8 == utf8str_s);
+ REQUIRE(utf32_to_utf8 == utf8str_s);
+ REQUIRE(wide_to_utf8 == utf8str_s);
+
+ std::wstring utf8_to_wide = lua["utf8"];
+ std::wstring utf16_to_wide = lua["utf16"];
+ std::wstring utf32_to_wide = lua["utf32"];
+ std::wstring wide_to_wide = lua["wide"];
+
+ REQUIRE(utf8_to_wide == widestr_s);
+ REQUIRE(utf16_to_wide == widestr_s);
+ REQUIRE(utf32_to_wide == widestr_s);
+ REQUIRE(wide_to_wide == widestr_s);
+
+ std::u16string utf8_to_utf16 = lua["utf8"];
+ std::u16string utf16_to_utf16 = lua["utf16"];
+ std::u16string utf32_to_utf16 = lua["utf32"];
+ std::u16string wide_to_utf16 = lua["wide"];
+
+ REQUIRE(utf8_to_utf16 == utf16str_s);
+ REQUIRE(utf16_to_utf16 == utf16str_s);
+ REQUIRE(utf32_to_utf16 == utf16str_s);
+ REQUIRE(wide_to_utf16 == utf16str_s);
+
+ std::u32string utf8_to_utf32 = lua["utf8"];
+ std::u32string utf16_to_utf32 = lua["utf16"];
+ std::u32string utf32_to_utf32 = lua["utf32"];
+ std::u32string wide_to_utf32 = lua["wide"];
+
+ REQUIRE(utf8_to_utf32 == utf32str_s);
+ REQUIRE(utf16_to_utf32 == utf32str_s);
+ REQUIRE(utf32_to_utf32 == utf32str_s);
+ REQUIRE(wide_to_utf32 == utf32str_s);
+
+ char32_t utf8_to_char32 = lua["utf8"];
+ char32_t utf16_to_char32 = lua["utf16"];
+ char32_t utf32_to_char32 = lua["utf32"];
+ char32_t wide_to_char32 = lua["wide"];
+
+ REQUIRE(utf8_to_char32 == utf32str[0]);
+ REQUIRE(utf16_to_char32 == utf32str[0]);
+ REQUIRE(utf32_to_char32 == utf32str[0]);
+ REQUIRE(wide_to_char32 == utf32str[0]);
+#endif // codecvt support
+}
+
+TEST_CASE("detail/demangling", "test some basic demangling cases") {
+ std::string teststr = sol::detail::short_demangle<test>();
+ std::string nsteststr = sol::detail::short_demangle<muh_namespace::ns_test>();
+ std::string nsateststr = sol::detail::short_demangle<muh_namespace::ns_anon_test>();
+
+ REQUIRE(teststr == "test");
+ REQUIRE(nsteststr == "ns_test");
+ REQUIRE(nsateststr == "ns_anon_test");
+}
+
+TEST_CASE("object/string-pushers", "test some basic string pushers with in_place constructor") {
+ sol::state lua;
+
+ sol::object ocs(lua, sol::in_place, "bark\0bark", 9);
+ sol::object os(lua, sol::in_place<std::string>, std::string("bark\0bark", 9), 8);
+ bool test1 = os.as<std::string>() == std::string("bark\0bar", 8);
+ bool test2 = ocs.as<std::string>() == std::string("bark\0bark", 9);
+ REQUIRE(test1);
+ REQUIRE(test2);
+}
diff --git a/3rdparty/sol2/test_tables.cpp b/3rdparty/sol2/test_tables.cpp
new file mode 100644
index 00000000000..cb8f291ee09
--- /dev/null
+++ b/3rdparty/sol2/test_tables.cpp
@@ -0,0 +1,548 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <catch.hpp>
+#include <sol.hpp>
+
+#include <iostream>
+#include <algorithm>
+#include <numeric>
+#include <vector>
+
+#include "test_stack_guard.hpp"
+
+std::string free_function() {
+ INFO("free_function()");
+ return "test";
+}
+
+struct object {
+ std::string operator() () {
+ INFO("member_test()");
+ return "test";
+ }
+};
+
+int plop_xyz(int x, int y, std::string z) {
+ INFO(x << " " << y << " " << z);
+ return 11;
+}
+
+TEST_CASE("tables/as-enums", "Making sure enums can be put in and gotten out as values") {
+ enum direction {
+ up,
+ down,
+ left,
+ right
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua["direction"] = lua.create_table_with(
+ "up", direction::up,
+ "down", direction::down,
+ "left", direction::left,
+ "right", direction::right
+ );
+
+ sol::object obj = lua["direction"]["up"];
+ bool isdir = obj.is<direction>();
+ REQUIRE(isdir);
+ auto dir = obj.as<direction>();
+ REQUIRE(dir == direction::up);
+}
+
+TEST_CASE("tables/as-enum-classes", "Making sure enums can be put in and gotten out as values") {
+ enum class direction {
+ up,
+ down,
+ left,
+ right
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua["direction"] = lua.create_table_with(
+ "up", direction::up,
+ "down", direction::down,
+ "left", direction::left,
+ "right", direction::right
+ );
+
+ sol::object obj = lua["direction"]["up"];
+ bool isdir = obj.is<direction>();
+ REQUIRE(isdir);
+ auto dir = obj.as<direction>();
+ REQUIRE(dir == direction::up);
+}
+
+TEST_CASE("tables/cleanup", "make sure tables leave the stack balanced") {
+ sol::state lua;
+ lua.open_libraries();
+
+ auto f = [] { return 5; };
+ for (int i = 0; i < 30; i++) {
+ std::string name = std::string("init") + std::to_string(i);
+ int top = lua_gettop(lua);
+ lua[name] = f;
+ int aftertop = lua_gettop(lua);
+ REQUIRE(aftertop == top);
+ int val = lua[name]();
+ REQUIRE(val == 5);
+ }
+}
+
+TEST_CASE("tables/nested-cleanup", "make sure tables leave the stack balanced") {
+ sol::state lua;
+ lua.open_libraries();
+
+ lua.script("A={}");
+ auto f = [] { return 5; };
+ for (int i = 0; i < 30; i++) {
+ std::string name = std::string("init") + std::to_string(i);
+ int top = lua_gettop(lua);
+ auto A = lua["A"];
+ int beforetop = lua_gettop(lua);
+ REQUIRE(beforetop == top);
+ A[name] = f;
+ int aftertop = lua_gettop(lua);
+ REQUIRE(aftertop == top);
+ int val = A[name]();
+ REQUIRE(val == 5);
+ }
+}
+
+TEST_CASE("tables/new_enum", "Making sure enums can be put in and gotten out as values") {
+ enum class direction {
+ up,
+ down,
+ left,
+ right
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_enum( "direction",
+ "up", direction::up,
+ "down", direction::down,
+ "left", direction::left,
+ "right", direction::right
+ );
+
+ direction d = lua["direction"]["left"];
+ REQUIRE(d == direction::left);
+ REQUIRE_THROWS(lua.script("direction.left = 50"));
+ d = lua["direction"]["left"];
+ REQUIRE(d == direction::left);
+}
+
+TEST_CASE("tables/for-each", "Testing the use of for_each to get values from a lua table") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.script("arr = {\n"
+ "[0] = \"Hi\",\n"
+ "[1] = 123.45,\n"
+ "[2] = \"String value\",\n"
+ // Does nothing
+ //"[3] = nil,\n"
+ //"[nil] = 3,\n"
+ "[\"WOOF\"] = 123,\n"
+ "}");
+ sol::table tbl = lua["arr"];
+ std::size_t tablesize = 4;
+ std::size_t iterations = 0;
+ auto fx = [&iterations](sol::object key, sol::object value) {
+ ++iterations;
+ sol::type keytype = key.get_type();
+ switch (keytype) {
+ case sol::type::number:
+ switch (key.as<int>()) {
+ case 0:
+ REQUIRE((value.as<std::string>() == "Hi"));
+ break;
+ case 1:
+ REQUIRE((value.as<double>() == 123.45));
+ break;
+ case 2:
+ REQUIRE((value.as<std::string>() == "String value"));
+ break;
+ case 3:
+ REQUIRE((value.is<sol::nil_t>()));
+ break;
+ }
+ break;
+ case sol::type::string:
+ if (key.as<std::string>() == "WOOF") {
+ REQUIRE((value.as<double>() == 123));
+ }
+ break;
+ case sol::type::nil:
+ REQUIRE((value.as<double>() == 3));
+ break;
+ default:
+ break;
+ }
+ };
+ auto fxpair = [&fx](std::pair<sol::object, sol::object> kvp) { fx(kvp.first, kvp.second); };
+ tbl.for_each(fx);
+ REQUIRE(iterations == tablesize);
+
+ iterations = 0;
+ tbl.for_each(fxpair);
+ REQUIRE(iterations == tablesize);
+}
+
+TEST_CASE("tables/for-each-empty", "empty tables should not crash") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.script("arr = {}");
+ sol::table tbl = lua["arr"];
+ REQUIRE(tbl.empty());
+ std::size_t tablesize = 0;
+ std::size_t iterations = 0;
+ auto fx = [&iterations](sol::object key, sol::object value) {
+ ++iterations;
+ sol::type keytype = key.get_type();
+ switch (keytype) {
+ case sol::type::number:
+ switch (key.as<int>()) {
+ case 0:
+ REQUIRE((value.as<std::string>() == "Hi"));
+ break;
+ case 1:
+ REQUIRE((value.as<double>() == 123.45));
+ break;
+ case 2:
+ REQUIRE((value.as<std::string>() == "String value"));
+ break;
+ case 3:
+ REQUIRE((value.is<sol::nil_t>()));
+ break;
+ }
+ break;
+ case sol::type::string:
+ if (key.as<std::string>() == "WOOF") {
+ REQUIRE((value.as<double>() == 123));
+ }
+ break;
+ case sol::type::nil:
+ REQUIRE((value.as<double>() == 3));
+ break;
+ default:
+ break;
+ }
+ };
+ auto fxpair = [&fx](std::pair<sol::object, sol::object> kvp) { fx(kvp.first, kvp.second); };
+ tbl.for_each(fx);
+ REQUIRE(iterations == tablesize);
+
+ iterations = 0;
+ tbl.for_each(fxpair);
+ REQUIRE(iterations == tablesize);
+
+ iterations = 0;
+ for (const auto& kvp : tbl) {
+ fxpair(kvp);
+ ++iterations;
+ }
+ REQUIRE(iterations == tablesize);
+}
+
+TEST_CASE("tables/iterators", "Testing the use of iteratrs to get values from a lua table") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.script("arr = {\n"
+ "[0] = \"Hi\",\n"
+ "[1] = 123.45,\n"
+ "[2] = \"String value\",\n"
+ // Does nothing
+ //"[3] = nil,\n"
+ //"[nil] = 3,\n"
+ "[\"WOOF\"] = 123,\n"
+ "}");
+ sol::table tbl = lua["arr"];
+ std::size_t tablesize = 4;
+ std::size_t iterations = 0;
+
+ int begintop = 0;
+ int endtop = 0;
+ {
+ test_stack_guard s(lua.lua_state(), begintop, endtop);
+ for (auto& kvp : tbl) {
+ [&iterations](sol::object key, sol::object value) {
+ ++iterations;
+ sol::type keytype = key.get_type();
+ switch (keytype) {
+ case sol::type::number:
+ switch (key.as<int>()) {
+ case 0:
+ REQUIRE((value.as<std::string>() == "Hi"));
+ break;
+ case 1:
+ REQUIRE((value.as<double>() == 123.45));
+ break;
+ case 2:
+ REQUIRE((value.as<std::string>() == "String value"));
+ break;
+ case 3:
+ REQUIRE((value.is<sol::nil_t>()));
+ break;
+ }
+ break;
+ case sol::type::string:
+ if (key.as<std::string>() == "WOOF") {
+ REQUIRE((value.as<double>() == 123));
+ }
+ break;
+ case sol::type::nil:
+ REQUIRE((value.as<double>() == 3));
+ break;
+ default:
+ break;
+ }
+ }(kvp.first, kvp.second);
+ }
+ } REQUIRE(begintop == endtop);
+ REQUIRE(iterations == tablesize);
+}
+
+TEST_CASE("tables/variables", "Check if tables and variables work as intended") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::os);
+ lua.get<sol::table>("os").set("name", "windows");
+ REQUIRE_NOTHROW(lua.script("assert(os.name == \"windows\")"));
+}
+
+TEST_CASE("tables/create", "Check if creating a table is kosher") {
+ sol::state lua;
+ lua["testtable"] = sol::table::create(lua.lua_state(), 0, 0, "Woof", "Bark", 1, 2, 3, 4);
+ sol::object testobj = lua["testtable"];
+ REQUIRE(testobj.is<sol::table>());
+ sol::table testtable = testobj.as<sol::table>();
+ REQUIRE((testtable["Woof"] == std::string("Bark")));
+ REQUIRE((testtable[1] == 2));
+ REQUIRE((testtable[3] == 4));
+}
+
+TEST_CASE("tables/create-local", "Check if creating a table is kosher") {
+ sol::state lua;
+ lua["testtable"] = lua.create_table(0, 0, "Woof", "Bark", 1, 2, 3, 4);
+ sol::object testobj = lua["testtable"];
+ REQUIRE(testobj.is<sol::table>());
+ sol::table testtable = testobj.as<sol::table>();
+ REQUIRE((testtable["Woof"] == std::string("Bark")));
+ REQUIRE((testtable[1] == 2));
+ REQUIRE((testtable[3] == 4));
+}
+
+TEST_CASE("tables/create-local-named", "Check if creating a table is kosher") {
+ sol::state lua;
+ sol::table testtable = lua.create_table("testtable", 0, 0, "Woof", "Bark", 1, 2, 3, 4);
+ sol::object testobj = lua["testtable"];
+ REQUIRE(testobj.is<sol::table>());
+ REQUIRE((testobj == testtable));
+ REQUIRE_FALSE((testobj != testtable));
+ REQUIRE((testtable["Woof"] == std::string("Bark")));
+ REQUIRE((testtable[1] == 2));
+ REQUIRE((testtable[3] == 4));
+}
+
+TEST_CASE("tables/create-with-local", "Check if creating a table is kosher") {
+ sol::state lua;
+ lua["testtable"] = lua.create_table_with("Woof", "Bark", 1, 2, 3, 4);
+ sol::object testobj = lua["testtable"];
+ REQUIRE(testobj.is<sol::table>());
+ sol::table testtable = testobj.as<sol::table>();
+ REQUIRE((testtable["Woof"] == std::string("Bark")));
+ REQUIRE((testtable[1] == 2));
+ REQUIRE((testtable[3] == 4));
+}
+
+TEST_CASE("tables/functions-variables", "Check if tables and function calls work as intended") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::os);
+ auto run_script = [](sol::state& lua) -> void {
+ lua.script("assert(os.fun() == \"test\")");
+ };
+
+ lua.get<sol::table>("os").set_function("fun",
+ []() {
+ INFO("stateless lambda()");
+ return "test";
+ }
+ );
+ REQUIRE_NOTHROW(run_script(lua));
+
+ lua.get<sol::table>("os").set_function("fun", &free_function);
+ REQUIRE_NOTHROW(run_script(lua));
+
+ // l-value, canNOT optimise
+ // prefer value semantics unless wrapped with std::reference_wrapper
+ {
+ auto lval = object();
+ lua.get<sol::table>("os").set_function("fun", &object::operator(), lval);
+ }
+ REQUIRE_NOTHROW(run_script(lua));
+
+ auto reflval = object();
+ lua.get<sol::table>("os").set_function("fun", &object::operator(), std::ref(reflval));
+ REQUIRE_NOTHROW(run_script(lua));
+
+
+ // stateful lambda: non-convertible, cannot be optimised
+ int breakit = 50;
+ lua.get<sol::table>("os").set_function("fun",
+ [&breakit]() {
+ INFO("stateful lambda()");
+ return "test";
+ }
+ );
+ REQUIRE_NOTHROW(run_script(lua));
+
+ // r-value, cannot optimise
+ lua.get<sol::table>("os").set_function("fun", &object::operator(), object());
+ REQUIRE_NOTHROW(run_script(lua));
+
+ // r-value, cannot optimise
+ auto rval = object();
+ lua.get<sol::table>("os").set_function("fun", &object::operator(), std::move(rval));
+ REQUIRE_NOTHROW(run_script(lua));
+}
+
+TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works properly") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.script("foo = 20\nbar = \"hello world\"");
+ // basic retrieval
+ std::string bar = lua["bar"];
+ int foo = lua["foo"];
+ REQUIRE(bar == "hello world");
+ REQUIRE(foo == 20);
+ // test operator= for stringification
+ // errors due to ambiguous operators
+ bar = lua["bar"];
+
+ // basic setting
+ lua["bar"] = 20.4;
+ lua["foo"] = "goodbye";
+
+ // doesn't modify the actual values obviously.
+ REQUIRE(bar == "hello world");
+ REQUIRE(foo == 20);
+
+ // function setting
+ lua["test"] = plop_xyz;
+ REQUIRE_NOTHROW(lua.script("assert(test(10, 11, \"hello\") == 11)"));
+
+ // function retrieval
+ sol::function test = lua["test"];
+ REQUIRE(test.call<int>(10, 11, "hello") == 11);
+
+ // setting a lambda
+ lua["lamb"] = [](int x) {
+ return x * 2;
+ };
+
+ REQUIRE_NOTHROW(lua.script("assert(lamb(220) == 440)"));
+
+ // function retrieval of a lambda
+ sol::function lamb = lua["lamb"];
+ REQUIRE(lamb.call<int>(220) == 440);
+
+ // test const table retrieval
+ auto assert1 = [](const sol::table& t) {
+ std::string a = t["foo"];
+ double b = t["bar"];
+ REQUIRE(a == "goodbye");
+ REQUIRE(b == 20.4);
+ };
+
+ REQUIRE_NOTHROW(assert1(lua.globals()));
+}
+
+TEST_CASE("tables/operator[]-valid", "Test if proxies on tables can lazily evaluate validity") {
+ sol::state lua;
+ bool isFullScreen = false;
+ auto fullscreennopers = lua["fullscreen"]["nopers"];
+ auto fullscreen = lua["fullscreen"];
+ REQUIRE_FALSE(fullscreennopers.valid());
+ REQUIRE_FALSE(fullscreen.valid());
+
+ lua["fullscreen"] = true;
+
+ REQUIRE_FALSE(fullscreennopers.valid());
+ REQUIRE(fullscreen.valid());
+ isFullScreen = lua["fullscreen"];
+ REQUIRE(isFullScreen);
+
+ lua["fullscreen"] = false;
+ REQUIRE_FALSE(fullscreennopers.valid());
+ REQUIRE(fullscreen.valid());
+ isFullScreen = lua["fullscreen"];
+ REQUIRE_FALSE(isFullScreen);
+}
+
+TEST_CASE("tables/operator[]-optional", "Test if proxies on tables can lazily evaluate validity") {
+ sol::state lua;
+
+ sol::optional<int> test1 = lua["no_exist_yet"];
+ bool present = (bool)test1;
+ REQUIRE_FALSE(present);
+
+ lua["no_exist_yet"] = 262;
+ sol::optional<int> test2 = lua["no_exist_yet"];
+ present = (bool)test2;
+ REQUIRE(present);
+ REQUIRE(test2.value() == 262);
+
+ sol::optional<int> nope = lua["nope"]["kek"]["hah"];
+ auto nope2 = lua.get<sol::optional<int>>(std::make_tuple("nope", "kek", "hah"));
+ present = (bool)nope;
+ REQUIRE_FALSE(present);
+ present = (bool)nope2;
+ REQUIRE_FALSE(present);
+ lua.create_named_table("nope", "kek", lua.create_table_with("hah", 1));
+ sol::optional<int> non_nope = lua["nope"]["kek"]["hah"].get<sol::optional<int>>();
+ sol::optional<int> non_nope2 = lua.get<sol::optional<int>>(std::make_tuple("nope", "kek", "hah"));
+ present = (bool)non_nope;
+ REQUIRE(present);
+ present = (bool)non_nope2;
+ REQUIRE(present);
+ REQUIRE(non_nope.value() == 1);
+ REQUIRE(non_nope2.value() == 1);
+
+ INFO("Keys: nope, kek, hah");
+ lua.set(std::make_tuple("nope", "kek", "hah"), 35);
+ sol::optional<int> non_nope3 = lua["nope"]["kek"]["hah"].get<sol::optional<int>>();
+ sol::optional<int> non_nope4 = lua.get<sol::optional<int>>(std::make_tuple("nope", "kek", "hah"));
+ present = (bool)non_nope3;
+ REQUIRE(present);
+ present = (bool)non_nope4;
+ REQUIRE(present);
+ REQUIRE(non_nope3.value() == 35);
+ REQUIRE(non_nope4.value() == 35);
+}
+
+TEST_CASE("tables/add", "Basic test to make sure the 'add' feature works") {
+ static const int sz = 120;
+
+ sol::state lua;
+ sol::table t = lua.create_table(sz, 0);
+
+ std::vector<int> bigvec( sz );
+ std::iota(bigvec.begin(), bigvec.end(), 1);
+
+ for (std::size_t i = 0; i < bigvec.size(); ++i) {
+ t.add(bigvec[i]);
+ }
+ for (std::size_t i = 0; i < bigvec.size(); ++i) {
+ int val = t[i + 1];
+ REQUIRE(val == bigvec[i]);
+ }
+}
diff --git a/3rdparty/sol2/test_usertypes.cpp b/3rdparty/sol2/test_usertypes.cpp
new file mode 100644
index 00000000000..8d5d6c01b72
--- /dev/null
+++ b/3rdparty/sol2/test_usertypes.cpp
@@ -0,0 +1,1425 @@
+#define SOL_CHECK_ARGUMENTS
+
+#include <sol.hpp>
+#include <catch.hpp>
+
+#include <iostream>
+#include <list>
+#include <memory>
+#include <mutex>
+
+struct vars {
+ vars() {
+
+ }
+
+ int boop = 0;
+
+ ~vars() {
+
+ }
+};
+
+struct fuser {
+ int x;
+ fuser() : x(0) {}
+
+ fuser(int x) : x(x) {}
+
+ int add(int y) {
+ return x + y;
+ }
+
+ int add2(int y) {
+ return x + y + 2;
+ }
+};
+
+namespace crapola {
+ struct fuser {
+ int x;
+ fuser() : x(0) {}
+ fuser(int x) : x(x) {}
+ fuser(int x, int x2) : x(x * x2) {}
+
+ int add(int y) {
+ return x + y;
+ }
+ int add2(int y) {
+ return x + y + 2;
+ }
+ };
+} // crapola
+
+class Base {
+public:
+ Base(int a_num) : m_num(a_num) { }
+
+ int get_num() {
+ return m_num;
+ }
+
+protected:
+ int m_num;
+};
+
+class Derived : public Base {
+public:
+ Derived(int a_num) : Base(a_num) { }
+
+ int get_num_10() {
+ return 10 * m_num;
+ }
+};
+
+class abstract_A {
+public:
+ virtual void a() = 0;
+};
+
+class abstract_B : public abstract_A {
+public:
+ virtual void a() override {
+ INFO("overridden a() in B : public A - BARK");
+ }
+};
+
+struct Vec {
+ float x, y, z;
+ Vec(float x, float y, float z) : x{ x }, y{ y }, z{ z } {}
+ float length() {
+ return sqrtf(x*x + y*y + z*z);
+ }
+ Vec normalized() {
+ float invS = 1 / length();
+ return{ x * invS, y * invS, z * invS };
+ }
+};
+
+struct giver {
+ int a = 0;
+
+ giver() {
+
+ }
+
+ void gief() {
+ a = 1;
+ }
+
+ static void stuff() {
+
+ }
+
+ static void gief_stuff(giver& t, int a) {
+ t.a = a;
+ }
+
+ ~giver() {
+
+ }
+
+};
+
+struct factory_test {
+private:
+ factory_test() { a = true_a; }
+ ~factory_test() { a = 0; }
+public:
+ static int num_saved;
+ static int num_killed;
+
+ struct deleter {
+ void operator()(factory_test* f) {
+ f->~factory_test();
+ }
+ };
+
+ static const int true_a;
+ int a;
+
+ static std::unique_ptr<factory_test, deleter> make() {
+ return std::unique_ptr<factory_test, deleter>(new factory_test(), deleter());
+ }
+
+ static void save(factory_test& f) {
+ new(&f)factory_test();
+ ++num_saved;
+ }
+
+ static void kill(factory_test& f) {
+ f.~factory_test();
+ ++num_killed;
+ }
+};
+
+int factory_test::num_saved = 0;
+int factory_test::num_killed = 0;
+const int factory_test::true_a = 156;
+
+bool something() {
+ return true;
+}
+
+struct thing {
+ int v = 100;
+
+ thing() {}
+ thing(int x) : v(x) {}
+};
+
+struct self_test {
+ int bark;
+
+ self_test() : bark(100) {
+
+ }
+
+ void g(const std::string& str) {
+ std::cout << str << '\n';
+ bark += 1;
+ }
+
+ void f(const self_test& t) {
+ std::cout << "got test" << '\n';
+ if (t.bark != bark)
+ throw sol::error("bark values are not the same for self_test f function");
+ if (&t != this)
+ throw sol::error("call does not reference self for self_test f function");
+ }
+};
+
+struct ext_getset {
+
+ int bark = 24;
+ const int meow = 56;
+
+ ext_getset() = default;
+ ext_getset(int v) : bark(v) {}
+ ext_getset(ext_getset&&) = default;
+ ext_getset(const ext_getset&) = delete;
+ ext_getset& operator=(ext_getset&&) = default;
+ ext_getset& operator=(const ext_getset&) = delete;
+ ~ext_getset() {
+
+ }
+
+ std::string x() {
+ return "bark bark bark";
+ }
+
+ int x2(std::string x) {
+ return static_cast<int>(x.length());
+ }
+
+ void set(sol::variadic_args, sol::this_state, int x) {
+ bark = x;
+ }
+
+ int get(sol::this_state, sol::variadic_args) {
+ return bark;
+ }
+
+ static void s_set(int) {
+
+ }
+
+ static int s_get(int x) {
+ return x + 20;
+ }
+
+};
+
+template <typename T>
+void des(T& e) {
+ e.~T();
+}
+
+TEST_CASE("usertype/usertype", "Show that we can create classes from usertype and use them") {
+ sol::state lua;
+
+ sol::usertype<fuser> lc{ "add", &fuser::add, "add2", &fuser::add2 };
+ lua.set_usertype(lc);
+
+ lua.script("a = fuser:new()\n"
+ "b = a:add(1)\n"
+ "c = a:add2(1)\n");
+
+ sol::object a = lua.get<sol::object>("a");
+ sol::object b = lua.get<sol::object>("b");
+ sol::object c = lua.get<sol::object>("c");
+ REQUIRE((a.is<sol::userdata_value>()));
+ auto atype = a.get_type();
+ auto btype = b.get_type();
+ auto ctype = c.get_type();
+ REQUIRE((atype == sol::type::userdata));
+ REQUIRE((btype == sol::type::number));
+ REQUIRE((ctype == sol::type::number));
+ int bresult = b.as<int>();
+ int cresult = c.as<int>();
+ REQUIRE(bresult == 1);
+ REQUIRE(cresult == 3);
+}
+
+TEST_CASE("usertype/usertype-constructors", "Show that we can create classes from usertype and use them with multiple constructors") {
+
+ sol::state lua;
+
+ sol::constructors<sol::types<>, sol::types<int>, sol::types<int, int>> con;
+ sol::usertype<crapola::fuser> lc(con, "add", &crapola::fuser::add, "add2", &crapola::fuser::add2);
+ lua.set_usertype(lc);
+
+ lua.script(
+ "a = fuser.new(2)\n"
+ "u = a:add(1)\n"
+ "v = a:add2(1)\n"
+ "b = fuser:new()\n"
+ "w = b:add(1)\n"
+ "x = b:add2(1)\n"
+ "c = fuser.new(2, 3)\n"
+ "y = c:add(1)\n"
+ "z = c:add2(1)\n");
+ sol::object a = lua.get<sol::object>("a");
+ auto atype = a.get_type();
+ REQUIRE((atype == sol::type::userdata));
+ sol::object u = lua.get<sol::object>("u");
+ sol::object v = lua.get<sol::object>("v");
+ REQUIRE((u.as<int>() == 3));
+ REQUIRE((v.as<int>() == 5));
+
+ sol::object b = lua.get<sol::object>("b");
+ auto btype = b.get_type();
+ REQUIRE((btype == sol::type::userdata));
+ sol::object w = lua.get<sol::object>("w");
+ sol::object x = lua.get<sol::object>("x");
+ REQUIRE((w.as<int>() == 1));
+ REQUIRE((x.as<int>() == 3));
+
+ sol::object c = lua.get<sol::object>("c");
+ auto ctype = c.get_type();
+ REQUIRE((ctype == sol::type::userdata));
+ sol::object y = lua.get<sol::object>("y");
+ sol::object z = lua.get<sol::object>("z");
+ REQUIRE((y.as<int>() == 7));
+ REQUIRE((z.as<int>() == 9));
+}
+
+TEST_CASE("usertype/usertype-utility", "Show internal management of classes registered through new_usertype") {
+ sol::state lua;
+
+ lua.new_usertype<fuser>("fuser", "add", &fuser::add, "add2", &fuser::add2);
+
+ lua.script("a = fuser.new()\n"
+ "b = a:add(1)\n"
+ "c = a:add2(1)\n");
+
+ sol::object a = lua.get<sol::object>("a");
+ sol::object b = lua.get<sol::object>("b");
+ sol::object c = lua.get<sol::object>("c");
+ REQUIRE((a.is<sol::userdata_value>()));
+ auto atype = a.get_type();
+ auto btype = b.get_type();
+ auto ctype = c.get_type();
+ REQUIRE((atype == sol::type::userdata));
+ REQUIRE((btype == sol::type::number));
+ REQUIRE((ctype == sol::type::number));
+ int bresult = b.as<int>();
+ int cresult = c.as<int>();
+ REQUIRE(bresult == 1);
+ REQUIRE(cresult == 3);
+}
+
+TEST_CASE("usertype/usertype-utility-derived", "usertype classes must play nice when a derived class does not overload a publically visible base function") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ sol::constructors<sol::types<int>> basector;
+ sol::usertype<Base> baseusertype(basector, "get_num", &Base::get_num);
+
+ lua.set_usertype(baseusertype);
+
+ lua.script("base = Base.new(5)");
+ REQUIRE_NOTHROW(lua.script("print(base:get_num())"));
+
+ sol::constructors<sol::types<int>> derivedctor;
+ sol::usertype<Derived> derivedusertype(derivedctor,
+ "get_num_10", &Derived::get_num_10,
+ "get_num", &Derived::get_num
+ );
+
+ lua.set_usertype(derivedusertype);
+
+ lua.script("derived = Derived.new(7)");
+ lua.script("dgn = derived:get_num()\n"
+ "print(dgn)");
+ lua.script("dgn10 = derived:get_num_10()\n"
+ "print(dgn10)");
+
+ REQUIRE((lua.get<int>("dgn10") == 70));
+ REQUIRE((lua.get<int>("dgn") == 7));
+}
+
+TEST_CASE("usertype/self-referential usertype", "usertype classes must play nice when C++ object types are requested for C++ code") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype<self_test>("test", "g", &self_test::g, "f", &self_test::f);
+
+ lua.script(
+ "local a = test.new()\n"
+ "a:g(\"woof\")\n"
+ "a:f(a)\n"
+ );
+}
+
+TEST_CASE("usertype/issue-number-twenty-five", "Using pointers and references from C++ classes in Lua") {
+ struct test {
+ int x = 0;
+ test& set() {
+ x = 10;
+ return *this;
+ }
+
+ int get() {
+ return x;
+ }
+
+ test* pget() {
+ return this;
+ }
+
+ test create_get() {
+ return *this;
+ }
+
+ int fun(int xa) {
+ return xa * 10;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.new_usertype<test>("test", "set", &test::set, "get", &test::get, "pointer_get", &test::pget, "fun", &test::fun, "create_get", &test::create_get);
+ REQUIRE_NOTHROW(lua.script("x = test.new()"));
+ REQUIRE_NOTHROW(lua.script("assert(x:set():get() == 10)"));
+ REQUIRE_NOTHROW(lua.script("y = x:pointer_get()"));
+ REQUIRE_NOTHROW(lua.script("y:set():get()"));
+ REQUIRE_NOTHROW(lua.script("y:fun(10)"));
+ REQUIRE_NOTHROW(lua.script("x:fun(10)"));
+ REQUIRE_NOTHROW(lua.script("assert(y:fun(10) == x:fun(10), '...')"));
+ REQUIRE_NOTHROW(lua.script("assert(y:fun(10) == 100, '...')"));
+ REQUIRE_NOTHROW(lua.script("assert(y:set():get() == y:set():get(), '...')"));
+ REQUIRE_NOTHROW(lua.script("assert(y:set():get() == 10, '...')"));
+}
+
+TEST_CASE("usertype/issue-number-thirty-five", "using value types created from lua-called C++ code, fixing user-defined types with constructors") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ sol::constructors<sol::types<float, float, float>> ctor;
+ sol::usertype<Vec> udata(ctor, "normalized", &Vec::normalized, "length", &Vec::length);
+ lua.set_usertype(udata);
+
+ REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
+ "print(v:length())"));
+ REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
+ "print(v:normalized():length())"));
+}
+
+TEST_CASE("usertype/lua-stored-usertype", "ensure usertype values can be stored without keeping usertype object alive") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ {
+ sol::constructors<sol::types<float, float, float>> ctor;
+ sol::usertype<Vec> udata(ctor,
+ "normalized", &Vec::normalized,
+ "length", &Vec::length);
+
+ lua.set_usertype(udata);
+ // usertype dies, but still usable in lua!
+ }
+
+ REQUIRE_NOTHROW(lua.script("collectgarbage()\n"
+ "v = Vec.new(1, 2, 3)\n"
+ "print(v:length())"));
+
+ REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
+ "print(v:normalized():length())"));
+}
+
+TEST_CASE("usertype/member-variables", "allow table-like accessors to behave as member variables for usertype") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ sol::constructors<sol::types<float, float, float>> ctor;
+ sol::usertype<Vec> udata(ctor,
+ "x", &Vec::x,
+ "y", &Vec::y,
+ "z", &Vec::z,
+ "normalized", &Vec::normalized,
+ "length", &Vec::length);
+ lua.set_usertype(udata);
+
+ REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
+ "v2 = Vec.new(0, 1, 0)\n"
+ "print(v:length())\n"
+ ));
+ REQUIRE_NOTHROW(lua.script("v.x = 2\n"
+ "v2.y = 2\n"
+ "print(v.x, v.y, v.z)\n"
+ "print(v2.x, v2.y, v2.z)\n"
+ ));
+ REQUIRE_NOTHROW(lua.script("assert(v.x == 2)\n"
+ "assert(v2.x == 0)\n"
+ "assert(v2.y == 2)\n"
+ ));
+ REQUIRE_NOTHROW(lua.script("v.x = 3\n"
+ "local x = v.x\n"
+ "assert(x == 3)\n"
+ ));
+
+ struct breaks {
+ sol::function f;
+ };
+
+ lua.open_libraries(sol::lib::base);
+ lua.set("b", breaks());
+ lua.new_usertype<breaks>("breaks",
+ "f", &breaks::f
+ );
+
+ breaks& b = lua["b"];
+ REQUIRE_NOTHROW(lua.script("b.f = function () print('BARK!') end"));
+ REQUIRE_NOTHROW(lua.script("b.f()"));
+ REQUIRE_NOTHROW(b.f());
+}
+
+TEST_CASE("usertype/nonmember-functions", "let users set non-member functions that take unqualified T as first parameter to usertype") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype<giver>("giver",
+ "gief_stuff", giver::gief_stuff,
+ "gief", &giver::gief,
+ "__tostring", [](const giver& t) {
+ return std::to_string(t.a) + ": giving value";
+ }
+ ).get<sol::table>("giver")
+ .set_function("stuff", giver::stuff);
+
+ REQUIRE_NOTHROW(lua.script("giver.stuff()"));
+ REQUIRE_NOTHROW(lua.script("t = giver.new()\n"
+ "print(tostring(t))\n"
+ "t:gief()\n"
+ "t:gief_stuff(20)\n"));
+ giver& g = lua.get<giver>("t");
+ REQUIRE(g.a == 20);
+}
+
+TEST_CASE("usertype/unique-shared-ptr", "manage the conversion and use of unique and shared pointers ('unique usertypes')") {
+ const int64_t unique_value = 0x7125679355635963;
+ auto uniqueint = std::make_unique<int64_t>(unique_value);
+ auto sharedint = std::make_shared<int64_t>(unique_value);
+ long preusecount = sharedint.use_count();
+ { sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.set("uniqueint", std::move(uniqueint));
+ lua.set("sharedint", sharedint);
+ std::unique_ptr<int64_t>& uniqueintref = lua["uniqueint"];
+ std::shared_ptr<int64_t>& sharedintref = lua["sharedint"];
+ int64_t* rawuniqueintref = lua["uniqueint"];
+ int64_t* rawsharedintref = lua["sharedint"];
+ int siusecount = sharedintref.use_count();
+ REQUIRE((uniqueintref.get() == rawuniqueintref && sharedintref.get() == rawsharedintref));
+ REQUIRE((uniqueintref != nullptr && sharedintref != nullptr && rawuniqueintref != nullptr && rawsharedintref != nullptr));
+ REQUIRE((unique_value == *uniqueintref.get() && unique_value == *sharedintref.get()));
+ REQUIRE((unique_value == *rawuniqueintref && unique_value == *rawsharedintref));
+ REQUIRE(siusecount == sharedint.use_count());
+ std::shared_ptr<int64_t> moreref = sharedint;
+ REQUIRE(unique_value == *moreref.get());
+ REQUIRE(moreref.use_count() == sharedint.use_count());
+ REQUIRE(moreref.use_count() == sharedintref.use_count());
+ }
+ REQUIRE(preusecount == sharedint.use_count());
+}
+
+TEST_CASE("regressions/one", "issue number 48") {
+ sol::state lua;
+ lua.new_usertype<vars>("vars",
+ "boop", &vars::boop);
+ REQUIRE_NOTHROW(lua.script("beep = vars.new()\n"
+ "beep.boop = 1"));
+ // test for segfault
+ auto my_var = lua.get<vars>("beep");
+ REQUIRE(my_var.boop == 1);
+ auto* ptr = &my_var;
+ REQUIRE(ptr->boop == 1);
+}
+
+TEST_CASE("usertype/get-set-references", "properly get and set with std::ref semantics. Note that to get, we must not use Unqualified<T> on the type...") {
+ sol::state lua;
+
+ lua.new_usertype<vars>("vars",
+ "boop", &vars::boop);
+ vars var{};
+ vars rvar{};
+ lua.set("beep", var);
+ lua.set("rbeep", std::ref(rvar));
+ auto& my_var = lua.get<vars>("beep");
+ auto& ref_var = lua.get<std::reference_wrapper<vars>>("rbeep");
+ vars& proxy_my_var = lua["beep"];
+ std::reference_wrapper<vars> proxy_ref_var = lua["rbeep"];
+ var.boop = 2;
+ rvar.boop = 5;
+
+ // Was return as a value: var must be diferent from "beep"
+ REQUIRE_FALSE(std::addressof(var) == std::addressof(my_var));
+ REQUIRE_FALSE(std::addressof(proxy_my_var) == std::addressof(var));
+ REQUIRE((my_var.boop == 0));
+ REQUIRE(var.boop != my_var.boop);
+
+ REQUIRE(std::addressof(ref_var) == std::addressof(rvar));
+ REQUIRE(std::addressof(proxy_ref_var.get()) == std::addressof(rvar));
+ REQUIRE(rvar.boop == 5);
+ REQUIRE(rvar.boop == ref_var.boop);
+}
+
+TEST_CASE("usertype/destructor-tests", "Show that proper copies / destruction happens") {
+ static int created = 0;
+ static int destroyed = 0;
+ static void* last_call = nullptr;
+ struct x {
+ x() { ++created; }
+ x(const x&) { ++created; }
+ x(x&&) { ++created; }
+ x& operator=(const x&) { return *this; }
+ x& operator=(x&&) { return *this; }
+ ~x() { ++destroyed; }
+ };
+ {
+ sol::state lua;
+ lua.new_usertype<x>("x");
+ x x1;
+ x x2;
+ lua.set("x1copy", x1, "x2copy", x2, "x1ref", std::ref(x1));
+ x& x1copyref = lua["x1copy"];
+ x& x2copyref = lua["x2copy"];
+ x& x1ref = lua["x1ref"];
+ REQUIRE(created == 4);
+ REQUIRE(destroyed == 0);
+ REQUIRE(std::addressof(x1) == std::addressof(x1ref));
+ REQUIRE(std::addressof(x1copyref) != std::addressof(x1));
+ REQUIRE(std::addressof(x2copyref) != std::addressof(x2));
+ }
+ REQUIRE(created == 4);
+ REQUIRE(destroyed == 4);
+}
+
+TEST_CASE("usertype/private-constructible", "Check to make sure special snowflake types from Enterprise thingamahjongs work properly.") {
+ int numsaved = factory_test::num_saved;
+ int numkilled = factory_test::num_killed;
+ {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype<factory_test>("factory_test",
+ "new", sol::initializers(factory_test::save),
+ "__gc", sol::destructor(factory_test::kill),
+ "a", &factory_test::a
+ );
+
+ std::unique_ptr<factory_test, factory_test::deleter> f = factory_test::make();
+ lua.set("true_a", factory_test::true_a, "f", f.get());
+ REQUIRE_NOTHROW(lua.script("assert(f.a == true_a)"));
+
+ REQUIRE_NOTHROW(lua.script(
+ "local fresh_f = factory_test:new()\n"
+ "assert(fresh_f.a == true_a)\n"));
+ }
+ int expectednumsaved = numsaved + 1;
+ int expectednumkilled = numkilled + 1;
+ REQUIRE(expectednumsaved == factory_test::num_saved);
+ REQUIRE(expectednumkilled == factory_test::num_killed);
+}
+
+TEST_CASE("usertype/const-pointer", "Make sure const pointers can be taken") {
+ struct A { int x = 201; };
+ struct B {
+ int foo(const A* a) { return a->x; };
+ };
+
+ sol::state lua;
+ lua.new_usertype<B>("B",
+ "foo", &B::foo
+ );
+ lua.set("a", A());
+ lua.set("b", B());
+ lua.script("x = b:foo(a)");
+ int x = lua["x"];
+ REQUIRE(x == 201);
+}
+
+TEST_CASE("usertype/overloading", "Check if overloading works properly for usertypes") {
+ struct woof {
+ int var;
+
+ int func(int x) {
+ return var + x;
+ }
+
+ double func2(int x, int y) {
+ return var + x + y + 0.5;
+ }
+
+ std::string func2s(int x, std::string y) {
+ return y + " " + std::to_string(x);
+ }
+ };
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype<woof>("woof",
+ "var", &woof::var,
+ "func", sol::overload(&woof::func, &woof::func2, &woof::func2s)
+ );
+
+ const std::string bark_58 = "bark 58";
+
+ REQUIRE_NOTHROW(lua.script(
+ "r = woof:new()\n"
+ "a = r:func(1)\n"
+ "b = r:func(1, 2)\n"
+ "c = r:func(58, 'bark')\n"
+ ));
+ REQUIRE((lua["a"] == 1));
+ REQUIRE((lua["b"] == 3.5));
+ REQUIRE((lua["c"] == bark_58));
+
+ REQUIRE_THROWS(lua.script("r:func(1,2,'meow')"));
+}
+
+TEST_CASE("usertype/overloading_values", "ensure overloads handle properly") {
+ struct overloading_test {
+ int print(int i) { INFO("Integer print: " << i); return 500 + i; }
+ int print() { INFO("No param print."); return 500; }
+ };
+
+ sol::state lua;
+ lua.new_usertype<overloading_test>("overloading_test", sol::constructors<>(),
+ "print", sol::overload(static_cast<int (overloading_test::*)(int)>(&overloading_test::print), static_cast<int (overloading_test::*)()>(&overloading_test::print)),
+ "print2", sol::overload(static_cast<int (overloading_test::*)()>(&overloading_test::print), static_cast<int (overloading_test::*)(int)>(&overloading_test::print))
+ );
+ lua.set("test", overloading_test());
+
+ sol::function f0_0 = lua.load("return test:print()");
+ sol::function f0_1 = lua.load("return test:print2()");
+ sol::function f1_0 = lua.load("return test:print(24)");
+ sol::function f1_1 = lua.load("return test:print2(24)");
+ int res = f0_0();
+ int res2 = f0_1();
+ int res3 = f1_0();
+ int res4 = f1_1();
+
+ REQUIRE(res == 500);
+ REQUIRE(res2 == 500);
+
+ REQUIRE(res3 == 524);
+ REQUIRE(res4 == 524);
+}
+
+TEST_CASE("usertype/reference-and-constness", "Make sure constness compiles properly and errors out at runtime") {
+ struct bark {
+ int var = 50;
+ };
+ struct woof {
+ bark b;
+ };
+
+ struct nested {
+ const int f = 25;
+ };
+
+ struct outer {
+ nested n;
+ };
+
+ sol::state lua;
+ lua.new_usertype<woof>("woof",
+ "b", &woof::b);
+ lua.new_usertype<bark>("bark",
+ "var", &bark::var);
+ lua.new_usertype<outer>("outer",
+ "n", &outer::n);
+ lua.set("w", woof());
+ lua.set("n", nested());
+ lua.set("o", outer());
+ lua.set("f", sol::c_call<decltype(&nested::f), &nested::f>);
+ lua.script(R"(
+ x = w.b
+ x.var = 20
+ val = w.b.var == x.var
+ v = f(n);
+ )");
+
+ woof& w = lua["w"];
+ bark& x = lua["x"];
+ nested& n = lua["n"];
+ int v = lua["v"];
+ bool val = lua["val"];
+ // enforce reference semantics
+ REQUIRE(std::addressof(w.b) == std::addressof(x));
+ REQUIRE(n.f == 25);
+ REQUIRE(v == 25);
+ REQUIRE(val);
+
+ REQUIRE_THROWS(lua.script("f(n, 50)"));
+ REQUIRE_THROWS(lua.script("o.n = 25"));
+}
+
+TEST_CASE("usertype/readonly-and-static-functions", "Check if static functions can be called on userdata and from their originating (meta)tables") {
+ struct bark {
+ int var = 50;
+
+ void func() {}
+
+ static void oh_boy() {}
+
+ static int oh_boy(std::string name) {
+ return static_cast<int>(name.length());
+ }
+
+ int operator()(int x) {
+ return x;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.new_usertype<bark>("bark",
+ "var", &bark::var,
+ "var2", sol::readonly(&bark::var),
+ "something", something,
+ "something2", [](int x, int y) { return x + y; },
+ "func", &bark::func,
+ "oh_boy", sol::overload(sol::resolve<void()>(&bark::oh_boy), sol::resolve<int(std::string)>(&bark::oh_boy)),
+ sol::meta_function::call_function, &bark::operator()
+ );
+
+ REQUIRE_NOTHROW(lua.script("assert(bark.oh_boy('woo') == 3)"));
+ REQUIRE_NOTHROW(lua.script("bark.oh_boy()"));
+
+ bark b;
+ lua.set("b", &b);
+
+ sol::table b_table = lua["b"];
+ sol::function member_func = b_table["func"];
+ sol::function s = b_table["something"];
+ sol::function s2 = b_table["something2"];
+
+ sol::table b_metatable = b_table[sol::metatable_key];
+ bool isvalidmt = b_metatable.valid();
+ REQUIRE(isvalidmt);
+ sol::function b_call = b_metatable["__call"];
+ sol::function b_as_function = lua["b"];
+
+ int x = b_as_function(1);
+ int y = b_call(b, 1);
+ bool z = s();
+ int w = s2(2, 3);
+ REQUIRE(x == 1);
+ REQUIRE(y == 1);
+ REQUIRE(z);
+ REQUIRE(w == 5);
+
+ lua.script(R"(
+lx = b(1)
+ly = getmetatable(b).__call(b, 1)
+lz = b.something()
+lz2 = bark.something()
+lw = b.something2(2, 3)
+lw2 = bark.something2(2, 3)
+ )");
+
+ int lx = lua["lx"];
+ int ly = lua["ly"];
+ bool lz = lua["lz"];
+ int lw = lua["lw"];
+ bool lz2 = lua["lz2"];
+ int lw2 = lua["lw2"];
+ REQUIRE(lx == 1);
+ REQUIRE(ly == 1);
+ REQUIRE(lz);
+ REQUIRE(lz2);
+ REQUIRE(lw == 5);
+ REQUIRE(lw2 == 5);
+ REQUIRE(lx == ly);
+ REQUIRE(lz == lz2);
+ REQUIRE(lw == lw2);
+
+ REQUIRE_THROWS(lua.script("b.var2 = 2"));
+}
+
+TEST_CASE("usertype/properties", "Check if member properties/variables work") {
+ struct bark {
+ int var = 50;
+ int var2 = 25;
+
+ int get_var2() const {
+ return var2;
+ }
+
+ int get_var3() {
+ return var2;
+ }
+
+ void set_var2(int x) {
+ var2 = x;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.new_usertype<bark>("bark",
+ "var", &bark::var,
+ "var2", sol::readonly(&bark::var2),
+ "a", sol::property(&bark::get_var2, &bark::set_var2),
+ "b", sol::property(&bark::get_var2),
+ "c", sol::property(&bark::get_var3),
+ "d", sol::property(&bark::set_var2)
+ );
+
+ bark b;
+ lua.set("b", &b);
+
+ lua.script("b.a = 59");
+ lua.script("var2_0 = b.a");
+ lua.script("var2_1 = b.b");
+ lua.script("b.d = 1568");
+ lua.script("var2_2 = b.c");
+
+ int var2_0 = lua["var2_0"];
+ int var2_1 = lua["var2_1"];
+ int var2_2 = lua["var2_2"];
+ REQUIRE(var2_0 == 59);
+ REQUIRE(var2_1 == 59);
+ REQUIRE(var2_2 == 1568);
+
+ REQUIRE_THROWS(lua.script("b.var2 = 24"));
+ REQUIRE_THROWS(lua.script("r = b.d"));
+ REQUIRE_THROWS(lua.script("r = b.d"));
+ REQUIRE_THROWS(lua.script("b.b = 25"));
+ REQUIRE_THROWS(lua.script("b.c = 11"));
+}
+
+TEST_CASE("usertype/safety", "crash with an exception -- not a segfault -- on bad userdata calls") {
+ class Test {
+ public:
+ void sayHello() { std::cout << "Hey\n"; }
+ };
+
+ sol::state lua;
+ lua.new_usertype<Test>("Test", "sayHello", &Test::sayHello);
+ static const std::string code = R"(
+ local t = Test.new()
+ t:sayHello() --Works fine
+ t.sayHello() --Uh oh.
+ )";
+ REQUIRE_THROWS(lua.script(code));
+}
+
+TEST_CASE("usertype/call_constructor", "make sure lua types can be constructed with function call constructors") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype<thing>("thing",
+ "v", &thing::v
+ , sol::call_constructor, sol::constructors<sol::types<>, sol::types<int>>()
+ );
+
+ lua.script(R"(
+t = thing(256)
+)");
+
+ thing& y = lua["t"];
+ INFO(y.v);
+ REQUIRE(y.v == 256);
+}
+
+TEST_CASE("usertype/call_constructor_2", "prevent metatable regression") {
+ class class01 {
+ public:
+ int x = 57;
+ class01() {}
+ };
+
+ class class02 {
+ public:
+ int x = 50;
+ class02() {}
+ class02(const class01& other) : x(other.x) {}
+ };
+
+ sol::state lua;
+
+ lua.new_usertype<class01>("class01",
+ sol::call_constructor, sol::constructors<sol::types<>, sol::types<const class01&>>()
+ );
+
+ lua.new_usertype<class02>("class02",
+ sol::call_constructor, sol::constructors<sol::types<>, sol::types<const class02&>, sol::types<const class01&>>()
+ );
+
+ REQUIRE_NOTHROW(lua.script(R"(
+x = class01()
+y = class02(x)
+)"));
+ class02& y = lua["y"];
+ REQUIRE(y.x == 57);
+}
+
+TEST_CASE("usertype/blank_constructor", "make sure lua types cannot be constructed if a blank / empty constructor is provided") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype<thing>("thing",
+ "v", &thing::v
+ , sol::call_constructor, sol::constructors<>()
+ );
+
+ REQUIRE_THROWS(lua.script("t = thing(256)"));
+}
+
+
+TEST_CASE("usertype/no_constructor", "make sure lua types cannot be constructed if a blank / empty constructor is provided") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ SECTION("order1")
+ {
+ lua.new_usertype<thing>("thing",
+ "v", &thing::v
+ , sol::call_constructor, sol::no_constructor
+ );
+ REQUIRE_THROWS(lua.script("t = thing.new()"));
+ }
+
+ SECTION("order2")
+ {
+ lua.new_usertype<thing>("thing"
+ , sol::call_constructor, sol::no_constructor
+ , "v", &thing::v
+ );
+ REQUIRE_THROWS(lua.script("t = thing.new()"));
+ }
+
+ REQUIRE_THROWS(lua.script("t = thing.new()"));
+}
+
+TEST_CASE("usertype/coverage", "try all the things") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype<ext_getset>("ext_getset",
+ sol::call_constructor, sol::constructors<sol::types<>, sol::types<int>>(),
+ sol::meta_function::garbage_collect, sol::destructor(des<ext_getset>),
+ "x", sol::overload(&ext_getset::x, &ext_getset::x2, [](ext_getset& m, std::string x, int y) {
+ return m.meow + 50 + y + x.length();
+ }),
+ "bark", &ext_getset::bark,
+ "meow", &ext_getset::meow,
+ "readonlybark", sol::readonly(&ext_getset::bark),
+ "set", &ext_getset::set,
+ "get", &ext_getset::get,
+ "sset", &ext_getset::s_set,
+ "sget", &ext_getset::s_get,
+ "propbark", sol::property(&ext_getset::set, &ext_getset::get),
+ "readonlypropbark", sol::property(&ext_getset::get),
+ "writeonlypropbark", sol::property(&ext_getset::set)
+ );
+
+ INFO("usertype created");
+
+ lua.script(R"(
+e = ext_getset()
+w = e:x(e:x(), e:x(e:x()))
+print(w)
+)");
+
+ int w = lua["w"];
+ REQUIRE(w == (56 + 50 + 14 + 14));
+
+ INFO("REQUIRE(w) successful");
+
+ lua.script(R"(
+e:set(500)
+e.sset(24)
+x = e:get()
+y = e.sget(20)
+)");
+
+ int x = lua["x"];
+ int y = lua["y"];
+ REQUIRE(x == 500);
+ REQUIRE(y == 40);
+
+ INFO("REQUIRE(x, y) successful");
+
+ lua.script(R"(
+e.bark = 5001
+a = e:get()
+print(e.bark)
+print(a)
+
+e.propbark = 9700
+b = e:get()
+print(e.propbark)
+print(b)
+)");
+ int a = lua["a"];
+ int b = lua["b"];
+
+ REQUIRE(a == 5001);
+ REQUIRE(b == 9700);
+
+ INFO("REQUIRE(a, b) successful");
+
+ lua.script(R"(
+c = e.readonlybark
+d = e.meow
+print(e.readonlybark)
+print(c)
+print(e.meow)
+print(d)
+)");
+
+ int c = lua["c"];
+ int d = lua["d"];
+ REQUIRE(c == 9700);
+ REQUIRE(d == 56);
+
+ INFO("REQUIRE(c, d) successful");
+
+ lua.script(R"(
+e.writeonlypropbark = 500
+z = e.readonlypropbark
+print(e.readonlybark)
+print(e.bark)
+)");
+
+ int z = lua["z"];
+ REQUIRE(z == 500);
+
+ INFO("REQUIRE(z) successful");
+
+ REQUIRE_THROWS(lua.script("e.readonlybark = 24"));
+ INFO("REQUIRE_THROWS 1 successful");
+ REQUIRE_THROWS(lua.script("e.readonlypropbark = 500"));
+ INFO("REQUIRE_THROWS 2 successful");
+ REQUIRE_THROWS(lua.script("y = e.writeonlypropbark"));
+ INFO("REQUIRE_THROWS 3 successful");
+
+}
+
+TEST_CASE("usertype/copyability", "make sure user can write to a class variable even if the class itself isn't copy-safe") {
+ struct NoCopy {
+ int get() const { return _you_can_copy_me; }
+ void set(int val) { _you_can_copy_me = val; }
+
+ int _you_can_copy_me;
+ std::mutex _haha_you_cant_copy_me;
+ };
+
+ sol::state lua;
+ lua.new_usertype<NoCopy>("NoCopy", "val", sol::property(&NoCopy::get, &NoCopy::set));
+
+ REQUIRE_NOTHROW(
+ lua.script(R"__(
+nocopy = NoCopy.new()
+nocopy.val = 5
+ )__")
+ );
+}
+
+TEST_CASE("usertype/protect", "users should be allowed to manually protect a function") {
+ struct protect_me {
+ int gen(int x) {
+ return x;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.new_usertype<protect_me>("protect_me",
+ "gen", sol::protect( &protect_me::gen )
+ );
+
+ REQUIRE_NOTHROW(
+ lua.script(R"__(
+pm = protect_me.new()
+value = pcall(pm.gen,pm)
+)__");
+ );
+ bool value = lua["value"];
+ REQUIRE_FALSE(value);
+}
+
+TEST_CASE("usertype/shared-ptr-regression", "usertype metatables should not screw over unique usertype metatables") {
+ static int created = 0;
+ static int destroyed = 0;
+ struct test {
+ test() {
+ ++created;
+ }
+
+ ~test() {
+ ++destroyed;
+ }
+ };
+ {
+ std::list<std::shared_ptr<test>> tests;
+ sol::state lua;
+ lua.open_libraries();
+
+ lua.new_usertype<test>("test",
+ "create", [&]() -> std::shared_ptr<test> {
+ tests.push_back(std::make_shared<test>());
+ return tests.back();
+ }
+ );
+ REQUIRE(created == 0);
+ REQUIRE(destroyed == 0);
+ lua.script("x = test.create()");
+ REQUIRE(created == 1);
+ REQUIRE(destroyed == 0);
+ REQUIRE_FALSE(tests.empty());
+ std::shared_ptr<test>& x = lua["x"];
+ std::size_t xuse = x.use_count();
+ std::size_t tuse = tests.back().use_count();
+ REQUIRE(xuse == tuse);
+ }
+ REQUIRE(created == 1);
+ REQUIRE(destroyed == 1);
+}
+
+TEST_CASE("usertype/double-deleter-guards", "usertype metatables internally must not rely on internal ") {
+ struct c_a { int x; };
+ struct c_b { int y; };
+ REQUIRE_NOTHROW( {
+ sol::state lua;
+ lua.new_usertype<c_a>("c_a", "x", &c_a::x);
+ lua.new_usertype<c_b>("c_b", "y", &c_b::y);
+ lua = sol::state();
+ lua.new_usertype<c_a>("c_a", "x", &c_a::x);
+ lua.new_usertype<c_b>("c_b", "y", &c_b::y);
+ lua = sol::state();
+ });
+}
+
+TEST_CASE("usertype/vars", "usertype vars can bind various class items") {
+ static int muh_variable = 25;
+ static int through_variable = 10;
+
+ sol::state lua;
+ lua.open_libraries();
+ struct test {};
+ lua.new_usertype<test>("test",
+ "straight", sol::var(2),
+ "global", sol::var(muh_variable),
+ "ref_global", sol::var(std::ref(muh_variable)),
+ "global2", sol::var(through_variable),
+ "ref_global2", sol::var(std::ref(through_variable))
+ );
+
+ int prets = lua["test"]["straight"];
+ int pretg = lua["test"]["global"];
+ int pretrg = lua["test"]["ref_global"];
+ int pretg2 = lua["test"]["global2"];
+ int pretrg2 = lua["test"]["ref_global2"];
+
+ REQUIRE(prets == 2);
+ REQUIRE(pretg == 25);
+ REQUIRE(pretrg == 25);
+ REQUIRE(pretg2 == 10);
+ REQUIRE(pretrg2 == 10);
+
+ lua.script(R"(
+print(test.straight)
+test.straight = 50
+print(test.straight)
+)");
+ int s = lua["test"]["straight"];
+ REQUIRE(s == 50);
+
+ lua.script(R"(
+t = test.new()
+print(t.global)
+t.global = 50
+print(t.global)
+)");
+ int mv = lua["test"]["global"];
+ REQUIRE(mv == 50);
+ REQUIRE(muh_variable == 25);
+
+
+ lua.script(R"(
+print(t.ref_global)
+t.ref_global = 50
+print(t.ref_global)
+)");
+ int rmv = lua["test"]["ref_global"];
+ REQUIRE(rmv == 50);
+ REQUIRE(muh_variable == 50);
+
+ REQUIRE(through_variable == 10);
+ lua.script(R"(
+print(test.global2)
+test.global2 = 35
+print(test.global2)
+)");
+ int tv = lua["test"]["global2"];
+ REQUIRE(through_variable == 10);
+ REQUIRE(tv == 35);
+
+ lua.script(R"(
+print(test.ref_global2)
+test.ref_global2 = 35
+print(test.ref_global2)
+)");
+ int rtv = lua["test"]["ref_global2"];
+ REQUIRE(rtv == 35);
+ REQUIRE(through_variable == 35);
+}
+
+TEST_CASE("usertypes/var-and-property", "make sure const vars are readonly and properties can handle lambdas") {
+ const static int arf = 20;
+
+ struct test {
+ int value = 10;
+ };
+
+ sol::state lua;
+ lua.open_libraries();
+
+ lua.new_usertype<test>("test",
+ "prop", sol::property(
+ [](test& t) {
+ return t.value;
+ },
+ [](test& t, int x) {
+ t.value = x;
+ }
+ ),
+ "global", sol::var(std::ref(arf))
+ );
+
+ lua.script(R"(
+t = test.new()
+print(t.prop)
+t.prop = 50
+print(t.prop)
+ )");
+
+ test& t = lua["t"];
+ REQUIRE(t.value == 50);
+
+
+ REQUIRE_THROWS(
+ lua.script(R"(
+t = test.new()
+print(t.global)
+t.global = 20
+print(t.global)
+ )"));
+}
+
+TEST_CASE("usertype/unique_usertype-check", "make sure unique usertypes don't get pushed as references with function calls and the like") {
+ class Entity {
+ public:
+ std::string GetName() {
+ return "Charmander";
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string, sol::lib::io);
+
+ lua.new_usertype<Entity>("Entity",
+ "new", sol::no_constructor,
+ "get_name", &Entity::GetName
+ );
+
+ lua.script(R"(
+ function my_func(entity)
+ print("INSIDE LUA")
+ print(entity:get_name())
+ end
+)");
+
+ sol::function my_func = lua["my_func"];
+ REQUIRE_NOTHROW({
+ auto ent = std::make_shared<Entity>();
+ my_func(ent);
+ Entity ent2;
+ my_func(ent2);
+ my_func(std::make_shared<Entity>());
+ });
+}
+
+TEST_CASE("usertype/abstract-base-class", "Ensure that abstract base classes and such can be registered") {
+ sol::state lua;
+ lua.new_usertype<abstract_A>("A", "a", &abstract_A::a);
+ lua.new_usertype<abstract_B>("B", sol::base_classes, sol::bases<abstract_A>());
+ lua.script(R"(local b = B.new()
+b:a()
+)");
+}
+
+TEST_CASE("usertype/as_function", "Ensure that variables can be turned into functions by as_function") {
+ class B {
+ public:
+ int bvar = 24;
+ };
+
+ sol::state lua;
+ lua.open_libraries();
+ lua.new_usertype<B>("B", "b", &B::bvar, "f", sol::as_function(&B::bvar));
+
+ B b;
+ lua.set("b", &b);
+ lua.script("x = b:f()");
+ lua.script("y = b.b");
+ int x = lua["x"];
+ int y = lua["y"];
+ REQUIRE(x == 24);
+ REQUIRE(y == 24);
+}
+
+TEST_CASE("usertype/destruction-test", "make sure usertypes are properly destructed and don't double-delete memory or segfault") {
+ sol::state lua;
+
+ class CrashClass {
+ public:
+ CrashClass() {
+ }
+
+ ~CrashClass() {
+ a = 10; // This will cause a crash.
+ }
+
+ private:
+ int a;
+ };
+
+ lua.new_usertype<CrashClass>("CrashClass",
+ sol::call_constructor, sol::constructors<sol::types<>>()
+ );
+
+ lua.script(R"(
+ function testCrash()
+ local x = CrashClass()
+ end
+ )");
+
+ for (int i = 0; i < 1000; ++i) {
+ lua["testCrash"]();
+ }
+}
diff --git a/3rdparty/sol2/tests.cpp b/3rdparty/sol2/tests.cpp
new file mode 100644
index 00000000000..9aeaf255a34
--- /dev/null
+++ b/3rdparty/sol2/tests.cpp
@@ -0,0 +1,680 @@
+#define CATCH_CONFIG_MAIN
+#define SOL_CHECK_ARGUMENTS
+
+#include <catch.hpp>
+#include <sol.hpp>
+
+#include <fstream>
+#include <iostream>
+#include <map>
+#include <unordered_map>
+#include <vector>
+
+#include "test_stack_guard.hpp"
+
+bool func_opt_ret_bool(sol::optional<int> i) {
+ if (i)
+ {
+ INFO(i.value());
+ }
+ else
+ {
+ INFO("optional isn't set");
+ }
+ return true;
+}
+
+TEST_CASE("table/traversal", "ensure that we can chain requests and tunnel down into a value if we desire") {
+
+ sol::state lua;
+ int begintop = 0, endtop = 0;
+
+ sol::function scriptload = lua.load("t1 = {t2 = {t3 = 24}};");
+ scriptload();
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ int traversex24 = lua.traverse_get<int>("t1", "t2", "t3");
+ REQUIRE(traversex24 == 24);
+ } REQUIRE(begintop == endtop);
+
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ int x24 = lua["t1"]["t2"]["t3"];
+ REQUIRE(x24 == 24);
+ } REQUIRE(begintop == endtop);
+
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ lua["t1"]["t2"]["t3"] = 64;
+ int traversex64 = lua.traverse_get<int>("t1", "t2", "t3");
+ REQUIRE(traversex64 == 64);
+ } REQUIRE(begintop == endtop);
+
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ int x64 = lua["t1"]["t2"]["t3"];
+ REQUIRE(x64 == 64);
+ } REQUIRE(begintop == endtop);
+
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ lua.traverse_set("t1", "t2", "t3", 13);
+ int traversex13 = lua.traverse_get<int>("t1", "t2", "t3");
+ REQUIRE(traversex13 == 13);
+ } REQUIRE(begintop == endtop);
+
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ int x13 = lua["t1"]["t2"]["t3"];
+ REQUIRE(x13 == 13);
+ } REQUIRE(begintop == endtop);
+}
+
+TEST_CASE("simple/set", "Check if the set works properly.") {
+ sol::state lua;
+ int begintop = 0, endtop = 0;
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ lua.set("a", 9);
+ } REQUIRE(begintop == endtop);
+ REQUIRE_NOTHROW(lua.script("if a ~= 9 then error('wrong value') end"));
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ lua.set("d", "hello");
+ } REQUIRE(begintop == endtop);
+ REQUIRE_NOTHROW(lua.script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
+
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ lua.set("e", std::string("hello"), "f", true);
+ } REQUIRE(begintop == endtop);
+ REQUIRE_NOTHROW(lua.script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
+ REQUIRE_NOTHROW(lua.script("if f ~= true then error('wrong value') end"));
+}
+
+TEST_CASE("simple/get", "Tests if the get function works properly.") {
+ sol::state lua;
+ int begintop = 0, endtop = 0;
+
+ lua.script("a = 9");
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ auto a = lua.get<int>("a");
+ REQUIRE(a == 9.0);
+ } REQUIRE(begintop == endtop);
+
+ lua.script("b = nil");
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ REQUIRE_NOTHROW(lua.get<sol::nil_t>("b"));
+ } REQUIRE(begintop == endtop);
+
+ lua.script("d = 'hello'");
+ lua.script("e = true");
+ {
+ test_stack_guard g(lua.lua_state(), begintop, endtop);
+ std::string d;
+ bool e;
+ std::tie(d, e) = lua.get<std::string, bool>("d", "e");
+ REQUIRE(d == "hello");
+ REQUIRE(e == true);
+ } REQUIRE(begintop == endtop);
+}
+
+TEST_CASE("simple/set-get-global-integer", "Tests if the get function works properly with global integers") {
+ sol::state lua;
+ lua[1] = 25.4;
+ lua.script("b = 1");
+ double a = lua.get<double>(1);
+ double b = lua.get<double>("b");
+ REQUIRE(a == 25.4);
+ REQUIRE(b == 1);
+}
+
+TEST_CASE("simple/get_or", "check if table.get_or works correctly") {
+ sol::state lua;
+
+ auto bob_table = lua.create_table("bob");
+ bob_table.set("is_set", 42);
+
+ int is_set = bob_table.get_or("is_set", 3);
+ int is_not_set = bob_table.get_or("is_not_set", 22);
+
+ REQUIRE(is_set == 42);
+ REQUIRE(is_not_set == 22);
+
+ lua["joe"] = 55.6;
+ double bark = lua.get_or<double>("joe", 60);
+ REQUIRE(bark == 55.6);
+}
+
+TEST_CASE("simple/proxy_get_or", "check if proxy.get_or works correctly") {
+ sol::state lua;
+
+ auto bob_table = lua.create_table("bob");
+ bob_table.set("is_set", 42);
+
+ int is_set = bob_table["is_set"].get_or(3);
+ int is_not_set = bob_table["is_not_set"].get_or(22);
+
+ REQUIRE(is_set == 42);
+ REQUIRE(is_not_set == 22);
+
+ lua["joe"] = 55.6;
+ double bark = lua["joe"].get_or<double>(60);
+ REQUIRE(bark == 55.6);
+}
+
+TEST_CASE("simple/addition", "check if addition works and can be gotten through lua.get and lua.set") {
+ sol::state lua;
+
+ lua.set("b", 0.2);
+ lua.script("c = 9 + b");
+ auto c = lua.get<double>("c");
+
+ REQUIRE(c == 9.2);
+}
+
+TEST_CASE("simple/if", "check if if statements work through lua") {
+ sol::state lua;
+
+ std::string program = "if true then f = 0.1 else f = 'test' end";
+ lua.script(program);
+ auto f = lua.get<double>("f");
+
+ REQUIRE(f == 0.1);
+ REQUIRE((f == lua["f"]));
+}
+
+TEST_CASE("negative/basic_errors", "Check if error handling works correctly") {
+ sol::state lua;
+
+ REQUIRE_THROWS(lua.script("nil[5]"));
+}
+
+TEST_CASE("libraries", "Check if we can open libraries") {
+ sol::state lua;
+ REQUIRE_NOTHROW(lua.open_libraries(sol::lib::base, sol::lib::os));
+}
+
+TEST_CASE("libraries2", "Check if we can open ALL the libraries") {
+ sol::state lua;
+ REQUIRE_NOTHROW(lua.open_libraries(sol::lib::base,
+ sol::lib::bit32,
+ sol::lib::coroutine,
+ sol::lib::debug,
+ sol::lib::ffi,
+ sol::lib::jit,
+ sol::lib::math,
+ sol::lib::os,
+ sol::lib::package,
+ sol::lib::string,
+ sol::lib::table));
+}
+
+TEST_CASE("interop/null-to-nil-and-back", "nil should be the given type when a pointer from C++ is returned as nullptr, and nil should result in nullptr in connected C++ code") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.set_function("lol", []() -> int* {
+ return nullptr;
+ });
+ lua.set_function("rofl", [](int* x) {
+ INFO(x);
+ });
+ REQUIRE_NOTHROW(lua.script("x = lol()\n"
+ "rofl(x)\n"
+ "assert(x == nil)"));
+}
+
+TEST_CASE("utilities/this_state", "Ensure this_state argument can be gotten anywhere in the function.") {
+ struct bark {
+ int with_state(sol::this_state l, int a, int b) {
+ lua_State* L = l;
+ int c = lua_gettop(L);
+ return a + b + (c - c);
+ }
+
+ static int with_state_2(int a, sol::this_state l, int b) {
+ INFO("inside with_state_2");
+ lua_State* L = l;
+ INFO("L is" << (void*)L);
+ int c = lua_gettop(L);
+ return a * b + (c - c);
+ }
+ };
+
+ sol::state lua;
+ INFO("created lua state");
+ lua.open_libraries(sol::lib::base);
+ lua.new_usertype<bark>("bark",
+ "with_state", &bark::with_state
+ );
+
+ INFO("setting b and with_state_2");
+ bark b;
+ lua.set("b", &b);
+ lua.set("with_state_2", bark::with_state_2);
+ INFO("finished setting");
+ INFO("getting fx");
+ sol::function fx = lua["with_state_2"];
+ INFO("calling fx");
+ int a = fx(25, 25);
+ INFO("finished setting fx");
+ INFO("calling a script");
+ lua.script("a = with_state_2(25, 25)");
+ INFO("calling c script");
+ lua.script("c = b:with_state(25, 25)");
+ INFO("getting a");
+ int la = lua["a"];
+ INFO("getting b");
+ int lc = lua["c"];
+
+ REQUIRE(lc == 50);
+ REQUIRE(a == 625);
+ REQUIRE(la == 625);
+}
+
+TEST_CASE("object/conversions", "make sure all basic reference types can be made into objects") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ struct d {};
+
+ lua.script("function f () print('bark') end");
+ lua["d"] = d{};
+ lua["l"] = static_cast<void*>(nullptr);
+
+ sol::table t = lua.create_table();
+ sol::thread th = sol::thread::create(lua);
+ sol::function f = lua["f"];
+ sol::protected_function pf = lua["f"];
+ sol::userdata ud = lua["d"];
+ sol::lightuserdata lud = lua["l"];
+
+ sol::object ot(t);
+ sol::object ot2 = ot;
+ sol::object oth(th);
+ sol::object of(f);
+ sol::object opf(pf);
+ sol::object od(ud);
+ sol::object ol(lud);
+
+ auto oni = sol::make_object(lua, 50);
+ auto ond = sol::make_object(lua, 50.0);
+
+ std::string somestring = "look at this text isn't it nice";
+ auto osl = sol::make_object(lua, "Bark bark bark");
+ auto os = sol::make_object(lua, somestring);
+
+ auto omn = sol::make_object(lua, sol::nil);
+
+ REQUIRE(ot.get_type() == sol::type::table);
+ REQUIRE(ot2.get_type() == sol::type::table);
+ REQUIRE(oth.get_type() == sol::type::thread);
+ REQUIRE(of.get_type() == sol::type::function);
+ REQUIRE(opf.get_type() == sol::type::function);
+ REQUIRE(od.get_type() == sol::type::userdata);
+ REQUIRE(ol.get_type() == sol::type::lightuserdata);
+ REQUIRE(oni.get_type() == sol::type::number);
+ REQUIRE(ond.get_type() == sol::type::number);
+ REQUIRE(osl.get_type() == sol::type::string);
+ REQUIRE(os.get_type() == sol::type::string);
+ REQUIRE(omn.get_type() == sol::type::nil);
+}
+
+TEST_CASE("state/require_file", "opening files as 'requires'") {
+ static const char FILE_NAME[] = "./tmp_thingy.lua";
+
+ std::fstream file(FILE_NAME, std::ios::out);
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ SECTION("with usertypes")
+ {
+ struct foo {
+ foo(int bar) : bar(bar) {}
+
+ const int bar;
+ };
+
+ lua.new_usertype<foo>("foo",
+ sol::constructors<sol::types<int>>{},
+ "bar", &foo::bar
+ );
+
+ file << "return { modfunc = function () return foo.new(221) end }" << std::endl;
+ file.close();
+
+ const sol::table thingy1 = lua.require_file("thingy", FILE_NAME);
+
+ CHECK(thingy1.valid());
+
+ const foo foo_v = thingy1["modfunc"]();
+
+ int val1 = foo_v.bar;
+
+ CHECK(val1 == 221);
+ }
+
+ SECTION("simple")
+ {
+ file << "return { modfunc = function () return 221 end }" << std::endl;
+ file.close();
+
+ const sol::table thingy1 = lua.require_file("thingy", FILE_NAME);
+ const sol::table thingy2 = lua.require_file("thingy", FILE_NAME);
+
+ CHECK(thingy1.valid());
+ CHECK(thingy2.valid());
+
+ int val1 = thingy1["modfunc"]();
+ int val2 = thingy2["modfunc"]();
+
+ CHECK(val1 == 221);
+ CHECK(val2 == 221);
+ // must have loaded the same table
+ CHECK(thingy1 == thingy2);
+ }
+
+ std::remove(FILE_NAME);
+}
+
+TEST_CASE("state/require_script", "opening strings as 'requires' clauses") {
+ std::string code = "return { modfunc = function () return 221 end }";
+
+ sol::state lua;
+ sol::table thingy1 = lua.require_script("thingy", code);
+ sol::table thingy2 = lua.require_script("thingy", code);
+
+ int val1 = thingy1["modfunc"]();
+ int val2 = thingy2["modfunc"]();
+ REQUIRE(val1 == 221);
+ REQUIRE(val2 == 221);
+ // must have loaded the same table
+ REQUIRE(thingy1 == thingy2);
+}
+
+TEST_CASE("state/require", "opening using a file") {
+ struct open {
+ static int open_func(lua_State* L) {
+ sol::state_view lua = L;
+ return sol::stack::push(L, lua.create_table_with("modfunc", sol::as_function([]() { return 221; })));
+ }
+ };
+
+ sol::state lua;
+ sol::table thingy1 = lua.require("thingy", open::open_func);
+ sol::table thingy2 = lua.require("thingy", open::open_func);
+
+ int val1 = thingy1["modfunc"]();
+ int val2 = thingy2["modfunc"]();
+ REQUIRE(val1 == 221);
+ REQUIRE(val2 == 221);
+ // THIS IS ONLY REQUIRED IN LUA 5.3, FOR SOME REASON
+ // must have loaded the same table
+ // REQUIRE(thingy1 == thingy2);
+}
+
+TEST_CASE("state/multi-require", "make sure that requires transfers across hand-rolled script implementation and standard requiref") {
+ struct open {
+ static int open_func(lua_State* L) {
+ sol::state_view lua = L;
+ return sol::stack::push(L, lua.create_table_with("modfunc", sol::as_function([]() { return 221; })));
+ }
+ };
+
+ std::string code = "return { modfunc = function () return 221 end }";
+ sol::state lua;
+ sol::table thingy1 = lua.require("thingy", open::open_func);
+ sol::table thingy2 = lua.require("thingy", open::open_func);
+ sol::table thingy3 = lua.require_script("thingy", code);
+
+ int val1 = thingy1["modfunc"]();
+ int val2 = thingy2["modfunc"]();
+ int val3 = thingy3["modfunc"]();
+ REQUIRE(val1 == 221);
+ REQUIRE(val2 == 221);
+ REQUIRE(val3 == 221);
+ // must have loaded the same table
+ // Lua is not obliged to give a shit. Thanks, Lua
+ //REQUIRE(thingy1 == thingy2);
+ // But we care, thankfully
+ //REQUIRE(thingy1 == thingy3);
+ REQUIRE(thingy2 == thingy3);
+}
+
+TEST_CASE("feature/indexing-overrides", "make sure index functions can be overridden on types") {
+ struct PropertySet {
+ sol::object get_property_lua(const char* name, sol::this_state s)
+ {
+ auto& var = props[name];
+ return sol::make_object(s, var);
+ }
+
+ void set_property_lua(const char* name, sol::stack_object object)
+ {
+ props[name] = object.as<std::string>();
+ }
+
+ std::unordered_map<std::string, std::string> props;
+ };
+
+ struct DynamicObject {
+ PropertySet& get_dynamic_props() {
+ return dynamic_props;
+ }
+
+ PropertySet dynamic_props;
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ lua.new_usertype<PropertySet>("PropertySet"
+ , sol::meta_function::new_index, &PropertySet::set_property_lua
+ , sol::meta_function::index, &PropertySet::get_property_lua
+ );
+ lua.new_usertype<DynamicObject>("DynamicObject"
+ , "props", sol::property(&DynamicObject::get_dynamic_props)
+ );
+
+ lua.script(R"__(
+obj = DynamicObject:new()
+obj.props.name = 'test name'
+print('name = ' .. obj.props.name)
+)__");
+
+ std::string name = lua["obj"]["props"]["name"];
+ REQUIRE(name == "test name");
+}
+
+TEST_CASE("features/indexing-numbers", "make sure indexing functions can be override on usertypes") {
+ class vector {
+ public:
+ double data[3];
+
+ vector() : data{ 0,0,0 } {}
+
+ double& operator[](int i)
+ {
+ return data[i];
+ }
+
+
+ static double my_index(vector& v, int i)
+ {
+ return v[i];
+ }
+
+ static void my_new_index(vector& v, int i, double x)
+ {
+ v[i] = x;
+ }
+ };
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.new_usertype<vector>("vector", sol::constructors<sol::types<>>(),
+ sol::meta_function::index, &vector::my_index,
+ sol::meta_function::new_index, &vector::my_new_index);
+ lua.script("v = vector.new()\n"
+ "print(v[1])\n"
+ "v[2] = 3\n"
+ "print(v[2])\n"
+ );
+
+ vector& v = lua["v"];
+ REQUIRE(v[0] == 0.0);
+ REQUIRE(v[1] == 0.0);
+ REQUIRE(v[2] == 3.0);
+}
+
+TEST_CASE("features/multiple-inheritance", "Ensure that multiple inheritance works as advertised") {
+ struct base1 {
+ int a1 = 250;
+ };
+
+ struct base2 {
+ int a2 = 500;
+ };
+
+ struct simple : base1 {
+
+ };
+
+ struct complex : base1, base2 {
+
+ };
+
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+ lua.new_usertype<base1>("base1",
+ "a1", &base1::a1
+ );
+ lua.new_usertype<base2>("base2",
+ "a2", &base2::a2
+ );
+ lua.new_usertype<simple>("simple",
+ "a1", &simple::a1,
+ sol::base_classes, sol::bases<base1>()
+ );
+ lua.new_usertype<complex>("complex",
+ "a1", &complex::a1,
+ "a2", &complex::a2,
+ sol::base_classes, sol::bases<base1, base2>()
+ );
+ lua.script("c = complex.new()\n"
+ "s = simple.new()\n"
+ "b1 = base1.new()\n"
+ "b2 = base1.new()\n"
+ );
+
+ base1* sb1 = lua["s"];
+ REQUIRE(sb1 != nullptr);
+ REQUIRE(sb1->a1 == 250);
+
+ base1* cb1 = lua["c"];
+ base2* cb2 = lua["c"];
+
+ REQUIRE(cb1 != nullptr);
+ REQUIRE(cb2 != nullptr);
+ REQUIRE(cb1->a1 == 250);
+ REQUIRE(cb2->a2 == 500);
+}
+
+
+TEST_CASE("regressions/std::ref", "Ensure that std::reference_wrapper<> isn't considered as a function by using unwrap_unqualified_t trait") {
+ struct base1 {
+ int a1 = 250;
+ };
+
+ sol::state lua;
+ base1 v;
+ lua["vp"] = &v;
+ lua["vr"] = std::ref(v);
+
+ base1* vp = lua["vp"];
+ base1& vr = lua["vr"];
+ REQUIRE(vp != nullptr);
+ REQUIRE(vp == &v);
+
+ REQUIRE(vp->a1 == 250);
+ REQUIRE(vr.a1 == 250);
+
+ v.a1 = 568;
+
+ REQUIRE(vp->a1 == 568);
+ REQUIRE(vr.a1 == 568);
+}
+
+TEST_CASE("optional/left-out-args", "Make sure arguments can be left out of optional without tanking miserably") {
+
+ sol::state lua;
+ lua.open_libraries(sol::lib::base);
+
+ // sol::optional needs an argument no matter what?
+ lua.set_function("func_opt_ret_bool", func_opt_ret_bool);
+ REQUIRE_NOTHROW(
+ lua.script(R"(
+ func_opt_ret_bool(42)
+ func_opt_ret_bool()
+ print('ok')
+ )");
+ );
+}
+
+TEST_CASE("pusher/constness", "Make sure more types can handle being const and junk") {
+ struct Foo {
+ Foo(const sol::function& f) : _f(f) {}
+ const sol::function& _f;
+
+ const sol::function& f() const { return _f; }
+ };
+
+ sol::state lua;
+
+ lua.new_usertype<Foo>("Foo",
+ sol::call_constructor, sol::no_constructor,
+ "f", &Foo::f
+ );
+
+ lua["func"] = []() { return 20; };
+ sol::function f = lua["func"];
+ lua["foo"] = Foo(f);
+ Foo& foo = lua["foo"];
+ int x = foo.f()();
+ REQUIRE(x == 20);
+}
+
+TEST_CASE("proxy/proper-pushing", "allow proxies to reference other proxies and be serialized as the proxy itself and not a function or something") {
+ sol::state lua;
+ lua.open_libraries(sol::lib::base, sol::lib::io);
+
+ class T {};
+ lua.new_usertype<T>("T");
+
+ T t;
+ lua["t1"] = &t;
+ lua["t2"] = lua["t1"];
+ lua.script("b = t1 == t2");
+ bool b = lua["b"];
+ REQUIRE(b);
+}
+
+TEST_CASE("compilation/const-regression", "make sure constness in tables is respected all the way down") {
+ struct State {
+ public:
+ State() {
+ this->state_.registry()["state"] = this;
+ }
+
+ sol::state state_;
+ };
+
+ State state;
+ State* s = state.state_.registry()["state"];
+ REQUIRE(s == &state);
+}