add opendcm constraint solver

This commit is contained in:
Stefan Tröger
2013-04-25 12:14:01 +02:00
committed by Stefan Tröger
parent d50f7f1787
commit 02bc130c42
53 changed files with 9940 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_DEFINES_STATE_H
#define DCM_DEFINES_STATE_H
#include "opendcm/core/property.hpp"
#include "opendcm/core/clustergraph.hpp"
namespace dcm {
namespace details {
struct cluster_vertex_prop {
typedef GlobalVertex type;
typedef cluster_property kind;
};
}
}
#endif

View File

@@ -0,0 +1,72 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EDGE_GENERATOR_H
#define DCM_EDGE_GENERATOR_H
#include "property_generator.hpp"
#include "object_generator.hpp"
#include "extractor.hpp"
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/support/is_sequence.hpp>
#include <boost/fusion/include/is_sequence.hpp>
namespace karma = boost::spirit::karma;
namespace phx = boost::phoenix;
namespace dcm {
namespace details {
template<typename Sys>
struct edge_generator : karma::grammar<Iterator, std::vector<fusion::vector3<typename Sys::Cluster::edge_bundle, GlobalVertex, GlobalVertex> >()> {
edge_generator();
karma::rule<Iterator, std::vector<fusion::vector3<typename Sys::Cluster::edge_bundle, GlobalVertex, GlobalVertex> >()> edge_range;
karma::rule<Iterator, fusion::vector3<typename Sys::Cluster::edge_bundle, GlobalVertex, GlobalVertex>()> edge;
karma::rule<Iterator, std::vector<typename Sys::Cluster::edge_bundle_single>&()> globaledge_range;
karma::rule<Iterator, typename Sys::Cluster::edge_bundle_single()> globaledge;
details::edge_prop_gen<Sys> edge_prop;
details::obj_gen<Sys> objects;
Extractor<Sys> ex;
};
template<typename Sys>
struct vertex_generator : karma::grammar<Iterator, std::vector<typename Sys::Cluster::vertex_bundle>()> {
vertex_generator();
karma::rule<Iterator, std::vector<typename Sys::Cluster::vertex_bundle>()> vertex_range;
karma::rule<Iterator, typename Sys::Cluster::vertex_bundle()> vertex;
details::vertex_prop_gen<Sys> vertex_prop;
details::obj_gen<Sys> objects;
Extractor<Sys> ex;
};
}//details
}//dcm
#ifndef USE_EXTERNAL
#include "edge_vertex_generator_imp.hpp"
#endif
#endif

View File

@@ -0,0 +1,57 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EDGE_GENERATOR_IMP_H
#define DCM_EDGE_GENERATOR_IMP_H
#include "edge_vertex_generator.hpp"
namespace dcm {
namespace details {
template<typename Sys>
edge_generator<Sys>::edge_generator() : edge_generator<Sys>::base_type(edge_range) {
globaledge = karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeID, ex, karma::_val, karma::_1)]
<< " source=" << karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeSource, ex, karma::_val, karma::_1)]
<< " target=" << karma::int_[phx::bind(&Extractor<Sys>::getGlobalEdgeTarget, ex, karma::_val, karma::_1)] << '>'
<< "+" << objects[karma::_1 = phx::at_c<0>(karma::_val)] << "-\n" ;
globaledge_range = *(karma::lit("<GlobalEdge id=")<<globaledge<<karma::lit("</GlobalEdge>"));
edge = karma::lit("source=")<<karma::int_[karma::_1 = phx::at_c<1>(karma::_val)] << " target="<<karma::int_[karma::_1 = phx::at_c<2>(karma::_val)] << ">+"
<< edge_prop[karma::_1 = phx::at_c<0>(phx::at_c<0>(karma::_val))]
<< karma::eol << globaledge_range[karma::_1 = phx::at_c<1>(phx::at_c<0>(karma::_val))] << '-' << karma::eol;
edge_range = (karma::lit("<Edge ") << edge << karma::lit("</Edge>")) % karma::eol;
};
template<typename Sys>
vertex_generator<Sys>::vertex_generator() : vertex_generator<Sys>::base_type(vertex_range) {
vertex = karma::int_ << ">+" << vertex_prop << objects << "-\n";
vertex_range = '\n' << (karma::lit("<Vertex id=") << vertex << karma::lit("</Vertex>")) % karma::eol;
};
}//details
}//dcm
#endif

View File

@@ -0,0 +1,71 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EDGE_VERTEX_PARSER_H
#define DCM_EDGE_VERTEX_PARSER_H
#include <boost/spirit/include/qi.hpp>
#include "opendcm/core/clustergraph.hpp"
#include "extractor.hpp"
namespace qi = boost::spirit::qi;
namespace fusion = boost::fusion;
namespace dcm {
typedef boost::spirit::istream_iterator IIterator;
namespace details {
template<typename Sys>
struct edge_parser : qi::grammar< IIterator, fusion::vector<LocalEdge, GlobalEdge, bool, bool>(typename Sys::Cluster*, Sys*),
qi::space_type > {
edge_parser();
details::obj_par<Sys> objects;
Injector<Sys> in;
qi::rule<IIterator, fusion::vector<LocalEdge, GlobalEdge, bool, bool>(typename Sys::Cluster*, Sys*), qi::space_type> edge;
qi::rule<IIterator, typename Sys::Cluster::edge_bundle_single(Sys*), qi::space_type> global_edge;
details::edge_prop_par<Sys> edge_prop;
};
template<typename Sys>
struct vertex_parser : qi::grammar< IIterator, fusion::vector<LocalVertex, GlobalVertex>(typename Sys::Cluster*, Sys*),
qi::space_type> {
vertex_parser();
details::obj_par<Sys> objects;
Injector<Sys> in;
qi::rule<IIterator, fusion::vector<LocalVertex, GlobalVertex>(typename Sys::Cluster*, Sys*), qi::space_type> vertex;
details::vertex_prop_par<Sys> prop;
};
}
}
//#ifndef USE_EXTERNAL
//#include "edge_vertex_parser_imp.hpp"
//#endif
#endif

View File

@@ -0,0 +1,55 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EDGE_PARSER_IMP_H
#define DCM_EDGE_PARSER_IMP_H
#include "edge_vertex_parser.hpp"
namespace dcm {
namespace details {
template<typename Sys>
edge_parser<Sys>::edge_parser() : edge_parser<Sys>::base_type(edge) {
global_edge = qi::lit("<GlobalEdge") >> qi::lit("id=") >> qi::int_[phx::bind(&GlobalEdge::ID, phx::at_c<1>(qi::_val)) = qi::_1]
>> qi::lit("source=") >> qi::int_[phx::bind(&GlobalEdge::source, phx::at_c<1>(qi::_val)) = qi::_1]
>> qi::lit("target=") >> qi::int_[phx::bind(&GlobalEdge::target, phx::at_c<1>(qi::_val)) = qi::_1] >> '>'
>> objects(qi::_r1)[phx::at_c<0>(qi::_val) = qi::_1] >> "</GlobalEdge>";
edge = (qi::lit("<Edge") >> "source=" >> qi::int_ >> "target=" >> qi::int_ >> '>')[qi::_val = phx::bind((&Sys::Cluster::addEdgeGlobal), qi::_r1, qi::_1, qi::_2)]
>> edge_prop[phx::bind(&Injector<Sys>::setEdgeProperties, in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> *global_edge(qi::_r2)
>> ("</Edge>");
};
template<typename Sys>
vertex_parser<Sys>::vertex_parser() : vertex_parser<Sys>::base_type(vertex) {
vertex = qi::lit("<Vertex")[phx::bind(&Injector<Sys>::addVertex, in, qi::_r1, qi::_val)] >> qi::lit("id=")
>> qi::int_[phx::at_c<1>(qi::_val) = phx::bind(&Sys::Cluster::setGlobalVertex, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> '>' >> prop[phx::bind(&Injector<Sys>::setVertexProperties, in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> objects(qi::_r2)[phx::bind(&Injector<Sys>::setVertexObjects, in, qi::_r1, phx::at_c<0>(qi::_val), qi::_1)]
>> ("</Vertex>");
};
}//details
}//dcm
#endif

View File

@@ -0,0 +1,119 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_EXTRACTOR_H
#define DCM_EXTRACTOR_H
#include "defines.hpp"
#include <opendcm/core/clustergraph.hpp>
#include <boost/fusion/include/at_c.hpp>
namespace fusion = boost::fusion;
namespace dcm {
typedef std::ostream_iterator<char> Iterator;
template<typename Sys>
struct Extractor {
typedef typename boost::graph_traits<typename Sys::Cluster>::vertex_iterator viter;
typedef typename boost::graph_traits<typename Sys::Cluster>::edge_iterator eiter;
void getVertexRange(typename Sys::Cluster& cluster, std::vector<typename Sys::Cluster::vertex_bundle>& range) {
std::pair<viter, viter> res = boost::vertices(cluster);
for(; res.first != res.second; res.first++)
range.push_back(cluster[*res.first]);
};
void getEdgeRange(typename Sys::Cluster& cluster,
std::vector<fusion::vector3<typename Sys::Cluster::edge_bundle, GlobalVertex, GlobalVertex> >& range) {
std::pair<eiter, eiter> res = boost::edges(cluster);
for(; res.first != res.second; res.first++)
range.push_back(fusion::make_vector(cluster[*res.first],
cluster.getGlobalVertex(boost::source(*res.first, cluster)),
cluster.getGlobalVertex(boost::target(*res.first, cluster))));
};
void getGlobalEdgeSource(typename Sys::Cluster::edge_bundle_single b, int& source) {
source = fusion::at_c<1>(b).source;
};
void getGlobalEdgeTarget(typename Sys::Cluster::edge_bundle_single b, int& target) {
target = fusion::at_c<1>(b).target;
};
void getGlobalEdgeID(typename Sys::Cluster::edge_bundle_single b, int& id) {
id = fusion::at_c<1>(b).ID;
};
void setVertexID(typename Sys::Cluster* cluster, LocalVertex v, long& l) {
if(v)
l = cluster->getGlobalVertex(v);
else
l = 0;
};
void getClusterRange(typename Sys::Cluster& cluster, std::vector<std::pair<GlobalVertex, typename Sys::Cluster*> >& range) {
typedef typename Sys::Cluster::const_cluster_iterator iter;
for(iter it = cluster.m_clusters.begin(); it != cluster.m_clusters.end(); it++) {
range.push_back( std::make_pair( cluster.getGlobalVertex((*it).first), (*it).second.get() ));
};
};
};
template<typename Sys>
struct Injector {
void setClusterProperties(typename Sys::Cluster* cluster,
typename details::pts<typename Sys::Cluster::cluster_properties>::type& prop) {
cluster->m_cluster_bundle = prop;
};
void setVertexProperties(typename Sys::Cluster* cluster, LocalVertex v,
typename details::pts<typename Sys::vertex_properties>::type& prop) {
fusion::at_c<1>(cluster->operator[](v)) = prop;
};
void setVertexObjects(typename Sys::Cluster* cluster, LocalVertex v,
typename details::sps<typename Sys::objects>::type& obj) {
fusion::at_c<2>(cluster->operator[](v)) = obj;
};
void setEdgeProperties(typename Sys::Cluster* cluster, LocalEdge e,
typename details::pts<typename Sys::edge_properties>::type& prop) {
fusion::at_c<0>(cluster->operator[](e)) = prop;
};
void setVertexProperty(typename Sys::Cluster* cluster, int value) {
cluster->template setClusterProperty<details::cluster_vertex_prop>(value);
};
void addCluster(typename Sys::Cluster* cluster, typename Sys::Cluster* addcl) {
LocalVertex v = cluster->getLocalVertex(addcl->template getClusterProperty<details::cluster_vertex_prop>()).first;
cluster->m_clusters[v] = boost::shared_ptr<typename Sys::Cluster>(addcl);
};
void addVertex(typename Sys::Cluster* cluster, fusion::vector<LocalVertex, GlobalVertex>& vec) {
vec = cluster->addVertex();
};
};
}//namespace dcm
#endif //DCM_GENERATOR_H

View File

@@ -0,0 +1,82 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_GENERATOR_H
#define DCM_GENERATOR_H
#include "property_generator.hpp"
#include "edge_vertex_generator.hpp"
#include "extractor.hpp"
#include <opendcm/core/clustergraph.hpp>
#include "traits.hpp"
#include "traits_impl.hpp"
#include "indent.hpp"
#include <boost/mpl/int.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/fusion/container/vector/convert.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace karma = boost::spirit::karma;
namespace phx = boost::phoenix;
namespace fusion = boost::fusion;
namespace dcm {
typedef std::ostream_iterator<char> Iterator;
template<typename Sys>
struct generator : karma::grammar<Iterator, typename Sys::Cluster& ()> {
typedef typename Sys::Cluster graph;
typedef typename graph::cluster_bundle graph_bundle;
typedef typename boost::graph_traits<graph>::vertex_iterator viter;
typedef typename boost::graph_traits<graph>::edge_iterator eiter;
generator();
karma::rule<Iterator, graph& ()> start;
karma::rule<Iterator, std::pair<GlobalVertex, graph*>()> cluster_pair;
karma::rule<Iterator, graph&()> cluster;
details::cluster_prop_gen<Sys> cluster_prop;
details::vertex_generator<Sys> vertex_range;
details::edge_generator<Sys> edge_range;
Extractor<Sys> ex;
};
}//namespace dcm
#ifndef USE_EXTERNAL
#include "generator_imp.hpp"
#endif
#endif //DCM_GENERATOR_H

View File

@@ -0,0 +1,72 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_GENERATOR_IMP_H
#define DCM_GENERATOR_IMP_H
#include "generator.hpp"
#include "opendcm/core/clustergraph.hpp"
//#include "karma_trans.hpp"
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
BOOST_FUSION_ADAPT_TPL_STRUCT(
(T1)(T2)(T3)(T4),
(dcm::ClusterGraph) (T1)(T2)(T3)(T4),
(int, test)
(typename dcm::details::pts<T3>::type, m_cluster_bundle))
namespace boost { namespace spirit { namespace traits
{
template <typename T1, typename T2, typename T3, typename T4>
struct transform_attribute<dcm::ClusterGraph<T1,T2,T3,T4>* const, dcm::ClusterGraph<T1,T2,T3,T4>&, karma::domain>
{
typedef dcm::ClusterGraph<T1,T2,T3,T4>& type;
static type pre(dcm::ClusterGraph<T1,T2,T3,T4>* const& val) {
return *val;
}
};
}}}
namespace dcm {
template<typename Sys>
generator<Sys>::generator() : generator<Sys>::base_type(start) {
cluster %= karma::omit[karma::int_] << cluster_prop << -vertex_range[phx::bind(&Extractor<Sys>::getVertexRange, ex, karma::_val, karma::_1)]
<< -karma::buffer["\n" << edge_range[phx::bind(&Extractor<Sys>::getEdgeRange, ex, karma::_val, karma::_1)]]
<< -karma::buffer["\n" << (cluster_pair % karma::eol)[phx::bind(&Extractor<Sys>::getClusterRange, ex, karma::_val, karma::_1)]] << "-\n"
<< "</Cluster>";
cluster_pair %= karma::lit("<Cluster id=") << karma::int_ << ">+"
<< karma::attr_cast<graph*,graph&>(cluster);
start %= karma::lit("<Cluster id=0>+") << cluster;
};
}//namespace dcm
#endif //DCM_GENERATOR_H

View File

@@ -0,0 +1,63 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_INDENT_H
#define DCM_INDENT_H
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/operations.hpp>
#include <boost/iostreams/filtering_stream.hpp>
class indent_filter : public boost::iostreams::output_filter {
public:
explicit indent_filter() : indent(0) {};
template<typename Sink>
bool put(Sink& dest, int c) {
if(c == '+') {
indent++;
return true;
} else if(c == '-') {
indent--;
return true;
} else if(c == '\n') {
bool ret = boost::iostreams::put(dest, c);
for(int i=0; (i<indent) && ret; i++) {
ret = boost::iostreams::put(dest, ' ');
ret = boost::iostreams::put(dest, ' ');
}
return ret;
};
indent = (indent < 0) ? 0 : indent;
return boost::iostreams::put(dest, c);
}
template<typename Source>
void close(Source&) {
indent = 0;
}
private:
int indent;
};
#endif //DCM_INDENT_H

View File

@@ -0,0 +1,155 @@
/*//////////////////////////////////////////////////////////////////////////////
Copyright (c) 2011 Jamboree
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//////////////////////////////////////////////////////////////////////////////*/
#ifndef BOOST_SPIRIT_REPOSITORY_KARMA_TRANS
#define BOOST_SPIRIT_REPOSITORY_KARMA_TRANS
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace repository
{
namespace tag
{
struct trans {};
}
namespace karma
{
// enables trans<T>(f)[...]
template <typename T, typename F>
inline
spirit::stateful_tag_type<F, tag::trans, T> trans(F f)
{
return spirit::stateful_tag_type<F, tag::trans, T>(f);
}
// enables trans(f)[...]
template <typename F>
inline
spirit::stateful_tag_type<F, tag::trans> trans(F f)
{
return spirit::stateful_tag_type<F, tag::trans>(f);
}
}
}}}
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables trans<T>(f)[...]
template <typename F, typename T>
struct use_directive<karma::domain, tag::stateful_tag<F, repository::tag::trans, T> >
: mpl::true_ {};
}} // namespace boost::spirit
namespace boost { namespace spirit { namespace repository {namespace karma
{
template <typename Subject, typename T, typename F>
struct trans_directive
: spirit::karma::unary_generator<trans_directive<Subject, T, F> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
: mpl::eval_if
<
is_same<T, unused_type>
, traits::attribute_of<subject_type, Context, Iterator>
, mpl::identity<T>
>
{};
trans_directive(Subject const& subject, F f)
: subject(subject), f(f)
{}
template
<
typename OutputIterator, typename Context
, typename Delimiter, typename Attribute
>
bool generate
(
OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
return subject.generate(sink, ctx, d, f(attr));
}
template <typename Context>
info what(Context& context) const
{
return info("trans", subject.what(context));
}
Subject subject;
F f;
};
}}}} // namespace boost::spirit::repository::karma
namespace boost { namespace spirit { namespace karma
{
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename F, typename T, typename Subject, typename Modifiers>
struct make_directive<tag::stateful_tag<F, repository::tag::trans, T>, Subject, Modifiers>
{
typedef repository::karma::trans_directive<Subject, T, F> result_type;
template <typename StatefulTag>
result_type operator()(
StatefulTag const& tag, Subject const& subject, unused_type) const
{
return result_type(subject, tag.data_);
}
};
}}} // namespace boost::spirit::karma
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename T, typename F>
struct has_semantic_action<repository::karma::trans_directive<Subject, T, F> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename T, typename F
, typename Attribute, typename Context, typename Iterator>
struct handles_container
<
repository::karma::trans_directive<Subject, T, F>
, Attribute, Context, Iterator
>
: mpl::false_ {}; // FIXME
}}} // namespace boost::spirit::traits
#endif

