add additional CMake presentation

Update container documentation
Fix ISSUE_TEMPLATE
Fix up documentation for quick and dirty, pulling example source directly from bundled code
addresses #578
This commit is contained in:
ThePhD 2018-02-08 00:40:34 -05:00
parent 22127fa6fa
commit 88ba80bb61
32 changed files with 373 additions and 432 deletions

View File

@ -1,14 +1,14 @@
The guidelines for reporting a bug are relatively simple and are as follows: Read these guidelines. They are relatively simple and will allow me to help you better:
1. Produce a simple, short, compilable test case that reproduces your problem. 1. Produce a simple, short, compilable test case that reproduces your problem.
2. Make a descriptive title that summarises the bug as a whole. 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. 3. Explain the bug in as much detail as you can in the body of the issue.
4. Include Compiler/IDE, Build and Deployment System, Language (C++, Objective-C++). 4. Include Compiler/IDE (Visual Studio, XCode...), Build and Deployment System, Language (C++, Objective-C++), and any special defines you have set.
If you want to request a feature: If you want to request a feature:
2. Produce any relevant imaginary code that illustrates what you would like or desired behavior. 1. Produce any relevant imaginary code that illustrates what you would like or desired behavior.
1. Include a description and title of what you would like. 2. Include a description and title of what you would like.
3. Annotate and describe the behavior through comments, asserts or just a small write up. 3. Annotate and describe the behavior through comments, asserts or just a small write up.
Thanks for helping sol! Thanks for helping sol grow!

2
.gitignore vendored
View File

@ -114,3 +114,5 @@ desktop.ini
external/ external/
scratch/ scratch/
.idea/ .idea/
cmake-build-debug/
cmake-build-relwithdebinfo/

View File

@ -1,231 +0,0 @@
#!/usr/bin/env python
import ninja_syntax
import os, sys, glob, re
import itertools
import argparse
import urllib.request
# 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()
# prepare paths and files
catch_file = os.path.join('external', 'Catch', 'include', 'catch.hpp')
os.makedirs(os.path.dirname(catch_file), exist_ok=True)
urllib.request.urlretrieve("https://github.com/catchorg/Catch2/releases/download/v2.0.1/catch.hpp", catch_file)
# general variables
include = [ '.', './include' ]
depends = [os.path.join('external', 'Catch', 'include')]
cxxflags = [ '-Wno-unknown-warning', '-Wno-unknown-warning-option', '-Wall', '-Wextra', '-Wpedantic', '-pedantic', '-pedantic-errors', '-Wno-noexcept-type', '-std=c++14', '-ftemplate-depth=1024' ]
cxxflags.extend([p for p in re.split("( |\\\".*?\\\"|'.*?')", args.cxx_flags) if p.strip()])
example_cxxflags = [ '-Wno-unknown-warning', '-Wno-unknown-warning-option', '-Wall', '-Wextra', '-Wpedantic', '-pedantic', '-pedantic-errors', '-Wno-noexcept-type', '-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]:i386', lua_version):
# luajit:i386
lua_incl = 'luajit-2.0'
lua_lib = lua_version[:-7] + '-' + lua_version[-7] + '.' + lua_version[-6]
cxxflags.append('-m32')
include.extend(['/usr/include/luajit-2.0/', '/usr/local/include/luajit-2.0/'])
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:
cxxflags.append('-pthread')
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('tests/test*.cpp'):
obj = object_file(f)
tests_inputs.append(f)
tests_object_files.append(obj)
examples = []
examples_input = []
def add_example (f):
if 'win32' in sys.platform:
example = os.path.join(builddir, replace_extension(f, '.exe'))
example = example.replace('/', '\\');
else:
example = os.path.join(builddir, replace_extension(f, ''))
example = example.replace('\\', '/');
#if ' ' in example:
# example = '"' + example + '"'
examples_input.append(f)
examples.append(example)
for f in glob.glob('examples/*.cpp'):
add_example(f)
for f in glob.glob('examples/tutorials/quick_n_dirty/**.cpp'):
add_example(f)
# 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')

View File

