Skip to content

Instantly share code, notes, and snippets.

@sanuj
Last active May 16, 2016 16:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sanuj/3a343c8a31c4e9a4c657 to your computer and use it in GitHub Desktop.
Save sanuj/3a343c8a31c4e9a4c657 to your computer and use it in GitHub Desktop.
Design Draft for parameter framework for Shogun

Tags and string parameters

Tags

Template class for Tag will look like:

template <class T>
class Tag
{
    public:
        Tag(std::string name) : name_(name) { };
        std::string getName() {return name_;};
    private:
        std::string name_;
};

Use a hashmap to set/get parameters for a class via Tags:

class SGObject
{
	public:
	    /** default constructor */
		SGObject() {};

		~SGObject();

	    template <typename T>
	    void set(Tag<T> tag, T value);

		template <typename T>
		T& get(Tag<T> tag);

	protected:
		std::unordered_map<std::string, Any*> tag_map;
};

template <typename T>
void SGObject::set(Tag<T> tag, T value)
{
	tag_map[tag.getName()] = new Any(value);
}

template <typename T>
T& SGObject::get(Tag<T> tag)
{
	Any* a = tag_map[tag.getName()];
	return a->as<T>();
}

SGObject::~SGObject() {
	// use auto here?
	for(std::unordered_map<std::string, Any*>::iterator it = tag_map.begin(); it != tag_map.end(); ++it)
		delete(it->second);
}

This is how to set/get parameters:

SGObject obj;

Tag<std::string> name_tag("name");
std::string s1 = "square";
obj.set(name_tag, s1);

Tag<int> length_tag("side");
obj.set(length_tag, 10);

std::cout << length_tag.getName() << " of a " << obj.get(name_tag) << " object is : " << obj.get(length_tag) << std::endl;
// Outputs --> side of a square object is : 10

String parameters

Ideally user should have an API like this:

kernel = shogun.GaussianKernel()
kernel.set("width", 1.0)

SWIG Interface

%module shogun
%include "std_string.i"
%{
#include <src/shogun/SGObject.hpp>
%}

%include <src/shogun/Tag.hpp>
%include <src/shogun/SGObject.hpp>

namespace shogun {
    %template(TagInt) Tag<int>;
    %template(TagFloat) Tag<float>;
    %template(TagString) Tag<std::string>;

    %template(setInt) SGObject::set<int>;
    %template(setFloat) SGObject::set<float>;
    %template(setString) SGObject::set<std::string>;

    %template(getInt) SGObject::get<int>;
    %template(getFloat) SGObject::get<float>;
    %template(getString) SGObject::get<std::string>;
}

The above code allows the following python magic:

from shogun import *

obj = SGObject()
num_tag = TagInt("num")
obj.setInt(num_tag, 10)
print 3 + obj.getInt(num_tag)		#outputs 13

# More features coming soon

A working demo can be found at this GitHub repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment