Re: [boost] How do you make MPL-compatible template meta-functions?

Hi Daryle Daryle Walker escribió:
Here's what I'm trying (to redo integer_test.cpp) [...] BOOST_STATIC_ASSERT ( (boost::is_same<distinct_integral_bit_counts, boost::mpl::list_c<int, 8, 16, 32, 64> >) ); }
I think there are two problems with this: 1. You're passing a *type* (boost::is_same<...>) to BOOST_STATIC_ASSERT when you should be passing a numeric contanst. Append ::value to the type. 2. Even with the correction above the thing won't work because is_same<T,Q> checks for strict equality of the types T and Q; in your case distinct_integral_bit_counts is *not* the same type as boost::mpl::list_c<...>, but only has the same components. You can use boost::mpl::equal to test this: BOOST_STATIC_ASSERT ( (boost::mpl::equal<distinct_integral_bit_counts, boost::mpl::list_c<int, 8, 16, 32> >::value) ); } Other than that, your type_to_digit_count is perfectly lambda-cabable AFAICS. HTH, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

on Wed Jul 09 2008, joaquin-AT-tid.es wrote:
Hi Daryle
Daryle Walker escribió:
Here's what I'm trying (to redo integer_test.cpp) [...] BOOST_STATIC_ASSERT ( (boost::is_same<distinct_integral_bit_counts, boost::mpl::list_c<int, 8, 16, 32, 64> >) ); }
I think there are two problems with this:
1. You're passing a *type* (boost::is_same<...>) to BOOST_STATIC_ASSERT when you should be passing a numeric contanst.
Or use BOOST_MPL_ASSERT, which does expect a type and gives better error messages: BOOST_MPL_ASSERT((boost::is_same< ... >));
Append ::value to the type. 2. Even with the correction above the thing won't work because is_same<T,Q> checks for strict equality of the types T and Q; in your case distinct_integral_bit_counts is *not* the same type as boost::mpl::list_c<...>, but only has the same components. You can use boost::mpl::equal to test this:
BOOST_STATIC_ASSERT ( (boost::mpl::equal<distinct_integral_bit_counts, boost::mpl::list_c<int, 8, 16, 32> >::value) ); }
BOOST_MPL_ASSERT((boost::mpl::equal< ... >)); is better -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Jul 9, 2008, at 4:33 AM, David Abrahams wrote:
BOOST_MPL_ASSERT((boost::mpl::equal< ... >));
is better
I'm continuing with this code, but now it says that boost::mpl::pop_back can't work with my type. Now I got: //====================================== typedef boost::mpl::list<unsigned char, unsigned short, unsigned, unsigned long long> distinct_unsigned_types; //... template < typename T > struct type_to_digit_count : integral_c<int, std::numeric_limits<T>::digits> {}; typedef boost::mpl::transform<distinct_unsigned_types, type_to_digit_count<boost::mpl::_1> >::type distinct_integral_bit_counts; BOOST_MPL_ASSERT( (boost::mpl::equal<distinct_integral_bit_counts, boost::mpl::list_c<int, 8, 16, 32, 64> >) ); // Make a list of the bit counts between each offical point typedef boost::mpl::pop_back<distinct_integral_bit_counts>::type out_shifted_dibc; BOOST_MPL_ASSERT( (boost::mpl::equal<out_shifted_dibc, boost::mpl::list_c<int, 8, 16, 32> >) ); typedef boost::mpl::push_front<out_shifted_dibc, integral_c<int, 0> >::type shifted_dibc; BOOST_MPL_ASSERT( (boost::mpl::equal<shifted_dibc, boost::mpl::list_c<int, 0, 8, 16, 32> >) ); //====================================== The compile chokes on the "pop_back" forming "out_shifted_dibc" in my altered "integer_test.cpp": //====================================== $(MY_BOOST)/boost/mpl/pop_back.hpp: In instantiation of 'boost::mpl::pop_back<<unnamed>::distinct_integral_bit_counts>': $(MY_BOOST)/libs/integer/test/integer_test.cpp:108: instantiated from here $(MY_BOOST)/boost/mpl/pop_back.hpp:31: error: invalid use of undefined type 'struct boost::mpl::pop_back_impl<boost::mpl::aux::list_tag>::apply<<unnamed>::d istinct_integral_bit_counts>' $(MY_BOOST)/boost/mpl/aux_/pop_back_impl.hpp:27: error: declaration of 'struct boost::mpl::pop_back_impl<boost::mpl::aux::list_tag>::apply<<unnamed>::d istinct_integral_bit_counts>' $(MY_BOOST)/libs/integer/test/integer_test.cpp:108: error: 'type' in class 'boost::mpl::pop_back<<unnamed>::distinct_integral_bit_counts>' does not name a type $(MY_BOOST)/libs/integer/test/integer_test.cpp:109: error: 'out_shifted_dibc' was not declared in this scope //====================================== And the errors cascade from there. Is there some (new) compatibility problem with "distinct_integral_bit_counts"? Also, I was originally going to elide "out_shifted_dibc" and merge it into the expression forming "shifted_dibc," but this decision has made debugging easier. Can I combine transformations, or do I have to create a new name for each type step? Of course, I may be doing this the wrong way. I have the list: {8, 16, 32, 64}, the distinct bit lengths for the built-in integral types. I want: {4, 8, 12, 16, 24, 32, 48, 64}, those lengths plus the mid-way lengths between them (and half of CHAR_BIT). I want to test lengths that don't exactly match an integral type. (I was trying to form a list of averages with "out_shifted_dibc" and "shifted_dibc.") -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com