@ -91,6 +91,7 @@ function(find_lua_build LUA_VERSION)
# # Export variables to the parent scope # # Export variables to the parent scope
set(LUA_LIBRARIES ${LUA_LIBRARIES} PARENT_SCOPE) set(LUA_LIBRARIES ${LUA_LIBRARIES} PARENT_SCOPE)
set(LUA_INTERPRETER ${LUA_INTERPRETER} PARENT_SCOPE) set(LUA_INTERPRETER ${LUA_INTERPRETER} PARENT_SCOPE)
set(LUA_INCLUDE_DIRS ${LUA_INCLUDE_DIRS} PARENT_SCOPE)
set(LUA_VERSION_STRING ${LUA_VERSION_STRING} PARENT_SCOPE) set(LUA_VERSION_STRING ${LUA_VERSION_STRING} PARENT_SCOPE)
set(LUABUILD_FOUND TRUE PARENT_SCOPE) set(LUABUILD_FOUND TRUE PARENT_SCOPE)
endfunction(find_lua_build) endfunction(find_lua_build)
@ -116,5 +117,5 @@ unset(find_lua_build)
# all listed variables are TRUE # all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaBuild FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaBuild
FOUND_VAR LUABUILD_FOUND FOUND_VAR LUABUILD_FOUND
REQUIRED_VARS LUA_LIBRARIES LUA_INTERPRETER REQUIRED_VARS LUA_LIBRARIES LUA_INTERPRETER LUA_INCLUDE_DIRS
VERSION_VAR LUA_VERSION_STRING) VERSION_VAR LUA_VERSION_STRING)

View File