View File

@@ -0,0 +1,98 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_MODULE_STATE_H
#define DCM_MODULE_STATE_H
#include <iosfwd>
#include "indent.hpp"
#include "generator.hpp"
#include "parser.hpp"
#include "defines.hpp"
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
namespace qi = boost::spirit::qi;
namespace dcm {
struct ModuleState {
template<typename Sys>
struct type {
typedef Unspecified_Identifier Identifier;
struct inheriter {
inheriter() {
m_this = (Sys*) this;
};
Sys* m_this;
void saveState(std::ostream& stream) {
boost::iostreams::filtering_ostream indent_stream;
indent_stream.push(indent_filter());
indent_stream.push(stream);
std::ostream_iterator<char> out(indent_stream);
generator<Sys> gen;
karma::generate(out, gen, *m_this->m_cluster);
};
void loadState(std::istream& stream) {
//disable skipping of whitespace
stream.unsetf(std::ios::skipws);
// wrap istream into iterator
boost::spirit::istream_iterator begin(stream);
boost::spirit::istream_iterator end;
// use iterator to parse file data
parser<Sys> par;
m_this->clear();
typename Sys::Cluster* cl_ptr = m_this->m_cluster.get();
qi::phrase_parse(begin, end, par(m_this), qi::space, cl_ptr);
};
};
//add only a property to the cluster as we need it to store the clusers global vertex
typedef mpl::vector1<details::cluster_vertex_prop> properties;
typedef mpl::vector0<> objects;
//nothing to do on startup
static void system_init(Sys& sys) {};
};
};
}
#endif //DCM_MODULE_STATE_H

View File

@@ -0,0 +1,72 @@
#ifndef DCM_OBJECT_GENERATOR_H
#define DCM_OBJECT_GENERATOR_H
#include "property_generator.hpp"
namespace fusion = boost::fusion;
namespace dcm {
typedef std::ostream_iterator<char> Iterator;
namespace details {
//grammar for a single object
template<typename Sys, typename Object, typename Gen>
struct obj_grammar : public karma::grammar<Iterator, boost::shared_ptr<Object>()> {
typename Gen::generator subrule;
karma::rule<Iterator, boost::shared_ptr<Object>()> start;
details::prop_gen<Sys, typename Object::Sequence > prop;
obj_grammar();
static void getProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::Sequence>::type& seq);
};
//when objects should not be generated we need to get a empy rule, as obj_rule_init
//trys always to access the rules attribute and when the parser_generator trait is not
//specialitzed it's impossible to have the attribute type right in the unspecialized trait
template<typename Sys, typename seq, typename state>
struct obj_generator_fold : mpl::fold< seq, state,
mpl::if_< parser_generate<mpl::_2, Sys>,
mpl::push_back<mpl::_1,
obj_grammar<Sys, mpl::_2, dcm::parser_generator<mpl::_2, Sys, Iterator> > >,
mpl::push_back<mpl::_1, details::empty_grammar > > > {};
//currently max. 10 objects are supported
template<typename Sys>
struct obj_gen : public karma::grammar<Iterator, typename details::sps<typename Sys::objects>::type()> {
typedef typename Sys::objects ObjectList;
//create a vector with the appropriate rules for all objects. Do this with the rule init struct, as it gives
//automatic initialisation of the rules when the objects are created
typedef typename obj_generator_fold<Sys, ObjectList,mpl::vector<> >::type init_rules_vector;
//push back a empty rule so that we know where to go when nothing is to do
typedef typename mpl::push_back<init_rules_vector, empty_grammar >::type rules_vector;
//create the fusion sequence of our rules
typedef typename fusion::result_of::as_vector<rules_vector>::type rules_sequnce;
//this struct returns the right accessvalue for the sequences. If we access a value bigger than the property vector size
//we use the last rule, as we made sure this is an empty one
template<int I>
struct index : public mpl::if_< mpl::less<mpl::int_<I>, mpl::size<ObjectList> >,
mpl::int_<I>, typename mpl::size<ObjectList>::prior >::type {};
//this struct tells us if we should execute the generator
template<int I>
struct valid : public mpl::less< mpl::int_<I>, mpl::size<ObjectList> > {};
rules_sequnce rules;
karma::rule<Iterator, typename details::sps<ObjectList>::type()> obj;
obj_gen();
};
} //namespace details
}//dcm
#ifndef USE_EXTERNAL
#include "object_generator_imp.hpp"
#endif
#endif //DCM_OBJECT_GENERATOR_H

View File

@@ -0,0 +1,57 @@
#ifndef DCM_OBJECT_GENERATOR_IMP_H
#define DCM_OBJECT_GENERATOR_IMP_H
#include "traits_impl.hpp"
#include "object_generator.hpp"
#include "property_generator_imp.hpp"
using namespace boost::spirit::karma;
namespace karma = boost::spirit::karma;
namespace phx = boost::phoenix;
namespace fusion = boost::fusion;
namespace dcm {
typedef std::ostream_iterator<char> Iterator;
namespace details {
template<typename Sys, typename Object, typename Gen>
obj_grammar<Sys, Object,Gen>::obj_grammar() : obj_grammar<Sys, Object,Gen>::base_type(start) {
Gen::init(subrule);
start = lit("\n<Object>") << '+' << eol << subrule
<< prop[phx::bind(&obj_grammar::getProperties, _val, karma::_1)]
<< '-' << eol << lit("</Object>");
};
template<typename Sys, typename Object, typename Gen>
void obj_grammar<Sys, Object,Gen>::getProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::Sequence>::type& seq) {
if(ptr) seq = ptr->m_properties;
else {
//TODO: throw
};
};
template<typename Sys>
obj_gen<Sys>::obj_gen() : obj_gen<Sys>::base_type(obj) {
obj = -(eps(valid<0>::value) << eps(phx::at_c<index<0>::value>(_val)) << fusion::at<index<0> >(rules)[karma::_1 = phx::at_c<index<0>::value>(_val)])
<< -(eps(valid<1>::value) << eps(phx::at_c<index<1>::value>(_val)) << fusion::at<index<1> >(rules)[karma::_1 = phx::at_c<index<1>::value>(_val)])
<< -(eps(valid<2>::value) << eps(phx::at_c<index<2>::value>(_val)) << fusion::at<index<2> >(rules)[karma::_1 = phx::at_c<index<2>::value>(_val)])
<< -(eps(valid<3>::value) << eps(phx::at_c<index<3>::value>(_val)) << fusion::at<index<3> >(rules)[karma::_1 = phx::at_c<index<3>::value>(_val)])
<< -(eps(valid<4>::value) << eps(phx::at_c<index<4>::value>(_val)) << fusion::at<index<4> >(rules)[karma::_1 = phx::at_c<index<4>::value>(_val)])
<< -(eps(valid<5>::value) << eps(phx::at_c<index<5>::value>(_val)) << fusion::at<index<5> >(rules)[karma::_1 = phx::at_c<index<5>::value>(_val)])
<< -(eps(valid<6>::value) << eps(phx::at_c<index<6>::value>(_val)) << fusion::at<index<6> >(rules)[karma::_1 = phx::at_c<index<6>::value>(_val)])
<< -(eps(valid<7>::value) << eps(phx::at_c<index<7>::value>(_val)) << fusion::at<index<7> >(rules)[karma::_1 = phx::at_c<index<7>::value>(_val)])
<< -(eps(valid<8>::value) << eps(phx::at_c<index<8>::value>(_val)) << fusion::at<index<8> >(rules)[karma::_1 = phx::at_c<index<8>::value>(_val)])
<< -(eps(valid<9>::value) << eps(phx::at_c<index<9>::value>(_val)) << fusion::at<index<9> >(rules)[karma::_1 = phx::at_c<index<9>::value>(_val)]);
};
} //namespace details
}//dcm
#endif //DCM_OBJECT_GENERATOR_H

