Note that there are some explanatory texts on larger screens.

plurals
  1. POBoost fusion oddity
    primarykey
    data
    text
    <p>I am trying out Fusion and found something very odd... Here is the code... I have highlighted the problematic code with // ############ TROUBLE HERE ######</p> <pre><code>#include &lt;tr1/cstdint&gt; #include &lt;tr1/functional&gt; #include &lt;string&gt; #include &lt;iostream&gt; // #define FUSION_MAX_VECTOR_SIZE 64 #define BOOST_MPL_LIMIT_STRING_SIZE 128 #include &lt;boost/type_traits.hpp&gt; #include &lt;boost/mpl/string.hpp&gt; #include &lt;boost/fusion/algorithm.hpp&gt; #include &lt;boost/fusion/tuple.hpp&gt; #include &lt;boost/fusion/container/vector.hpp&gt; #include &lt;boost/fusion/container/generation.hpp&gt; #include &lt;boost/fusion/container/generation/vector_tie.hpp&gt; typedef std::tr1::int32_t int32; typedef std::tr1::int64_t int64; template &lt; class type_const_ref &gt; struct remove_const_reference { typedef typename boost::remove_reference &lt; type_const_ref &gt;::type type_const; typedef typename boost::remove_const &lt; type_const &gt;::type type; }; template &lt; class T &gt; class MetaClass; namespace fusion = boost::fusion; template &lt; class T &gt; struct ConstRefFieldMap { typedef typename MetaClass &lt; T &gt;::FieldNames FieldNames; typedef typename MetaClass &lt; T &gt;::ConstRefFields ConstRefFields; typedef typename boost::fusion::result_of::zip &lt; FieldNames const, ConstRefFields const &gt;::type type; }; template &lt; class T &gt; static typename MetaClass &lt; T &gt;::FieldNames fieldNames() { return typename MetaClass &lt; T &gt;::FieldNames(); } template &lt; class T &gt; static typename MetaClass &lt; T &gt;::ConstRefFields constRefFields(T const &amp;obj) { return MetaClass &lt; T &gt;::constRefFields(obj); } template &lt; class T &gt; static typename ConstRefFieldMap &lt; T &gt;::type const constRefFieldMap(T const &amp;obj) { return boost::fusion::zip(fieldNames &lt; T &gt;(), constRefFields(obj)); } class Currency { private: typedef MetaClass &lt; Currency &gt; Meta; friend class MetaClass &lt; Currency &gt;; private: std::string m_isoCode; int32 m_rank; public: Currency(std::string const &amp;isoCode, int32 const rank) : m_isoCode(isoCode) , m_rank(rank) { } std::string const&amp; getIsoCode() const { return m_isoCode; } int32 const getRank() const { return m_rank; } private: void setIsoCode(std::string const &amp;isoCode) { m_isoCode = isoCode; } public: void setRank(int32 rank) { m_rank = rank; } }; template &lt;&gt; class MetaClass &lt; Currency &gt; { public: typedef Currency data_type; public: typedef std::string IsoCodeType; typedef int32 RankType; typedef boost::fusion::vector &lt; boost::mpl::string &lt; 'i', 's', 'o', 'C', 'o', 'd', 'e' &gt; , boost::mpl::string &lt; 'r', 'a', 'n', 'k' &gt; &gt; FieldNames; typedef boost::fusion::vector &lt; IsoCodeType &amp; , RankType &amp; &gt; MutableRefFields; typedef boost::fusion::vector &lt; IsoCodeType const &amp; , RankType const &amp; &gt; ConstRefFields; static MutableRefFields mutableRefFields(Currency &amp;obj) { return MutableRefFields(obj.m_isoCode, obj.m_rank); } static ConstRefFields constRefFields(Currency const &amp;obj) { return ConstRefFields(obj.m_isoCode, obj.m_rank); } }; template &lt; class T, class U &gt; static typename ConstRefFieldMap &lt; T &gt;::type const constRefFieldMapTest(T const &amp;obj, U const &amp;u) { return boost::fusion::zip(fieldNames &lt; T &gt;(), u); } int main() { Currency const EUR("EUR", 500); using boost::fusion::any; { std::cout &lt;&lt; boost::fusion::at_c &lt; 0 &gt;(constRefFields(EUR)) &lt;&lt; " : " &lt;&lt; boost::fusion::at_c &lt; 1 &gt;(constRefFields(EUR)) &lt;&lt; std::endl; ConstRefFieldMap &lt; Currency &gt;::type const &amp;fm = boost::fusion::zip(fieldNames &lt; Currency &gt;(), constRefFields(EUR)); // ############ TROUBLE HERE ###### // ConstRefFieldMap &lt; Currency &gt;::type const &amp;fm = constRefFieldMap(EUR); // ############ TROUBLE HERE ###### { { typedef boost::fusion::result_of::at_c &lt; ConstRefFieldMap &lt; Currency &gt;::type, 0 &gt;::type field_value_type; field_value_type const v = boost::fusion::at_c &lt; 0 &gt;(fm); typedef boost::fusion::result_of::at_c &lt; field_value_type, 0 &gt;::type field_name_type; field_name_type const n = boost::fusion::at_c &lt; 0 &gt;(v); typedef boost::fusion::result_of::at_c &lt; field_value_type, 1 &gt;::type field_data_type; field_data_type const d = boost::fusion::at_c &lt; 1 &gt;(v); std::cout &lt;&lt; boost::mpl::c_str &lt; remove_const_reference &lt; field_name_type &gt;::type &gt;::value &lt;&lt; " : " &lt;&lt; d &lt;&lt; std::endl; } { typedef boost::fusion::result_of::at_c &lt; ConstRefFieldMap &lt; Currency &gt;::type, 1 &gt;::type field_value_type; field_value_type const v = boost::fusion::at_c &lt; 1 &gt;(fm); typedef boost::fusion::result_of::at_c &lt; field_value_type, 0 &gt;::type field_name_type; field_name_type const n = boost::fusion::at_c &lt; 0 &gt;(v); typedef boost::fusion::result_of::at_c &lt; field_value_type, 1 &gt;::type field_data_type; field_data_type const d = boost::fusion::at_c &lt; 1 &gt;(v); std::cout &lt;&lt; boost::mpl::c_str &lt; remove_const_reference &lt; field_name_type &gt;::type &gt;::value &lt;&lt; " : " &lt;&lt; d &lt;&lt; std::endl; } } } } </code></pre> <p>I get garbage values or SIGSEGV if I use the constRefFieldMap() function. If I call boost::fusion::zip directly it works perfectly. Here is the output...</p> <pre><code>EUR : 500 isoCode : EUR rank : 500 </code></pre> <p>I have looked at this <a href="https://stackoverflow.com/questions/3926192/boost-fusion-container-of-shared-pointers-shared-ptr-causing-segmentation-fault">question</a> earlier... am I running into the same problem here???</p> <p><strong>EDIT 1:</strong></p> <p>Presenting an example of what I am trying to do...</p> <p>Actually... I am trying to write code like this.</p> <pre><code>MetaObject &lt; Currency const &gt; EUR_META(make_meta_object(EUR)); std::cout &lt;&lt; get_field &lt; std::string &gt;("isoCode", EUR_META.constRefFieldMap()) &lt;&lt; std::endl; MetaObject &lt; Currency &gt; GBP_META(make_meta_object(GBP)); MutableRefFieldMap &lt; Currency &gt;::type const &amp;fm = GBP_META.mutableRefFieldMap(); std::cout &lt;&lt; set_field("rank", fm, 497) &lt;&lt; std::endl; </code></pre> <p>Accessors and modifiers that I can invoke by field names...</p> <p>I plan to write a spirit parser to parse JSON &amp; XML and create objects... with some help from my code generators. The main idea is to avoid generating the parsing code for every object, but only for those objects that get used and hence reduce the binary size. I have 1000s of objects now.</p> <p>I have got this working now.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload