require("import")	-- the import fn
import("li_std_string")	-- import lib

for k,v in pairs(li_std_string) do _G[k]=v end -- move to global

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- helper to check type
function is_std_string(s)
	return type(s)=='userdata' and swig_type(s)=='std::string *'
end

-- std::string by value is just a Lua string
s=test_value("foo")
assert(type(s)=="string" and s=="foo")

-- std::string by const ref is also just a Lua string
s=test_const_reference("foo")
assert(type(s)=="string" and s=="foo")

-- std:string* is an object
obj=test_pointer_out()
assert(is_std_string(obj) and obj:c_str()=="x")	-- check type & value

test_pointer(obj)	-- this wants an object

cobj=test_const_pointer_out()
assert(is_std_string(cobj) and cobj:c_str()=="x")	-- check type & value

test_const_pointer(cobj)

-- this shouldn't work, but it does
-- swig doesn't appear to diff between const object ptrs & object ptrs very well
test_pointer(cobj)	-- this wants an non const object (give it a const one!)

-- refs are also wrappered as ptrs (unless the correct typemaps are applied)
robj=test_reference_out()
assert(is_std_string(robj) and robj:c_str()=="test_reference_out message")	-- check type & value

test_reference(robj)
test_reference(obj)	-- object ptr is ok
test_reference(cobj)	-- obj const ptr is also ok

-- throwing string
ok,ex=pcall(test_throw)
assert(ok==false and type(ex)=="string")	-- failed & threw string

ok,ex=pcall(test_const_reference_throw)
assert(ok==false and type(ex)=="string")	-- failed & threw string

-- const ptrs are now converted to lua strings
-- they used to be std::string*
ok,ex=pcall(test_const_pointer_throw)
assert(ok==false and type(ex)=="string")	-- failed & threw object

-- ditto non const ptrs
ok,ex=pcall(test_pointer_throw)
assert(ok==false and type(ex)=="string")	-- failed & threw object

-- testing std::string variables
-- Global variables
s = "initial string"
assert (li_std_string.GlobalString2 == "global string 2")
li_std_string.GlobalString2 = s
assert (li_std_string.GlobalString2 == s)
assert (li_std_string.ConstGlobalString == "const global string")

-- Member variables
myStructure = Structure()
assert(myStructure.MemberString2 == "member string 2")
myStructure.MemberString2 = s
assert (myStructure.MemberString2 == s)
assert (myStructure.ConstMemberString == "const member string")

assert (li_std_string.Structure_StaticMemberString2 == "static member string 2")
li_std_string.Structure_StaticMemberString2 = s
assert (li_std_string.Structure_StaticMemberString2 == s)
assert (li_std_string.Structure_ConstStaticMemberString == "const static member string")

-- testing the structure (these are some old tests which predated the std::string variable tests above)
struc=Structure()

assert(type(struc.MemberString2)=="string") -- typemaps make this a string
assert(type(struc.ConstMemberString)=="string")

-- set a const (should fail with error)
assert(pcall(function () struc.ConstMemberString="c" end)==false)
--print(struc.MemberString:data(),struc.MemberString2,struc.ConstMemberString:data())

--check type again
assert(type(struc.MemberString2)=="string") -- typemaps make this a string
assert(type(struc.ConstMemberString)=="string")

-- for static types: they are really variables,
-- so we must still use the module name

-- check static type
assert(type(li_std_string.Structure_StaticMemberString2)=="string")
assert(type(li_std_string.Structure_ConstStaticMemberString)=="string")

-- try setting (should fail with error)
--li_std_string.Structure_StaticMemberString2='e'
assert(pcall(function () li_std_string.Structure_ConstStaticMemberString='f' end)==false)
--[[print(li_std_string.Structure_StaticMemberString:data(),
		li_std_string.Structure_StaticMemberString2,
		li_std_string.Structure_ConstStaticMemberString:data())]]

-- check static type again
assert(type(li_std_string.Structure_StaticMemberString)=="string")
assert(type(li_std_string.Structure_StaticMemberString2)=="string")
assert(type(li_std_string.Structure_ConstStaticMemberString)=="string")


require("import")	-- the import fn
import("smart_pointer_simple")	-- import lib into global
sps=smart_pointer_simple --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo1 = sps.Foo()
foo1.x = 5
assert(foo1.x == 5)
assert(foo1:getx() == 5)

bar1 = sps.Bar(foo1)
bar1.x = 3
assert(bar1.x == 3)
assert(bar1:getx() == 3)

bar1.x = 5
assert(bar1.x == 5)
assert(bar1:getx() == 5)


require("import")	-- the import fn
import("cpp11_strongly_typed_enumerations")	-- import lib

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

function enumCheck(actual, expected)
  if not (actual == expected) then
    error("Enum value mismatch. Expected: "..expected.." Actual: "..actual)
  end
  return expected + 1
end

--val = 0
--val = enumCheck(cpp11_strongly_typed_enumerations.cpp11_strongly_typed_enumerations.Enum1_Val1, val)
local val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Enum1_Val1, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum1_Val2, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum1_Val3, 13)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum1_Val4, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum1_Val5a, 13)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum1_Val6a, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Enum2_Val1, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum2_Val2, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum2_Val3, 23)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum2_Val4, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum2_Val5b, 23)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum2_Val6b, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Val1, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Val2, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Val3, 43)
val = enumCheck(cpp11_strongly_typed_enumerations.Val4, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Enum5_Val1, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum5_Val2, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum5_Val3, 53)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum5_Val4, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Enum6_Val1, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum6_Val2, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum6_Val3, 63)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum6_Val4, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Enum7td_Val1, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum7td_Val2, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum7td_Val3, 73)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum7td_Val4, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Enum8_Val1, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum8_Val2, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum8_Val3, 83)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum8_Val4, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Enum10_Val1, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum10_Val2, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum10_Val3, 103)
val = enumCheck(cpp11_strongly_typed_enumerations.Enum10_Val4, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum12_Val1, 1121)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum12_Val2, 1122)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum12_Val3, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum12_Val4, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum12_Val5c, 1121)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum12_Val6c, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Val1, 1131)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Val2, 1132)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Val3, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Val4, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Val5d, 1131)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Val6d, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum14_Val1, 1141)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum14_Val2, 1142)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum14_Val3, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum14_Val4, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum14_Val5e, 1141)
val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Enum14_Val6e, val)

-- Requires nested class support to work
--val = 0
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum12_Val1, 3121)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum12_Val2, 3122)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum12_Val3, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum12_Val4, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum12_Val5f, 3121)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum12_Val6f, val)
--
--val = 0
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Val1, 3131)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Val2, 3132)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Val3, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Val4, val)
--
--val = 0
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum14_Val1, 3141)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum14_Val2, 3142)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum14_Val3, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum14_Val4, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum14_Val5g, 3141)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum14_Val6g, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum12_Val1, 2121)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum12_Val2, 2122)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum12_Val3, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum12_Val4, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum12_Val5h, 2121)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum12_Val6h, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Val1, 2131)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Val2, 2132)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Val3, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Val4, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Val5i, 2131)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Val6i, val)

val = 0
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum14_Val1, 2141)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum14_Val2, 2142)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum14_Val3, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum14_Val4, val)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum14_Val5j, 2141)
val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Enum14_Val6j, val)

-- Requires nested class support to work
--val = 0
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum12_Val1, 4121)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum12_Val2, 4122)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum12_Val3, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum12_Val4, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum12_Val5k, 4121)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum12_Val6k, val)
--
--val = 0
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Val1, 4131)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Val2, 4132)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Val3, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Val4, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Val5l, 4131)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Val6l, val)
--
--val = 0
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum14_Val1, 4141)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum14_Val2, 4142)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum14_Val3, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum14_Val4, val)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum14_Val5m, 4141)
--val = enumCheck(cpp11_strongly_typed_enumerations.Class2.Struct1.Enum14_Val6m, val)

class1 = cpp11_strongly_typed_enumerations.Class1()
enumCheck(class1:class1Test1(cpp11_strongly_typed_enumerations.Enum1_Val5a), 13)
enumCheck(class1:class1Test2(cpp11_strongly_typed_enumerations.Class1.Enum12_Val5c), 1121)
--enumCheck(class1:class1Test3(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum12_Val5f), 3121)

enumCheck(cpp11_strongly_typed_enumerations.globalTest1(cpp11_strongly_typed_enumerations.Enum1_Val5a), 13)
enumCheck(cpp11_strongly_typed_enumerations.globalTest2(cpp11_strongly_typed_enumerations.Class1.Enum12_Val5c), 1121)
--enumCheck(globalTest3(cpp11_strongly_typed_enumerations.Class1.Struct1.Enum12_Val5f), 3121)


require("import")	-- the import fn
import("newobject2",true)	-- import code

foo1 = newobject2.makeFoo()	-- lua doesn't yet support static fns properly
assert(newobject2.fooCount() == 1)	-- lua doesn't yet support static fns properly

foo2 = newobject2.makeFoo()
assert(newobject2.fooCount() == 2)

foo1 = nil
collectgarbage()
assert(newobject2.fooCount() == 1)

foo2 = nil
collectgarbage()
assert(newobject2.fooCount() == 0)


require("import")	-- the import fn
import("enum_template")	-- import lib
et=enum_template

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(et.eTest0 ~= nil)
assert(et.eTest1 ~= nil)

et.TakeETest(et.eTest0)

res = et.MakeETest()
et.TakeETest(res)