View File

@@ -0,0 +1,98 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_OBJECT_PARSER_H
#define DCM_OBJECT_PARSER_H
#include "property_parser.hpp"
namespace dcm {
namespace details {
template<typename Obj, typename Sys>
struct empty_obj_parser : public qi::grammar<IIterator, boost::shared_ptr<Obj>(Sys*), qi::space_type> {
qi::rule<IIterator, boost::shared_ptr<Obj>(Sys*), qi::space_type> start;
empty_obj_parser(): empty_obj_parser::base_type(start) {
//start = qi::eps(false);
};
};
//grammar for a single object
template<typename Sys, typename Object, typename Par>
struct obj_parser : public qi::grammar<IIterator, boost::shared_ptr<Object>(Sys*), qi::space_type> {
typename Par::parser subrule;
qi::rule<IIterator, boost::shared_ptr<Object>(Sys*), qi::space_type> start;
prop_par<Sys, typename Object::Sequence > prop;
obj_parser();
static void setProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::Sequence>::type& seq);
};
//when objects should not be generated we need to get a empy rule, as obj_rule_init
//trys always to access the rules attribute and when the parser_generator trait is not
//specialitzed it's impossible to have the attribute type right in the unspecialized trait
template<typename Sys, typename seq, typename state>
struct obj_parser_fold : mpl::fold< seq, state,
mpl::if_< parser_parse<mpl::_2, Sys>,
mpl::push_back<mpl::_1,
obj_parser<Sys, mpl::_2, dcm::parser_parser<mpl::_2, Sys, IIterator> > >,
mpl::push_back<mpl::_1, empty_obj_parser<mpl::_2, Sys> > > > {};
//currently max. 10 objects are supported
template<typename Sys>
struct obj_par : public qi::grammar<IIterator,
typename details::sps<typename Sys::objects>::type(Sys*),
qi::space_type> {
typedef typename Sys::objects ObjectList;
//create a vector with the appropriate rules for all objects. Do this with the rule init struct, as it gives
//automatic initialisation of the rules when the objects are created
typedef typename obj_parser_fold<Sys, ObjectList, mpl::vector<> >::type init_rules_vector;
//push back a empty rule so that we know where to go when nothing is to do
typedef typename mpl::push_back<init_rules_vector,
empty_obj_parser<typename mpl::back<ObjectList>::type, Sys> >::type rules_vector;
//create the fusion sequence of our rules
typedef typename fusion::result_of::as_vector<rules_vector>::type rules_sequnce;
//this struct returns the right accessvalue for the sequences. If we access a value bigger than the property vector size
//we use the last rule, as we made sure this is an empty one
template<int I>
struct index : public mpl::if_< mpl::less<mpl::int_<I>, mpl::size<ObjectList> >,
mpl::int_<I>, typename mpl::size<ObjectList>::prior >::type {};
//this struct tells us if we should execute the generator
template<int I>
struct valid : public mpl::less< mpl::int_<I>, mpl::size<ObjectList> > {};
rules_sequnce rules;
qi::rule<IIterator, typename details::sps<ObjectList>::type(Sys*), qi::space_type> obj;
obj_par();
};
}//details
}//DCM
#ifndef USE_EXTERNAL
#include "property_parser_imp.hpp"
#endif
#endif

View File

@@ -0,0 +1,63 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_OBJECT_PARSER_IMP_H
#define DCM_OBJECT_PARSER_IMP_H
#include "object_parser.hpp"
#include "property_parser_imp.hpp"
namespace dcm {
namespace details {
template<typename Sys, typename Object, typename Par>
obj_parser<Sys, Object, Par>::obj_parser(): obj_parser::base_type(start) {
Par::init(subrule);
start = qi::lit("<Object>") >> subrule(qi::_r1)[qi::_val = qi::_1]
>> qi::eps(qi::_val)[ phx::bind(&Sys::template push_back<Object>, qi::_r1, qi::_val)]
>> prop[phx::bind(&obj_parser::setProperties, qi::_val, qi::_1)]
>> qi::lit("</Object>");
};
template<typename Sys, typename Object, typename Par>
void obj_parser<Sys, Object, Par>::setProperties(boost::shared_ptr<Object> ptr, typename details::pts<typename Object::Sequence>::type& seq) {
if(ptr) ptr->m_properties = seq;
};
template<typename Sys>
obj_par<Sys>::obj_par(): obj_par<Sys>::base_type(obj) {
obj = -(qi::eps(valid<0>::value) >> fusion::at<index<0> >(rules)(qi::_r1)[phx::at_c<index<0>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<1>::value) >> fusion::at<index<1> >(rules)(qi::_r1)[phx::at_c<index<1>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<2>::value) >> fusion::at<index<2> >(rules)(qi::_r1)[phx::at_c<index<2>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<3>::value) >> fusion::at<index<3> >(rules)(qi::_r1)[phx::at_c<index<3>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<4>::value) >> fusion::at<index<4> >(rules)(qi::_r1)[phx::at_c<index<4>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<5>::value) >> fusion::at<index<5> >(rules)(qi::_r1)[phx::at_c<index<5>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<6>::value) >> fusion::at<index<6> >(rules)(qi::_r1)[phx::at_c<index<6>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<7>::value) >> fusion::at<index<7> >(rules)(qi::_r1)[phx::at_c<index<7>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<8>::value) >> fusion::at<index<8> >(rules)(qi::_r1)[phx::at_c<index<8>::value>(qi::_val) = qi::_1])
>> -(qi::eps(valid<9>::value) >> fusion::at<index<9> >(rules)(qi::_r1)[phx::at_c<index<9>::value>(qi::_val) = qi::_1]);
};
}//details
}//DCM
#endif

