[boost][MPL] Numeric metafunctions protocol/infrastructure

Once Tropical Storm Jeanne passes away, I should be through with hurricanes for a while. The latest-and-greatest MPL looks great! The new ability to plug in custom numeric metatypes so that they work with existing numeric ops makes it a definite keeper. The part of my sub-library that I've updated to work with the new MPL is at <http://groups.yahoo.com/group/boost/files/mpl_math.zip>, and has been tested with MinGW 3.2 and MSVC 7.1 (2003 Toolkit). Renaming issues aren't too bad; I just have to remember (for one thing) that reverse_copy is defined at copy.hpp and not reverse_copy.hpp as I originally thought. I also noticed that BOOST_MPL_AUX_TYPEOF is no longer there, but I've managed to eliminate the need for it. A major issue I have is how to properly use numeric_cast in order to make something like the following statement work correctly: typedef plus<int_<1>,fraction_c<long,4,3> >::type fraction_7_over_3; Right now I've made N^2 specializations of plus_impl, where N here means the total number of built-in and custom numeric metatypes. For my sub-library, N==4, which means I've made 16 specializations of plus_impl alone! Factor in the comparison ops as well the arithmetic ops, and my code is starting to look bloated. I've supplied a couple of convenience macros to reduce the copy-and-pasting, but I still think I'm missing something crucial here, and I think that something is how to use (or specialize) numeric_cast. Pointers welcome! Cromwell Enage __________________________________ Do you Yahoo!? New and Improved Yahoo! Mail - 100MB free storage! http://promotions.yahoo.com/new_mail

Cromwell Enage writes:
Once Tropical Storm Jeanne passes away, I should be through with hurricanes for a while.
The latest-and-greatest MPL looks great! The new ability to plug in custom numeric metatypes so that they work with existing numeric ops makes it a definite keeper.
The part of my sub-library that I've updated to work with the new MPL is at <http://groups.yahoo.com/group/boost/files/mpl_math.zip>, and has been tested with MinGW 3.2 and MSVC 7.1 (2003 Toolkit).
I'll surely take a look at it once we are done with release.
Renaming issues aren't too bad; I just have to remember (for one thing) that reverse_copy is defined at copy.hpp and not reverse_copy.hpp as I originally thought.
That's to keep the number of headers manageable.
I also noticed that BOOST_MPL_AUX_TYPEOF is no longer there,
Yep; it was an internal facility in the first place.
but I've managed to eliminate the need for it.
That's what I'd expect; it shouldn't be needed anymore.
A major issue I have is how to properly use numeric_cast in order to make something like the following statement work correctly:
typedef plus<int_<1>,fraction_c<long,4,3> >::type fraction_7_over_3;
Right now I've made N^2 specializations of plus_impl, where N here means the total number of built-in and custom numeric metatypes. For my sub-library, N==4, which means I've made 16 specializations of plus_impl alone!
Hmm, this doesn't sound right. You've seen the complex numbers test/example referred from the changelog -- http://tinyurl.com/6e7pw (http://cvs.sourceforge.net/viewcvs.py/boost/boost/libs/mpl/test/numeric_ops....), right? Something like this should be enough: struct fraction_c_tag : int_<20> {}; template<> struct numeric_cast< integral_c_tag,fraction_c_tag > { template< typename N > struct apply : fraction_c< typename N::value_type,N::value,1 > { }; };
Factor in the comparison ops as well the arithmetic ops, and my code is starting to look bloated. I've supplied a couple of convenience macros to reduce the copy-and-pasting, but I still think I'm missing something crucial here, and I think that something is how to use (or specialize) numeric_cast.
Let me know if the above doesn't cover it. -- Aleksey Gurtovoy MetaCommunications Engineering

--- Aleksey Gurtovoy <agurtovoy@meta-comm.com> wrote:
Something like this should be enough:
struct fraction_c_tag : int_<20> {};
template<> struct numeric_cast< integral_c_tag,fraction_c_tag > { template< typename N > struct apply : fraction_c< typename N::value_type,N::value,1 > { }; };
Alas, no. I hadn't tried inheritance/nested forwarding for the sake of portability before looking at your message, opting instead to typedef ... type in the struct body. (Now I'm using BOOST_MPL_CFG_NO_NESTED_FORWARDING to branch out the code.) Either way it still didn't work without my macros. :( The other major issue I have is that the big_integral examples are taking longer to compile than before. In fact, it takes too long for even one division operation. But that can wait until after the release. Cromwell Enage __________________________________ Do you Yahoo!? Yahoo! Mail is new and improved - Check it out! http://promotions.yahoo.com/new_mail