require("import")	-- the import fn
import("extend_variable")	-- import lib into global
ev=extend_variable --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

e1 = ev.ExtendMe()
answ = 1.0
assert(e1:set(7.0))
--assert(e1:get(answ)) -- doesn't work. Lua can't pass primitive type by non-const reference
--assert(answ == 7.0)

e1.ExtendVar = 5.0
assert(e1.ExtendVar == 5.0)

assert(ev.Foo.Bar == 42)
assert(ev.Foo.AllBarOne == 4422)

assert(ev.Foo.StaticInt == 1111)
ev.Foo.StaticInt = 3333
assert(ev.Foo.StaticInt == 3333)

assert(ev.Foo.StaticConstInt == 2222)

b1 = ev.Bar()
assert(b1.x == 1)


require("import")	-- the import fn
import("disown")	-- import code

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

for x=0,100 do
    a=disown.A()
    b=disown.B()
    b:acquire(a)
end
collectgarbage() -- this will double delete unless the memory is managed properly

a=disown.A()
a:__disown()
b:remove(a)
a=nil
collectgarbage() -- this will double delete unless the manual disown call worked


require("import")	-- the import fn
import("import_nomodule")	-- import code

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

f = import_nomodule.create_Foo()
import_nomodule.test1(f,42)
import_nomodule.delete_Foo(f)

b = import_nomodule.Bar()
import_nomodule.test1(b,37)

collectgarbage()


require("import")	-- the import fn
import("lua_inherit_getitem")	-- import lib

local t = lua_inherit_getitem;
local base = t.CBase()
local derived = t.CDerived()

assert(base.Foo ~= nil)
assert(base:Foo() == "CBase::Foo")
assert(derived.Foo == base.Foo)
assert(derived:Foo() == "CBase::Foo")


require("import")	-- the import fn
import("overload_null")	-- import lib into global

o = overload_null.Overload()
x = overload_null.X()

assert(1 == o:byval1(x))
assert(2 == o:byval1(nil))

assert(3 == o:byval2(nil))
assert(4 == o:byval2(x))

assert(5 == o:byref1(x))
assert(6 == o:byref1(nil))

assert(7 == o:byref2(nil))
assert(8 == o:byref2(x))

assert(9 == o:byconstref1(x))
assert(10 == o:byconstref1(nil))

assert(11 == o:byconstref2(nil))
assert(12 == o:byconstref2(x))

-- const pointer references
assert(13 == o:byval1cpr(x))
assert(14 == o:byval1cpr(nil))

assert(15 == o:byval2cpr(nil))
assert(16 == o:byval2cpr(x))

-- forward class declaration
assert(17 == o:byval1forwardptr(x))
assert(18 == o:byval1forwardptr(nil))

assert(19 == o:byval2forwardptr(nil))
assert(20 == o:byval2forwardptr(x))

assert(21 == o:byval1forwardref(x))

assert(22 == o:byval2forwardref(x))


require("import")	-- the import fn
import("enum_scope_template")	-- import lib
est=enum_scope_template

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(est.TreeInt.Oak ~= nil)
assert(est.TreeInt_Oak ~= nil)
assert(est.TreeInt.Cedar ~= nil)


require("import")	-- the import fn
import("abstract_access")	-- import code

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- trying to instantiate pure virtual classes
-- should fail
assert(pcall(abstract_access.A)==false)
assert(pcall(abstract_access.B)==false)
assert(pcall(abstract_access.C)==false)

-- instantiate object
d=abstract_access.D()

--call fn
assert(d:do_x()==1)


-- demo of lua swig capacities (operator overloading)
require("import")	-- the import fn
import("operator_overload")	-- import lib

for k,v in pairs(operator_overload) do _G[k]=v end -- move to global

-- first check all the operators are implemented correctly from pure C++ code
Op_sanity_check()

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- test routine:
a=Op()
b=Op(5)
c=Op(b) -- copy construct
d=Op(2)
dd=d; -- assignment operator

-- test equality
assert(a~=b)
assert(b==c)
assert(a~=d)
assert(d==dd)

-- test <
assert(a<b)
assert(a<=b)
assert(b<=c)
assert(b>=c)
assert(b>d)
assert(b>=d)

-- lua does not support += operators: skipping

-- test +
f=Op(1)
g=Op(1)
assert(f+g==Op(2))
assert(f-g==Op(0))
assert(f*g==Op(1))
assert(f/g==Op(1))
--assert(f%g==Op(0))	-- lua does not support %

-- test unary operators
--assert((not a)==true) -- lua does not allow overloading for not operator
--assert((not b)==false) -- lua does not allow overloading for not operator

--lua 5.0.2 defines that unary - is __unm(self,nil)
--lua 5.1.2 defines that unary - is __unm(self,self)
--C++ expects unary - as operator-()
--however the latest version of SWIG strictly checks the number of args
--and will complain if too many args are provided
--therefore disabling these tests for now
-- (solution will to be not to check args for this test case)
assert(-a==a)
assert(-b==Op(-5))

-- test []
h=Op(3)
assert(h[0]==3)
assert(h[1]==0)
h[0]=2	-- set
assert(h[0]==2)
h[1]=2	-- ignored
assert(h[0]==2)
assert(h[1]==0)

-- test ()
i=Op(3)
assert(i()==3)
assert(i(1)==4)
assert(i(1,2)==6)

-- plus add some code to check the __str__ fn
assert(tostring(Op(1))=="Op(1)")
assert(tostring(Op(-3))=="Op(-3)")

-- check that operator overloads are correctly propagated down inheritance hierarchy

a_d=OpDerived()
b_d=OpDerived(5)
c_d=OpDerived(5)
d_d=OpDerived(2)
-- test equality
assert(a_d~=b_d)
assert(b_d==c_d)
assert(a_d~=d_d)

-- test <
assert(a_d<b_d)
assert(a_d<=b_d)
assert(b_d<=c_d)
assert(b_d>=c_d)
assert(b_d>d_d)
assert(b_d>=d_d)
--
-- test + inheritance
f_d=OpDerived(1)
g_d=OpDerived(1)
assert(f_d+g_d==Op(2))
assert(f_d-g_d==Op(0))
assert(f_d*g_d==Op(1))
assert(f_d/g_d==Op(1))
--
-- plus add some code to check the __str__ fn inheritance
assert(tostring(OpDerived(1))=="Op(1)")
assert(tostring(OpDerived(-3))=="Op(-3)")

--[[
/* Sample test code in C++

#include <assert.h>
#include <stdio.h>

int main(int argc,char** argv)
{
	// test routine:
	Op a;
	Op b=5;
	Op c=b;	// copy construct
	Op d=2;

	// test equality
	assert(a!=b);
	assert(b==c);
	assert(a!=d);

	// test <
	assert(a<b);
	assert(a<=b);
	assert(b<=c);
	assert(b>=c);
	assert(b>d);
	assert(b>=d);

	// test +=
	Op e=3;
	e+=d;
	assert(e==b);
	e-=c;
	assert(e==a);
	e=Op(1);
	e*=b;
	assert(e==c);
	e/=d;
	assert(e==d);
	e%=c;
	assert(e==d);

	// test +
	Op f(1),g(1);
	assert(f+g==Op(2));
	assert(f-g==Op(0));
	assert(f*g==Op(1));
	assert(f/g==Op(1));
	assert(f%g==Op(0));

	// test unary operators
	assert(!a==true);
	assert(!b==false);
	assert(-a==a);
	assert(-b==Op(-5));

	// test []
	Op h=3;
	assert(h[0]==3);
	assert(h[1]==0);
	h[0]=2;	// set
	assert(h[0]==2);
	h[1]=2;	// ignored
	assert(h[0]==2);
	assert(h[1]==0);

	// test ()
	Op i=3;
	assert(i()==3);
	assert(i(1)==4);
	assert(i(1,2)==6);

	// plus add some code to check the __str__ fn
	//assert(str(Op(1))=="Op(1)");
	//assert(str(Op(-3))=="Op(-3)");

	printf("ok\n");
}
*/
]]


require("import")	-- the import fn
import("cpp_typedef")	-- import lib into global
ct = cpp_typedef --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo1 = ct.Foo()
bar1 = foo1:bar()
bar2 = ct.Foo.sbar()

u1 = ct.UnnamedStruct()
n1 = ct.TypedefNamedStruct()

test = ct.Test()

u2 = test:test1(u1)
n2 = test:test2(n1)
n3 = test:test3(n1)
n4 = test:test4(n1)


require("import")	-- the import fn
import("template_default_arg")	-- import code
--for k,v in pairs(template_default_arg) do _G[k]=v end -- move to global

helloInt = template_default_arg.Hello_int()
assert(template_default_arg.Hello_int_hi ~= nil)
helloInt:foo(template_default_arg.Hello_int_hi)

x = template_default_arg.X_int()
assert(x:meth(20.0, 200) == 200,"X_int test 1 failed")
assert(x:meth(20) == 20,"X_int test 2 failed")
assert(x:meth() == 0,"X_int test 3 failed")

y = template_default_arg.Y_unsigned()
assert(y:meth(20.0, 200) == 200,"Y_unsigned test 1 failed")
assert(y:meth(20) == 20,"Y_unsigned test 2 failed")
assert(y:meth() == 0,"Y_unsigned test 3 failed")

x = template_default_arg.X_longlong()
x = template_default_arg.X_longlong(20.0)
x = template_default_arg.X_longlong(20.0, 200) -- note: long longs just treated as another number