View File

@@ -0,0 +1,82 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_PARSER_H
#define DCM_PARSER_H
#include <iosfwd>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/spirit/include/qi_string.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include "opendcm/core/clustergraph.hpp"
#include "property_parser.hpp"
#include "object_parser.hpp"
#include "edge_vertex_parser.hpp"
#include "extractor.hpp"
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
namespace dcm {
typedef boost::spirit::istream_iterator IIterator;
struct sp : qi::grammar<IIterator, std::string()> {
qi::rule<IIterator, std::string()> start;
sp() : sp::base_type(start) {
start %= +qi::char_;
};
static void print(std::string s) {
std::cout<<"parsed string:"<<std::endl<<s<<std::endl<<"done print string"<<std::endl;
};
};
template<typename Sys>
struct parser : qi::grammar<IIterator, typename Sys::Cluster*(Sys*), qi::locals<int>, qi::space_type> {
typedef typename Sys::Cluster graph;
parser();
qi::rule<IIterator, graph*(Sys*), qi::locals<int>, qi::space_type> cluster;
details::cluster_prop_par<Sys> cluster_prop;
details::obj_par<Sys> objects;
details::vertex_parser<Sys> vertex;
details::edge_parser<Sys> edge;
sp str;
Injector<Sys> in;
};
}
#ifndef USE_EXTERNAL
#include "parser_imp.hpp"
#endif
#endif //DCM_PARSER_H

View File

@@ -0,0 +1,71 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_PARSER_IMP_H
#define DCM_PARSER_IMP_H
#include <boost/spirit/include/qi_attr_cast.hpp>
#include "opendcm/core/system.hpp"
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
BOOST_FUSION_ADAPT_TPL_STRUCT(
(T1)(T2)(T3)(T4),
(dcm::ClusterGraph) (T1)(T2)(T3)(T4),
(typename dcm::details::pts<T3>::type, m_cluster_bundle))
#include "parser.hpp"
namespace boost { namespace spirit { namespace traits
{
template <typename T1, typename T2, typename T3, typename T4>
struct transform_attribute<dcm::ClusterGraph<T1,T2,T3,T4>*, dcm::ClusterGraph<T1,T2,T3,T4>, qi::domain>
{
typedef dcm::ClusterGraph<T1,T2,T3,T4>& type;
static type pre(dcm::ClusterGraph<T1,T2,T3,T4>* const& val) {
return *val;
}
static void post(dcm::ClusterGraph<T1,T2,T3,T4>* const& val, dcm::ClusterGraph<T1,T2,T3,T4> const& attr) {}
static void fail(dcm::ClusterGraph<T1,T2,T3,T4>* const&) {}
};
}}}
namespace dcm {
typedef boost::spirit::istream_iterator IIterator;
template<typename Sys>
parser<Sys>::parser() : parser<Sys>::base_type(cluster) {
cluster %= qi::lit("<Cluster id=") >> qi::omit[qi::int_[qi::_a = qi::_1]] >> ">"
>> -(qi::eps( qi::_a > 0 )[qi::_val = phx::new_<typename Sys::Cluster>()])
>> qi::eps[phx::bind(&Injector<Sys>::setVertexProperty, in, qi::_val, qi::_a)]
>> qi::attr_cast<graph*, graph>(cluster_prop >> qi::eps)
>> qi::omit[*vertex(qi::_val, qi::_r1)]
>> qi::omit[*edge(qi::_val, qi::_r1)]
>> qi::omit[*(cluster(qi::_r1)[phx::bind(&Injector<Sys>::addCluster, in, qi::_val, qi::_1)])]
>> "</Cluster>";// >> str[&sp::print];
};
}
#endif //DCM_PARSER_H

View File

@@ -0,0 +1,102 @@
#ifndef DCM_PROPERTY_GENERATOR_H
#define DCM_PROPERTY_GENERATOR_H
#include <boost/fusion/include/as_vector.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/minus.hpp>
#include <boost/mpl/less_equal.hpp>
#include "traits.hpp"
namespace karma = boost::spirit::karma;
namespace fusion = boost::fusion;
namespace mpl = boost::mpl;
namespace dcm {
typedef std::ostream_iterator<char> Iterator;
namespace details {
//a grammar that does nothing exept failing
struct empty_grammar : public karma::grammar<Iterator> {
karma::rule<Iterator> start;
empty_grammar(): empty_grammar::base_type(start) {
start = karma::eps(true);
};
empty_grammar(const empty_grammar& other) : empty_grammar::base_type(start) {};
};
template<typename Prop>
struct skip_grammar : public karma::grammar<Iterator, typename Prop::type&()> {
karma::rule<Iterator, typename Prop::type&()> start;
skip_grammar() : skip_grammar<Prop>::base_type(start) {
start = karma::eps(true);
};
skip_grammar(const skip_grammar& other) : skip_grammar::base_type(start) {};
};
//grammar for a single property
template<typename Prop, typename Gen>
struct prop_grammar : public karma::grammar<Iterator, typename Prop::type&()> {
typename Gen::generator subrule;
karma::rule<Iterator, typename Prop::type&()> start;
prop_grammar();
prop_grammar(const prop_grammar& other) : prop_grammar::base_type(start) {};
};
template<typename Sys, typename seq, typename state>
struct prop_generator_fold : mpl::fold< seq, state,
mpl::if_< parser_generate<mpl::_2, Sys>,
mpl::push_back<mpl::_1,
prop_grammar<mpl::_2, dcm::parser_generator<mpl::_2, Sys, Iterator> > >,
mpl::push_back<mpl::_1, skip_grammar<mpl::_2> > > > {};
//grammar for a fusion sequence of properties. currently max. 10 properties are supported
template<typename Sys, typename PropertyList>
struct prop_gen : karma::grammar<Iterator, typename details::pts<PropertyList>::type&()> {
//create a vector with the appropriate rules for all properties.
typedef typename prop_generator_fold<Sys, PropertyList, mpl::vector<> >::type init_rules_sequence;
//allow max 10 types as the following code expect this
BOOST_MPL_ASSERT((mpl::less_equal< mpl::size<init_rules_sequence>, mpl::int_<10> >));
//we want to process 10 elements, so create a vector with (10-prop.size()) empty rules
//and append it to our rules vector
typedef mpl::range_c<int,0, mpl::minus< mpl::int_<10>, mpl::size<init_rules_sequence> >::value > range;
typedef typename mpl::fold< range,
init_rules_sequence,
mpl::push_back<mpl::_1, empty_grammar> >::type rules_sequence;
typename fusion::result_of::as_vector<rules_sequence>::type rules;
karma::rule<Iterator, typename details::pts<PropertyList>::type&()> prop;
prop_gen();
};
//special prop classes for better externalisaton, therefore the outside constructor to avoid auto inline
template<typename Sys>
struct cluster_prop_gen : public prop_gen<Sys, typename Sys::Cluster::cluster_properties> {
cluster_prop_gen();
};
template<typename Sys>
struct vertex_prop_gen : public prop_gen<Sys, typename Sys::Cluster::vertex_properties> {
vertex_prop_gen();
};
template<typename Sys>
struct edge_prop_gen : public prop_gen<Sys, typename Sys::Cluster::edge_properties> {
edge_prop_gen();
};
}//details
}//dcm
#ifndef USE_EXTERNAL
#include "property_generator_imp.hpp"
#endif
#endif //DCM_PROPERTY_GENERATOR_H

