C++ Multi type map like PHP stdClass - c++

I'm using the libjson for parsing a JSON file in C++. I was wondering if you could do something like a PHP style notation for a map:
Just some pseudo code:
mapObj["id"] = 4;
mapObj["tags"] = vector {"Foo", "Bar"};
structMapObj = {
{"name", "FooBar"},
{"size", 1234567},
{"date", "2014-12-24"}
};
mapObj["file"] = anotherMapObject;
// for the vector
mapObj["tags"][0];
mapObj["tags"][1];
mapObj["tags"].size();
mapObj["tags"].pushBack("Foo");
// for the map
mapObj["file"]["name"]
...
Is it possible to receive a result like this?
Maybe an enum for the current type in the BaseClass?
myObj["key"].getType; // returns a 1 for example an INT
I tried to make it with a BaseClass and a template class, but I wasn't able to iterate through the object. Or should I even overload the operators for my BaseClass? Or is it necessary to inherit the BaseClass for each case (a class for the map-type object, a class for the int-type, for string and so on)?
I'm a a little bit desperate right now. Just need someone who leads me into the right direction :-P
PS: I don't want to use boost :-/
Thank you very much,
Daniel

I appreciate that you don't want to use boost. However, this problem has been solved in boost.
You are essentially wanting a map of strings to variants.
Have a look at the source code for boost::variant and boost::any. Take particular note of how boost gets round the problem of recursive definitions, for example when you want to store a map inside an element of another map.
This will teach you more than you ever wanted to know on this subject :-)

There is an open source project for C++Builder programmer called JSonCBB library. This library provides a semantic like to your need: http://www.cbuilderblog.com/jsoncbuilderblog-class-library/

Related

C++ 'object'? alike the .NET's and Java's object

In C# you can write the below and if the type is correct it just works. Is there something like that which exist in C++?
object o = anything;
...
var anything2=(Anything)o;
Maybe boost::any is what you are looking for? It is not quite the same but might be applicable for your particular scenario
Avoid using object use interface or templates instead. Which is the reason you need something like that?? In case if you need to store a group of objects in the same list (for example) or something like that then all of your objects probably has something common. So all of them should implement an interface and your list will be like ( std::list< IMyObject* > ).
If you want a type that is a pointer to anything, then that would be void*.
The difference is that in C#, you can safely convert (almost) anything into a reference. In C++, it's not that simple and if you have something that's not a pointer, you can't just convert it to void* and expect it to work.
But, I try to avoid using object in C# whenever possible. And the same applies to void* in C++. Try to use the type system, not work around it.

exposing boost::tuple part of class to boost python

I've been trying to figure out how to expose a property in my class that is a boost::tuple. The tuple is defined as follows:
typedef boost::shared_ptr<Action> action_ptr;
typedef boost::tuple<BattleCharacter*, action_ptr > ActionTargetTuple;
It's contained with a class defined as follows:
class Action : public Cloneable<Action>
{
public:
//Irrelevant Code Omitted
std::vector<ActionTargetTuple> Targets;
}
I've seen numerous articles while I was searching about how to convert a boost::tuple into a python tuple, but that's not what I'm looking to do. I want to be able to access the tuple as it exists on the Action class. (I know how to do the vector part).
class_<Action, std::auto_ptr<ActionWrapper> >("Action")
.def("Targets", &Action::Targets)
;
I expose it simply as above. I figured I might be able to expose it by some variation on the below:
class_<ActionTargetTuple>("ActionTargetTuple")
.def("get", &ActionTargetTuple::get<int>, return_value_policy<reference_existing_object>())
;
then use get from python, but if it is doable in this way, I'm not sure what the set up needs to be. Does anyone know how to do this/could suggest an alternative?
Thanks
You can use:
...
.add_property("Targets", & ActionTargetTuple::get, &ActionTargetTuple::set)
to make a read-write property using getter/setter methods in c++
If you want to control ownership:
namespace bp = boost::python;
...
.add_property("Targets",
bp::make_function(&ActionTargetTuple::get, bp::return_value_policy<...>()),
bp::make_function(&ActionTargetTuple::set, bp::return_value_policy<...>())
)
Besides using add_property as explained in the previous answer, and writing accessor functions, you can consider writing converters for your tuple (between boost::tuple and boost::python::tuple) and exposing those attributes directly with def_readonly or def_readwrite. It is worth it if you have many such attributes to expose.
This has a template you adapt can for c++→python conversion (use boost::tuple instead of std::pair), though unless you go c++0x, you have to write out templates for different number of arguments.
If your property is read-write, additionaly define from-python converter, you find examples on the web. Here is my code I use to define generic sequence-std::vector converter. In your case, you have to check that the python object is a sequence, that it has the right number of items, that you can extract required types from each of them; and then return new boost::tuple object.
HTH, edx.
P.S. I found ackward has the converters ready, perhaps you could just reuse it. Doc here

How to allow your data structure to take in objects of any class - C++