Methinks I found the problem, not in numeric_cast, but in the numeric ops themselves. The divides metafunction, for example, inherits from the apply template nested inside the divides_impl template. The problem is that the primary divides_impl template inherits from if_c, which doesn't have a nested apply template, although its argument types do. The same type of problem occurs in all other numeric ops, including the comparison ops. Changing the primary *_impl template for each numeric op to something like the following code should vanquish the problem. (It did for me when I edited the appropriate files.) template <typename Tag1, typename Tag2> struct NUMERIC_OP_IMPL { template <typename N1, typename N2> struct apply { BOOST_STATIC_CONSTANT( bool, cond = BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1) > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ); typedef typename eval_if_c< cond, identity<N1>, apply_wrap1< BOOST_MPL_AUX_NUMERIC_CAST< Tag1,Tag2 >, N1 > >::type n_1; typedef typename eval_if_c< cond, apply_wrap1< BOOST_MPL_AUX_NUMERIC_CAST< Tag1,Tag2 >, N2 >, identity<N2> >::type n_2; typedef typename apply_wrap2< NUMERIC_OP_IMPL< typename n_1::tag, typename n_2::tag >, n_1, n_2 >::type type; }; }; Some preprocessed files may need similar editing so that other compilers (which I don't have) will also succeed. I may be offline for a while, as I'm about to ride out yet another hurricane. HTH Cromwell Enage __________________________________ Do you Yahoo!? Yahoo! Mail is new and improved - Check it out! http://promotions.yahoo.com/new_mail

I wrote:
template <typename Tag1, typename Tag2> struct NUMERIC_OP_IMPL { template <typename N1, typename N2> struct apply { BOOST_STATIC_CONSTANT( bool, cond = BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1)
BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2) ); typedef typename eval_if_c< cond, identity<N1>, apply_wrap1< BOOST_MPL_AUX_NUMERIC_CAST< Tag1,Tag2 >, N1 > >::type n_1; typedef typename eval_if_c< cond, apply_wrap1< BOOST_MPL_AUX_NUMERIC_CAST< Tag1,Tag2
Should be Tag2,Tag1
>, N2 >, identity<N2> >::type n_2; typedef typename apply_wrap2< NUMERIC_OP_IMPL< typename n_1::tag, typename n_2::tag >, n_1, n_2 >::type type; }; };
Is <boost/mpl/aux_/numeric_op.hpp> the right file to patch for this particular problem? The header files in the boost/mpl/aux_/preprocessed/gcc/ directory say "DO NOT MODIFY". Are they (the numeric ops) pregenerated from this file? If so, I've attached the diff to this message. Cromwell Enage __________________________________ Do you Yahoo!? Yahoo! Mail is new and improved - Check it out! http://promotions.yahoo.com/new_mail

Cromwell Enage writes:
Methinks I found the problem, not in numeric_cast, but in the numeric ops themselves.
The divides metafunction, for example, inherits from the apply template nested inside the divides_impl template. The problem is that the primary divides_impl template inherits from if_c, which doesn't have a nested apply template, although its argument types do. The same type of problem occurs in all other numeric ops, including the comparison ops.
Cromwell, I just fixed this both in the main trunk and RC_1_32_0 branch. Sorry that it took me so long to address the issue, and thanks for reporting it! -- Aleksey Gurtovoy MetaCommunications Engineering

--- Aleksey Gurtovoy <agurtovoy@meta-comm.com> wrote:
I just fixed this both in the main trunk and RC_1_32_0 branch.
I've tested your fix and it works like a charm! Thanks! I've added some reference docs to my sub-library, including an overview of what the final numeric_cast relationship between numeric types should like and indications of how far I am from reaching that goal. Cromwell Enage _______________________________ Do you Yahoo!? Declare Yourself - Register online to vote today! http://vote.yahoo.com
participants (2)
-
Aleksey Gurtovoy
-
Cromwell Enage