View File

@@ -0,0 +1,43 @@
#ifndef DCM_PROPERTY_GENERATOR_IMP_H
#define DCM_PROPERTY_GENERATOR_IMP_H
#include "property_generator.hpp"
#include "traits_impl.hpp"
namespace dcm {
typedef std::ostream_iterator<char> Iterator;
namespace details {
//grammar for a single property
template<typename Prop, typename Gen>
prop_grammar<Prop, Gen>::prop_grammar() : prop_grammar<Prop, Gen>::base_type(start) {
Gen::init(subrule);
start = karma::lit("\n<Property>") << '+' << karma::eol << subrule
<< '-' << karma::eol << karma::lit("</Property>");
};
template<typename Sys, typename PropertyList>
prop_gen<Sys, PropertyList>::prop_gen() : prop_gen<Sys, PropertyList>::base_type(prop) {
prop = fusion::at_c<0>(rules) << fusion::at_c<1>(rules) << fusion::at_c<2>(rules)
<< fusion::at_c<3>(rules) << fusion::at_c<4>(rules) << fusion::at_c<5>(rules)
<< fusion::at_c<6>(rules) << fusion::at_c<7>(rules) << fusion::at_c<8>(rules)
<< fusion::at_c<9>(rules);
};
template<typename Sys>
cluster_prop_gen<Sys>::cluster_prop_gen() : prop_gen<Sys, typename Sys::Cluster::cluster_properties>() {};
template<typename Sys>
vertex_prop_gen<Sys>::vertex_prop_gen() : prop_gen<Sys, typename Sys::Cluster::vertex_properties>() {};
template<typename Sys>
edge_prop_gen<Sys>::edge_prop_gen() : prop_gen<Sys, typename Sys::Cluster::edge_properties>() {};
}//details
}//dcm
#endif //DCM_PROPERTY_GENERATOR_H

View File

@@ -0,0 +1,120 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_PROPERTY_PARSER_H
#define DCM_PROPERTY_PARSER_H
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/spirit/include/qi_string.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/mpl/less.hpp>
#include <boost/mpl/int.hpp>
namespace fusion = boost::fusion;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
namespace mpl = boost::mpl;
namespace dcm {
typedef boost::spirit::istream_iterator IIterator;
namespace details {
struct empty_parser : public qi::grammar<IIterator> {
qi::rule<IIterator> start;
empty_parser(): empty_parser::base_type(start) {
start = qi::eps(true);
};
empty_parser(const empty_parser& other) : empty_parser::base_type(start) {};
};
template<typename Prop>
struct skip_parser : public qi::grammar<IIterator, typename Prop::type()> {
qi::rule<IIterator, typename Prop::type()> start;
skip_parser() : skip_parser<Prop>::base_type(start) {
start = qi::eps(true);
};
skip_parser(const skip_parser& other) : skip_parser::base_type(start) {};
};
template<typename Prop, typename Par>
struct prop_parser : qi::grammar<IIterator, typename Prop::type(), qi::space_type> {
typename Par::parser subrule;
qi::rule<IIterator, typename Prop::type(), qi::space_type> start;
prop_parser();
prop_parser(const prop_parser& other) : prop_parser::base_type(start) {};
};
template<typename Sys, typename seq, typename state>
struct prop_parser_fold : mpl::fold< seq, state,
mpl::if_< dcm::parser_parse<mpl::_2, Sys>,
mpl::push_back<mpl::_1,
prop_parser<mpl::_2, dcm::parser_parser<mpl::_2, Sys, IIterator> > >,
mpl::push_back<mpl::_1, skip_parser<mpl::_2> > > > {};
//grammar for a fusion sequence of properties. currently max. 10 properties are supported
template<typename Sys, typename PropertyList>
struct prop_par : qi::grammar<IIterator, typename details::pts<PropertyList>::type(), qi::space_type> {
//create a vector with the appropriate rules for all properties.
typedef typename prop_parser_fold<Sys, PropertyList, mpl::vector<> >::type init_rules_sequence;
//allow max 10 types as the following code expect this
BOOST_MPL_ASSERT((mpl::less_equal< mpl::size<init_rules_sequence>, mpl::int_<10> >));
//we want to process 10 elements, so create a vector with (10-prop.size()) empty rules
//and append it to our rules vector
typedef mpl::range_c<int,0, mpl::minus< mpl::int_<10>, mpl::size<init_rules_sequence> >::value > range;
typedef typename mpl::fold< range,
init_rules_sequence,
mpl::push_back<mpl::_1, empty_parser> >::type rules_sequence;
typename fusion::result_of::as_vector<rules_sequence>::type rules;
qi::rule<IIterator, typename details::pts<PropertyList>::type(), qi::space_type> prop;
prop_par();
};
//special prop classes for better externalisaton, therefore the outside constructor to avoid auto inline
template<typename Sys>
struct cluster_prop_par : public prop_par<Sys, typename Sys::Cluster::cluster_properties> {
cluster_prop_par();
};
template<typename Sys>
struct vertex_prop_par : public prop_par<Sys, typename Sys::Cluster::vertex_properties> {
vertex_prop_par();
};
template<typename Sys>
struct edge_prop_par : public prop_par<Sys, typename Sys::Cluster::edge_properties> {
edge_prop_par();
};
} //DCM
} //details
#ifndef USE_EXTERNAL
#include "property_parser_imp.hpp"
#endif
#endif

View File