How do I do that? Like you know in Java, you can use an ArrayList and it will take any object as long as you cast it down to whatever it is when you're retrieving the object.
Even better, you can specify what class of objects that ArrayList would store by doing...
new ArrayList()< whateverObject >
I've implemented a linked list data structure in C++ and I'd like to know how I can allow it to do this...
At the moment, I'm just using...
typedef whateverObject ItemType
at the start of my header file for my linked list and then manipulating "ItemType" throughout the implementation of the linked list. So every time I want to change the type, e.g. instead of using the list for storing strings, I want to store an int, I'll have to change the typedef in my linked list's header but I want to be able to simply use it for any object so...
How?!
Thanks.
Templates are the answer to your question.
Define your linked list as follows :
template<typename ItemType>
class ArrayList
{
// What's inside your class definition does not need to be changed
// Include your method definitions here and you'll be fine
};
The type to use is then ArrayList<WhateverObject>.
Use templates. It's a lot to explain so I'll just give you a link where it's explained much better than I'll ever be able to do here: C++ FAQ - Templates.
While you're at it, if you have the time, I suggest you read the whole FAQ, it's really a great resource!
If I have understood well what you ask, templates is what you want.
Take a look here:
http://www.cplusplus.com/doc/tutorial/templates/
In java you can do so, because all classes are inherited from one base class Object. In C++ you do not have it. The reason is that Object base class impose overhead for all objects, while C++ do not like any unnecessary overhead.
If you want to store any object - you can store "void *" data type. The question remained - what you will be able to do with objects, without the knowledge of the type? If you do know - you can cast to the needed type and use it. The practice described above is not safe, and templates are better in most cases.

What is the typical usage of boost any library?

What are the advantages of using boost.any library ? Could you please give me some real life examples ? Why the same functionality couldn't be achieved by having some generic type in the root of object's hierarchy and creating containers with that base type ?
boost::any will happily store ints and floats, types that clearly have no base classes. A real-life example where you can use it is a virtual machine for a high-level interpreted language. Your "function" objects will need an array of arguments. This can easily be implemented with a std::list<boost::any> behind the scenes.
I consider that Boost.Variant should always be preferred as it's non-intrusive and still calls for very structured programming.
But i guess the main idea behind boost.any is to provide the equivalent of java and c# object types. It's a way of saying "yes we can" ! :-)
We've used it in a property map, (std::map<std::string, boost::any>), to store a lot of things dynamically in a simple, flat dataspace.
Mostly we either stored smart-ptr-to-scriptable-objects or strings, but some entries where other types (floats, vec3f, matrices, and other non-standard objects).
It works pretty well for adding more dynamic capabilities to c++, or wherever you want some type-erasure to just add any type of data to an object.
Why the same functionality couldn't be achieved by having some generic type in the root of object's hierarchy and creating containers with that base type ?
That calls an object hierarchy -- a construct you are injecting in artificially in to the design for solving a peripheral problem. Further, such a construct is easy to get wrong and a wrong implementation can wreak havoc. Boost.Any is a community reviewed safe, well-tested alternative.
Could you please give me some real life examples ?
TinyJSON uses boost.Any.
What are the advantages of using boost.any library ?
I refer the introductory documentation.
We use boost.any as the carrier type for a type-safe tagged variadic container. Here's what that means:
We have a "raft" object, which travels through a set of filters. When a filter wants to add data to the raft, it can do something like this:
raft.addTaggedData<ETag1>(3.0);
raft.addTaggedData<ETag2>("a string")`;
std::string str = raft.getTaggedData<ETag2>();
int a = raft.getTaggedData<ETag1>(); // <-- Compile error
Where ETag1 and ETag2 are members of an enum, and we use a traits template to map tags to types.
The raft class is using a list of pair<ETagType, boost::any> as a backing store. Boost.any saved us the pain of managing raw buffers for various types.

Best way to take a snapshot of an object to a file

What's the best way to output the public contents of an object to a human-readable file? I'm looking for a way to do this that would not require me to know of all the members of the class, but rather use the compiler to tell me what members exist, and what their names are. There have to be macros or something like that, right?
Contrived example:
class Container
{
public:
Container::Container() {/*initialize members*/};
int stuff;
int otherStuff;
};
Container myCollection;
I would like to be able to do something to see output along the lines of "myCollection: stuff = value, otherStuff = value".
But then if another member is added to Container,
class Container
{
public:
Container::Container() {/*initialize members*/};
int stuff;
string evenMoreStuff;
int otherStuff;
};
Container myCollection;
This time, the output of this snapshot would be "myCollection: stuff = value, evenMoreStuff=value, otherStuff = value"
Is there a macro that would help me accomplish this? Is this even possible? (Also, I can't modify the Container class.)
Another note: I'm most interested about a potential macros in VS, but other solutions are welcome too.
What you're looking for is "[reflection](http://en.wikipedia.org/wiki/Reflection_(computer_science)#C.2B.2B)".
I found two promising links with a Google search for "C++ reflection":
http://www.garret.ru/cppreflection/docs/reflect.html
http://seal-reflex.web.cern.ch/seal-reflex/index.html
Boost has a serialization library that can serialize into text files. You will, however, not be able to get around with now knowing what members the class contains. You would need reflection, which C++ does not have.
Take a look at this library .
What you need is object serialization or object marshalling. A recurrent thema in stackoverflow.
I'd highly recommend taking a look at Google's Protocol Buffers.
There's unfortunately no macro that can do this for you. What you're looking for is a reflective type library. These can vary from fairly simple to home-rolled monstrosities that have no place in a work environment.
There's no real simple way of doing this, and though you may be tempted to simply dump the memory at an address like so:
char *buffer = new char[sizeof(Container)];
memcpy(buffer, containerInstance, sizeof(Container));
I'd really suggest against it unless all you have are simple types.
If you want something really simple but not complete, I'd suggest writing your own
printOn(ostream &) member method.
XDR is one way to do this in a platform independent way.