Iterating C array-type container class from Lua using LuaBridge - c++

This may be a newbie question, but I have not been able to find an answer with web searching that will even help me get started. I have a container class that at heart is a C-style array. For simplicity, let's depict it as this:
int *myArray = new int[mySize];
With LuaBridge we can assume I have successfully registered it as my_array in the global namespace. I would like to iterate over it from Lua like this:
for n in each(my_array) do
... -- do something with n
end
I'm guessing I probably need to register a function each in the global namespace. The problem is, I don't know what that function should look like in C++.
<return-type> DoForEach (<function-signature that includes luabridge::LuaRef>)
{
// execute callback using luabridge::LuaRef, which I think I know how to do
return <return-type>; //what do I return here?
}
This would perhaps have been easier if the code had used std::vector but I am trying to create a Lua interface to an existing code base that is complicated to change.

I'm answering my own question, because I have figured out that the question makes some incorrect assumptions. The existing code I was working with was a true iterator class (which is what it is called in the Lua docs) implemented in c++. These cannot be used with for loops, but that's how you get a callback function in c++.
To do what I was originally asking, we'll assume we've made myArray available as table my_array in lua using LuaBridge or whichever interface you prefer. (This may require a wrapper class.) You implement what I was asking entirely in Lua as follows. (This is almost exactly an example in the Lua documentation, but somehow I missed it earlier.)
function each (t)
local i = 0
local n = table.getn(t)
return function ()
i = i + 1
if i <= n then return t[i] end
end
end
--my_array is a table linked to C++ myArray
--this can be done with a wrapper class if necessary
for n in each(my_array) do
... -- do something with n
end
If you want to provide the each function to every script you run, you add it directly from C++ as follows, before executing the script.
luaL_dostring(l,
"function each (t)" "\n"
"local i = 0" "\n"
"local n = table.getn(t)" "\n"
"return function ()" "\n"
" i = i + 1" "\n"
" if i <= n then return t[i] end" "\n"
"end" "\n"
"end"
);

Related

Define a c++ array as int[int] array(5);

I was experimenting with FreeFem++, which is basically a c++ compiler with some added libraries.
As you can see here: https://doc.freefem.org/references/types.html a 5-element array can be defined and printed as:
int n = 5;
real[int] Ai(n);
for (int i = 0; i < n; i++)
Ai[i] = i;
cout << Ai << endl;
(note that real is a custom type which is in fact a double).
As a (novice) c++ developer, I would have defined the class real using templates, and with the proper constructor I would have been able to do the same with some call like real<int>.
Question
is it possible to write a c++ library to make the above FreeFem++ code work (specifically, I want squared [] brackets, not <>)?
My attempt
Being FreeFem++ open source, I tried to have a look a t the code.
https://github.com/FreeFem/FreeFem-sources/blob/master/src/fflib/array_real.cpp
I can not really decipher it, however my guess is that it is not possible, and in fact is the FreeFem++ compiler that swaps the [int] with some <int>.
Bonus
Sometimes I also see parts of code like
cout << v[] << endl;
where it prints a vector, however to access elements of the vector I have to do v[][5]. What kind of sorcery is that? Overloading operator[](void) would never work, right?

Heterogeneous container of base class when the derived instances are not pointers