@@ -0,0 +1,60 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_PROPERTY_PARSER_IMP_H
#define DCM_PROPERTY_PARSER_IMP_H
#include "property_parser.hpp"
namespace dcm {
typedef boost::spirit::istream_iterator IIterator;
namespace details {
template<typename Prop, typename Par>
prop_parser<Prop, Par>::prop_parser() : prop_parser<Prop, Par>::base_type(start) {
Par::init(subrule);
start %= qi::lit("<Property>") >> subrule >> qi::lit("</Property>");
};
template<typename Sys, typename PropertyList>
prop_par<Sys, PropertyList>::prop_par() : prop_par<Sys, PropertyList>::base_type(prop) {
prop %= fusion::at_c<0>(rules) >> fusion::at_c<1>(rules) >> fusion::at_c<2>(rules)
>> fusion::at_c<3>(rules) >> fusion::at_c<4>(rules) >> fusion::at_c<5>(rules)
>> fusion::at_c<6>(rules) >> fusion::at_c<7>(rules) >> fusion::at_c<8>(rules)
>> fusion::at_c<9>(rules);
};
template<typename Sys>
cluster_prop_par<Sys>::cluster_prop_par() : prop_par<Sys, typename Sys::Cluster::cluster_properties>() {};
template<typename Sys>
vertex_prop_par<Sys>::vertex_prop_par() : prop_par<Sys, typename Sys::Cluster::vertex_properties>() {};
template<typename Sys>
edge_prop_par<Sys>::edge_prop_par() : prop_par<Sys, typename Sys::Cluster::edge_properties>() {};
} //DCM
} //details
#endif

View File

@@ -0,0 +1,53 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_PARSER_TRAITS_H
#define DCM_PARSER_TRAITS_H
#include <boost/mpl/bool.hpp>
#include <assert.h>
namespace dcm {
template<typename type, typename System>
struct parser_generate : public boost::mpl::false_ {};
template<typename type, typename System, typename iterator>
struct parser_generator {
typedef int generator;
static void init(generator& r) {
assert(false);
};
};
template<typename type, typename System>
struct parser_parse : public boost::mpl::false_ {};
template<typename type, typename System, typename iterator>
struct parser_parser {
typedef int parser;
static void init(parser& r) {
assert(false);
};
};
}
#endif //DCM_PARSER_TRAITS_H

View File

@@ -0,0 +1,160 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
//move the traits specializations outside of the traits definition to avoid the spirit header parsing every
//time this module is included and just parse it in externalisation mode when the generator is build
#ifndef DCM_PARSER_TRAITS_IMPL_H
#define DCM_PARSER_TRAITS_IMPL_H
#include "traits.hpp"
#include "defines.hpp"
#include <boost/mpl/bool.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/karma_string.hpp>
#include <boost/spirit/include/karma_int.hpp>
#include <boost/spirit/include/karma_bool.hpp>
#include <boost/spirit/include/karma_rule.hpp>
#include <boost/spirit/include/karma_auto.hpp>
namespace karma = boost::spirit::karma;
namespace qi = boost::spirit::qi;
namespace boost {
namespace spirit {
namespace traits {
template <>
struct create_generator<dcm::No_Identifier> {
typedef BOOST_TYPEOF(karma::eps(false)) type;
static type call() {
return karma::eps(false);
}
};
}
}
}
namespace dcm {
template<typename System>
struct parser_generate<type_prop, System> : public mpl::true_ {};
template<typename System, typename iterator>
struct parser_generator<type_prop, System, iterator> {
typedef karma::rule<iterator, int&()> generator;
static void init(generator& r) {
r = karma::lit("<type>clustertype</type>\n<value>") << karma::int_ <<"</value>";
};
};
template<typename System>
struct parser_generate<changed_prop, System> : public mpl::true_ {};
template<typename System, typename iterator>
struct parser_generator<changed_prop, System, iterator> {
typedef karma::rule<iterator, bool&()> generator;
static void init(generator& r) {
r = karma::lit("<type>clusterchanged</type>\n<value>") << karma::bool_ <<"</value>";
};
};
template<typename System>
struct parser_generate<id_prop<typename System::Identifier>, System>
: public mpl::not_<boost::is_same<typename System::Identifier, No_Identifier> > {};
template<typename System, typename iterator>
struct parser_generator<id_prop<typename System::Identifier>, System, iterator> {
typedef karma::rule<iterator, typename System::Identifier()> generator;
static void init(generator& r) {
r = karma::lit("<type>id</type>\n<value>") << karma::auto_ <<"</value>";
};
};
template<typename System>
struct parser_parse<type_prop, System> : public mpl::true_ {};
template<typename System, typename iterator>
struct parser_parser<type_prop, System, iterator> {
typedef qi::rule<iterator, int(), qi::space_type> parser;
static void init(parser& r) {
r = qi::lit("<type>clustertype</type>") >> ("<value>") >> qi::int_ >>"</value>";
};
};
template<typename System>
struct parser_parse<changed_prop, System> : public mpl::true_ {};
template<typename System, typename iterator>
struct parser_parser<changed_prop, System, iterator> {
typedef qi::rule<iterator, bool(), qi::space_type> parser;
static void init(parser& r) {
r = qi::lit("<type>clusterchanged</type>") >> ("<value>") >> qi::bool_ >>"</value>";
};
};
template<typename System>
struct parser_parse<id_prop<typename System::Identifier>, System>
: public mpl::not_<boost::is_same<typename System::Identifier, No_Identifier> > {};
template<typename System, typename iterator>
struct parser_parser<id_prop<typename System::Identifier>, System, iterator> {
typedef qi::rule<iterator, typename System::Identifier(), qi::space_type> parser;
static void init(parser& r) {
r = qi::lit("<type>id</type>") >> ("<value>") >> qi::auto_ >>"</value>";
};
};
/*
template<typename System>
struct parser_generate<details::cluster_vertex_prop, System>
: public mpl::true_ {};
template<typename System, typename iterator>
struct parser_generator<details::cluster_vertex_prop, System, iterator> {
typedef karma::rule<iterator, int()> generator;
static void init(generator& r) {
r = karma::lit("<type>id</type>\n<value>") << karma::int_ <<"</value>";
};
};
template<typename System>
struct parser_parse<details::cluster_vertex_prop, System> : public mpl::true_ {};
template<typename System, typename iterator>
struct parser_parser<details::cluster_vertex_prop, System, iterator> {
typedef qi::rule<iterator, int(), qi::space_type> parser;
static void init(parser& r) {
r = qi::lit("<type>id</type>") >> ("<value>") >> qi::int_ >>"</value>";
};
};*/
} //namespace dcm
#endif //DCM_PARSER_TRAITS_IMPL_H