x = template_default_arg.X_int()
x = template_default_arg.X_int(20.0)
x = template_default_arg.X_int(20.0, 200)

x = template_default_arg.X_hello_unsigned()
x = template_default_arg.X_hello_unsigned(20.0)
x = template_default_arg.X_hello_unsigned(20.0, template_default_arg.Hello_int())

y = template_default_arg.Y_hello_unsigned()
y:meth(20.0, template_default_arg.Hello_int())
y:meth(template_default_arg.Hello_int())
y:meth()

fz = template_default_arg.Foo_Z_8()
x = template_default_arg.X_Foo_Z_8()
fzc = x:meth(fz)

-- Templated functions

-- plain function: int ott(Foo<int>)
assert(template_default_arg.ott(template_default_arg.Foo_int()) == 30,"ott test 1 failed")

-- %template(ott) ott<int, int>
assert(template_default_arg.ott() == 10,"ott test 2 failed")
assert(template_default_arg.ott(1) == 10,"ott test 3 failed")
assert(template_default_arg.ott(1, 1) == 10,"ott test 4 failed")

assert(template_default_arg.ott("hi") == 20,"ott test 5 failed")
assert(template_default_arg.ott("hi", 1) == 20,"ott test 6 failed")
assert(template_default_arg.ott("hi", 1, 1) == 20,"ott test 7 failed")

-- %template(ott) ott<const char *>
assert(template_default_arg.ottstring(template_default_arg.Hello_int(), "hi") == 40,"ott test 8 failed")
assert(template_default_arg.ottstring(template_default_arg.Hello_int()) == 40,"ott test 9 failed")

-- %template(ott) ott<int>
assert(template_default_arg.ottint(template_default_arg.Hello_int(), 1) == 50,"ott test 10 failed")
assert(template_default_arg.ottint(template_default_arg.Hello_int()) == 50,"ott test 11 failed")

-- %template(ott) ott<double>
assert(template_default_arg.ott(template_default_arg.Hello_int(), 1.0) == 60,"ott test 12 failed")
assert(template_default_arg.ott(template_default_arg.Hello_int()) == 60,"ott test 13 failed")


require("import")	-- the import fn
import("smart_pointer_templatemethods")	-- import lib into global
spt=smart_pointer_templatemethods --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

o1 = spt.Objct()

iid = spt.InterfaceId()

po2 = o1:QueryInterfaceObjct(iid)
-- we can't call po2:DisposeObjct, because smart pointer Ptr<T> always return 0 when dereferencing
-- (see interface file). So we only check that po2 has necessary method
assert(po2.DisposeObjct ~= nil)
assert(po2.QueryInterfaceObjct ~= nil)


require("import")	-- the import fn
import("pointer_reference",true)	-- import code

s=pointer_reference.get()
assert(s.value == 10)

ss = pointer_reference.Struct(20);
pointer_reference.set(ss);
assert(pointer_reference.Struct_instance.value == 20)

assert(pointer_reference.overloading(1) == 111)
assert(pointer_reference.overloading(ss) == 222)


require("import")	-- the import fn
import("arrays_global")	-- import lib
ag = arrays_global

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(ag.BeginString_FIX44a == "FIX.a.a")
assert(ag.BeginString_FIX44b == "FIX.b.b")

assert(ag.BeginString_FIX44c == "FIX.c.c")
assert(ag.BeginString_FIX44d == "FIX.d.d")


require("import")	-- the import fn
import("template_construct")	-- import lib into global
tc=template_construct --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo = tc.Foo_int(1)


require("import")   -- the import fn
import("chartest")   -- import code

function char_assert(char, code)
  assert(type(char) == 'string')
  assert(char:len() == 1)
  assert(char:byte() == code)
end

char_assert(chartest.GetPrintableChar(), 0x61)
char_assert(chartest.GetUnprintableChar(), 0x7F)

char_assert(chartest.printable_global_char, 0x61)
char_assert(chartest.unprintable_global_char, 0x7F)


require("import")	-- the import fn
import("grouping")	-- import lib into global
g=grouping --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(g.test1(5) == 5)
g.test2(42) -- Return value is int* packed into userdata. We can't do anything with it

assert(g.test3 == 37)
g.test3 = 42
assert(g.test3 == 42)

assert(g.NEGATE ~= nil)
assert(g.do_unary(5, g.NEGATE) == -5)


require("import")	-- the import fn
import("smart_pointer_multi")	-- import lib into global
spm=smart_pointer_multi --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo = spm.Foo()
foo.x = 5
assert(foo:getx() == 5)

bar = spm.Bar(foo)
spam = spm.Spam(bar)
grok = spm.Grok(bar)

assert(bar:getx() == 5)
assert(spam:getx() == 5)
spam.x = 7
assert(grok:getx() == 7)
grok.x = 10
assert(foo:getx() == 10)


require("import")	-- the import fn
import("equality")	-- import code
eq=equality    -- renaming import

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- === No equality operator ===

-- logically same data without equality operator are not equal
p1 = eq.MakePoint(10,9);
p2 = eq.MakePoint(10,9);

assert( p1 ~= p2 );

-- different wrappers for same Point* are equal
p3 = eq.GetZeroPointPtr()
p4 = eq.GetZeroPointPtr()

assert( p3 == p4 )

-- === Logically correct equality operator ===

ed1 = eq.EqualOpDefined(10)
ed2 = eq.EqualOpDefined(10)
ed3 = eq.EqualOpDefined(15)

assert( ed1 == ed2 )
assert( ed1 ~= ed3 )

-- === Logically incorrect equality operator ===

ew1 = eq.EqualOpWrong()
ew2 = eq.EqualOpWrong()

assert( ew1 ~= ew2 );

ew3 = eq.EqualOpWrong.GetStaticObject()
ew4 = eq.EqualOpWrong.GetStaticObject()

-- Even though these are pointers to same object, operator== overload should
-- state that they are not equal
assert( ew3 ~= ew4 )


-- Run file
require("import")	-- the import fn
import("cpp_nodefault")	-- import lib into global
cn=cpp_nodefault --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo1 = cn.Foo(1,2)
foo1.a = 5
assert(foo1.a == 5)

foo2 = cn.create(1,2)

cn.consume(foo1,foo2)

bar1 = cn.Bar()
bar1:consume(cn.gvar, foo2)
foo3 = bar1:create(1,2)

foo3.a = 6
assert(foo3.a == 6)


require("import")	-- the import fn
import("keyword_rename")	-- import lib into global
kn=keyword_rename--alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- Check renaming of Lua keywords
assert(kn.c_end(5) == 5)
assert(kn.c_nil(7) == 7)


require("import")	-- the import fn
import("static_const_member_2")	-- import lib
scm=static_const_member_2

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(scm.CavityPackFlags.forward_field == 1)
assert(scm.CavityPackFlags.backward_field == 2)
assert(scm.CavityPackFlags.cavity_flags == 3)

assert(scm.CavityPackFlags.flags == 0)
scm.CavityPackFlags.flags = 91
assert(scm.CavityPackFlags.flags == 91)
assert(scm.CavityPackFlags_flags == 91) -- old style bindings

assert(scm.CavityPackFlags.reftest == 42)

assert(scm.Test_int.LeftIndex ~= nil)
assert(scm.Test_int.current_profile == 4)

assert(scm.Foo.BAR.val == 1)
assert(scm.Foo.BAZ.val == 2)

assert(scm.Foo_BAR.val == 1)
assert(scm.Foo_BAZ.val == 2)

scm.Foo.BAR.val = 4
scm.Foo.BAZ.val = 5

assert(scm.Foo.BAR.val == 4)
assert(scm.Foo.BAZ.val == 5)

assert(scm.Foo_BAR.val == 4)
assert(scm.Foo_BAZ.val == 5)


require("import")	-- the import fn
import("extend")	-- import lib into global
e=extend --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

base1 = e.Base()
assert(base1.value == 0)
base2 = e.Base(10)
assert(base2.value == 10)

assert(base1:method(5) == 5)
assert(e.Base.zeroVal() == 0)
assert(base2:currentValue() == 10)
assert(base2:extendmethod(7) == 14)

der1 = e.Derived(0)
assert(der1.value == 0)
assert(der1:method(5) == 10)

der2 = e.Derived(17)
assert(der2.value == 34)
der2.extendval = 200.0
assert(math.abs(der2.actualval - 2.0) < 0.001)
assert(math.abs(der2.extendval - 200.0) < 0.001)


require("import")	-- the import fn
import("enum_plus")	-- import lib
ep=enum_plus

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(ep.iFoo_Phoo == 50) -- Old variant of enum bindings
assert(ep.iFoo.Phoo == 50) -- New variant of enum bindings


require("import")	-- the import fn
import("overload_template")	-- import code
for k,v in pairs(overload_template) do _G[k]=v end -- move to global

-- lua has only one numeric type, so maximum(int,int) and maximum(double,double) are the same
-- whichever one was wrapper first will be used (which is int)

f = foo()

a = maximum(3,4)

-- mix 1
assert(mix1("hi") == 101)
assert(mix1(1.0, 1.0) == 102)
assert(mix1(1.0) == 103)

-- mix 2
assert(mix2("hi") == 101)
assert(mix2(1.0, 1.0) == 102)
assert(mix2(1.0) == 103)

-- mix 3
assert(mix3("hi") == 101)
assert(mix3(1.0, 1.0) == 102)
assert(mix3(1.0) == 103)

-- Combination 1
assert(overtparams1(100) == 10)
assert(overtparams1(100.0, 100) == 20)

-- Combination 2
assert(overtparams2(100.0, 100) == 40)

-- Combination 3
assert(overloaded() == 60)
assert(overloaded(100.0, 100) == 70)

-- Combination 4
assert(overloadedagain("hello") == 80)
assert(overloadedagain() == 90)

-- specializations
assert(specialization(10) == 202 or specialization(10.0) == 203) -- only one works
assert(specialization(10, 10) == 204 or specialization(10.0, 10.0) == 205) -- ditto
assert(specialization("hi", "hi") == 201)

-- simple specialization
xyz()
xyz_int()
xyz_double()

-- a bit of everything
assert(overload("hi") == 0)
assert(overload(1) == 10)
assert(overload(1, 1) == 20)
assert(overload(1, "hello") == 30)

k = Klass()
assert(overload(k) == 10)
assert(overload(k, k) == 20)
assert(overload(k, "hello") == 30)
-- this one is incorrect: it mactches overload(10.0, "hi") with int overload(T t, const char *c)
--print(overload(10.0, "hi"))
--assert(overload(10.0, "hi") == 40)
assert(overload() == 50)

-- everything put in a namespace
assert(nsoverload("hi") == 1000,"nsoverload()")
assert(nsoverload(1) == 1010,"nsoverload(int t)")
assert(nsoverload(1, 1) == 1020,"nsoverload(int t, const int &)")
assert(nsoverload(1, "hello") == 1030,"nsoverload(int t, const char *)")
assert(nsoverload(k) == 1010,"nsoverload(Klass t)")
assert(nsoverload(k, k) == 1020,"nsoverload(Klass t, const Klass &)")
assert(nsoverload(k, "hello") == 1030,"nsoverload(Klass t, const char *)")
-- again this one fails
--assert(nsoverload(10.0, "hi") == 1040,"nsoverload(double t, const char *)")
assert(nsoverload() == 1050,"nsoverload(const char *)")

A_foo(1)
b = B()
b:foo(1)


require("import")  -- the import fn
import("li_factory") -- import code

-- moving to global
for k,v in pairs(li_factory) do _G[k]=v end

-- catch "undefined" global variables
setmetatable(getfenv(),{__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

circle = Geometry_create(Geometry_CIRCLE)
r = circle:radius()
assert(r == 1.5)

point = Geometry_create(Geometry_POINT)
w = point:width()
assert(w == 1.0)


require("import")	-- the import fn
import("rename_simple")	-- import lib
rs = rename_simple

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(rs.NewStruct ~= nil)
assert(rs.NewStruct.NewStaticVariable == 444)
assert(rs.NewStruct_NewStaticVariable == 444)

assert(rs.NewStruct.NewStaticMethod() == 333)
assert(rs.NewStruct_NewStaticMethod() == 333)

assert(rs.NewStruct.ONE == 1)
assert(rs.NewStruct_ONE == 1)

assert(rs.NewFunction() == 555)

assert(rs.OldStruct == nil)
assert(rs.OldFunction == nil)
assert(rs.OldGlobalVariable == nil)
assert(rs.OldStruct_ONE == nil)


require("import")	-- the import fn
import("fvirtual")	-- import lib into global
f=fvirtual --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

n1 = f.Node()
n2 = f.Node()
assert(n1:addChild(n2) == 1)

ns = f.NodeSwitch()
assert(ns:addChild(n2) == 2)
assert(ns:addChild(ns) == 2)
assert(ns:addChild(n1, false) == 3)


require("import")	-- the import fn
import("extend_typedef_class")	-- import lib into global
etc=extend_typedef_class --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

function test_obj(obj, const)
  obj.membervar = const
  assert(obj:getvar() == const)
end

a1 = etc.AClass()
test_obj(a1,1)

b1 = etc.BClass()
test_obj(b1,2)

c1 = etc.CClass()
test_obj(c1,3)

d1 = etc.DClass()
test_obj(d1,4)

a2 = etc.AStruct()
test_obj(a2,5)

b2 = etc.BStruct()
test_obj(b2,6)

c2 = etc.CStruct()
test_obj(c2,7)

d2 = etc.DStruct()
test_obj(d2,8)


require("import")	-- the import fn
import("li_typemaps")	-- import code

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- Check double INPUT typemaps
assert(li_typemaps.in_double(22.22) == 22.22)
assert(li_typemaps.inr_double(22.22) == 22.22)

-- Check double OUTPUT typemaps
assert(li_typemaps.out_double(22.22) == 22.22)
assert(li_typemaps.outr_double(22.22) == 22.22)

-- Check double INOUT typemaps
assert(li_typemaps.inout_double(22.22) == 22.22)
assert(li_typemaps.inoutr_double(22.22) == 22.22)

-- check long long
assert(li_typemaps.in_ulonglong(20)==20)
assert(li_typemaps.inr_ulonglong(20)==20)
assert(li_typemaps.out_ulonglong(20)==20)
assert(li_typemaps.outr_ulonglong(20)==20)
assert(li_typemaps.inout_ulonglong(20)==20)
assert(li_typemaps.inoutr_ulonglong(20)==20)

-- check bools
assert(li_typemaps.in_bool(true)==true)
assert(li_typemaps.inr_bool(false)==false)
assert(li_typemaps.out_bool(true)==true)
assert(li_typemaps.outr_bool(false)==false)
assert(li_typemaps.inout_bool(true)==true)
assert(li_typemaps.inoutr_bool(false)==false)

-- the others
a,b=li_typemaps.inoutr_int2(1,2)
assert(a==1 and b==2)

f,i=li_typemaps.out_foo(10)
assert(f.a==10 and i==20)


require("import")	-- the import fn
import("friends")	-- import lib into global
f=friends --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

f.globalscope()

b1 = f.B(5)
a1 = f.A(10)

assert(f.get_val1(a1) == 10)
assert(f.get_val1(a1, 2) == 12)
assert(f.get_val2(a1) == 20)
assert(f.get_val3(a1) == 30)

assert(f.get_val1(100, 1, 2) == 100)

assert(f.mix(a1,b1) == 15);

d1 = f.D_i(7)
assert(f.get_val1(d1) == 7)
f.set(d1,9)
assert(f.get_val1(d1) == 9)


require("import")	-- the import fn
import("enum_rename")	-- import lib
er=enum_rename

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(er.M_Jan ~= nil)
assert(er.May ~= nil)


require("import")	-- the import fn
import("nspace_extend")	-- import lib

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

ne = nspace_extend

-- Inner1

-- Constructors
in1_clr1 = ne.Outer.Inner1.Color()
in1_clr2 = ne.Outer.Inner1.Color.create()
in1_clr3 = ne.Outer.Inner1.Color(in1_clr2)

-- methods
in1_clr1:colorInstanceMethod(1.0)
ne.Outer.Inner1.Color.colorStaticMethod(2.0)

-- Inner2

-- Constructors
in2_clr1 = ne.Outer.Inner2.Color()
in2_clr2 = ne.Outer.Inner2.Color.create()
in2_clr3 = ne.Outer.Inner2.Color(in2_clr2)

assert(pcall(ne.Outer.Inner2.Color, in1_clr1) == false)

-- methods
in2_clr1:colorInstanceMethod(1.0)
ne.Outer.Inner2.Color.colorStaticMethod(2.0)

in2_clr3:colors(in1_clr1, in1_clr2, in2_clr2, in2_clr2, in2_clr3)

assert(pcall(in2_clr3.colors, in2_clr3,
  in2_clr1, in2_clr2, in1_clr2, in2_clr2, in2_clr3) == false)


require("import")	-- the import fn
import("refcount")	-- import lib
r=refcount

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

a = r.A()
assert(a:ref_count() == 1)

b1 = r.B(a)
assert(a:ref_count() == 2)

b2 = r.B.create(a)
assert(a:ref_count() == 3)

b3 = b2:cloner()
assert(a:ref_count() == 4)

rca = b1:get_rca() -- RCPtr<A> is not wrapped
assert(a:ref_count() == 5)

b4 = r.global_create(a)
assert(a:ref_count() == 6)


require("import")	-- the import fn
import("primitive_ref")	-- import code
pr=primitive_ref --alias

assert(pr.ref_int(3)==3)

assert(pr.ref_uint(3) == 3)

assert(pr.ref_short(3) == 3)

assert(pr.ref_ushort(3) == 3)

assert(pr.ref_long(3) == 3)

assert(pr.ref_ulong(3) == 3)

assert(pr.ref_schar(3) == 3)

assert(pr.ref_uchar(3) == 3)

assert(pr.ref_float(3.5) == 3.5)

assert(pr.ref_double(3.5) == 3.5)

assert(pr.ref_bool(true) == true)

assert(pr.ref_char('x') == 'x')

assert(pr.ref_over(0) == 0)

a=pr.A(12)
assert(pr.ref_over(a)==12)


require("import")	-- the import fn
import("smart_pointer_extend")	-- import lib into global
spe=smart_pointer_extend --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(spe.CBase.hello() == 1)
assert(spe.CBase.z == 1)

base1 = spe.CBase()
base1.x = 7

p1 = spe.CPtr()

assert(spe.get_hello(p1) == 1)
assert(p1:foo() == 1)
assert(p1:bar() == 2)
assert(p1:boo(5) == 5)

foo = spe.Foo()
bar = spe.Bar(foo)

assert(bar:extension(5,7) == 5)
assert(bar:extension(7) == 7)
assert(bar:extension() == 1)

dfoo = spe.DFoo()
dptr = spe.DPtrFoo(dfoo)

assert(dptr:Ext() == 2)
assert(dptr:Ext(5) == 5)


require("import")	-- the import fn
import("valuewrapper")	-- import code
v=valuewrapper    -- renaming import

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(v.Xi ~= nil)
assert(v.YXi ~= nil)

x1 = v.Xi(5)

y1 =v.YXi()
assert(y1:spam(x1) == 0)
assert(y1:spam() == 0)


require("import")	-- the import fn
import("overload_simple")	-- import code
for k,v in pairs(overload_simple) do _G[k]=v end -- move to global

-- lua has only one numeric type, foo(int) and foo(double) are the same
-- whichever one was wrapper first will be used

assert(foo(3)=="foo:int" or foo(3)=="foo:double") -- could be either
assert(foo("hello")=="foo:char *")

f=Foo()
b=Bar()

assert(foo(f)=="foo:Foo *")
assert(foo(b)=="foo:Bar *")

v = malloc_void(32)

assert(foo(v) == "foo:void *")

s = Spam()

assert(s:foo(3) == "foo:int" or s:foo(3.0) == "foo:double") -- could be either
assert(s:foo("hello") == "foo:char *")
assert(s:foo(f) == "foo:Foo *")
assert(s:foo(b) == "foo:Bar *")
assert(s:foo(v) == "foo:void *")

assert(Spam_bar(3) == "bar:int" or Spam_bar(3.0) == "bar:double")
assert(Spam_bar("hello") == "bar:char *")
assert(Spam_bar(f) == "bar:Foo *")
assert(Spam_bar(b) == "bar:Bar *")
assert(Spam_bar(v) == "bar:void *")

-- Test constructors

s = Spam()
assert(s.type == "none")

s = Spam(3)
assert(s.type == "int" or s.type == "double")

s = Spam("hello")
assert(s.type == "char *")

s = Spam(f)
assert(s.type == "Foo *")

s = Spam(b)
assert(s.type == "Bar *")

s = Spam(v)
assert(s.type == "void *")

free_void(v)


require("import")	-- the import fn
import("cpp_enum")	-- import code
ce=cpp_enum    -- renaming import

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(ce.ENUM_ONE ~= nil)
assert(ce.ENUM_TWO ~= nil)

-- Enums inside classes
assert(ce.Foo.Hi == 0)
assert(ce.Foo.Hello == 1);
-- old-style bindings
assert(ce.Foo_Hi == 0)
assert(ce.Foo_Hello == 1);

assert(ce.Hi == 0)
assert(ce.Hello == 1)


require("import")	-- the import fn
import("inherit_missing")	-- import lib
im=inherit_missing

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

bar = im.Bar()
spam = im.Spam()

assert(im.do_blah(bar) == "Bar::blah")
assert(im.do_blah(spam) == "Spam::blah")


require("import")	-- the import fn
-- need to load two modules
import("imports_a")	-- import code
import("imports_b")	-- import code

b=imports_b.B()
b:hello() -- call member function in A which is in a different SWIG generated library.
b:bye()

assert (b:member_virtual_test(imports_a.A_memberenum1) == imports_a.A_memberenum2)
assert (b:global_virtual_test(imports_a.globalenum1) == imports_a.globalenum2)

imports_b.global_test(imports_a.A_memberenum1)

--[[    B b = new B();
    b.hello(); //call member function in A which is in a different SWIG generated library.

            B b = new B();
        b.hello(); //call member function in A which is in a different SWIG generated library.
        b.bye();

        if (b.member_virtual_test(A.MemberEnum.memberenum1) != A.MemberEnum.memberenum2)
          throw new Exception("Test 1 failed");
        if (b.global_virtual_test(GlobalEnum.globalenum1) != GlobalEnum.globalenum2)
          throw new Exception("Test 2 failed");

        imports_b.global_test(A.MemberEnum.memberenum1);
]]


require("import")	-- the import fn
import("li_carrays_cpp")	-- import code
lc = li_carrays_cpp

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- Testing for %array_functions(int,intArray)
ary = lc.new_intArray(2)
lc.intArray_setitem(ary, 0, 0)
lc.intArray_setitem(ary, 1, 1)
assert(lc.intArray_getitem(ary, 0)==0)
assert(lc.intArray_getitem(ary, 1)==1)
lc.delete_intArray(ary)

-- Testing for %array_class(double, doubleArray)
d = lc.doubleArray(10)
d[0] = 7
d[5] = d[0] + 3
assert(d[5] + d[0] == 17)
--print(d[5] + d[0])

ptr = d:cast()	-- to ptr
d2 = lc.doubleArray_frompointer(ptr) -- and back to array
assert(d2[5] + d2[0] == 17)
--print(d2[5] + d2[0])


require("import")	-- the import fn
import("li_std_pair")	-- import code

for k,v in pairs(li_std_pair) do _G[k]=v end -- move to global

intPair = makeIntPair(7, 6)
assert(intPair.first==7 and intPair.second==6)

intPairPtr = makeIntPairPtr(7, 6)
assert(intPairPtr.first==7 and intPairPtr.second==6)

intPairRef = makeIntPairRef(7, 6)
assert(intPairRef.first == 7 and intPairRef.second == 6)

intPairConstRef = makeIntPairConstRef(7, 6)
assert(intPairConstRef.first == 7 and intPairConstRef.second == 6)

-- call fns
assert(product1(intPair) == 42)
assert(product2(intPair) == 42)
assert(product3(intPair) == 42)

-- also use the pointer version
assert(product1(intPairPtr) == 42)
assert(product2(intPairPtr) == 42)
assert(product3(intPairPtr) == 42)

-- or the other types
assert(product1(intPairRef) == 42)
assert(product2(intPairRef) == 42)
assert(product3(intPairRef) == 42)
assert(product1(intPairConstRef) == 42)
assert(product2(intPairConstRef) == 42)
assert(product3(intPairConstRef) == 42)


require("import")	-- the import fn
import("dynamic_cast")	-- import code

f = dynamic_cast.Foo()
b = dynamic_cast.Bar()

x = f:blah()
y = b:blah()

-- swig_type is a swiglua specific function which gets the swig_type_info's name
assert(swig_type(f)==swig_type(x))
assert(swig_type(b)==swig_type(y))

-- the real test: is y a Foo* or a Bar*?
assert(dynamic_cast.do_test(y)=="Bar::test")


require("import")	-- the import fn
import("template_extend2")	-- import lib into global
te=template_extend2 --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

lb = te.lBaz()
assert(lb:foo() == "lBaz::foo")

db = te.dBaz()
assert(db:foo() == "dBaz::foo")


require("import")	-- the import fn
import("template_extend1")	-- import lib into global
te=template_extend1 --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

lb = te.lBaz()
assert(lb:foo() == "lBaz::foo")

db = te.dBaz()
assert(db:foo() == "dBaz::foo")


require("import")	-- the import fn
import("smart_pointer_rename")	-- import lib into global
spr=smart_pointer_rename --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

foo = spr.Foo()
assert(foo:ftest1(1) == 1)
assert(foo:ftest2(1,2) == 2)

bar = spr.Bar(foo)
assert(bar:test() == 3)
assert(bar:ftest1(1) == 1)
assert(bar:ftest2(1,2) == 2)


require("import")	-- the import fn
import("enums")	-- import lib

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

-- check values
assert(enums.CSP_ITERATION_FWD==0)
assert(enums.CSP_ITERATION_BWD==11)
assert(enums.ABCDE==0)
assert(enums.FGHJI==1)
assert(enums.boo==0)
assert(enums.hoo==5)
assert(enums.globalinstance1==0)
assert(enums.globalinstance2==1)
assert(enums.globalinstance3==30)
assert(enums.AnonEnum1==0)
assert(enums.AnonEnum2==100)

-- In C enums from struct are exported into global namespace (without prefixing with struct name)
-- In C++ they are prefixed (as compatibility thing).
-- We are emulating xor :)
assert(enums.BAR1 ~= enums.Foo_BAR1) -- It is either C style, or C++ style, but not both
assert((enums.BAR1 ~= nil ) or (enums.Foo_BAR1 ~= nil))

assert(enums.Phoo ~= enums.iFoo_Phoo)
assert((enums.Phoo == 50) or (enums.iFoo_Phoo == 50))
-- no point in checking fns, C will allow any value


require("import")	-- the import fn
import("varargs")	-- import lib
v=varargs

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(v.test("Hello") == "Hello")
assert(v.test_def("Hello",0) == "Hello")

assert(v.Foo.statictest("Hello") == "Hello")
assert(v.Foo.statictest("Hello",1) == "Hello")

assert(v.test_plenty("Hello") == "Hello")
assert(v.test_plenty("Hello",1) == "Hello")
assert(v.test_plenty("Hello",1,2) == "Hello")


--Example using pointers to member functions
require("import")	-- the import fn
import("member_pointer")	-- import code
mp = member_pointer

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

function check(what, expected, actual)
	assert(expected == actual,"Failed: "..what.." Expected: "..expected.." Actual: "..actual)
end

-- Get the pointers
area_pt = mp.areapt()
perim_pt = mp.perimeterpt()

-- Create some objects
s = mp.Square(10)

-- Do some calculations
check ("Square area ", 100.0, mp.do_op(s,area_pt))
check ("Square perim", 40.0, mp.do_op(s,perim_pt))

-- Try the variables
-- these have to still be part of the 'member_pointer' table
memberPtr = mp.areavar
memberPtr = mp.perimetervar

check ("Square area ", 100.0, mp.do_op(s,mp.areavar))
check ("Square perim", 40.0, mp.do_op(s,mp.perimetervar))

-- Modify one of the variables
mp.areavar = perim_pt

check ("Square perimeter", 40.0, mp.do_op(s,mp.areavar))

-- Try the constants
memberPtr = mp.AREAPT
memberPtr = mp.PERIMPT
memberPtr = mp.NULLPT

check ("Square area ", 100.0, mp.do_op(s,mp.AREAPT))
check ("Square perim", 40.0, mp.do_op(s,mp.PERIMPT))


require("import")	-- the import fn
import("cpp_namespace")	-- import lib into global
cn=cpp_namespace --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(cn.fact(4) == 24)
assert(cn.Foo == 42)

t1 = cn.Test()
assert(t1:method() == "Test::method")

cn.weird("t1", 4)

assert(cn.do_method(t1) == "Test::method")
assert(cn.do_method2(t1) == "Test::method")

t2 = cn.Test2()
assert(t2:method() == "Test2::method")

assert(cn.foo3(5) == 5)

assert(cn.do_method3(t2, 7) == "Test2::method")


require("import")	-- the import fn
import("template_static")	-- import lib
ts=template_static

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(ts.foo_i.test == 0)
ts.foo_i.test = 42
assert(ts.foo_i.test == 42)
assert(ts.foo_i_test == 42)
ts.foo_i_test = 57
assert(ts.foo_i.test == 57)
assert(ts.foo_i_test == 57)
assert(ts.foo_d.test == 0)

assert(ts.Foo.bar_double(4) == 1.0)
assert(ts.Foo_bar_double(4) == 1.0)


require("import")	-- the import fn
import("sizet")	-- import code

s = 2000
s = sizet.test1(s+1)
s = sizet.test2(s+1)
s = sizet.test3(s+1)
s = sizet.test4(s+1)
assert(s == 2004)


require("import")	-- the import fn
import("exception_partial_info")	-- import code

-- catch "undefined" global variables
setmetatable(getfenv(),{__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

imp=exception_partial_info.Impl()

-- trying to call throwing methods
-- should fail
assert(pcall(function() imp:f1() end)==false)
assert(pcall(function() imp:f2() end)==false)


require("import")	-- the import fn
import("global_namespace")	-- import lib into global
gn=global_namespace --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

k1 = gn.Klass1()
k2 = gn.Klass2()
k3 = gn.Klass3()
k4 = gn.Klass4()
k5 = gn.Klass5()
k6 = gn.Klass6()
k7 = gn.Klass7()

gn.KlassMethods.methodA(k1,k2,k3,k4,k5,k6,k7)
gn.KlassMethods.methodB(k1,k2,k3,k4,k5,k6,k7)

k1 = gn.getKlass1A()
k2 = gn.getKlass2A()
k3 = gn.getKlass3A()
k4 = gn.getKlass4A()
k5 = gn.getKlass5A()
k6 = gn.getKlass6A()
k7 = gn.getKlass7A()

gn.KlassMethods.methodA(k1,k2,k3,k4,k5,k6,k7)
gn.KlassMethods.methodB(k1,k2,k3,k4,k5,k6,k7)

k1 = gn.getKlass1B()
k2 = gn.getKlass2B()
k3 = gn.getKlass3B()
k4 = gn.getKlass4B()
k5 = gn.getKlass5B()
k6 = gn.getKlass6B()
k7 = gn.getKlass7B()

gn.KlassMethods.methodA(k1,k2,k3,k4,k5,k6,k7)
gn.KlassMethods.methodB(k1,k2,k3,k4,k5,k6,k7)

x1 = gn.XYZ1()
x2 = gn.XYZ2()
x3 = gn.XYZ3()
x4 = gn.XYZ4()
x5 = gn.XYZ5()
x6 = gn.XYZ6()
x7 = gn.XYZ7()

gn.XYZMethods.methodA(x1,x2,x3,x4,x5,x6,x7)
gn.XYZMethods.methodB(x1,x2,x3,x4,x5,x6,x7)

gn.AnEnumMethods.methodA(gn.anenum1, gn.anenum2, gn.anenum3)
gn.AnEnumMethods.methodB(gn.anenum1, gn.anenum2, gn.anenum3)

gn.TheEnumMethods.methodA(gn.theenum1, gn.theenum2, gn.theenum3)
gn.TheEnumMethods.methodB(gn.theenum1, gn.theenum2, gn.theenum3)


require("import")	-- the import fn
import("nested_workaround")	-- import lib
nw=nested_workaround

-- catch "undefined" global variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

i1 = nw.Inner(5)
assert(i1:getValue() == 5)
i1:setValue(7)
assert(i1:getValue() == 7)

o1 = nw.Outer()
i2 = o1:createInner(9)
assert(i2:getValue() == 9)
i2:setValue(11)
assert(o1:getInnerValue(i2) == 11)

i3 = o1:doubleInnerValue(i2)
assert(i3:getValue() == 22)


require("import")	-- the import fn
import("static_const_member")	-- import lib into global
scm=static_const_member --alias

-- catching undefined variables
local env = _ENV -- Lua 5.2
if not env then env = getfenv () end -- Lua 5.1
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})

assert(scm.X.PN == 0)
assert(scm.X.CN == 1)
assert(scm.X.EN == 2)
assert(scm.X.CHARTEST == "A")

-- Old-style bindings
assert(scm.X_PN == 0)
assert(scm.X_CN == 1)
assert(scm.X_EN == 2)
assert(scm.X_CHARTEST == "A")


require("import")	-- the import fn
import("smart_pointer_overload")	-- import code
for k,v in pairs(smart_pointer_overload) do _G[k]=v end -- move to global

f = Foo()
b = Bar(f)

assert(f:test(3) == 1)
--assert(f:test(3.5) == 2)	-- won't work due to being unable to overloads
assert(f:test("hello") == 3)

assert(b:test(3) == 1)
--assert(b:test(3.5) == 2)	-- won't work due to being unable to overloads
assert(b:test("hello") == 3)


import

-- import
-- the lua 5.0 loading mechanism is rather poor & relies upon the loadlib() fn
-- the lua 5.1 loading mechanism is simplicity itself
-- for now we need a bridge which will use the correct version

function import_5_0(module)
	-- imports the file into the program
	-- for a module 'example'
	-- this must load 'example.dll' or 'example.so'
	-- and look for the fn 'Example_Init()' (note the capitalisation)
	if rawget(_G,module)~=nil then return end -- module appears to be loaded

	-- capitalising the first letter
	local c=string.upper(string.sub(module,1,1))
	local fnname=c..string.sub(module,2).."_Init"

	local suffix,lib
	-- note: as there seems to be no way in lua to determine the platform
	-- we will try loading all possible names
	-- providing one works, we can load
	for _,suffix in pairs{".dll",".so"} do
		lib=loadlib(module..suffix,fnname)
		if lib then -- found
			break
		end
	end
	assert(lib,"error loading module:"..module)

	lib() -- execute the function: initialising the lib
	local m=rawget(_G,module)	-- gets the module object
	assert(m~=nil,"no module table found")
end

function import_5_1(module)
	require(module)
end

if string.sub(_VERSION,1,7)=='Lua 5.0' then
	import=import_5_0
else
	import=import_5_1
end


runme

print "[lua] This is runme.lua"
-- test program for embedded lua
-- we do not need to load the library, as it was already in the interpreter
-- but let's check anyway
assert(type(example)=='table',"Don't appear to have loaded the example module")

-- note: we will copy the functions from example table into global
-- this will help us later
for k,v in pairs(example) do _G[k]=v end

-- our add function
-- we will be calling this from C
function add(a,b)
    print("[lua] this is function add(",a,b,")")
    c=a+b
    print("[lua] returning",c)
    return c
end

function append(a,b)
    print("[lua] this is function append(",a,b,")")
    c=a..b
    print("[lua] returning",c)
    return c
end


-- file: runme.lua

-- This file illustrates class C++ interface generated
-- by SWIG.

---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

ex = example

-- Calling a module function ( aka global function )
assert( ex.module_function() == 7 )
print("example.module_function(): ", ex.module_function())

-- Accessing a module (aka global) variable
assert( ex.module_variable == 9 )
print("example.module_variable: ", ex.module_variable)

-- Creating an instance of the class
w1 = ex.MyWorld.World()
print("Creating class instance: w1 = ex.MyWorld.World(): ", w1)

-- Accessing class members
assert( ex.MyWorld.World():create_world() == 17 )
print( "w1:create_world() = ", w1:create_world() )
assert( w1:create_world() == 17 )
print( "w1:world_max_count = ", w1.world_max_count )
assert( w1.world_max_count == 9 )

-- Accessing enums from class within namespace
print( "Accessing enums: ex.MyWorld.Nested.Dweller.MALE = ", ex.MyWorld.Nested.Dweller.MALE )
assert( ex.MyWorld.Nested.Dweller.MALE == 0 )
print( "Accessing enums: ex.MyWorld.Nested.Dweller.FEMALE = ", ex.MyWorld.Nested.Dweller.FEMALE )
assert( ex.MyWorld.Nested.Dweller.FEMALE == 1 )

-- Accessing static member function
print( "Accessing static member function: ex.MyWorld.Nested.Dweller.count() = ", ex.MyWorld.Nested.Dweller.count() )
assert( ex.MyWorld.Nested.Dweller.count() == 19 )


-- Operator overloading example
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

a = example.intSum(0)
b = example.doubleSum(100.0)

-- Use the objects.  They should be callable just like a normal
-- lua function.

for i=0,100 do
    a(i)                -- Note: function call
    b(math.sqrt(i))     -- Note: function call
end
print("int sum 0..100 is",a:result(),"(expected 5050)")
print("double sum 0..100 is",b:result(),"(expected ~771.46)")


# Test various properties of classes defined in separate modules

print("Testing the %import directive")

if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	function loadit(a)
		lib=loadlib(a..'.dll','luaopen_'..a) or loadlib(a..'.so','luaopen_'..a)
		assert(lib)()
	end
	loadit('base')
	loadit('foo')
	loadit('bar')
	loadit('spam')
else
	-- lua 5.1 does
	require 'base'
	require 'foo'
	require 'bar'
	require 'spam'
end

-- Create some objects

print("Creating some objects")

a = base.Base()
b = foo.Foo()
c = bar.Bar()
d = spam.Spam()

-- Try calling some methods
print("Testing some methods")
print("Should see 'Base::A' ---> ",a:A())
print("Should see 'Base::B' ---> ",a:B())

print("Should see 'Foo::A' ---> ",b:A())
print("Should see 'Foo::B' ---> ",b:B())

print("Should see 'Bar::A' ---> ",c:A())
print("Should see 'Bar::B' ---> ",c:B())

print("Should see 'Spam::A' ---> ",d:A())
print("Should see 'Spam::B' ---> ",d:B())

-- Try some casts

print("\nTesting some casts")

x = a:toBase()
print("Should see 'Base::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())

x = b:toBase()
print("Should see 'Foo::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())

x = c:toBase()
print("Should see 'Bar::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())

x = d:toBase()
print("Should see 'Spam::A' ---> ",x:A())
print("Should see 'Base::B' ---> ",x:B())

x = d:toBar()
print("Should see 'Bar::B' ---> ",x:B())

print "\nTesting some dynamic casts\n"
x = d:toBase()

print " Spam -> Base -> Foo : "
y = foo.Foo_fromBase(x)
if y then
      print "bad swig"
else
      print "good swig"
end

print " Spam -> Base -> Bar : "
y = bar.Bar_fromBase(x)
if y then
      print "good swig"
else
      print "bad swig"
end

print " Spam -> Base -> Spam : "
y = spam.Spam_fromBase(x)
if y then
      print "good swig"
else
      print "bad swig"
end

print " Foo -> Spam : "
y = spam.Spam_fromBase(b)
if y then
      print "bad swig"
else
      print "good swig"
end


print "[lua] This is runme.lua"
-- test program for embedded lua
-- we do not need to load the library, as it was already in the interpreter
-- but let's check anyway
assert(type(example)=='table',"Don't appear to have loaded the example module")

-- a test function to run the tests
function do_tests()
	print("[lua] We are now in Lua, inside the do_tests() function")
	print("[lua] We will be calling example.gcd() and changing example.Foo")
	-- Call our gcd() function
	x = 42
	y = 105
	g = example.gcd(x,y)
	print("[lua] The gcd of",x,"and",y,"is",g)

	-- Manipulate the Foo global variable

	-- Output its current value
	print("[lua] Foo = ", example.Foo)

	-- Change its value
	example.Foo = 3.1415926

	-- See if the change took effect
	print("[lua] Foo = ", example.Foo)
	print("[lua] ending the do_tests() function")
end

function call_greeting()
	print("[lua] We are now in Lua, inside the call_greeting() function")
	example.greeting()
	print("[lua] ending the call_greeting() function")
end


-- file: example.lua

---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

print("ICONST  = "..example.ICONST.." (should be 42)")
print("FCONST  = "..example.FCONST.." (should be 2.1828)")
print("CCONST  = "..example.CCONST.." (should be 'x')")
print("CCONST2 = "..example.CCONST2.." (this should be on a new line)")
print("SCONST  = "..example.SCONST.." (should be 'Hello World')")
print("SCONST2 = "..example.SCONST2.." (should be '\"Hello World\"')")
print("EXPR    = "..example.EXPR.." (should be 48.5484)")
print("iconst  = "..example.iconst.." (should be 37)")
print("fconst  = "..example.fconst.." (should be 3.14)")

-- helper to check that a fn failed
function checkfail(fn)
	if pcall(fn)==true then
		print("that shouldn't happen, it worked")
	else
		print("function failed as expected")
	end
end

-- these should fail
-- example.EXTERN is a nil value, so concatentatin will make it fail
checkfail(function() print("EXTERN = "..example.EXTERN) end)
checkfail(function() print("FOO = "..example.FOO) end)


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

-- Try to set the values of some global variables

example.ivar   =  42
example.svar   = -31000
example.lvar   =  65537
example.uivar  =  123456
example.usvar  =  61000
example.ulvar  =  654321
example.scvar  =  -13
example.ucvar  =  251
example.cvar   =  "S"
example.fvar   =  3.14159
example.dvar   =  2.1828
example.strvar =  "Hello World"
example.iptrvar= example.new_int(37)
example.ptptr  = example.new_Point(37,42)
example.name   = "Bill"

-- Now print out the values of the variables

print("Variables (values printed from Lua)")

print("ivar      =", example.ivar)
print("svar      =", example.svar)
print("lvar      =", example.lvar)
print("uivar     =", example.uivar)
print("usvar     =", example.usvar)
print("ulvar     =", example.ulvar)
print("scvar     =", example.scvar)
print("ucvar     =", example.ucvar)
print("fvar      =", example.fvar)
print("dvar      =", example.dvar)
print("cvar      =", example.cvar)
print("strvar    =", example.strvar)
print("cstrvar   =", example.cstrvar)
print("iptrvar   =", example.iptrvar)
print("name      =", example.name)
print("ptptr     =", example.ptptr, example.Point_print(example.ptptr))
print("pt        =", example.pt, example.Point_print(example.pt))

print("\nVariables (values printed from C)")

example.print_vars()

print "\nNow I'm going to try and modify some read only variables";

print "     Trying to set 'path' to 'Whoa!'";
if pcall(function() example.path = "Whoa!" end)==true then
	print "     That's funny, it didn't give an error!"
else
	print "     It gave an error, as it should"
end
print("     Just checking the value: path      =", example.path)

print "     Trying to set 'status' to '0'";
if pcall(function() example.status = 0 end)==true then
	print "     That's funny, it didn't give an error!"
else
	print "     It gave an error, as it should"
end
print("     Just checking the value: status    =", example.status)

print "\nI'm going to try and update a structure variable.\n"

example.pt = example.ptptr

print "The new value is"
example.pt_print()
print("You should see the value", example.Point_print(example.ptptr))


-- file: runme.lua

-- This file illustrates class C++ interface generated
-- by SWIG.

---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

----- Object creation -----

print("Creating some objects:")
c = example.Circle(10)
print("    Created circle", c)
s = example.Square(10)
print("    Created square", s)

----- Access a static member -----

print("\nA total of",example.Shape_nshapes,"shapes were created")

----- Member data access -----

-- Set the location of the object

c.x = 20
c.y = 30

s.x = -10
s.y = 5

print("\nHere is their current position:")
print(string.format("    Circle = (%f, %f)",c.x,c.y))
print(string.format("    Square = (%f, %f)",s.x,s.y))

----- Call some methods -----

print("\nHere are some properties of the shapes:")
for _,o in pairs({c,s}) do
      print("   ", o)
      print("        area      = ", o:area())
      print("        perimeter = ", o:perimeter())
end

print("\nGuess I'll clean up now")

-- Note: this invokes the virtual destructor
c=nil
s=nil

-- call gc to make sure they are collected
collectgarbage()

print(example.Shape_nshapes,"shapes remain")
print "Goodbye"


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

-- a helper to print a Lua table
function print_table(t)
    print(table.concat(t,","))
end

-- a helper to print a C array
function print_array(arr,len)
    for i=0,len-1 do
        io.write(example.int_getitem(arr,i),",")
    end
    io.write("\n")
end

math.randomseed(0)  -- init random

--[[ version 1: passing a C array to the code
let's test call sort_int()
this requires a C array, so is the hardest to use]]
ARRAY_SIZE=10
arr=example.new_int(ARRAY_SIZE)
for i=0,ARRAY_SIZE-1 do
    example.int_setitem(arr,i,math.random(1000))
end
print "unsorted"
print_array(arr,ARRAY_SIZE)
example.sort_int(arr,ARRAY_SIZE)
print "sorted"
print_array(arr,ARRAY_SIZE)
example.delete_int(arr) -- must delete it
print ""

--[[ version 2: using %luacode to write a helper
a simpler way is to use a %luacode
which is a lua function added into the module
this can do the conversion for us
so we can just add a lua table directly
(what we do is move the lua code into the module instead)
]]
t={}
for i=1,ARRAY_SIZE do
    t[i]=math.random(1000)
end
print "unsorted"
print_table(t)
example.sort_int2(t) -- calls lua helper which then calls C
print "sorted"
print_table(t)
print ""

--[[ version 3: use a typemap
this is the best way
it uses the SWIG-Lua typemaps to do the work
one item of note: the typemap creates a copy, rather than edit-in-place]]
t={}
for i=1,ARRAY_SIZE do
    t[i]=math.random(1000)/10
end
print "unsorted"
print_table(t)
t=example.sort_double(t) -- replace t with the result
print "sorted"
print_table(t)


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

a = 37
b = 42

-- Now call our C function

print("Trying some C functions")
print("    a        =", a)
print("    b        =", b)
print("    add(a,b) =", example.add(a,b))
print("    sub(a,b) =", example.sub(a,b))
print("    mul(a,b) =", example.mul(a,b))

print("Calling them using the my_func()")
print("    add(a,b) =", example.callback(a,b,example.add))
print("    sub(a,b) =", example.callback(a,b,example.sub))
print("    mul(a,b) =", example.callback(a,b,example.mul))

print("Now let us write our own function")
function foo(a,b) return 101 end
print("    foo(a,b) =", example.callback(a,b,foo))

print("Now let us try something that will fail")
local ok,c=pcall(example.callback,a,b,print)
if ok==false then
	print("this failed as expected, error:",c)
else
	print("oops, that worked! result:",c)
end

-- part2 stored function
print("trying a stored fn")
print("the_func=",example.the_func)
print("setting to print")
example.the_func=print
print("the_func=",example.the_func)
print("call_the_func(5)")
example.call_the_func(5)

function bar(i) print("bar",i) end
print("setting to bar")
example.the_func=bar
print("call_the_func(5)")
example.call_the_func(5)


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

-- Call our gcd() function
x = 42
y = 105
g = example.gcd(x,y)
print("The gcd of",x,"and",y,"is",g)

-- Manipulate the Foo global variable

-- Output its current value
print("Foo = ", example.Foo)

-- Change its value
example.Foo = 3.1415926

-- See if the change took effect
print("Foo = ", example.Foo)


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end
-- First create some objects using the pointer library.
print("Testing the pointer library")
a = example.new_intp()
b = example.new_intp()
c = example.new_intp()
example.intp_assign(a,37)
example.intp_assign(b,42)
print("     a = "..tostring(a))
print("     b = "..tostring(b))
-- Now try the typemap library
-- This should be much easier. Now how it is no longer
-- necessary to manufacture pointers.
print("Trying the typemap library")
r = example.sub(37,42)
print("     37 - 42 = "..r)
-- Now try the version with multiple return values
print("Testing multiple return values")
q,r = example.divide(42,37)
print("     42/37 = "..q.." remainder "..r)


-- file: example.lua

---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

-- throw a lot of exceptions:
-- you must catch exceptions using pcall and then checking the result

t = example.Test()

print "calling t:unknown()"
ok,res=pcall(function() t:unknown() end)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res)
end

print "calling t:simple()"
ok,res=pcall(function() t:simple() end)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res)
end

print "calling t:message()"
ok,res=pcall(function() t:message() end)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res)
end

print "calling t:hosed()"
ok,res=pcall(function() t:hosed() end)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res.code,res.msg)
end

