SkillAgentSearch skills...

Svar

A Tiny Modern C++ Header Brings Unified Interface for Different Languages

Install / Use

/learn @zdzhaoyong/Svar
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Svar, A Tiny Modern C++ Header Brings Unified Interface for Different Languages


Build Status Build Status Codacy Badge License Version

Paper Introduction: https://arxiv.org/abs/2108.08464 , if you wanna use Svar in your research, please cite:

@misc{zhao2021svar,
      title={Svar: A Tiny C++ Header Brings Unified Interface for Multiple programming Languages}, 
      author={Yong Zhao and Pengcheng Zhao and Shibiao Xu and Lin Chen and Pengcheng Han and Shuhui Bu and Hongkai Jiang},
      year={2021},
      eprint={2108.08464},
      archivePrefix={arXiv},
      primaryClass={cs.PL}
}

Quick start

<table> <tr> <th>1. Bind C++ to hello.so</th> <th>2. Import by C++</th> <th>3. Import by Python</th> </tr> <tr> <td valign="top"> <pre> #include &lt;Svar.h&gt; &nbsp; void say(std::string v){ std::cerr&lt;&lt;v&lt;&lt;std::endl; } REGISTER_SVAR_MODULE(hello) { svar["say"] = say; } EXPORT_SVAR_INSTANCE </pre></td> <td valign="top"> <pre> #include &lt;Svar.h&gt; &nbsp; auto m=svar.import("hello"); int main(){ m["say"]("hello world"); return 0; } </pre></td> <td valign="top"> <pre> import svar hello = svar.load("hello") hello.say("hello world") </pre></td> <tr> <th>4. Import by Javascript</th> <th>5. C++ import Python</th> <th>6. Javascript import Python</th> </tr> <tr> <td valign="top"> <pre> svar = require('./svar') hello = svar('hello') hello.say("hello world") </pre></td> <td valign="top"> <pre> #include &lt;Svar.h&gt; &nbsp; auto py=svar.import("svarpy"); int main(){ auto os = py["import]("os"); std::cout&lt;&lt;"Pid is:" &lt;&lt;os["getpid"](); return 0; } </pre></td> <td valign="top"> <pre> svar=require("./svar") python=svar("svarpy") os=python.import("os") print("Pid is", os.getpid()) </pre></td> </table>

Why Svar?

Svar is a powerful tiny modern c++ header implemented the following functionals:

  • JSON with buffer: Svar natually support JSON, but more than JSON, where JSON is only a subset of Svar data structure.
  • Argument parsing: Svar manages parameter in tree style, so that configuration in JSON format can be supported.
  • More than std::any after c++17: Svar is able to hold everything, including variables, functions, and classes. They can be used directly without declare header, just like writing Python or JavaScript!
  • A general plugin form. The released library comes with documentation, making *.h header file interface description unnecessary.
  • Auto multi-languages api. By Using Svar, your C++ library can be called easily with different languages like C++, Java, Python and Javascript.

Compile and Install

Obtain source code from github

git clone https://github.com/zdzhaoyong/Svar

Compile the source code with cmake:

cd Svar
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
sudo make install

Usages

Perform tests

Usage help:

svar --help
svar tests

Use Svar like JSON

Svar natually support JSON and here is some basic usage demo:

    Svar null=nullptr;
    Svar b=false;
    Svar i=1;
    Svar d=2.1;
    Svar s="hello world";
    Svar v={1,2,3};
    Svar m={{"b",false},{"s","hello world"},{"n",nullptr},{"u",Svar()}};

    Svar obj;
    obj["m"]=m;
    obj["pi"]=3.14159;

    std::cout<<obj<<std::endl;

    if(s.is<std::string>()) // use is to check type
        std::cout<<"raw string is "<<s.as<std::string>()<<std::endl; // use as to cast, never throw

    double db=i.castAs<double>();// use castAs, this may throw SvarException

    for(auto it:v) std::cout<<it<<std::endl;

    for(std::pair<std::string,Svar> it:m) std::cout<<it.first<<":"<<it.second<<std::endl;

    std::string json=m.dump_json();
    m=Svar::parse_json(json);

You can run the above code with:

svar sample -json

Use Svar for Argument Parsing

Svar provides argument parsing functional with JSON configuration loading. Here is a small demo shows how to use Svar for argument parsing:


int main(int argc,char** argv)
{
    svar.parseMain(argc,argv);

    int  argInt=svar.arg<int>("i",0,"This is a demo int parameter");
    bool bv=svar.arg("b.dump",false,"Svar supports tree item assign");
    Svar m =svar.arg("obj",Svar(),"Svar support json parameter");

    if(svar.get<bool>("help",false)){
        svar.help();
        return 0;
    }
    if(svar["b"]["dump"].as<bool>())
        std::cerr<<svar;
    return 0;
}

