stlmap.bmx ======== This project implements a TIntMap object which you can use to store BlitzMax objects using integer keys. The code utilizes a second c++ file to do the hard work.
If you are new to C/C++ programming, there is a difference! Files ending with .c are c programs which are extremely easy to link to from BlitzMax. C++ programs use the .cpp suffix and require a few more skills when imported into blitzmax files.
' stlmap.bmx
' example of utilizing c++ stl from blitzmax
Import "stlmap.cpp"
Extern "C"
Function intmap_create%()
Function intmap_set%(intmap%,key%,value:Object)
Function intmap_get:Object(intmap%,key%)
End Extern
Type TIntMap
Field intmap
Method New()
intmap=intmap_create()
End Method
Method Set(key:Int,value:Object)
intmap_set(intmap,key,value)
End Method
Method Get:Object(key:Int)
Return intmap_get(intmap,key)
End Method
End Type
Local imap:TIntMap
imap=New TIntMap
imap.Set(3,"Three")
imap.Set(5,"Five")
imap.Set(8,"Eight")
For i=1 To 5000
l$=String(imap.Get(Rand(10)))
If l<>Null Print "l="+l
Next
Print "Done"
The import command references the following file which should be created with the specified name in the same folder as the intmap.bmx.
The Extern "C" block lists the C style interfaces to the c++ functions we implement below. Unfortunately BlitzMax is not capable of interfacing with c++ objects at a class level (with the exception of com style iunknown interfaces). This may change in future but for now C++ code will usually require some "C" exported declarations in order for it to be usable from BlitzMax.
// stlmap.cpp
// example of utilizing c++ stl from blitzmax
#include <set>
#include <map>
#include <list>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
// this stuff would normally going in separate .h file...
#include <brl.mod/blitz.mod/blitz.h>
extern "C"{
void *intmap_create();
void intmap_set(void*stlmap,int key,BBObject*value);
BBObject *intmap_get(void *stlmap,int key);
}
// and now the the code...
using namespace std;
typedef map<int,BBObject*> intmap;
void *intmap_create(){
return new intmap();
}
void intmap_set(void*stlmap,int key,BBObject*value){
intmap *imap;
BBObject *obj;
imap=(intmap*)stlmap;
//release old value
obj=(*imap)[key];
if (obj) bbObjectRelease(obj);
// retain new value if not null
if (value==&bbNullObject)
value=0;
else
bbObjectRetain(value);
// and set...
(*imap)[key]=value;
}
BBObject *intmap_get(void *stlmap,int key){
intmap *imap;
BBObject *obj;
imap=(intmap*)stlmap;
//release old value
obj=(*imap)[key];
if (!obj) obj=&bbNullObject;
return obj;
}
A few things to note about the c++ code is the use of the blitz.h header file from the brl.blitz module. Blitzmax helpfully adds $blitzmax/mod as a default path whenever compiling C/C++ so the blitz.h file doesnt require an absolute path, making the project nice and portable.
This blitz.h file enables us to behave nicely with Blitz objects passed into the code with the above illustrating the use of the bbObjectRetain, bbObjectRelease and bbNullObject which are actually defined in blitz_object.h which is included along with a bunch of other very interesting headers by the blitz.h file.
The extern "C" block is where the C style interface is defined that matches the Export "C" block of the bmx file. If a c++ function is not declared prior to definition as extern "C" it will suffer from a name mangling process that makes it difficult to locate from blitzmax and will not on some compilers use the stdcall calling convention resulting in possibly erroneous behavior.
Exercises for the reader:
Implement a clear method to wipe the map and dereference all the bbObjects referenced.
Implement a count method that returns the number of items in the map.
Implement a method for enumerating either keys or values in the tree.
|