147 lines
3.8 KiB
C++
147 lines
3.8 KiB
C++
/* ----------------------------------------------------------------------------
|
|
|
|
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
|
* Atlanta, Georgia 30332-0415
|
|
* All Rights Reserved
|
|
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
|
|
|
* See LICENSE for the license information
|
|
|
|
* -------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
* @file Template.h
|
|
* @brief Template name
|
|
* @author Frank Dellaert
|
|
* @date Nov 11, 2014
|
|
**/
|
|
|
|
#pragma once
|
|
|
|
#include <wrap/Qualified.h>
|
|
|
|
namespace wrap {
|
|
|
|
/// The template specification that goes before a method or a class
|
|
class Template {
|
|
std::string argName_;
|
|
std::vector<Qualified> argValues_;
|
|
std::vector<int> intList_;
|
|
friend struct TemplateGrammar;
|
|
public:
|
|
/// The only way to get values into a Template is via our friendly Grammar
|
|
Template() {
|
|
}
|
|
void clear() {
|
|
argName_.clear();
|
|
argValues_.clear();
|
|
intList_.clear();
|
|
}
|
|
const std::string& argName() const {
|
|
return argName_;
|
|
}
|
|
const std::vector<int>& intList() const {
|
|
return intList_;
|
|
}
|
|
const std::vector<Qualified>& argValues() const {
|
|
return argValues_;
|
|
}
|
|
bool empty() const {
|
|
return argValues_.empty() && intList_.empty();
|
|
}
|
|
size_t nrValues() const {
|
|
return argValues_.size();
|
|
}
|
|
const Qualified& operator[](size_t i) const {
|
|
return argValues_[i];
|
|
}
|
|
bool valid() const {
|
|
return !argName_.empty() && argValues_.size() > 0;
|
|
}
|
|
|
|
};
|
|
|
|
/* ************************************************************************* */
|
|
// http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html
|
|
struct IntListGrammar: public classic::grammar<IntListGrammar > {
|
|
|
|
typedef std::vector<int> IntList;
|
|
IntList& result_; ///< successful parse will be placed in here
|
|
|
|
/// Construct type grammar and specify where result is placed
|
|
IntListGrammar(IntList& result) :
|
|
result_(result) {
|
|
}
|
|
|
|
/// Definition of type grammar
|
|
template<typename ScannerT>
|
|
struct definition {
|
|
|
|
classic::rule<ScannerT> integer_p, intList_p;
|
|
|
|
definition(IntListGrammar const& self) {
|
|
using namespace classic;
|
|
|
|
integer_p = int_p[push_back_a(self.result_)];
|
|
|
|
intList_p = '{' >> !integer_p >> *(',' >> integer_p) >> '}';
|
|
}
|
|
|
|
classic::rule<ScannerT> const& start() const {
|
|
return intList_p;
|
|
}
|
|
|
|
};
|
|
};
|
|
// IntListGrammar
|
|
|
|
/* ************************************************************************* */
|
|
// http://boost-spirit.com/distrib/spirit_1_8_2/libs/spirit/doc/grammar.html
|
|
struct TemplateGrammar: public classic::grammar<TemplateGrammar> {
|
|
|
|
Template& result_; ///< successful parse will be placed in here
|
|
TypeListGrammar<'{', '}'> argValues_g; ///< TypeList parser
|
|
IntListGrammar intList_g; ///< TypeList parser
|
|
|
|
/// Construct type grammar and specify where result is placed
|
|
TemplateGrammar(Template& result) :
|
|
result_(result), argValues_g(result.argValues_), //
|
|
intList_g(result.intList_) {
|
|
}
|
|
|
|
/// Definition of type grammar
|
|
template<typename ScannerT>
|
|
struct definition: BasicRules<ScannerT> {
|
|
|
|
classic::rule<ScannerT> templateArgValues_p;
|
|
|
|
definition(TemplateGrammar const& self) {
|
|
using classic::str_p;
|
|
using classic::assign_a;
|
|
templateArgValues_p = (str_p("template") >> '<'
|
|
>> (BasicRules<ScannerT>::name_p)[assign_a(self.result_.argName_)]
|
|
>> '=' >> (self.argValues_g | self.intList_g) >> '>');
|
|
}
|
|
|
|
classic::rule<ScannerT> const& start() const {
|
|
return templateArgValues_p;
|
|
}
|
|
|
|
};
|
|
};
|
|
// TemplateGrammar
|
|
|
|
/// Cool initializer for tests
|
|
static inline boost::optional<Template> CreateTemplate(const std::string& s) {
|
|
Template result;
|
|
TemplateGrammar g(result);
|
|
bool success = parse(s.c_str(), g, classic::space_p).full;
|
|
if (success)
|
|
return result;
|
|
else
|
|
return boost::none;
|
|
}
|
|
|
|
} // \namespace wrap
|
|
|