Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>As noted in the comments, first take a look at <code>BOOST_FUSION_ADAPT_STRUCT</code> (and friends):</p> <pre><code>#include &lt;boost/fusion/include/adapt_struct.hpp&gt; #include &lt;string&gt; struct Data { std::string firstMember; std::string secondMember; std::string thirdMember; }; BOOST_FUSION_ADAPT_STRUCT( Data, (std::string, firstMember) (std::string, secondMember) (std::string, thirdMember) ) </code></pre> <p>This turns your <code>Data</code> structure into a sequence usable by Fusion:</p> <pre><code>#include &lt;boost/fusion/include/at_c.hpp&gt; int main() { Data d = { "firstData", "secondData", "thirdData" }; std::cout &lt;&lt; boost::fusion::at_c&lt;0&gt;(d) &lt;&lt; std::endl; } </code></pre> <p>This prints <code>"firstData"</code>. Change the index to refer to the members in order.</p> <p>There, now we can refer to members at compile-time using a number. But you wanted a name. Also noted in the comments, processing strings is a runtime feature...almost. C++11 gives us <code>constexpr</code>.</p> <p>It's a bit tricky, but ultimately it looks like this:</p> <pre><code>#include &lt;boost/fusion/include/adapt_struct.hpp&gt; #include &lt;boost/preprocessor/cat.hpp&gt; #include &lt;boost/preprocessor/repetition/repeat.hpp&gt; #include &lt;boost/preprocessor/seq.hpp&gt; #include &lt;boost/preprocessor/tuple/elem.hpp&gt; #include &lt;stdexcept&gt; // and repeat for BOOST_FUSION_ADAPT_TPL_STRUCT, etc... #define REFLECT_STRUCT(NAME, ATTRIBUTES) \ REFLECT_STRUCT_DETAIL(NAME, \ ATTRIBUTES, \ BOOST_PP_SEQ_POP_FRONT( \ BOOST_PP_CAT( \ /* warning: uses fusion implementation details: */ \ BOOST_FUSION_ADAPT_STRUCT_FILLER_0(0,0)ATTRIBUTES, \ _END))) \ #define REFLECT_STRUCT_DETAIL(NAME, ATTRIBUTES, WRAPPEDATTRIBUTES) \ BOOST_FUSION_ADAPT_STRUCT(NAME, ATTRIBUTES) \ \ namespace detail \ { \ namespace BOOST_PP_CAT(reflect_, NAME) \ { \ template &lt;int N&gt; \ struct member_name; \ \ BOOST_PP_SEQ_FOR_EACH_I(REFLECT_STRUCT_DETAIL_MEMBER_NAME, \ BOOST_PP_EMPTY, \ WRAPPEDATTRIBUTES) \ \ template &lt;int N&gt; \ constexpr bool member_match_index(const std::size_t index, \ const char* const str, \ const std::size_t len) \ { \ return index == len || \ (member_name&lt;N&gt;::value()[index] == str[index] \ &amp;&amp; member_match_index&lt;N&gt;(index + 1, str, len)); \ } \ \ template &lt;int N&gt; \ constexpr bool member_match(const char* const str, \ const std::size_t len) \ { \ return len == member_name&lt;N&gt;::value_length \ &amp;&amp; member_match_index&lt;N&gt;(0, str, len); \ } \ \ constexpr int find_member(const char* const str, \ const std::size_t len) \ { \ return BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(WRAPPEDATTRIBUTES), \ REFLECT_STRUCT_DETAIL_MEMBER_NAME_TEST, \ BOOST_PP_EMPTY) \ throw std::runtime_error("could not find " \ BOOST_PP_STRINGIZE(NAME) \ " member"); \ } \ } \ } \ \ constexpr int BOOST_PP_CAT(indexof_, NAME)(const char* const str, \ const std::size_t len) \ { \ return detail::BOOST_PP_CAT(reflect_, NAME)::find_member(str, len); \ } \ \ template &lt;std::size_t N&gt; \ constexpr int BOOST_PP_CAT(indexof_, NAME)(const char (&amp;str)[N]) \ { \ return detail::BOOST_PP_CAT(reflect_, NAME)::find_member(&amp;str[0], N); \ } #define REFLECT_STRUCT_DETAIL_EXTRACT_NAME(pair) \ BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(1, pair)) #define REFLECT_STRUCT_DETAIL_MEMBER_NAME(r, data, n, elem) \ REFLECT_STRUCT_DETAIL_MEMBER_NAME_DETAIL(n, REFLECT_STRUCT_DETAIL_EXTRACT_NAME(elem)) #define REFLECT_STRUCT_DETAIL_MEMBER_NAME_DETAIL(n, name) \ template &lt;&gt; \ struct member_name&lt;n&gt; \ { \ static constexpr std::size_t value_length = sizeof(name); \ typedef const char value_type[value_length]; \ \ static constexpr const value_type&amp; value() \ { \ return name; \ } \ }; #define REFLECT_STRUCT_DETAIL_MEMBER_NAME_TEST(z, n, text) \ member_match&lt;n&gt;(str, len) ? n : </code></pre> <p>It looks scary but its readable if you take the time to pick it apart.</p> <p>We have to introduce our own macros to give constant-expression access to the member names; most of the ugly comes from processing Boost.Preprocessor lists. Although Fusion does record the names during adaptation as well (see <code>boost::fusion::extension::struct_member_name</code>), they are not marked as <code>constexpr</code> so aren't usable to us, unfortunately.</p> <p>This gives:</p> <pre><code>#include &lt;boost/fusion/include/at_c.hpp&gt; #include &lt;iostream&gt; #include &lt;string&gt; struct Data { std::string firstMember; std::string secondMember; std::string thirdMember; }; REFLECT_STRUCT( Data, (std::string, firstMember) (std::string, secondMember) (std::string, thirdMember) ) // your desired code: // (note the use of at_c ensures this is evaluated at comple-time) #define GETMEMBER(data, member) boost::fusion::at_c&lt;indexof_Data(member)&gt;(data) int main() { Data d = { "firstData", "secondData", "thirdData" }; std::cout &lt;&lt; boost::fusion::at_c&lt;indexof_Data("firstMember")&gt;(d) &lt;&lt; std::endl; std::cout &lt;&lt; GETMEMBER(d, "secondMember") &lt;&lt; std::endl; std::cout &lt;&lt; GETMEMBER(d, "thirdMember") &lt;&lt; std::endl; /* causes error: std::cout &lt;&lt; GETMEMBER(d, "nonexistent_member") &lt;&lt; std::endl; */ } </code></pre> <p>Which I think is close to what you were after.</p> <p>But keep in mind this may not all be necessary: Boost.Fusion may already have what you need. It lives in the area between pure compile-time stuff (Boost.MPL) and regular run-time stuff; adapt your struct and you can already do things like iterate over it (<code>boost::fusion::for_each</code>).</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.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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