When you use "--help" or "-help", the terminal should show the below introduction:

-> sample_use --help
Usage:
sample_use [--help] [-conf configure_file] [-arg_name arg_value]...

Using Svar supported argument parsing. The following table listed several argume
nt introductions.

Argument        Type(default->setted)           Introduction
--------------------------------------------------------------------------------
-i              int(0)                          This is a demo int parameter
-b.dump         bool(false)                     Svar supports tree item assign
-obj            svar(undefined)                 Svar support json parameter
-conf           str("Default.cfg")              The default configure file going
                                                 to parse.
-help           bool(false->true)               Show the help information.

"help" and "conf" is two default parameters and users can use "conf" to load JSON file for configuration loading.

Svar supports the following parsing styles:

  • "-arg value": two '-' such as "--arg value" is the same
  • "-arg=value": two "--" such as "--arg=value" is the same
  • "arg=value"
  • "-arg" : this is the same with "arg=true", but the next argument should not be a value

Svar supports to use brief Json instead of strict Json:

sample_use -b.dump -obj '{a:1,b:false}'

Svar Holding Everything

Hold Class Instances

Svar support to hold different values:

    struct A{int a,b,c;}; // define a struct

    A a={1,2,3};
    Svar avar=a;      // support directly value copy assign
    Svar aptrvar=&a;  // support pointer value assign
    Svar uptrvar=std::unique_ptr<A>(new A({2,3,4}));
    Svar sptrvar=std::shared_ptr<A>(new A({2,3,4})); // support shared_ptr lvalue

    std::cout<<avar.as<A>().a<<std::endl;
    std::cout<<aptrvar.as<A>().a<<std::endl;
    std::cout<<uptrvar.as<A>().a<<std::endl;
    std::cout<<sptrvar.as<A>().a<<std::endl;

    std::cout<<avar.castAs<A*>()->b<<std::endl;
    std::cout<<aptrvar.as<A*>()->b<<std::endl;
    std::cout<<uptrvar.castAs<A*>()->b<<std::endl;
    std::cout<<sptrvar.castAs<A*>()->b<<std::endl;

    std::cout<<uptrvar.as<std::unique_ptr<A>>()->b<<std::endl;
    std::cout<<sptrvar.as<std::shared_ptr<A>>()->b<<std::endl;

Run the above sample with 'svar sample -instance'.

Hold Functions

void c_func_demo(Svar arg){
    std::cout<<"Calling a c_func with arg "<<arg<<std::endl;
}

int sample_func(){
    Svar c_func=c_func_demo;
    c_func("I love Svar");

    Svar lambda=[](std::string arg){std::cout<<arg<<std::endl;};
    lambda("Using a lambda");

    Svar member_func(&SvarBuffer::md5);
    std::cout<<"Obtain md5 with member function: "
            <<member_func(SvarBuffer(3)).as<std::string>()<<std::endl;

    return 0;
}

Run the above sample with 'svar sample -func'.

Hold and use a Class


class Person{
public:
    Person(int age,std::string name)
        : _age(age),_name(name){
        all_person()[name]=_age;
    }

    virtual std::string intro()const{
        return Svar({{"Person",{_age,_name}}}).dump_json();
    }

    int age()const{return _age;}

    static Svar& all_person(){
        static Svar all;
        return all;
    }

    int _age;
    std::string _name;
};

class Student: public Person{
public:
    Student(int age,std::string name,std::string school)
        : Person(age,name),_school(school){}

    virtual std::string intro()const{
        return Svar({{"Student",{_age,_name,_school}}}).dump_json();
    }

    void setSchool(const std::string& school){
        _school=school;
    }

    std::string _school;
};

{
    // define the class to svar
    Class<Person>("Person","The base class")
            .construct<int,std::string>()
            .def("intro",&Person::intro)
            .def_static("all",&Person::all_person)
            .def("age",&Person::age)
            .def_readonly("name",&Person::_name,"The name of a person");

    Class<Student>("Student","The derived class")
            .construct<int,std::string,std::string>()
            .inherit<Person>()
            .def("intro",&Student::intro)
            .def("setSchool",&Student::setSchool)
 

Related Skills

View on GitHub
GitHub Stars158
CategoryDevelopment
Updated1mo ago
Forks19

Languages

C++

Security Score

80/100

Audited on Mar 3, 2026

No findings