-- this is a rather strange way to perform the multiple catch of exceptions
print "calling t:multi()"
for i=1,3 do
    ok,res=pcall(function() t:multi(i) end)
    if ok then
        print "  that worked! Funny"
    else
        if swig_type(res)=="Exc *" then
            print("  call failed with Exc exception:",res.code,res.msg)
        else
            print("  call failed with error:",res)
        end
    end
end

-- this is a bit crazy, but it shows obtaining of the stacktrace
function a()
    b()
end
function b()
    t:message()
end
print [[
Now let's call function a()
 which calls b()
 which calls into C++
 which will throw an exception!]]
ok,res=pcall(a)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res)
end
print "Now let's do the same using xpcall(a,debug.traceback)"
ok,res=xpcall(a,debug.traceback)
if ok then
    print "  that worked! Funny"
else
    print("  call failed with error:",res)
end
print "As you can see, the xpcall gives a nice stacktrace to work with"

ok,res=pcall(a)
print(ok,res)
ok,res=xpcall(a,debug.traceback)
print(ok,res)


---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

x,y = 42,105
print("add1 - simple arg passing and single return value -- ")
print(example.add1(x,y))
print("add2 - pointer arg passing and single return value through pointer arg -- ")
print(example.add2(x,y))
print("add3 - simple arg passing and double return value through return and ptr arg -- ")
print(example.add3(x,y))
print("add4 - dual use arg and return value -- ")
print(example.add4(x,y))


-- Operator overloading example
---- importing ----
if string.sub(_VERSION,1,7)=='Lua 5.0' then
	-- lua5.0 doesn't have a nice way to do this
	lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
	assert(lib)()
else
	-- lua 5.1 does
	require('example')
end

print "ok, let's test Lua's ownership of C++ objects"
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")

print "\nLet's make a couple"
a=example.Square(10)
b=example.Circle(1)
print("Currently there are",example.Shape_nshapes,"shapes (there should be 2)")

print "\nNote let's use the createX functions"
c=example.createCircle(5)
d=example.createSquare(3)
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")

print "\nWe will run the garbage collector & see if they are till here"
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")

print "\nLet's get rid of them all, collect garbage & see if they are till here"
a,b,c,d=nil,nil,nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")

print "\nLet's start putting stuff into the ShapeOwner"
print "The ShapeOwner now owns the shapes, but Lua still has pointers to them"
o=example.ShapeOwner()
a=example.Square(10)
b=example.Circle(1)
o:add(a)
o:add(b)
o:add(example.createSquare(5))
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")

print "\nWe will nil our references,run the garbage collector & see if they are still here"
print "they should be, as the ShapeOwner owns them"
a,b=nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")

print "\nWe will access them and check that they are still valid"
a=o:get(0)
b=o:get(1)
print(" Area's are",a:area(),b:area(),o:get(2):area())
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")

print "\nWe will remove one from the C++ owner & pass its ownership to Lua,"
print " then check that they are still unchanged"
a,b=nil,nil
a=o:remove(0) -- a now owns it
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")

print "\nDelete the ShapeOwner (this should destroy two shapes),"
print " but we have one left in Lua"
o=nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 1)")

print "\nFinal tidy up "
a=nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")

print "Final test, we will create some Shapes & pass them around like mad"
print "If there is any memory leak, you will see it in the memory usage"
io.flush()
sh={}
-- make some objects
for i=0,10 do
    a=example.Circle(i)
    b=example.Square(i)
    sh[a]=true
    sh[b]=true
end
o=example.ShapeOwner()
for i=0,10000 do
    for k,_ in pairs(sh) do
        o:add(k)
    end
    sh={}   -- clear it
    while true do
        a=o:remove(0)
        if a==nil then break end
        sh[a]=true
    end
    if i%100==0 then collectgarbage() end
end
print "done"
o,sh=nil,nil
collectgarbage()
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
print "that's all folks!"


print "[lua] This is runme.lua"
-- test program for embedded lua
-- we do not need to load the library, as it was already in the interpreter
-- but let's check anyway

assert(type(example)=='table',"Don't appear to have loaded the example module. Do not run this file directly, run the embed3 executable")

print "[lua] looking to see if we have a pointer to the engine"
if type(pEngine)=="userdata" then
    print "[lua] looks good"
else
    print "[lua] nope, no signs of it"
end

-- the embedded program expects a function void onEvent(Event)
-- this is it

function onEvent(e)
    print("[Lua] onEvent with event",e.mType)
    -- let's do something with the Engine
    -- nothing clever, but ...
    if e.mType==example.Event_STARTUP then
        pEngine:start()
    elseif e.mType==example.Event_KEYPRESS then
        pEngine:accelerate(0.4)
    elseif e.mType==example.Event_MOUSEPRESS then
        pEngine:decelerate(0.4)
    elseif e.mType==example.Event_SHUTDOWN then
        pEngine:stop()
    else
        error("unknown event type")
    end
    print("[Lua] ending onEvent")
end


	project "BulletFileLoader"

	kind "StaticLib"

	includedirs {
		"../../../src"
	}

	files {
		"**.cpp",
		"**.h"
	}


	project "BulletWorldImporter"

	kind "StaticLib"

	includedirs {
		"../BulletFileLoader",
		"../../../src"
	}

	files {
		"**.cpp",
		"**.h"
	}


	project "BulletDynamics"
	kind "StaticLib"
	includedirs {
		"..",
	}
	files {
		"Dynamics/*.cpp",
                "Dynamics/*.h",
                "ConstraintSolver/*.cpp",
                "ConstraintSolver/*.h",
                "Featherstone/*.cpp",
                "Featherstone/*.h",
                "MLCPSolvers/*.cpp",
                "MLCPSolvers/*.h",
                "Vehicle/*.cpp",
                "Vehicle/*.h",
                "Character/*.cpp",
                "Character/*.h"

	}


	project "LinearMath"

	kind "StaticLib"
	includedirs {
		"..",
	}
	files {
		"*.cpp",
		"*.h"
	}


	project "BulletCollision"

	kind "StaticLib"
	includedirs {
		"..",
	}
	files {
		"*.cpp",
		"*.h",
		"BroadphaseCollision/*.cpp",
		"BroadphaseCollision/*.h",
		"CollisionDispatch/*.cpp",
                "CollisionDispatch/*.h",
		"CollisionShapes/*.cpp",
		"CollisionShapes/*.h",
		"Gimpact/*.cpp",
		"Gimpact/*.h",
		"NarrowPhaseCollision/*.cpp",
		"NarrowPhaseCollision/*.h",
	}


	project "BulletSoftBody"

	kind "StaticLib"

	includedirs {
		"..",
	}
	files {
		"**.cpp",
		"**.h"
	}