On Jul 9, 2008, at 3:02 AM, joaquin@tid.es wrote:
Daryle Walker escribió:
Here's what I'm trying (to redo integer_test.cpp) [...] BOOST_STATIC_ASSERT ( (boost::is_same<distinct_integral_bit_counts, boost::mpl::list_c<int, 8, 16, 32, 64> >) ); }
I think there are two problems with this:
1. You're passing a *type* (boost::is_same<...>) to BOOST_STATIC_ASSERT when you should be passing a numeric contanst. Append ::value to the type.
Can't believe I missed that....
2. Even with the correction above the thing won't work because is_same<T,Q> checks for strict equality of the types T and Q; in your case distinct_integral_bit_counts is *not* the same type as boost::mpl::list_c<...>, but only has the same components. You can use boost::mpl::equal to test this:
BOOST_STATIC_ASSERT ( (boost::mpl::equal<distinct_integral_bit_counts, boost::mpl::list_c<int, 8, 16, 32> >::value) ); }
Other than that, your type_to_digit_count is perfectly lambda- cabable AFAICS. HTH,
Thanks. I switched to mpl::equal and it compiled. I later switched to BOOST_MPL_ASSERT. (Remember to take _out_ the "::value" part!) I originally had the "integral_c" part of "type_to_digit_count" as a member called "type," instead of as a base class, then I switched back and forth. Both ways work. Why is that? And which way is best (if they're not equally good, and without a better third alternative)? //============================== // New type list: integral type -> (wrapped) number of bits // Should the "integral_c" part be a base class or direct member? template < typename T > struct type_to_digit_count //: integral_c<int, std::numeric_limits<T>::digits> { typedef integral_c<int, std::numeric_limits<T>::digits> type; }; typedef boost::mpl::transform<distinct_unsigned_types, type_to_digit_count<boost::mpl::_1> >::type distinct_integral_bit_counts; BOOST_MPL_ASSERT( (boost::mpl::equal<distinct_integral_bit_counts, boost::mpl::list_c<int, 8, 16, 32, 64> >) ); //============================== -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com
participants (4)
-
Daryle Walker
-
David Abrahams
-
joaquin@tid.es
-
Steven Watanabe