Template tightening
parent
de650069e2
commit
aceeb2037b
|
@ -319,11 +319,11 @@ void Class::addMethod(bool verbose, bool is_const, Str methodName,
|
|||
const ArgumentList& argumentList, const ReturnValue& returnValue,
|
||||
const Template& tmplate) {
|
||||
// Check if templated
|
||||
if (!tmplate.argName.empty() && tmplate.argValues.size() > 0) {
|
||||
if (tmplate.valid()) {
|
||||
// Create method to expand
|
||||
// For all values of the template argument, create a new method
|
||||
BOOST_FOREACH(const Qualified& instName, tmplate.argValues) {
|
||||
const TemplateSubstitution ts(tmplate.argName, instName, *this);
|
||||
BOOST_FOREACH(const Qualified& instName, tmplate.argValues()) {
|
||||
const TemplateSubstitution ts(tmplate.argName(), instName, *this);
|
||||
// substitute template in arguments
|
||||
ArgumentList expandedArgs = argumentList.expandTemplate(ts);
|
||||
// do the same for return type
|
||||
|
|
|
@ -200,7 +200,7 @@ void Module::parseMarkup(const std::string& data) {
|
|||
Rule class_p =
|
||||
eps_p[assign_a(cls,cls0)]
|
||||
>> (!(classTemplate_g
|
||||
[push_back_a(cls.templateArgs, classTemplate.argName)]
|
||||
[push_back_a(cls.templateArgs, classTemplate.argName())]
|
||||
| templateList_p)
|
||||
>> !(str_p("virtual")[assign_a(cls.isVirtual, true)])
|
||||
>> str_p("class")
|
||||
|
@ -216,7 +216,7 @@ void Module::parseMarkup(const std::string& data) {
|
|||
[assign_a(cls.namespaces_, namespaces)]
|
||||
[assign_a(cls.deconstructor.name,cls.name_)]
|
||||
[bl::bind(&handle_possible_template, bl::var(classes), bl::var(cls),
|
||||
bl::var(classTemplate.argValues))]
|
||||
bl::var(classTemplate.argValues()))]
|
||||
[clear_a(classTemplate)]
|
||||
[assign_a(constructor, constructor0)]
|
||||
[assign_a(cls,cls0)];
|
||||
|
|
|
@ -23,13 +23,34 @@
|
|||
namespace wrap {
|
||||
|
||||
/// The template specification that goes before a method or a class
|
||||
struct Template {
|
||||
std::string argName;
|
||||
std::vector<Qualified> argValues;
|
||||
void clear() {
|
||||
argName.clear();
|
||||
argValues.clear();
|
||||
class Template {
|
||||
std::string argName_;
|
||||
std::vector<Qualified> argValues_;
|
||||
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();
|
||||
}
|
||||
const std::string& argName() const {
|
||||
return argName_;
|
||||
}
|
||||
const std::vector<Qualified>& argValues() const {
|
||||
return argValues_;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
@ -41,7 +62,7 @@ struct TemplateGrammar: public classic::grammar<TemplateGrammar> {
|
|||
|
||||
/// Construct type grammar and specify where result is placed
|
||||
TemplateGrammar(Template& result) :
|
||||
result_(result), argValues_g(result.argValues) {
|
||||
result_(result), argValues_g(result.argValues_) {
|
||||
}
|
||||
|
||||
/// Definition of type grammar
|
||||
|
@ -51,9 +72,10 @@ struct TemplateGrammar: public classic::grammar<TemplateGrammar> {
|
|||
classic::rule<ScannerT> templateArgValues_p;
|
||||
|
||||
definition(TemplateGrammar const& self) {
|
||||
using namespace classic;
|
||||
using classic::str_p;
|
||||
using classic::assign_a;
|
||||
templateArgValues_p = (str_p("template") >> '<'
|
||||
>> (BasicRules<ScannerT>::name_p)[assign_a(self.result_.argName)]
|
||||
>> (BasicRules<ScannerT>::name_p)[assign_a(self.result_.argName_)]
|
||||
>> '=' >> self.argValues_g >> '>');
|
||||
}
|
||||
|
||||
|
@ -65,5 +87,16 @@ struct TemplateGrammar: public classic::grammar<TemplateGrammar> {
|
|||
};
|
||||
// TemplateGrammar
|
||||
|
||||
}// \namespace wrap
|
||||
/// 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
|
||||
|
||||
|
|
|
@ -39,17 +39,14 @@ TEST( Class, OverloadingMethod ) {
|
|||
bool verbose = true, is_const = true;
|
||||
ArgumentList args;
|
||||
const ReturnValue retVal;
|
||||
const string templateArgName;
|
||||
vector<Qualified> templateArgValues;
|
||||
cls.addMethod(verbose, is_const, name, args, retVal, templateArgName,
|
||||
templateArgValues);
|
||||
const Template tmplate;
|
||||
cls.addMethod(verbose, is_const, name, args, retVal, tmplate);
|
||||
EXPECT_LONGS_EQUAL(1, cls.nrMethods());
|
||||
EXPECT(cls.exists(name));
|
||||
Method method = cls.method(name);
|
||||
EXPECT_LONGS_EQUAL(1, method.nrOverloads());
|
||||
|
||||
cls.addMethod(verbose, is_const, name, args, retVal, templateArgName,
|
||||
templateArgValues);
|
||||
cls.addMethod(verbose, is_const, name, args, retVal, tmplate);
|
||||
EXPECT_LONGS_EQUAL(1, cls.nrMethods());
|
||||
EXPECT_LONGS_EQUAL(2, method.nrOverloads());
|
||||
}
|
||||
|
@ -67,12 +64,10 @@ TEST( Class, TemplatedMethods ) {
|
|||
arg.type.name_ = "T";
|
||||
args.push_back(arg);
|
||||
const ReturnValue retVal(ReturnType("T"));
|
||||
const string templateArgName("T");
|
||||
vector<Qualified> templateArgValues;
|
||||
templateArgValues.push_back(Qualified("Point2"));
|
||||
templateArgValues.push_back(Qualified("Point3"));
|
||||
cls.addMethod(verbose, is_const, name, args, retVal, templateArgName,
|
||||
templateArgValues);
|
||||
boost::optional<Template> tmplate = //
|
||||
CreateTemplate("template<T = {Point2, Point3}>");
|
||||
CHECK(tmplate);
|
||||
cls.addMethod(verbose, is_const, name, args, retVal, *tmplate);
|
||||
EXPECT_LONGS_EQUAL(2, cls.nrMethods());
|
||||
EXPECT(cls.exists(name+"Point2"));
|
||||
EXPECT(cls.exists(name+"Point3"));
|
||||
|
|
|
@ -32,22 +32,35 @@ TEST( Template, grammar ) {
|
|||
TemplateGrammar g(actual);
|
||||
|
||||
EXPECT(parse("template<T = {gtsam::Point2, Matrix}>", g, space_p).full);
|
||||
EXPECT_LONGS_EQUAL(2, actual.argValues.size());
|
||||
EXPECT(actual.argName=="T");
|
||||
EXPECT(actual.argValues[0]==Qualified("gtsam","Point2",Qualified::CLASS));
|
||||
EXPECT(actual.argValues[1]==Qualified("Matrix",Qualified::EIGEN));
|
||||
EXPECT_LONGS_EQUAL(2, actual.nrValues());
|
||||
EXPECT(actual.argName()=="T");
|
||||
EXPECT(actual[0]==Qualified("gtsam","Point2",Qualified::CLASS));
|
||||
EXPECT(actual[1]==Qualified("Matrix",Qualified::EIGEN));
|
||||
actual.clear();
|
||||
|
||||
EXPECT(parse("template<ARG = {gtsam::Point2, gtsam::Point3, Vector, Matrix}>", g, space_p).full);
|
||||
EXPECT_LONGS_EQUAL(4, actual.argValues.size());
|
||||
EXPECT(actual.argName=="ARG");
|
||||
EXPECT(actual.argValues[0]==Qualified("gtsam","Point2",Qualified::CLASS));
|
||||
EXPECT(actual.argValues[1]==Qualified("gtsam","Point3",Qualified::CLASS));
|
||||
EXPECT(actual.argValues[2]==Qualified("Vector",Qualified::EIGEN));
|
||||
EXPECT(actual.argValues[3]==Qualified("Matrix",Qualified::EIGEN));
|
||||
EXPECT(
|
||||
parse("template<ARG = {gtsam::Point2, gtsam::Point3, Vector, Matrix}>", g, space_p).full);
|
||||
EXPECT_LONGS_EQUAL(4, actual.nrValues());
|
||||
EXPECT(actual.argName()=="ARG");
|
||||
EXPECT(actual[0]==Qualified("gtsam","Point2",Qualified::CLASS));
|
||||
EXPECT(actual[1]==Qualified("gtsam","Point3",Qualified::CLASS));
|
||||
EXPECT(actual[2]==Qualified("Vector",Qualified::EIGEN));
|
||||
EXPECT(actual[3]==Qualified("Matrix",Qualified::EIGEN));
|
||||
actual.clear();
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
TEST( Template, CreateTemplate ) {
|
||||
boost::optional<Template> actual = //
|
||||
CreateTemplate("template<T = {gtsam::Point2, Matrix}>");
|
||||
CHECK(actual);
|
||||
// aborts if not true
|
||||
EXPECT_LONGS_EQUAL(2, actual->nrValues());
|
||||
EXPECT(actual->argName()=="T");
|
||||
EXPECT((*actual)[0]==Qualified("gtsam","Point2",Qualified::CLASS));
|
||||
EXPECT((*actual)[1]==Qualified("Matrix",Qualified::EIGEN));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int main() {
|
||||
TestResult tr;
|
||||
|
|
Loading…
Reference in New Issue