I have a base class and I want to store instances of its derivatives in a collection of some sort.
At first I created a map:
std::map<int, Variable> varriableItems;
and then ussing templates I created functions for each derivative and I tried passing in the derivatives like so:
template <>
void Array::addToMap<Number>(Number input)
{
numberVariables[itemCount_] = input;
itemCount_++;
}
By doing so this function was not called because everything was of type Variable of course and I found out about slicing.
So instead I changed my map to take in pointers to my base class
std::map<int, Variable*> varriableItems;
but the problem I have is that all my objects are not created as pointers so I could not pass them in and I was getting errors.
No suitable conversion from "Number" to "Variable" exists.
Due to my implementation I can only create instances of objects
like so:
auto aNumberVariable = Number{50};
Ofcourse if I instead do:
Number aNumberVariable = new Number(50);
it works great.
The reason am doing this is explained bellow.
Please bear with me because this is a weird assignment.
We were asked to create a program that behaves/understands the syntax of a programming language called Logo, without actually analyzing the text as an input file, but rather "disguise" it to appear as such while in fact we just use C++ using what we learned from C++ and lots of overloads and pre-processor tricks
We have to be able to make our own "types" of variables called NUMBER,WORD,BOOLEAN,ARRAY, LIST,SENTENCE.
To declare them we have to use(note no semi-colons should be used):
//define number variable with value 21
MAKE number = NUMBER: 21
//define hello variable with value “hello”
MAKE hello = WORD: “hello”
//define myMoves variable contains list of turtle moves
MAKE myMoves = LIST [
LIST [WORD: “FORWARD”, NUMBER: 100],
LIST [WORD: “LEFT”, NUMBER: 90],
LIST [WORD: “FORWARD”, NUMBER: 100]
]
//define array variable with empty array
MAKE array = ARRAY {
number,
hello,
NUMBER: 12
BOOLEAN: TRUE,
ARRAY {
myMoves,
LIST [WORD: “BACK”, NUMBER: 100]
}
}
//define book variable with sentence type
MAKE book = SENTENCE (hello, WORD: “hello!”)
That's just a small part, we later have to support functions, nested loops , etc.
So do this I have to find a way to use the colon since I cannot overload it, so I did this:
//Create an instance of Number and write the first half of the ternary operator so we
//always get the false value so we can use the : like this
#define NUMBER Number{} = (false) ? 0
//semicolon infront for the previous command that needs it
#define MAKE ;auto
So now this:
//following commands will deal with the semicolon
MAKE myNumber = NUMBER: 21
worked great and it actually gets replaced by the processor to this:
auto myNumber = Number{} = (false) ? 0 : 21
So i worked with this for all my derivatives and I proceeded to overload operators to compare them, implement if else function in a similarly weird syntax.
Now I either have to figure out a way to make this work again but this time creating them as pointer instead (Which I assume is the only way for this to work, but I so far I couldn't figure it out) or create a single class for all types but doing it in separate objects that all inherit from a single base class makes more sense to me.
And am not sure how strict they will be, it is an unconventional project assignment for sure.
The reason I want to hold them together in a container is so I can then implement an Array and list object that can hold every type. At first I tried to use a different container for each type and made an iterator to iterate multiple maps separately, but when I got to the LIST implementation things got weird.
The list syntax is using the brackets [ ] which can only get 1 input value, so the idea was to collect them by overloading the comma operator and pass in one value to the list object.
I know this is weird , thank you for your time
I didn't read through all of your post. (actually I did because your task is so ... beyond words) but if you need polymorphism in a container and you also need the container to hold the objects, then the solution is unique_ptr:
container<std::unique_ptr<Base>>
In your case it would go something along this:
std::unordered_map<int, std::unique_ptr<Variable>> varriableItems;
varriableItems[0] = std::make_unique<Number>(50);

How to return void in a function in OCaml?

Simple example: I have some functions and I need to call them all, to modify a structure, only in one function. With these simple functions the task can be made in ways that don't use void, but in others tasks you have to use void. So what can you do?
type player = { mutable name : string; mutable points : int } ;;
let putname brad = match brad with
{ name = x; points = y } -> { name = brad; points = y } ;;
let putpoint guy score = match guy with
{ name = x; points = y } -> { name = x; points = score } ;;
let loosers listplayer guy = guy :: listplayer ;;
Here is the problem - How can I do the next function?
let someoneloses guy = void
guy = putpoint guy 0 ;;
listplayer = loosers (listplayer guy) ;;
Given you are using the name "void" I'm assuming you are more familiar with C (or C++). In OCaml the equivalent of "void" (the name of the type for no value) is "unit". There is another difference though: while in C the syntax is complex enough that it have constructs for no values (for instance, you can either "return a_value;" or "return;", two differents yet syntactically valid use cases for the keyword "return"), in OCaml the syntax is simpler and always require a value. So we have a notation for "nothing", which is, astutely but maybe also confusedly, is written "()".
So, the OCaml equivalent of the C:
void do_nothing(void) { return; }
is written:
let do_nothing () = ()
(notice how OCaml syntax is simpler and easier to grok once you got the "()" trick).
Now that this is hopefully clearer, back to your question.
A function that returns nothing is a function that return "()", either explicitly (as "do_nothing" above) or because it ends with an expression that has "()" as its value. For instance, an assignment (something tell me you'll love assignments), such as:
let putpoint guy score = guy.points <- score
Now back to your problem. You seem to be doing some kind of game with players represented as mutable records and some functions modifying those records as the game develop. You need not use pattern matching for that. Actually, functions such as "putpoint" above is probably what you want. But then you need some more state in your program: the list of loosers for instance is probably going to be a reference to a list that you modify etc.
This is the "imperative" side of OCaml but there is another one, which is usually regarded as more elegant although often slower in general (but not in functional languages which are optimised for this technique), consisting of refraining from altering state (changing values of things) but instead using functions merely taking values and returning values. Implemented like this, a player would be represented as an immutable record and each function acting a user would take an "old user" and return a "new user", and the same goes with the list of loosers, and so on. Actually, the whole game state would be represented as a big value that the "main loop" of your program would, given the previous value, and possible also the time and user inputs, would compute the "new state" and return it.
Have fun!
Also, your question has nothing to do with ocaml-batteries.
since you are using mutable data, you just have to assigned the value directly.
let p = {name = "me";points=0};;
let update x = x.name <- "you";
x.points <- 3;;
update p ;;

Adding "->" in Objective C

Ok so I'm fairly new to objective c and i'm building a concordance class, inside the class i got a method which adds a word from a book into a a _ListofPtrsToUniqueWords, uniqueWord is another class i built for storing the word being cataloged, well in c++ my method Adds the UniqueWord to an Array of Unique Words, if it already exist its skips the word but it add a line number to the _CurrentLineArray list, this is the method i used on C++
/* Attempts to add a word to the concordance. If it already exists, the existing entry is updated with the new line. */
void Concordance::add(const string word, const int line)
{
int insertion, index;
UniqueWord *uw = new UniqueWord(word, line);//creates the uniqueWord object
insertion = newIndex(*uw, index);//figures out where my word belongs in my array to be alphabetized
if (insertion == -1)
{
// The word already exists - add a line number.
delete uw;
ListOfUniqueWordsPtrs[index]->addLine(line);//I'm trying to do this in Objective C.
//My friend recommended i do this but i never asks what exactly does it do, addLine is a Unique word method
}
else
{
ListOfUniqueWordsPtrs.insert(ListOfUniqueWordsPtrs.begin() + insertion, uw);
}
}
Now i'm trying to do the same in Objective C but i don't understand what this symbol does "->", my friend just recommended i do this but i don't understand what it does and how can i implament this in Objective C
-(void) add:(NSString *)currentWordBeingCatalog and:(NSNumber*)CurrentLineNumber{
NSInteger insertion, index=0;
UniqueWord *CurrentWord=[[UniqueWord alloc] initWithString:currentWordBeingCatalog andline:CurrentLineNumber];
insertion=[self NewIndexToFindOutIf:CurrentWord is:[NSNumber numberWithLong:index]];
if(insertion==-1){
/*If the word already exist, it would delete the word and add the line number to the _linenumber NSMutableArray*/
CurrentWord=NULL;
[_ArrayOfPtrsToUniqueWords objectAtIndex:index]->[CurrentWord addALineNumberToCurrentLineNumberArray:CurrentLineNumber]];//This is where i'm trying to figure out what to do
}else{
[_ArrayOfPtrsToUniqueWords insertObject:CurrentWord atIndex:(0+insertion)];
}
}
I hope i give you guys enough information on this code, thank you
This is the syntax you are looking for:
[[_ArrayOfPtrsToUniqueWords objectAtIndex:index] addALineNumberToCurrentLineNumberArray:CurrentLineNumber];
... which is to say, you're asking the array to return one of its elements, and then you're asking that element to add a line number.
You can break it down like this if you prefer:
UniqueWord *existingWord = [_ArrayOfPtrsToUniqueWords objectAtIndex:index];
[existingWord addALineNumberToCurrentLineNumberArray:CurrentLineNumber];
You can also use array subscripting directly on NSArray and NSMutableArray objects, so if _ArrayOfPtrsToUniqueWords is an NSMutableArray, you can do this:
UniqueWord *existingWord = _ArrayOfPtrsToUniqueWords[index];
[existingWord addALineNumberToCurrentLineNumberArray:CurrentLineNumber];
or this:
[_ArrayOfPtrsToUniqueWords[index] addALineNumberToCurrentLineNumberArray:CurrentLineNumber];
The -> does something similar in Objective-C to what it does in C++, it is placed after a pointer to an object to access it's instance variables (in C++ it is also used to call methods, whereas in Objective-C the [instance methodName] syntax is used). Properties are usually preferred to the -> notation in Objective-C however. It's use in your code seems erroneous, rob mayoff did a pretty good job of rectifying it.

Simplest lua function that returns a vector of strings

I need a very simple c++ function that calls a lua function that returns an array of strings, and stores them as a c++ vector. The function can look something like this:
std::vector<string> call_lua_func(string lua_source_code);
(where lua source code contains a lua function that returns an array of strings).
Any ideas?
Thanks!
Here is some source that may work for you. It may need some more polish and testing. It expects that the Lua chunk is returning the array of strings, but with slight modification could call a named function in the chunk. So, as-is, it works with "return {'a'}" as a parameter, but not "function a() return {'a'} end" as a parameter.
extern "C" {
#include "../src/lua.h"
#include "../src/lauxlib.h"
}
std::vector<string> call_lua_func(string lua_source_code)
{
std::vector<string> list_strings;
// create a Lua state
lua_State *L = luaL_newstate();
lua_settop(L,0);
// execute the string chunk
luaL_dostring(L, lua_source_code.c_str());
// if only one return value, and value is a table
if(lua_gettop(L) == 1 && lua_istable(L, 1))
{
// for each entry in the table
int len = lua_objlen(L, 1);
for(int i=1;i <= len; i++)
{
// get the entry to stack
lua_pushinteger(L, i);
lua_gettable(L, 1);
// get table entry as string
const char *s = lua_tostring(L, -1);
if(s)
{
// push the value to the vector
list_strings.push_back(s);
}
// remove entry from stack
lua_pop(L,1);
}
}
// destroy the Lua state
lua_close(L);
return list_strings;
}
First of all, remember Lua arrays can contain not only integers but also other types as keys.
Then, you can import the Lua source code using luaL_loadstring.
At this point, the only requirement left is the "return vector".
Now, you can use lua_istable to check whether a value is a table(array) and use lua_gettable to extract the multiple fields(see http://www.lua.org/pil/25.1.html) and manually add them one by one to the vector.
If you can not figure out how to deal with the stack, there seem to be some tutorials to help you. To find the number of elements, I found this mailing list post, which might be helpful.
Right now, I don't have Lua installed, so I can't test this information. But I hope it helps anyway.
Not really an answer to your question:
I've had a lot of trouble when writing c++ <=> lua interface code with the plain lua c-api. Then I tested many different lua-wrapper and I really suggest luabind if you are trying to achieve anything more or less complex. It's possible to make types available to lua in seconds, the support for smart pointers works great and (compared to other projects) the documentation is more or less good.