@ -366,3 +366,4 @@ set_target_properties(${luainterpreter}
# set externally-visible target indicator # set externally-visible target indicator
set(LUA_LIBRARIES ${lualib}) set(LUA_LIBRARIES ${lualib})
set(LUA_INTERPRETER ${luainterpreter}) set(LUA_INTERPRETER ${luainterpreter})
set(LUA_INCLUDE_DIRS "${LUA_JIT_SOURCE_DIR}")

View File

@ -401,3 +401,4 @@ endif()
set(LUA_LIBRARIES ${liblua}) set(LUA_LIBRARIES ${liblua})
set(LUA_INTERPRETER ${luainterpreter}) set(LUA_INTERPRETER ${luainterpreter})
set(LUA_COMPILER ${luacompiler}) set(LUA_COMPILER ${luacompiler})
set(LUA_INCLUDE_DIRS "${LUA_VANILLA_SOURCE_DIR}")

View File

@ -96,60 +96,62 @@ container operations
Below are the many container operations and their override points for ``container_traits<T>``. Please use these to understand how to use any part of the implementation. Below are the many container operations and their override points for ``container_traits<T>``. Please use these to understand how to use any part of the implementation.
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| operation | lua syntax | container_traits<T> | stack argument order | notes/caveats | | operation | lua syntax | container_traits<T> | stack argument order | notes/caveats |
| | | extension point | | | | | | extension point | | |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| set | ``c:set(key, value)`` | ``static int set(lua_State*);`` | 1 self | - if ``value`` is nil, it performs an erase in default implementation | | set | ``c:set(key, value)`` | ``static int set(lua_State*);`` | 1 self | - if ``value`` is nil, it performs an erase in default implementation |
| | | | 2 key | - if this is a sequence container and it support insertion and ``key``,is an index equal to the size of the container,+ 1, it will insert at,the end of the container (this is a Lua idiom) | | | | | 2 key | - if this is a sequence container and it support insertion and ``key``,is an index equal to the size of the container,+ 1, it will insert at,the end of the container (this is a Lua idiom) |
| | | | 3 value | | | | | | 3 value | |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| index_set | ``c[key] = value`` | ``static int index_set(lua_State*);`` | 1 self | - default implementation calls "set" | | index_set | ``c[key] = value`` | ``static int index_set(lua_State*);`` | 1 self | - default implementation calls "set" |
| | | | 2 key | - if this is a sequence container and it support insertion and ``key`` is an index equal to the size of the container + 1, it will insert at the end of the container (this is a Lua idiom) | | | | | 2 key | - if this is a sequence container and it support insertion and ``key`` is an index equal to the size of the container + 1, it will insert at the end of the container (this is a Lua idiom) |
| | | | 3 value | | | | | | 3 value | |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| get | ``v = c:get(key)`` | ``static int get(lua_State*);`` | 1 self | - can return multiple values | | get | ``v = c:get(key)`` | ``static int get(lua_State*);`` | 1 self | - can return multiple values |
| | | | 2 key | - default implementation increments iterators linearly for non-random-access | | | | | 2 key | - default implementation increments iterators linearly for non-random-access |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| index_get | ``v = c[key]`` | ``static int index_get(lua_State*);`` | 1 self | - can only return 1 value | | index_get | ``v = c[key]`` | ``static int index_get(lua_State*);`` | 1 self | - can only return 1 value |
| | | | 2 key | - default implementation just calls "get" | | | | | 2 key | - default implementation just calls "get" |
| | | | | - if ``key`` is a string and ``key`` is one of the other member functions, it will return that member function rather than perform a lookup / index get | | | | | | - if ``key`` is a string and ``key`` is one of the other member functions, it will return that member function rather than perform a lookup / index get |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| find | ``c:find(target)`` | ``static int find(lua_State*);`` | 1 self | - ``target`` is a value for non-lookup containers (fixed containers, sequence containers, non-associative and non-ordered containers) | | find | ``c:find(target)`` | ``static int find(lua_State*);`` | 1 self | - ``target`` is a value for non-lookup containers (fixed containers, sequence containers, non-associative and non-ordered containers) |
| | | | 2 target | | | | | | 2 target | |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| erase | ``c:erase(target)`` | ``static int erase(lua_State*);`` | 1 self | - for sequence containers, ``target`` is an index to erase | | erase | ``c:erase(target)`` | ``static int erase(lua_State*);`` | 1 self | - for sequence containers, ``target`` is an index to erase |
| | | | 2 target | - for lookup containers, ``target`` is the key type | | | | | 2 target | - for lookup containers, ``target`` is the key type |
| | | | | - uses linear incrementation to spot for sequence containers that do not have random access iterators (``std::list``, ``std::forward_list``, and similar) | | | | | | - uses linear incrementation to spot for sequence containers that do not have random access iterators (``std::list``, ``std::forward_list``, and similar) |
| | | | | - invalidates iteration | | | | | | - invalidates iteration |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| insert | ``c:insert(target, value)`` | | 1 self | - for sequence containers, ``target`` is an index, otherwise it is the key type | | insert | ``c:insert(target, value)`` | | 1 self | - for sequence containers, ``target`` is an index, otherwise it is the key type |
| | | | 2 target | - inserts into a container if possible at the specified location | | | | | 2 target | - inserts into a container if possible at the specified location |
| | | | 3 key | | | | | | 3 key | |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| add | ``c:add(key, value)`` or ``c:add(value)`` | ``static int add(lua_State*);`` | 1 self | - 2nd argument (3rd on stack) is provided for associative containers to add | | add | ``c:add(key, value)`` or ``c:add(value)`` | ``static int add(lua_State*);`` | 1 self | - 2nd argument (3rd on stack) is provided for associative containers to add |
| | | | 2 key/value | - ordered containers will insert into the appropriate spot, not necessarily at the end | | | | | 2 key/value | - ordered containers will insert into the appropriate spot, not necessarily at the end |
| | | | 3 value | | | | | | 3 value | |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| size | ``#c`` | ``static int size(lua_State*);`` | 1 self | - default implementation calls ``.size()`` if present | | size | ``#c`` | ``static int size(lua_State*);`` | 1 self | - default implementation calls ``.size()`` if present |
| | | | | - otherwise, default implementation uses ``std::distance(begin(L, self), end(L, self))`` | | | | | | - otherwise, default implementation uses ``std::distance(begin(L, self), end(L, self))`` |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| clear | ``c:clear()`` | ``static int clear(lua_State*);`` | 1 self | - default implementation provides no fallback if there's no ``clear`` operation | | clear | ``c:clear()`` | ``static int clear(lua_State*);`` | 1 self | - default implementation provides no fallback if there's no ``clear`` operation |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| begin | n/a | ``static int begin(lua_State*, T&);`` | n/a | - called by default implementation | | offset | n/a | ``static int index_adjustment(lua_State*, T&);`` | n/a | - returns an index that adds to the passed-in numeric index for array acces (default implementation is ``return -1`` to simulate 1-based indexing from Lua) |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| end | n/a | ``static int end(lua_State*, T&);`` | n/a | - called by default implementation | | begin | n/a | ``static int begin(lua_State*, T&);`` | n/a | - called by default implementation |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| pairs | | ``static int pairs(lua_State*);`` | 1 self | - implement if advanced user only that understands caveats | | end | n/a | ``static int end(lua_State*, T&);`` | n/a | - called by default implementation |
| | | | | - override begin and end instead and leave this to default implementation if you do not know what ``__pairs`` is for or how to implement it and the ``next`` function | +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| | | | | - works only in Lua 5.2+ | | pairs | | ``static int pairs(lua_State*);`` | 1 self | - implement if advanced user only that understands caveats |
| | | | | - calling ``pairs( c )`` in Lua 5.1 / LuaJIT will crash with assertion failure (Lua expects ``c`` to be a table) | | | | | | - override begin and end instead and leave this to default implementation if you do not know what ``__pairs`` is for or how to implement it and the ``next`` function |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | | | | | - works only in Lua 5.2+ |
| ipairs | | ``static int ipairs(lua_State*);`` | 1 self | - implement if advanced user only that understands caveats | | | | | | - calling ``pairs( c )`` in Lua 5.1 / LuaJIT will crash with assertion failure (Lua expects ``c`` to be a table) |
| | | | | - override begin and end instead and leave this to default implementation if you do not know what ``__ipairs`` is for or how to implement it and the ``next`` function | +-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| | | | | - works only in Lua 5.2, deprecated in Lua 5.3 (but might still be called in compatibiltiy modes) | | ipairs | | ``static int ipairs(lua_State*);`` | 1 self | - implement if advanced user only that understands caveats |
| | | | | - calling ``ipairs( c )`` in Lua 5.1 / LuaJIT will crash with assertion failure (Lua expects ``c`` to be a table) | | | | | | - override begin and end instead and leave this to default implementation if you do not know what ``__ipairs`` is for or how to implement it and the ``next`` function |
+-----------+-------------------------------------------+---------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | | | | | - works only in Lua 5.2, deprecated in Lua 5.3 (but might still be called in compatibiltiy modes) |
| | | | | - calling ``ipairs( c )`` in Lua 5.1 / LuaJIT will crash with assertion failure (Lua expects ``c`` to be a table) |
+-----------+-------------------------------------------+--------------------------------------------------+----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
.. note:: .. note::

View File

@ -20,6 +20,7 @@ The implementation for ``assert.hpp`` with ``c_assert`` looks like so:
.. literalinclude:: ../../../examples/assert.hpp .. literalinclude:: ../../../examples/assert.hpp
:linenos: :linenos:
:lines: 1-8, 19-
This is the assert used in the quick code below. This is the assert used in the quick code below.
@ -212,93 +213,24 @@ Everything that is not a:
Is set as a :doc:`userdata + usertype<../api/usertype>`. Is set as a :doc:`userdata + usertype<../api/usertype>`.
.. code-block:: cpp
struct Doge { .. literalinclude:: ../../../examples/tutorials/quick_n_dirty/userdata.cpp
int tailwag = 50; :linenos:
}; :lines: 1-57
Doge dog{}; ``std::unique_ptr``/``std::shared_ptr``'s reference counts / deleters will :doc:`be respected<../api/unique_usertype_traits>`.
// 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{}; If you want it to refer to something, whose memory you know won't die in C++ while it is used/exists in Lua, do the following:
lua.set("dog", dog2); .. literalinclude:: ../../../examples/tutorials/quick_n_dirty/userdata_memory_reference.cpp
lua.set("dog", std::move(dog2)); :linenos:
lua.set("dog", Doge{}); :lines: 1-45
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: You can retrieve the userdata in the same way as everything else. Importantly, 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:
.. code-block:: cpp .. literalinclude:: ../../../examples/tutorials/quick_n_dirty/userdata_memory_reference.cpp
:linenos:
struct Doge { :lines: 46-
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 C++ classes put into Lua
@ -314,42 +246,9 @@ namespacing
You can emulate namespacing by having a table and giving it the namespace names you want before registering enums or usertypes: You can emulate namespacing by having a table and giving it the namespace names you want before registering enums or usertypes:
.. code-block:: cpp .. literalinclude:: ../../../examples/tutorials/quick_n_dirty/namespacing.cpp
:linenos:
struct my_class { :lines: 1-
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
// can add functions, as well (just like the global table)
bark.set_function("print_my_class", [](my_class& self) { std::cout << "my_class { b: " << self.b << " }" << std::endl; });
// 'bark' namespace
lua.script("obj = bark.my_class.new()" );
lua.script("obj:g()");
// access the function on the 'namespace'
lua.script("bark.print_my_class(obj)");
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. 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.

View File

@ -20,7 +20,7 @@
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # 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. # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# # # # sol2 tests # # # sol2 Examples
file(GLOB EXAMPLES_SRC *.cpp tutorials/quick_n_dirty/*.cpp) file(GLOB EXAMPLES_SRC *.cpp tutorials/quick_n_dirty/*.cpp)
source_group(examples FILES ${EXAMPLES_SRC}) source_group(examples FILES ${EXAMPLES_SRC})
@ -40,7 +40,7 @@ function (MAKE_EXAMPLE example_source_file is_single)
set(example_output_name "${example_output_relative_dir_name}.${example_name}") set(example_output_name "${example_output_relative_dir_name}.${example_name}")
endif() endif()
add_executable(${example_name} ${example_source_file}) add_executable(${example_name} ${example_source_file} assert.hpp)
set_target_properties(${example_name} set_target_properties(${example_name}
PROPERTIES PROPERTIES
OUTPUT_NAME "${example_output_name}") OUTPUT_NAME "${example_output_name}")
@ -62,10 +62,10 @@ function (MAKE_EXAMPLE example_source_file is_single)
if (MSVC) if (MSVC)
else() else()
target_compile_options(${example_name} target_compile_options(${example_name}
PRIVATE -Wno-noexcept-type) PRIVATE -Wno-noexcept-type)
endif() endif()
if (TESTS_EXAMPLES) if (TESTS_EXAMPLES)
if ((NOT is_single) OR (is_single AND TESTS_SINGLE)) if ((NOT is_single) OR (is_single AND TESTS_SINGLE))
add_test(NAME ${example_output_name} COMMAND ${example_name}) add_test(NAME ${example_output_name} COMMAND ${example_name})
@ -74,6 +74,8 @@ function (MAKE_EXAMPLE example_source_file is_single)
install(TARGETS ${example_name} RUNTIME DESTINATION bin) install(TARGETS ${example_name} RUNTIME DESTINATION bin)
endfunction(MAKE_EXAMPLE) endfunction(MAKE_EXAMPLE)
add_subdirectory(require_dll_example)
foreach(example_source_file ${EXAMPLES_SRC}) foreach(example_source_file ${EXAMPLES_SRC})
MAKE_EXAMPLE(${example_source_file} FALSE) MAKE_EXAMPLE(${example_source_file} FALSE)
endforeach() endforeach()

View File

@ -4,6 +4,17 @@
#ifndef NDEBUG #ifndef NDEBUG
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <cstdlib>
#ifdef SOL2_CI
struct pre_main {
pre_main() {
#ifdef _MSC_VER
_set_abort_behavior(0, _WRITE_ABORT_MSG);
#endif
}
} pm;
#endif // Prevent lockup when doing Continuous Integration
# define m_assert(condition, message) \ # define m_assert(condition, message) \
do { \ do { \

View File

@ -0,0 +1,99 @@
# # # # sol2
# The MIT License (MIT)
#
# Copyright (c) 2013-2017 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.
# # # sol2 Examples - require_from_dll
# # Reusable function to call for single target
# # Also hides variables from directory/global scope
function(make_require_from_dll_example target_lib is_single)
# define sources
set(my_object_sources my_object.cpp my_object.hpp my_object_api.hpp assert.hpp)
set(require_from_dll_sources require_from_dll.cpp)
# define names
set(example_lib_name my_object)
set(example_name require_from_dll)
if (is_single)
set(example_lib_name "${example_lib_name}.single")
set(example_name "${example_name}.single")
endif()
# is the lua library a shared or static library?
get_target_property(lua_lib_type ${LUA_LIBRARIES} TYPE)
# add library target my_object for the require_from_dll program
add_library(${example_lib_name} SHARED ${my_object_sources})
set_target_properties(${example_lib_name} PROPERTIES
PREFIX "")
target_include_directories(${example_lib_name} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
target_compile_features(${example_lib_name} PRIVATE ${CXX_FEATURES})
target_compile_definitions(${example_lib_name} PUBLIC MY_OBJECT_DLL PRIVATE MY_OBJECT_BUILD)
if(CMAKE_DL_LIBS)
target_link_libraries(${example_lib_name} PRIVATE ${CMAKE_DL_LIBS})
endif()
if (CI)
target_compile_definitions(${example_lib_name} PRIVATE SOL2_CI)
endif()
if (NOT MSVC)
target_compile_options(${example_lib_name} PRIVATE -Wno-noexcept-type)
if (lua_lib_type MATCHES "STATIC")
# ensure that the whole archive is input into the linker
# this ensure static builds are included properly
target_link_libraries(${example_lib_name} PRIVATE
-Wl,-whole-archive ${LUA_LIBRARIES} -Wl,-no-whole-archive)
else()
target_link_libraries(${example_lib_name} PRIVATE ${LUA_LIBRARIES})
endif()
else()
target_link_libraries(${example_lib_name} PUBLIC ${LUA_LIBRARIES})
endif()
target_link_libraries(${example_lib_name} PRIVATE ${target_lib})
# add executable target that represents require_from_dll program
add_executable(${example_name} ${require_from_dll_sources})
target_compile_features(${example_name} PRIVATE ${CXX_FEATURES})
if(CMAKE_DL_LIBS)
target_link_libraries(${example_name} PRIVATE ${CMAKE_DL_LIBS})
endif()
if (CI)
target_compile_definitions(${example_name} PRIVATE SOL2_CI)
endif()
if (NOT MSVC)
target_compile_options(${example_name} PRIVATE -Wno-noexcept-type)
endif()
target_link_libraries(${example_name} PRIVATE my_object ${target_lib})
# avoid multiply defined references due to linking in the same static library
# twice over, and get "multiple definition" errors during linking
# target_link_libraries(${example_name} PRIVATE ${LUA_LIBRARIES})
target_include_directories(${example_name} PRIVATE ${LUA_INCLUDE_DIRS})
if (TESTS_EXAMPLES)
if ((NOT is_single) OR (is_single AND TESTS_SINGLE))
add_test(NAME ${example_name} COMMAND ${example_name})
endif()
endif()
endfunction()
make_require_from_dll_example(sol2 FALSE)
if (EXAMPLES_SINGLE OR TESTS_SINGLE)
make_require_from_dll_example(sol2_single TRUE)
endif()

View File

@ -0,0 +1,41 @@
#ifndef EXAMPLES_ASSERT_HPP
#define EXAMPLES_ASSERT_HPP
#ifndef NDEBUG
#include <exception>
#include <iostream>
#include <cstdlib>
#ifdef SOL2_CI
struct pre_main {
pre_main() {
#ifdef _MSC_VER
_set_abort_behavior(0, _WRITE_ABORT_MSG);
#endif
}
} pm;
#endif // Prevent lockup when doing Continuous Integration
# define m_assert(condition, message) \
do { \
if (! (condition)) { \
std::cerr << "Assertion `" #condition "` failed in " << __FILE__ \
<< " line " << __LINE__ << ": " << message << std::endl; \
std::terminate(); \
} \
} while (false)
# define c_assert(condition) \
do { \
if (! (condition)) { \
std::cerr << "Assertion `" #condition "` failed in " << __FILE__ \
<< " line " << __LINE__ << std::endl; \
std::terminate(); \
} \
} while (false)
#else
# define m_assert(condition, message) do { if (false) { (void)(condition); (void)sizeof(message); } } while (false)
# define c_assert(condition) do { if (false) { (void)(condition); } } while (false)
#endif
#endif // EXAMPLES_ASSERT_HPP

View File

@ -10,15 +10,22 @@ int main(int, char*[]) {
std::cout << "=== require from DLL example ===" << std::endl; std::cout << "=== require from DLL example ===" << std::endl;
sol::state lua; sol::state lua;
lua.open_libraries(sol::lib::package); lua.open_libraries(sol::lib::package, sol::lib::base);
lua.script_file(R"( const auto& code = R"(
mo = require("my_object") mo = require("my_object")
obj = mo.test.new(24) obj = mo.test.new(24)
print(obj.value) print(obj.value))";
)"); auto script_result = lua.safe_script(code, &sol::script_pass_on_error);
if (script_result.valid()) {
std::cout << "The DLL was require'd from successfully!" << std::endl;
}
else {
sol::error err = script_result;
std::cout << "Something bad happened: " << err.what() << std::endl;
}
c_assert(script_result.valid());
my_object::test& obj = lua["obj"]; my_object::test& obj = lua["obj"];
c_assert(obj.value == 24); c_assert(obj.value == 24);

View File

@ -0,0 +1,41 @@
#ifndef EXAMPLES_ASSERT_HPP
#define EXAMPLES_ASSERT_HPP
#ifndef NDEBUG
#include <exception>
#include <iostream>
#include <cstdlib>
#ifdef SOL2_CI
struct pre_main {
pre_main() {
#ifdef _MSC_VER
_set_abort_behavior(0, _WRITE_ABORT_MSG);
#endif
}
} pm;
#endif // Prevent lockup when doing Continuous Integration
# define m_assert(condition, message) \
do { \
if (! (condition)) { \
std::cerr << "Assertion `" #condition "` failed in " << __FILE__ \
<< " line " << __LINE__ << ": " << message << std::endl; \
std::terminate(); \
} \
} while (false)
# define c_assert(condition) \
do { \
if (! (condition)) { \
std::cerr << "Assertion `" #condition "` failed in " << __FILE__ \
<< " line " << __LINE__ << std::endl; \
std::terminate(); \
} \
} while (false)
#else
# define m_assert(condition, message) do { if (false) { (void)(condition); (void)sizeof(message); } } while (false)
# define c_assert(condition) do { if (false) { (void)(condition); } } while (false)
#endif
#endif // EXAMPLES_ASSERT_HPP

View File

@ -1,7 +1,7 @@
#define SOL_CHECK_ARGUMENTS 1 #define SOL_CHECK_ARGUMENTS 1
#include <sol.hpp> #include <sol.hpp>
#include "../../assert.hpp" #include "assert.hpp"
#include <iostream> #include <iostream>
void some_function() { void some_function() {

View File

@ -1,7 +1,7 @@
#define SOL_CHECK_ARGUMENTS 1 #define SOL_CHECK_ARGUMENTS 1
#include <sol.hpp> #include <sol.hpp>
#include "../../assert.hpp" #include "assert.hpp"
int main(int, char*[]) { int main(int, char*[]) {
sol::state lua; sol::state lua;

View File

@ -1,7 +1,7 @@
#define SOL_CHECK_ARGUMENTS 1 #define SOL_CHECK_ARGUMENTS 1
#include <sol.hpp> #include <sol.hpp>
#include "../../assert.hpp" #include "assert.hpp"
int main(int, char* []) { int main(int, char* []) {
sol::state lua; sol::state lua;

View File

@ -1,7 +1,7 @@
#define SOL_CHECK_ARGUMENTS 1 #define SOL_CHECK_ARGUMENTS 1
#include <sol.hpp> #include <sol.hpp>
#include "../../assert.hpp" #include "assert.hpp"
int main(int, char* []) { int main(int, char* []) {
sol::state lua; sol::state lua;

View File

@ -1,7 +1,7 @@
#define SOL_CHECK_ARGUMENTS 1 #define SOL_CHECK_ARGUMENTS 1
#include <sol.hpp> #include <sol.hpp>
#include "../../assert.hpp" #include "assert.hpp"
int main(int, char* []) { int main(int, char* []) {
sol::state lua; sol::state lua;

View File

@ -2,7 +2,7 @@
#include <sol.hpp> #include <sol.hpp>
#include <iostream> #include <iostream>
#include "../../assert.hpp" #include "assert.hpp"
int main() { int main() {
std::cout << "=== namespacing example ===" << std::endl; std::cout << "=== namespacing example ===" << std::endl;

View File

@ -2,7 +2,7 @@
#include <sol.hpp> #include <sol.hpp>
#include <iostream> #include <iostream>
#include "../../assert.hpp" #include "assert.hpp"
int main(int, char*[]) { int main(int, char*[]) {
std::cout << "=== opening a state example ===" << std::endl; std::cout << "=== opening a state example ===" << std::endl;

View File

@ -3,7 +3,7 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include "../../assert.hpp" #include "assert.hpp"
int main(int, char*[]) { int main(int, char*[]) {
std::cout << "=== running lua code example ===" << std::endl; std::cout << "=== running lua code example ===" << std::endl;

View File

@ -4,7 +4,7 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <cstdio> #include <cstdio>
#include "../../assert.hpp" #include "assert.hpp"
int main(int, char*[]) { int main(int, char*[]) {
std::cout << "=== running lua code (low level) example ===" << std::endl; std::cout << "=== running lua code (low level) example ===" << std::endl;

View File

@ -1,7 +1,7 @@
#define SOL_CHECK_ARGUMENTS 1 #define SOL_CHECK_ARGUMENTS 1
#include <sol.hpp> #include <sol.hpp>
#include "../../assert.hpp" #include "assert.hpp"
int main(int, char*[]) { int main(int, char*[]) {
sol::state lua; sol::state lua;

View File

@ -1,7 +1,7 @@
#define SOL_CHECK_ARGUMENTS 1 #define SOL_CHECK_ARGUMENTS 1
#include <sol.hpp> #include <sol.hpp>
#include "../../assert.hpp" #include "assert.hpp"
int main(int, char*[]) { int main(int, char*[]) {
sol::state lua; sol::state lua;

View File

@ -1,7 +1,7 @@
#define SOL_CHECK_ARGUMENTS 1 #define SOL_CHECK_ARGUMENTS 1
#include <sol.hpp> #include <sol.hpp>
#include "../../assert.hpp" #include "assert.hpp"
int main(int, char*[]) { int main(int, char*[]) {

View File

@ -1,7 +1,7 @@
#define SOL_CHECK_ARGUMENTS 1 #define SOL_CHECK_ARGUMENTS 1
#include <sol.hpp> #include <sol.hpp>
#include "../../assert.hpp" #include "assert.hpp"
#include <iostream> #include <iostream>
struct Doge { struct Doge {

View File

@ -0,0 +1,65 @@
#define SOL_CHECK_ARGUMENTS 1
#include <sol.hpp>
#include "assert.hpp"
#include <iostream>
struct Doge {
int tailwag = 50;
Doge() {
}
Doge(int wags)
: tailwag(wags) {
}
~Doge() {
std::cout << "Dog at " << this << " is being destroyed..." << std::endl;
}
};
int main(int, char* []) {
std::cout << "=== userdata memory reference example ===" << std::endl;
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 ) );
Doge& dog_ref = lua["dog"]; // References Lua memory
Doge* dog_pointer = lua["dog"]; // References Lua memory
Doge dog_copy = lua["dog"]; // Copies, will not affect lua
lua.new_usertype<Doge>("Doge",
"tailwag", &Doge::tailwag
);
dog_copy.tailwag = 525;
// Still 50
lua.script("assert(dog.tailwag == 50)");
dog_ref.tailwag = 100;
// Now 100
lua.script("assert(dog.tailwag == 100)");
dog_pointer->tailwag = 345;
// Now 345
lua.script("assert(dog.tailwag == 345)");
std::cout << std::endl;
return 0;
}

View File

@ -3,9 +3,9 @@
struct pre_main { struct pre_main {
pre_main() { pre_main() {
#ifdef SOL2_CI #ifdef SOL2_CI
#ifdef _MSC_VER #ifdef _MSC_VER
_set_abort_behavior(0, _WRITE_ABORT_MSG); _set_abort_behavior(0, _WRITE_ABORT_MSG);
#endif #endif
#endif #endif
} }
} pm; } pm;