[mpl] Integral Constant is over specified

Hi, IMO the Integral Constant Concept is over specified in the mpl docs. What is the rationale behind the next<..> and prior <..> requirements? These seem to have little to do with an Integral Constant. Maybe they should rather be another Concept , such as Iterable? Where N is a model of Iterable: next<N>::type prior<N>::type Currently for example, mpl::bool_ is stated to be a model of Integral Constant, but it fails to meet the curently stated requirments, nor can it ever AFAICS. Further the requirements currently include a member ::value_type. According to the TMP book, this is a classic example of a traits blob. (section 2.2). Surely access should be specified using value_type<C>::type? IOW maybe a ValueType Concept. Finally the runtime evaluation requirement could be removed and a refinement of ValueType such as RunTime Evaluable be stated in terms such as: Where T is a type modelling Runtime Evaluable value_type<T>::type = t(); For a type N The current Integral Constant spec would then, in those places where these requirements are required: N is a model of Iterable, Integral Constant and Runtime Evaluable. This would allow me to meet the new Integral Constant requirements without unneccesary baggage. Further a bool_ could be correctly specified in terms of the above Concepts regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> wrote in message news:ea4hqs$lg0$1@sea.gmane.org... Further the following code should work AFAICS, at least according to the documentation #include <boost/mpl/equal_to.hpp> #include <boost/mpl/integral_c.hpp> #include <boost/mpl/next.hpp> #include <boost/mpl/prior.hpp> #include <boost/mpl/assert.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/static_assert.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/integral_c.hpp> #include <iostream> // Write a type fulfilling the Integral Constant requirements // http://www.boost.org/libs/mpl/doc/refmanual/integral-constant.html template <int N> struct my_int{ typedef int value_type; static const int value = N; operator int ()const { return value;} typedef my_int type; }; namespace boost{ namespace mpl{ template <int N > struct next<my_int<N> > { typedef my_int<N+1> type; }; template <int N > struct prior<my_int<N> > { typedef my_int<N-1> type; }; }} /* Check a type is a model of Integral Constant http://www.boost.org/libs/mpl/doc/refmanual/integral-constant.html */ template <typename T> void IntegralConstantConcept() { typedef typename boost::mpl::next<T>::type next_type; typedef typename boost::mpl::prior<T>::type prior_type; typedef typename T::type type; typedef typename T::value_type value_type; typename T::value_type t = T::value; typename T::value_type t1 = T(); static int const next_value = T::value +1; static int const prior_value = T::value -1; BOOST_MPL_ASSERT( (boost::is_same<type,T>) ); BOOST_STATIC_ASSERT( (next_type::value == next_value)); BOOST_STATIC_ASSERT( (prior_type::value == prior_value)); std::cout << typeid (T).name() << "passed Integral Concept Concept Check\n"; }; namespace mpl = boost::mpl; int main() { // Concept check IntegralConstantConcept<my_int<1> >(); IntegralConstantConcept<mpl::integral_c<int,1> >(); IntegralConstantConcept<mpl::int_<1> >(); // fails // IntegralConstantConcept<mpl::bool_<true> >(); // should fail // IntegralConstantConcept<int >(); // Should work ! // http://www.boost.org/libs/mpl/doc/refmanual/equal-to.html bool result = mpl::equal_to< my_int<1>,my_int<1> >::value ; std::cout << result << '\n'; } regards Andy Little

Andy Little writes:
Further the following code should work AFAICS, at least according to the documentation
[...]
// Write a type fulfilling the Integral Constant requirements // http://www.boost.org/libs/mpl/doc/refmanual/integral-constant.html template <int N> struct my_int{
typedef boost::mpl::integral_c_tag tag;
typedef int value_type; static const int value = N; operator int ()const { return value;} typedef my_int type; };
[...]
// Should work ! // http://www.boost.org/libs/mpl/doc/refmanual/equal-to.html
bool result = mpl::equal_to< my_int<1>,my_int<1> >::value ;
That's a documentation bug, please see the above and http://www.boost.org/libs/mpl/doc/tutorial/numeric-metafunction.html. OK, fixed in the sources now, thanks for the report! -- Aleksey Gurtovoy MetaCommunications Engineering

Andy Little writes:
IMO the Integral Constant Concept is over specified in the mpl docs. What is the rationale behind the next<..> and prior <..> requirements?
The corresponding operations are handy and available for every integral type?
These seem to have little to do with an Integral Constant.
IMO that's equivalent to saying that operations of increment and decrement have little to do with a concept of an integer number.
Maybe they should rather be another Concept , such as Iterable?
They _could be_ factored out in a separate concept, but that doesn't automatically means denying users the guarantee of having convenient access to the basic operations like increment/decrement.
Where N is a model of Iterable:
next<N>::type prior<N>::type
Currently for example, mpl::bool_ is stated to be a model of Integral Constant, but it fails to meet the curently stated requirments, nor can it ever AFAICS.
Surely this could work and would make sense, no? BOOST_MPL_ASSERT(( is_same< next<false_>::type, true_ > )); BOOST_MPL_ASSERT(( is_same< prior<true_>::type, false_ > ));
Further the requirements currently include a member ::value_type. According to the TMP book, this is a classic example of a traits blob. (section 2.2).
In a way.
Surely access should be specified using value_type<C>::type?
It could be (ignoring for the moment the fact that the 'value_type' name is already taken), but it has nothing to do with the presence of the requirement, in whatever form, in the concept.
IOW maybe a ValueType Concept.
Theoretically, we could factor out every single requirement in its own concept, but that doesn't necessarily going to improve the quality of the resulting concept language.
Finally the runtime evaluation requirement could be removed and a refinement of ValueType such as RunTime Evaluable be stated in terms such as:
Where T is a type modelling Runtime Evaluable
value_type<T>::type = t();
Again, I don't see any value in denying users of the concept access to the functionality that is by definition available for every possible model of the concept.
For a type N The current Integral Constant spec would then, in those places where these requirements are required:
N is a model of Iterable, Integral Constant and Runtime Evaluable.
I don't see how this is an improvement, given that IMO every integral constant is by definition Iterable and Runtime Evaluable.
This would allow me to meet the new Integral Constant requirements without unneccesary baggage.
May be if you start with describing what you are trying to achieve and how the Integral Constant's requirements stand in your way, we'd have better chances of figuring out the best way to resolve these issues. -- Aleksey Gurtovoy MetaCommunications Engineering

"Aleksey Gurtovoy" <agurtovoy@meta-comm.com> wrote in message news:m13bcp56mg.fsf@meta-comm.com...
Andy Little writes:
IMO the Integral Constant Concept is over specified in the mpl docs. What is the rationale behind the next<..> and prior <..> requirements?
The corresponding operations are handy and available for every integral type?
I am sure no expert on Concepts, but my understanding is that a Concept should specify the minimum requirements, not the maximum or try to include anything that *might* come in handy, which would anyway be impossible. next and prior can be trivially specified in terms of the math operations of addition and subtraction. IOW if a type t is an Integral Constant and is Addable then next<t>::type can be generated automatically, but the basic math, comparison and logical operations, arent in the Integral Constant requirements, at least in boost-1.33.1. A bool_ is stated to be a model of Integral Constant, but it patently doesnt and can never meet the next / prior requirements. It is arguable whether a bool should be a model of Integral Constant anyway ( in fact I believe that there should be a separate Boolean Constant and the Boost type traits functions should use a model of that where appropriate rather than integral_constant), but that depends on how the Concept is specified. If Addition is specified for example, then the semantics are different for boolean types ( and for a bool_ next and prior is ambiguous then), a good argument for not making bool_ a model of integral constant in that case. If a bool_ is a model of Integral Constant then Addition should not be specified for Integral Constant and by implication next/ prior should not be specified either as they are just special cases of the more general Concepts. In my use of integral constants, comparison for equality is the most used operation, followed by arithmetic. I have never used the next ,prior functions. To me math ,comparison and logic operations are more likely candidates for Integral Constant Requirements. Some of these are required by both bools and integers and some not. The point where the requirements or semantic differ is probably the level of detail that the Concepts should be specified at.
These seem to have little to do with an Integral Constant.
IMO that's equivalent to saying that operations of increment and decrement have little to do with a concept of an integer number.
increment and decrement are more precise terms than next and prior but they can be trivially specified in terms of the usual math operations, addition and subtraction. That is given a number is Addable and Subtractible, it is automatically Incrementable and Decrementable. It should also be stated that these constants arent perfect models of integers, what happens in the case of math on constants of different value_types , whether a given math operation is possible ( without overflow) and so on.
Maybe they should rather be another Concept , such as Iterable?
They _could be_ factored out in a separate concept, but that doesn't automatically means denying users the guarantee of having convenient access to the basic operations like increment/decrement.
They arent denied anything, if, in places where such functionality is required, that it is stated that X is required to be a model of Iterable. FWIW my use has never needed such a requirement. I do however usually need comparisons and math, but again not math in the case of boolean constants.
Where N is a model of Iterable:
next<N>::type prior<N>::type
Currently for example, mpl::bool_ is stated to be a model of Integral Constant, but it fails to meet the curently stated requirments, nor can it ever AFAICS.
Surely this could work and would make sense, no?
BOOST_MPL_ASSERT(( is_same< next<false_>::type, true_ > )); BOOST_MPL_ASSERT(( is_same< prior<true_>::type, false_ > ));
How often do you need to do this ? and what does next<true_>::type mean? true and false arent numbers. false is not less than true. (boolean != binary before anyone makes the link)
Further the requirements currently include a member ::value_type. According to the TMP book, this is a classic example of a traits blob. (section 2.2).
In a way.
OK. The book goes on to say, "we will avoid this idiom at all costs, since it creates major problems."
Surely access should be specified using value_type<C>::type?
It could be (ignoring for the moment the fact that the 'value_type' name is already taken), but it has nothing to do with the presence of the requirement, in whatever form, in the concept.
It was suggested to me that I use the mpl Integral Constant Concept in my own work. I am also attempting to use the mpl Concepts as a guide to good style. I am examining Integral Constant from this viewpoint. I am currently trying to write Concepts for my own types parameters.. Bearing in mind that the inadequate Concept documentation was one of the main reasons that PQS was rejected., so now I am trying to get it right. One concept in the quan library is currently called StaticAbstractQuantity: http://tinyurl.com/len5m One goal of this Concept is that it should be possible to make a raw mpl::vector a model of StaticAbstractQuantity. In order to do this I have opted to use 'free' metafunctions for the associated types. For other developers working on the project I need to explain why this is a good idea. Of course developers can point to examples like this and say, mpl doesnt do that. Why should we?
Theoretically, we could factor out every single requirement in its own concept, but that doesn't necessarily going to improve the quality of the resulting concept language.
Mixing orthogonal Concepts has resulted in the problems with bool_. By factoring out the separate Concepts it is possible to see which apply to bool_ and which don't.
Finally the runtime evaluation requirement could be removed and a refinement of ValueType such as RunTime Evaluable be stated in terms such as:
Where T is a type modelling Runtime Evaluable
value_type<T>::type = t();
Again, I don't see any value in denying users of the concept access to the functionality that is by definition available for every possible model of the concept.
By making this a separate Concept, I could write algorithms which only have the Runtime Evaluable requirement. They dont need to be members of Integral Constant. A compile time rational could be evaluated at runtime for example, but it is not a model of Integral Constant. If the only requirement is Runtime Evaluable, both rational and int_ are models.
For a type N The current Integral Constant spec would then, in those places where these requirements are required:
N is a model of Iterable, Integral Constant and Runtime Evaluable.
I don't see how this is an improvement, given that IMO every integral constant is by definition Iterable and Runtime Evaluable.
Sure and there is a lot to be gained by identifying these as separate Concepts. And what we have in mpl Integral Constant is a bag of loosely related Concepts.
This would allow me to meet the new Integral Constant requirements without unneccesary baggage.
May be if you start with describing what you are trying to achieve and how the Integral Constant's requirements stand in your way, we'd have better chances of figuring out the best way to resolve these issues.
I hope I have explained some of the problems I have with it. Another problem is that there are in fact hidden requirements, not mentioned in the Documentation, as I tried to demonstrate in the example code in the other message in this thread. regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
A bool_ is stated to be a model of Integral Constant, but it patently doesnt and can never meet the next / prior requirements.
Well, that's not strictly true. false_ and true_ can meet the next/prior requirements just as well as int_<INT_MIN> and int_<INT_MAX> can. Any bounded type has the same problem; maybe we need to be more precise about what happens at the endpoints of the range. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:umzaulykv.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
A bool_ is stated to be a model of Integral Constant, but it patently doesnt and can never meet the next / prior requirements.
Well, that's not strictly true. false_ and true_ can meet the next/prior requirements just as well as int_<INT_MIN> and int_<INT_MAX> can.
Which is that they cant, so the statement is strictly true, INT_MIN and INT_MAX arent models of Integral Constant either, similar for unsigned types.
Any bounded type has the same problem; maybe we need to be more precise about what happens at the endpoints of the range.
I have found it essential for maths on a compile time rational, but its more critical there. As regards bool_ , the debate is interesting for theoreticians but for practical programmers, it should be a separate Concept .. simple and many of the type_traits functions should use that, which would remove the need for the true_or_false_type mullarkey. Also I suspect that the change from boost::is_same to std::is_same is going to break a lot of code, unless the mpl tag requiremnet is lifted ;-) regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:umzaulykv.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
A bool_ is stated to be a model of Integral Constant, but it patently doesnt and can never meet the next / prior requirements.
Well, that's not strictly true. false_ and true_ can meet the next/prior requirements just as well as int_<INT_MIN> and int_<INT_MAX> can.
Which is that they cant, so the statement is strictly true, INT_MIN and INT_MAX arent models of Integral Constant either, similar for unsigned types.
Yes, but then if int_<INT_MIN> is not a model, then by induction, nothing is... beceause prev<int_<INT_MIN+1> >::type can't yield an integral constant, and so on. You can't claim that's because next/prev requiremens don't belong in Integral Constant; we'd have the same problem with an "iterable" concept. We just need a better way to specify what happens at the endpoints of the range. And, I should add, calling Integral Constant a "traits blob" is a serious stretch. Integral Constant is a type concept that includes "self-returning metafunction" mostly for convenience reasons. That is, the primary role of Integral Constant is not as a metafunction.
Any bounded type has the same problem; maybe we need to be more precise about what happens at the endpoints of the range.
I have found it essential for maths on a compile time rational, but its more critical there.
As regards bool_ , the debate is interesting for theoreticians but for practical programmers, it should be a separate Concept ..
You have said so many times but I have not seen any convincing evidence that the existing concept definition is problematic other than violating your personal sense of how things should be.
simple and many of the type_traits functions should use that, which would remove the need for the true_or_false_type mullarkey.
I don't know what you're referring to.
Also I suspect that the change from boost::is_same to std::is_same is going to break a lot of code, unless the mpl tag requiremnet is lifted ;-)
Ditto. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
Also I suspect that the change from boost::is_same to std::is_same is going to break a lot of code, unless the mpl tag requiremnet is lifted ;-)
Ditto.
The boost type_traits integral constant is derived from mpl::integral_c which has a tag type member, without which boost:::integral_constant wouldnt work with mpl types such as equal_to. The std version doesnt specify the tag, nor does the boost type_traits version in its documentation. Without the tag, boost::integral_constant would not work with mpl types such as equal_to as demonstrated in another mail in this thread. Therefore changing from boost::integral_constant to std::integral_constant will break code that uses mpl. Maybe its not important, but the innocent std:: integral_constant will appear to be bug ridden. regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
Also I suspect that the change from boost::is_same to std::is_same is going to break a lot of code, unless the mpl tag requiremnet is lifted ;-)
Ditto.
The boost type_traits integral constant is derived from mpl::integral_c which has a tag type member, without which boost:::integral_constant wouldnt work with mpl types such as equal_to.
?? equal_to isn't a type.
The std version doesnt specify the tag, nor does the boost type_traits version in its documentation. Without the tag, boost::integral_constant would not work with mpl types such as equal_to as demonstrated in another mail in this thread. Therefore changing from boost::integral_constant to std::integral_constant will break code that uses mpl. Maybe its not important, but the innocent std:: integral_constant will appear to be bug ridden.
I see no requirement that a `tag' type member be included in http://boost.org/libs/mpl/doc/refmanual/integral-constant.html. However, it does look like the current implementation of equal_to depends on the presence of `tag'. I'm not sure what the plan was here; Aleksey? It would be easy enough to make most of the MPL numeric metafunctions work on types that don't supply `tag'. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:ulkqccd9c.fsf@boost-consulting.com...
I see no requirement that a `tag' type member be included in http://boost.org/libs/mpl/doc/refmanual/integral-constant.html. However, it does look like the current implementation of equal_to depends on the presence of `tag'. I'm not sure what the plan was here; Aleksey?
It would be easy enough to make most of the MPL numeric metafunctions work on types that don't supply `tag'.
The larger problem (potentially) is that boost::integral_constant which is used by a lot of type_traits metafunctions does have the tag memeber(because its derived from mpl::integral_c), but it doesnt advertise it in its documentation. It would be interesting to try a version of boost::integral_constant which matches the std::integral_constant requirements and no more and see what if any problems it causes, particularly for code that uses mpl, to see what problems might be caused by replacing boost::integral_constant with std::integral_constant. Of course I may be making a fuss out of nothing, but to me it looks like this issue could cause a lot of problems. Also perhaps boost::integral-constant (the type_traits version) should then be changed to implement only the requirements of the std::integral_constant... IOW not derive from mpl::integral_c ? regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:ulkqccd9c.fsf@boost-consulting.com...
Also perhaps boost::integral-constant (the type_traits version) should then be changed to implement only the requirements of the std::integral_constant... IOW not derive from mpl::integral_c ?
I believe that derivation is important, at least for a while (and perhaps forever), to avoid breaking user code. I've written plenty of code like this: void f(mpl::true_) { ... } void f(mpl::false_) { ... } f(is_pointer<X>()) -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams writes:
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
The std version doesnt specify the tag, nor does the boost type_traits version in its documentation. Without the tag, boost::integral_constant would not work with mpl types such as equal_to as demonstrated in another mail in this thread. Therefore changing from boost::integral_constant to std::integral_constant will break code that uses mpl. Maybe its not important, but the innocent std:: integral_constant will appear to be bug ridden.
I see no requirement that a `tag' type member be included in http://boost.org/libs/mpl/doc/refmanual/integral-constant.html. However, it does look like the current implementation of equal_to depends on the presence of `tag'. I'm not sure what the plan was here; Aleksey?
Please see http://article.gmane.org/gmane.comp.lib.boost.devel/146324. -- Aleksey Gurtovoy MetaCommunications Engineering

Andy Little writes:
The boost type_traits integral constant is derived from mpl::integral_c which has a tag type member, without which boost:::integral_constant wouldnt work with mpl types such as equal_to. The std version doesnt specify the tag, nor does the boost type_traits version in its documentation. Without the tag, boost::integral_constant would not work with mpl types such as equal_to as demonstrated in another mail in this thread. Therefore changing from boost::integral_constant to std::integral_constant will break code that uses mpl. Maybe its not important, but the innocent std:: integral_constant will appear to be bug ridden.
Ideally, I'd like to link the '::tag' requirement with the mixed-type arithmetic operations (for which the tag was introduced) and move it out of the Integral Constant requirements into a corresponding concept. Either way, making the above work is not a major issue. -- Aleksey Gurtovoy MetaCommunications Engineering

Andy Little writes:
"Aleksey Gurtovoy" <agurtovoy@meta-comm.com> wrote in message news:m13bcp56mg.fsf@meta-comm.com...
Andy Little writes:
IMO the Integral Constant Concept is over specified in the mpl docs. What is the rationale behind the next<..> and prior <..> requirements?
The corresponding operations are handy and available for every integral type?
I am sure no expert on Concepts, but my understanding is that a Concept should specify the minimum requirements,
There is no absolute notion of the minimum set of requirements. For one, the abstract minimum is of course having no requirements at all, and obviously that would hardly give us a useful set of concepts. A meaningful minimum can only be derived from the relevant use cases, and it's pointless to discuss one without having those on the table.
not the maximum or try to include anything that *might* come in handy, which would anyway be impossible.
I didn't say these are included because they *might* come in handy. They are included because they are proven to be handy, are heavily exercised throughout the library, and are almost exclusively the only arithmetic requirements the library itself puts on the concept's models.
next and prior can be trivially specified in terms of the math operations of addition and subtraction.
Assuming that Integral Constant is required to provide the latter, which it doesn't. We can discuss whether it should, but I want to make sure you understand that you are actually arguing towards putting a heavier set of requirements on the concept.
IOW if a type t is an Integral Constant and is Addable then next<t>::type can be generated automatically,
At the price of a (much higher) performance overhead, depending on what Addable is.
but the basic math, comparison and logical operations, arent in the Integral Constant requirements, at least in boost-1.33.1.
Yep, they are not.
A bool_ is stated to be a model of Integral Constant, but it patently doesnt and can never meet the next / prior requirements.
Of course it can.
It is arguable whether a bool should be a model of Integral Constant anyway ( in fact I believe that there should be a separate Boolean Constant and the Boost type traits functions should use a model of that where appropriate rather than integral_constant), but that depends on how the Concept is specified. If Addition is specified for example, then the semantics are different for boolean types ( and for a bool_ next and prior is ambiguous then),
How so?
a good argument for not making bool_ a model of integral constant in that case.
Or a good argument not to burden Integral Constant with Addition.
If a bool_ is a model of Integral Constant then Addition should not be specified for Integral Constant and by implication next/ prior should not be specified either as they are just special cases of the more general Concepts.
The current use cases indicate that they are in fact very important special cases, important enough to warrant support on their own.
In my use of integral constants, comparison for equality is the most used operation, followed by arithmetic. I have never used the next ,prior functions. To me math ,comparison and logic operations are more likely candidates for Integral Constant Requirements.
IMO they are too heavy-weight. I understand your desire to have a concept encompassing these, but so far I don't see a compelling reason why Integral Constant should be such a concept (and I find it somewhat amusing that the title of this thread is "Integral Constant is over specified" :).
Some of these are required by both bools and integers and some not. The point where the requirements or semantic differ is probably the level of detail that the Concepts should be specified at.
These seem to have little to do with an Integral Constant.
IMO that's equivalent to saying that operations of increment and decrement have little to do with a concept of an integer number.
increment and decrement are more precise terms than next and prior but they can be trivially specified in terms of the usual math operations, addition and subtraction. That is given a number is Addable and Subtractible, it is automatically Incrementable and Decrementable.
I believe I've commented on this point earlier.
It should also be stated that these constants arent perfect models of integers, what happens in the case of math on constants of different value_types , whether a given math operation is possible ( without overflow) and so on.
Stated where?
Maybe they should rather be another Concept , such as Iterable?
They _could be_ factored out in a separate concept, but that doesn't automatically means denying users the guarantee of having convenient access to the basic operations like increment/decrement.
They arent denied anything, if, in places where such functionality is required, that it is stated that X is required to be a model of Iterable.
I don't think that such level granularity will improve the library's usability. Every integral constant _is_ Iterable; whether X excercises that capability or not is often an implementation detail. (That's not to say that having an Iterable concept won't be an improvement.)
FWIW my use has never needed such a requirement. I do however usually need comparisons and math, but again not math in the case of boolean constants.
Where N is a model of Iterable:
next<N>::type prior<N>::type
Currently for example, mpl::bool_ is stated to be a model of Integral Constant, but it fails to meet the curently stated requirments, nor can it ever AFAICS.
Surely this could work and would make sense, no?
BOOST_MPL_ASSERT(( is_same< next<false_>::type, true_ > )); BOOST_MPL_ASSERT(( is_same< prior<true_>::type, false_ > ));
How often do you need to do this ?
Rarely, but I'm yet to see a compelling reason to disallow it either.
and what does next<true_>::type mean?
It's unspecified?
true and false arent numbers. false is not less than true. (boolean != binary before anyone makes the link)
So it should be impossible to sort a container of booleans, then?
Further the requirements currently include a member ::value_type. According to the TMP book, this is a classic example of a traits blob. (section 2.2).
In a way.
OK. The book goes on to say, "we will avoid this idiom at all costs, since it creates major problems."
I'd have gladly went with 'value_type' metafunction if the name wasn't already taken. I'm not a big fan of 'value_type_of' convention (and there is no precedent of such in the library). Suggestions are welcome.
Surely access should be specified using value_type<C>::type?
It could be (ignoring for the moment the fact that the 'value_type' name is already taken), but it has nothing to do with the presence of the requirement, in whatever form, in the concept.
It was suggested to me that I use the mpl Integral Constant Concept in my own work. I am also attempting to use the mpl Concepts as a guide to good style. I am examining Integral Constant from this viewpoint.
Understood.
I am currently trying to write Concepts for my own types parameters.. Bearing in mind that the inadequate Concept documentation was one of the main reasons that PQS was rejected., so now I am trying to get it right. One concept in the quan library is currently called StaticAbstractQuantity:
One goal of this Concept is that it should be possible to make a raw mpl::vector a model of StaticAbstractQuantity. In order to do this I have opted to use 'free' metafunctions for the associated types. For other developers working on the project I need to explain why this is a good idea. Of course developers can point to examples like this and say, mpl doesnt do that. Why should we?
I'm more than willing to work with you on fixing these cases.
Theoretically, we could factor out every single requirement in its own concept, but that doesn't necessarily going to improve the quality of the resulting concept language.
Mixing orthogonal Concepts has resulted in the problems with bool_.
Personally, I think that the only problem with bool_ is that its implementation doesn't confirm to the docs.
By factoring out the separate Concepts it is possible to see which apply to bool_ and which don't.
Finally the runtime evaluation requirement could be removed and a refinement of ValueType such as RunTime Evaluable be stated in terms such as:
Where T is a type modelling Runtime Evaluable
value_type<T>::type = t();
Again, I don't see any value in denying users of the concept access to the functionality that is by definition available for every possible model of the concept.
By making this a separate Concept, I could write algorithms which only have the Runtime Evaluable requirement. They dont need to be members of Integral Constant.
Right; I'd be happy to work on such concept once we have at least one use case for it. In any case, you said that "the runtime evaluation requirement could be removed", and that's what I was (and am) objecting to, not factoring it out into a separate concept per se.
A compile time rational could be evaluated at runtime for example, but it is not a model of Integral Constant.
This value_type<T>::type = t(); is not going to work for a compile time rational. Finding out what will is a job that requires both time and actual, not hypothetical, cases at hand. If you have them, please present and we can work on it.
If the only requirement is Runtime Evaluable, both rational and int_ are models.
For a type N The current Integral Constant spec would then, in those places where these requirements are required:
N is a model of Iterable, Integral Constant and Runtime Evaluable.
I don't see how this is an improvement, given that IMO every integral constant is by definition Iterable and Runtime Evaluable.
Sure and there is a lot to be gained by identifying these as separate Concepts.
Proposals are welcome! -- Aleksey Gurtovoy MetaCommunications Engineering

"Aleksey Gurtovoy" <agurtovoy@meta-comm.com> wrote in message news:m1k65tgzvi.fsf@meta-comm.com...
Andy Little writes:
<...>
There is no absolute notion of the minimum set of requirements. For one, the abstract minimum is of course having no requirements at all, and obviously that would hardly give us a useful set of concepts.
AnyType would be a useful Concept, similar to the universal set: Where A and B are models of AnyType boost::is_same<A,B> Another use of AnyType would be to check that you have covered all use cases, when using enable_if for example. I don't know what the notation would be but for example The union of ConstAnyType with NonConstAnyType is AnyType. Obviously things can become much more complicated than this in practise, so its a useful general Concept, but maybe not inside mpl.
A meaningful minimum can only be derived from the relevant use cases, and it's pointless to discuss one without having those on the table.
The minimal use of a StaticConstant is to return its value Where C is a model of StaticConstant get_value<C>::value A check on whether a type is a model of StaticConstant would also be useful: where C is a model of StaticConstant. is_constant<C>::value is true A simple model struct zero; template <> get_value<zero> {static int const value = 0;}; template <> struct is_constant<zero> : true_{}; With typeof, the type of the value of any StaticConstant can be found from that information template <typename C, typename Enable = void> struct get_value_type; template <typename T> struct get_value_type<T, typename boost::enable_if<is_constant<T> >::type> { typedef BOOST_TYPEOF_TPL(get_value<T>::value) type; }; <...>
In my use of integral constants, comparison for equality is the most used operation, followed by arithmetic. I have never used the next ,prior functions. To me math ,comparison and logic operations are more likely candidates for Integral Constant Requirements.
IMO they are too heavy-weight. I understand your desire to have a concept encompassing these, but so far I don't see a compelling reason why Integral Constant should be such a concept (and I find it somewhat amusing that the title of this thread is "Integral Constant is over specified" :).
Sure. mpl::IntegralConstant is designed for use inside mpl. My problem arose because it was suggested to me that I make some of my own types models of mpl::Integral Constant. mpl::IntegralConstant obviously works very well inside of mpl. Its probably unfair to expect it to stand up for general purpose use, but that is the way it was suggested I use it. <...>
It should also be stated that these constants arent perfect models of integers, what happens in the case of math on constants of different value_types , whether a given math operation is possible ( without overflow) and so on.
Stated where?
In general, wherever it is possible that a mistake and particularly a silent one can occur. Means to detect these conditions (or not) might be dealt with by an Iterable Concept. <...>
I am currently trying to write Concepts for my own types parameters.. Bearing in mind that the inadequate Concept documentation was one of the main reasons that PQS was rejected., so now I am trying to get it right. One concept in the quan library is currently called StaticAbstractQuantity:
One goal of this Concept is that it should be possible to make a raw mpl::vector a model of StaticAbstractQuantity. In order to do this I have opted to use 'free' metafunctions for the associated types. For other developers working on the project I need to explain why this is a good idea. Of course developers can point to examples like this and say, mpl doesnt do that. Why should we?
I'm more than willing to work with you on fixing these cases.
As I said in another post, my major problem is not mpl's problem. It is the fact that many type_traits functions make use of mpl::integral_c. I'm wondering now wnat happens if I decide to change from using boost::is_same to std::is_same and so on. Ideally I would like to be able to use both mpl and std::is_same of course. That is possible, but currently I need to make my own specialisations of boost::mpl::equal_to and so on and specify that others do the same in order for things to work in all combinations. That is a bit messy. The other option is to create my own system that fits. <...>
N is a model of Iterable, Integral Constant and Runtime Evaluable.
I don't see how this is an improvement, given that IMO every integral constant is by definition Iterable and Runtime Evaluable.
I realise that things might be clarified if the mpl Integral Constant was always documented outside mpl (or at least in my own docs) as mpl::IntegralConstant . That I think agrees for instance with the way Conceptgcc documents things. I think the naming is the source of some confusion, maybe for me anyway. Integral Constant conveys to me something intended for general purpose use. If the mpl::integralConstant was always prefixed as such, one could then talk about an Integral Constant or maybe StaticIntegralConstant as being a general term as opposed to mpl::IntegralConstant which is designed for use inside mpl. Again though that isnt mpl's problem I guess. regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"Aleksey Gurtovoy" <agurtovoy@meta-comm.com> wrote in message news:m1k65tgzvi.fsf@meta-comm.com...
Andy Little writes:
<...>
There is no absolute notion of the minimum set of requirements. For one, the abstract minimum is of course having no requirements at all, and obviously that would hardly give us a useful set of concepts.
AnyType would be a useful Concept, similar to the universal set:
Where A and B are models of AnyType
That's meaningless. Just leave out the "where."
boost::is_same<A,B>
Another use of AnyType would be to check that you have covered all use cases, when using enable_if for example. I don't know what the notation would be but for example
Well, your example is too vague for me to understand. Maybe if you could provide some notation...
The union of ConstAnyType with NonConstAnyType is AnyType.
You have a problem with ConstType and NonConstType? "Any" adds nothing here.
Obviously things can become much more complicated than this in practise, so its a useful general Concept, but maybe not inside mpl.
Nothing you've written here leads me to conclude that it's useful. Please show a real example (or just retract that claim; I doubt it's central).
A meaningful minimum can only be derived from the relevant use cases, and it's pointless to discuss one without having those on the table.
The minimal use of a StaticConstant is to return its value
No, that's called CopyConstructible.
Where C is a model of StaticConstant get_value<C>::value
A check on whether a type is a model of StaticConstant would also be useful:
where C is a model of StaticConstant.
is_constant<C>::value is true
That's certainly not in the minimal set of requirements, since a proven useful set (the one in MPL) doesn't include it.
In my use of integral constants, comparison for equality is the most used operation, followed by arithmetic. I have never used the next ,prior functions. To me math ,comparison and logic operations are more likely candidates for Integral Constant Requirements.
IMO they are too heavy-weight. I understand your desire to have a concept encompassing these, but so far I don't see a compelling reason why Integral Constant should be such a concept (and I find it somewhat amusing that the title of this thread is "Integral Constant is over specified" :).
Aleksey's point here is that you are now advocating *more* specification, which contradicts your subject line.
It should also be stated that these constants arent perfect models of integers, what happens in the case of math on constants of different value_types , whether a given math operation is possible ( without overflow) and so on.
Stated where?
In general, wherever it is possible that a mistake and particularly a silent one can occur.
Technically that's right, but I don't think it's a serious omission when taken against a background of short,int,long,... all of which have the same problem. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:upsfhdfsd.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"Aleksey Gurtovoy" <agurtovoy@meta-comm.com> wrote in message news:m1k65tgzvi.fsf@meta-comm.com...
Andy Little writes:
<...>
There is no absolute notion of the minimum set of requirements. For one, the abstract minimum is of course having no requirements at all, and obviously that would hardly give us a useful set of concepts.
AnyType would be a useful Concept, similar to the universal set:
Where A and B are models of AnyType
That's meaningless. Just leave out the "where."
What's meaningless? the AnyType Concept or just the where?
boost::is_same<A,B>
Another use of AnyType would be to check that you have covered all use cases, when using enable_if for example. I don't know what the notation would be but for example
Well, your example is too vague for me to understand. Maybe if you could provide some notation...
I think even Anytype has some requirements. The only two I can think of are: typeid(AnyType) AnyType* An aspiration AnyType f(); BOOST_TYPEOF(f());
The union of ConstAnyType with NonConstAnyType is AnyType.
You have a problem with ConstType and NonConstType? "Any" adds nothing here.
Ok.
Obviously things can become much more complicated than this in practise, so its a useful general Concept, but maybe not inside mpl.
Nothing you've written here leads me to conclude that it's useful. Please show a real example (or just retract that claim; I doubt it's central).
What claim? That an AnyType Concept may not be useful in MPL? If it was useful it would be there right? Hence I deduce that *maybe* it wasnt found to be useful inside MPL. In general though an AnyType Concept would be a useful statement that there are no restrictions on the types allowed. It expresses the current situation regarding template parameters as a Concept. Its the most fundamental Concept of type and already exists in every template type parameter. In fact it is currently the only Concept we have.
A meaningful minimum can only be derived from the relevant use cases, and it's pointless to discuss one without having those on the table.
The minimal use of a StaticConstant is to return its value
No, that's called CopyConstructible.
At compile time?
Where C is a model of StaticConstant get_value<C>::value
A check on whether a type is a model of StaticConstant would also be useful:
where C is a model of StaticConstant.
is_constant<C>::value is true
That's certainly not in the minimal set of requirements, since a proven useful set (the one in MPL) doesn't include it.
Its roughly equivalent to the member ::tag requirement, currently at least, required by mpl::equal_to when acting on models of mpl::IntegralConstant
In my use of integral constants, comparison for equality is the most used operation, followed by arithmetic. I have never used the next ,prior functions. To me math ,comparison and logic operations are more likely candidates for Integral Constant Requirements.
IMO they are too heavy-weight. I understand your desire to have a concept encompassing these, but so far I don't see a compelling reason why Integral Constant should be such a concept (and I find it somewhat amusing that the title of this thread is "Integral Constant is over specified" :).
Aleksey's point here is that you are now advocating *more* specification, which contradicts your subject line.
Nope. Having next prior as requirements but not the usual operations on integers strikes me as odd. IOW if remove the next prior requirements, that is less specification, not more.
It should also be stated that these constants arent perfect models of integers, what happens in the case of math on constants of different value_types , whether a given math operation is possible ( without overflow) and so on.
Stated where?
In general, wherever it is possible that a mistake and particularly a silent one can occur.
Technically that's right, but I don't think it's a serious omission when taken against a background of short,int,long,... all of which have the same problem.
So what? The compiler cant warn about it at runtime. Maybe its not a problem for the use mpl::IntegralConstant is designed for. regards Andy Little

FWIW Here is one way that The separate Concepts in mpl::IntegralConstant could be broken down. If algorithms are specified in those terms then a wider range of types can be used. Note that the RuntimeEvaluable is useful on its own, as is Iterable. Its somewhat unfair to include The Numerics and comparisons, but note the warnings emitted in VC7.1 warning level 3(but none if warnings are turned off!) when a bool_ is used for maths, which suggest *Strongly* to me that it should be a separate Concept. Also not that bool_ fails the Iterable check so that check is commented out. regards Andy Little -------------------- #include <boost/typeof/typeof.hpp> #include <boost/type_traits/is_same.hpp> #include <iostream> #include <boost/mpl/integral_c.hpp> #include <boost/mpl/logical.hpp> #include <boost/mpl/comparison.hpp> #include <boost/mpl/arithmetic.hpp> #include <boost/mpl/bool.hpp> #include <boost/concept_check.hpp> #include <boost/mpl/next_prior.hpp> // UnaryMetaFunction Concept template <typename T> void UnaryMetaFunction() { typedef typename T::type type; bool result = boost::is_same<typename T::type, T> ::value; if(result) std::cout << typeid(T).name() << ((result)?" passed":"failed") << " UnaryMetaFunction test\n"; } template <typename T, T v> struct static_value_check{}; template <typename T> void ConstantMetaFunction() { /*refinement of */ UnaryMetaFunction<T>(); static_value_check<BOOST_TYPEOF(T::value),T::value> tested; boost::ignore_unused_variable_warning(tested); std::cout << typeid(T).name() << " passed ConstantMetaFunction test\n"; } template <typename T> void BooleanMetaFunction() { /*refinement of */ ConstantMetaFunction<T>(); static const bool equal_to = boost::mpl::equal_to<T,T>::value; typedef typename boost::mpl::not_<T>::type notT; static const bool not_equal_to = boost::mpl::not_equal_to<notT,T>::value; static const bool and_ = boost::mpl::and_<T,T>::value; static const bool or_ = boost::mpl::or_<T,notT>::value; static const bool result = equal_to && not_equal_to && and_ && or_; // etc std::cout << typeid(T).name() << ((result)?" passed":"failed") << " BooleanMetaFunction test\n"; } template <typename T> void IterableMetaFunction() { /*refinement of */ ConstantMetaFunction<T>(); typedef typename boost::mpl::next<T>::type next; typedef typename boost::mpl::prior<T>::type prior; std::cout << typeid(T).name() << " passed IterableMetaFunction test\n"; } template <typename T> void NumericMetaFunction() { /*refinement of */ BooleanMetaFunction<T>(); typedef typename boost::mpl::plus<T,T>::type plus; typedef typename boost::mpl::minus<T,T>::type minus; typedef typename boost::mpl::times<T,T>::type times; typedef typename boost::mpl::divides<T,T>::type divides; typedef typename boost::mpl::negate<T>::type negate; typedef typename boost::mpl::modulus<T,T>::type modulus; // todo ... check results std::cout << typeid(T).name() << " passed NumericMetaFunction test\n"; } template <typename T> void RuntimeEvaluableMetaFunction() { BOOST_AUTO_TPL(value,T()); std::cout << typeid(T).name() << " passed RuntimeEvaluableMetaFunction test\n"; } int main() { typedef boost::mpl::integral_c<int,1> integral_c; BooleanMetaFunction<integral_c>(); IterableMetaFunction<integral_c>(); NumericMetaFunction<integral_c>(); RuntimeEvaluableMetaFunction<integral_c>(); typedef boost::mpl::true_ true_; BooleanMetaFunction<true_>(); //fail IterableMetaFunction<true_>(); // warns in VC7.1 output below ---> NumericMetaFunction<true_>(); RuntimeEvaluableMetaFunction<true_>(); // also works for other types RuntimeEvaluableMetaFunction<float>(); } /* c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\plus.hpp(136) : warning C4305: 'specialization' : truncation from 'int' to 'boost::mpl::if_c<C,T1,T2>::type' with [ C=true, T1=boost::mpl::bool_<true>::value_type, T2=boost::mpl::bool_<true>::value_type ] c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\plus.hpp(108) : see reference to class template instantiation 'boost::mpl::plus_impl<boost::mpl::integral_c_tag,boost::mpl::integral_c_tag>::apply<N1,N2>' being compiled with [ N1=true_, N2=true_ ] e:\Projects\Test\test.cpp(60) : see reference to class template instantiation 'boost::mpl::plus<N1,N2>' being compiled with [ N1=true_, N2=true_ ] e:\Projects\Test\test.cpp(81) : see reference to function template instantiation 'void NumericMetaFunction<true_>(void)' being compiled c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\divides.hpp(135) : warning C4804: '/' : unsafe use of type 'bool' in operation c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\divides.hpp(108) : see reference to class template instantiation 'boost::mpl::divides_impl<boost::mpl::integral_c_tag,boost::mpl::integral_c_tag>::apply<N1,N2>' being compiled with [ N1=true_, N2=true_ ] e:\Projects\Test\test.cpp(63) : see reference to class template instantiation 'boost::mpl::divides<N1,N2>' being compiled with [ N1=true_, N2=true_ ] c:\boost\include\boost-1_33_1\boost\mpl\negate.hpp(73) : warning C4804: '-' : unsafe use of type 'bool' in operation c:\boost\include\boost-1_33_1\boost\mpl\negate.hpp(41) : see reference to class template instantiation 'boost::mpl::negate_impl<boost::mpl::integral_c_tag>::apply<N>' being compiled with [ N=true_ ] e:\Projects\Test\test.cpp(64) : see reference to class template instantiation 'boost::mpl::negate<N>' being compiled with [ N=true_ ] c:\boost\include\boost-1_33_1\boost\mpl\negate.hpp(73) : warning C4305: 'specialization' : truncation from 'int' to 'boost::mpl::bool_<C_>::value_type' with [ C_=true ] c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\modulus.hpp(93) : warning C4804: '%' : unsafe use of type 'bool' in operation c:\boost\include\boost-1_33_1\boost\mpl\aux_\preprocessed\plain\modulus.hpp(72) : see reference to class template instantiation 'boost::mpl::modulus_impl<boost::mpl::integral_c_tag,boost::mpl::integral_c_tag>::apply<N1,N2>' being compiled with [ N1=true_, N2=true_ ] e:\Projects\Test\test.cpp(65) : see reference to class template instantiation 'boost::mpl::modulus<N1,N2>' being compiled with [ N1=true_, N2=true_ ] */

"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:upsfhdfsd.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"Aleksey Gurtovoy" <agurtovoy@meta-comm.com> wrote in message news:m1k65tgzvi.fsf@meta-comm.com...
Andy Little writes:
<...>
There is no absolute notion of the minimum set of requirements. For one, the abstract minimum is of course having no requirements at all, and obviously that would hardly give us a useful set of concepts.
AnyType would be a useful Concept, similar to the universal set:
Where A and B are models of AnyType
That's meaningless. Just leave out the "where."
What's meaningless? the AnyType Concept or just the where?
boost::is_same<A,B>
Another use of AnyType would be to check that you have covered all use cases, when using enable_if for example. I don't know what the notation would be but for example
Well, your example is too vague for me to understand. Maybe if you could provide some notation...
I think even Anytype has some requirements. The only two I can think of are:
typeid(AnyType)
Well, c'mon. That's like saying AnyName "can be written down." typedef X y; is also required where X is any type. We don't need a new Concept for that, because the C++ standard gives us "type."
AnyType*
Not unless you want to rule out reference types.
An aspiration AnyType f();
Not unless you want to rule out array and function types.
Obviously things can become much more complicated than this in practise, so its a useful general Concept, but maybe not inside mpl.
Nothing you've written here leads me to conclude that it's useful. Please show a real example (or just retract that claim; I doubt it's central).
What claim? That an AnyType Concept may not be useful in MPL?
No, that "AnyType would be a useful Concept."
In general though an AnyType Concept would be a useful statement that there are no restrictions on the types allowed. It expresses the current situation regarding template parameters as a Concept. Its the most fundamental Concept of type and already exists in every template type parameter.
Yeah, it's called "type."
In fact it is currently the only Concept we have.
?? We've defined several type concepts in MPL, such as "nullary Metafunction."
A meaningful minimum can only be derived from the relevant use cases, and it's pointless to discuss one without having those on the table.
The minimal use of a StaticConstant is to return its value
No, that's called CopyConstructible.
At compile time?
You'd better be more precise in your language. You can't literally "return a value" at compile time.
Where C is a model of StaticConstant get_value<C>::value
A check on whether a type is a model of StaticConstant would also be useful:
where C is a model of StaticConstant.
is_constant<C>::value is true
That's certainly not in the minimal set of requirements, since a proven useful set (the one in MPL) doesn't include it.
Its roughly equivalent to the member ::tag requirement, currently at least, required by mpl::equal_to when acting on models of mpl::IntegralConstant
Not at all. It's one thing to require X::value or Y::tag, and quite another to require is_constant<C>::value.
In my use of integral constants, comparison for equality is the most used operation, followed by arithmetic. I have never used the next ,prior functions. To me math ,comparison and logic operations are more likely candidates for Integral Constant Requirements.
IMO they are too heavy-weight. I understand your desire to have a concept encompassing these, but so far I don't see a compelling reason why Integral Constant should be such a concept (and I find it somewhat amusing that the title of this thread is "Integral Constant is over specified" :).
Aleksey's point here is that you are now advocating *more* specification, which contradicts your subject line.
Nope.
Yep.
Having next prior as requirements but not the usual operations on integers strikes me as odd.
Yes, but that's not necessarily a good criterion for determining what should be a concept.
IOW if remove the next prior requirements, that is less specification, not more.
If we just do that, sure, but you're advocating the replacement of specification for the simple next/prior requirements with that of all the math, comparison, and logic operations!
It should also be stated that these constants arent perfect models of integers, what happens in the case of math on constants of different value_types , whether a given math operation is possible ( without overflow) and so on.
Stated where?
In general, wherever it is possible that a mistake and particularly a silent one can occur.
Technically that's right, but I don't think it's a serious omission when taken against a background of short,int,long,... all of which have the same problem.
So what? The compiler cant warn about it at runtime.
I don't understand your point. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:uy7u32kxw.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:upsfhdfsd.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"Aleksey Gurtovoy" <agurtovoy@meta-comm.com> wrote in message news:m1k65tgzvi.fsf@meta-comm.com...
Andy Little writes:
In my use of integral constants, comparison for equality is the most
used operation, followed by arithmetic. I have never used the next ,prior functions. To me math ,comparison and logic operations are more likely candidates for Integral Constant Requirements.
IMO they are too heavy-weight. I understand your desire to have a concept encompassing these, but so far I don't see a compelling reason why Integral Constant should be such a concept (and I find it somewhat amusing that the title of this thread is "Integral Constant is over specified" :).
Aleksey's point here is that you are now advocating *more* specification, which contradicts your subject line.
Nope.
Yep.
Nope. I am still advocating removing the next prior requirements, hence the title of the thread.
Having next prior as requirements but not the usual operations on integers strikes me as odd.
Yes, but that's not necessarily a good criterion for determining what should be a concept.
mpl::bool_ is stated to be a model of mpl::IntegralConstant, but exercising the requirements on it results in a failure to compile. Maybe the mismatch is acceptable to you, but I don't find it satisfactory. regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:uy7u32kxw.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:upsfhdfsd.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"Aleksey Gurtovoy" <agurtovoy@meta-comm.com> wrote in message news:m1k65tgzvi.fsf@meta-comm.com...
Andy Little writes:
> In my use of integral constants, comparison for equality is the most > used operation, followed by arithmetic. I have never used the next > ,prior functions. To me math ,comparison and logic operations are > more likely candidates for Integral Constant Requirements.
IMO they are too heavy-weight. I understand your desire to have a concept encompassing these, but so far I don't see a compelling reason why Integral Constant should be such a concept (and I find it somewhat amusing that the title of this thread is "Integral Constant is over specified" :).
Aleksey's point here is that you are now advocating *more* specification, which contradicts your subject line.
Nope.
Yep.
Nope. I am still advocating removing the next prior requirements, hence the title of the thread.
This is getting silly. Are you, or are you not, advocating adding a bunch of other requirements (math ,comparison and logic operations) to the concept as well?
Having next prior as requirements but not the usual operations on integers strikes me as odd.
Yes, but that's not necessarily a good criterion for determining what should be a concept.
mpl::bool_ is stated to be a model of mpl::IntegralConstant, but exercising the requirements on it results in a failure to compile. Maybe the mismatch is acceptable to you, but I don't find it satisfactory.
It isn't satisfactory. Look, we've been through this before; there are lots of ways to deal with that problem. Clearly the requirements need a small adjustment to handle boundary cases anyway, because exercising the requirements on int_<INT_MAX> results in undefined behavior, which by induction means int_<X> is not an IntegralConstant either. Maybe bool_<true> needs next and bool_<false> needs prior also. Until bool x = false; bool y = x + bool(1); becomes illegal I'm not going to agree that next/prior is a defect in IntegralConstant, and if it did become illegal I might just say we need a new concept for bool. If you want to say IntegralConstant could be more intuitively (or even better) defined, great. But your approach is to assert that next/prior are definitively wrong is just off-putting, because I know it's not as black-and-white as you seem to assert. If you have run into an actual problem, please describe it and how it has come up in your work, and we can try to look for an appropriate solution. Changing concept requirements is a serious documentation- and code-breaking change, and I wouldn't do it just because the concept seems odd to you. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote in message news:uy7u227q7.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:uy7u32kxw.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote in message news:upsfhdfsd.fsf@boost-consulting.com...
"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"Aleksey Gurtovoy" <agurtovoy@meta-comm.com> wrote in message news:m1k65tgzvi.fsf@meta-comm.com... > Andy Little writes: > >> In my use of integral constants, comparison for equality is the most >> used operation, followed by arithmetic. I have never used the next >> ,prior functions. To me math ,comparison and logic operations are >> more likely candidates for Integral Constant Requirements. > > IMO they are too heavy-weight. I understand your desire to have a > concept encompassing these, but so far I don't see a compelling reason > why Integral Constant should be such a concept (and I find it somewhat > amusing that the title of this thread is "Integral Constant is over > specified" :).
Aleksey's point here is that you are now advocating *more* specification, which contradicts your subject line.
Nope.
Yep.
Nope. I am still advocating removing the next prior requirements, hence the title of the thread.
This is getting silly. Are you, or are you not, advocating adding a bunch of other requirements (math ,comparison and logic operations) to the concept as well?
Nope. I am still advocating removing the next prior requirements, hence the title of the thread.
Having next prior as requirements but not the usual operations on integers strikes me as odd.
Yes, but that's not necessarily a good criterion for determining what should be a concept.
mpl::bool_ is stated to be a model of mpl::IntegralConstant, but exercising the requirements on it results in a failure to compile. Maybe the mismatch is acceptable to you, but I don't find it satisfactory.
It isn't satisfactory. Look, we've been through this before; there are lots of ways to deal with that problem. Clearly the requirements need a small adjustment to handle boundary cases anyway, because exercising the requirements on int_<INT_MAX> results in undefined behavior, which by induction means int_<X> is not an IntegralConstant either. Maybe bool_<true> needs next and bool_<false> needs prior also.
Until
bool x = false; bool y = x + bool(1);
becomes illegal I'm not going to agree that next/prior is a defect in IntegralConstant, and if it did become illegal I might just say we need a new concept for bool.
I found a useful reference in the C++ standard. Annex D D.1. Also see: 5.3.2-2 5.2.6 5.3.2 That is probably as close as you will get ... Anyway FWIW bool x = false; bool y = x | bool(1); is superior: int main() { bool x = false; bool y = x + bool(1); bool y1 = x | bool(1); } // asm unoptimised in VC8 ; 6 : bool x = false; mov BYTE PTR _x$[ebp], 0 ; 7 : bool y = x + bool(1); movzx eax, BYTE PTR _x$[ebp] add eax, 1 setne cl mov BYTE PTR _y$[ebp], cl ; 8 : bool y1 = x | bool(1); movzx edx, BYTE PTR _x$[ebp] or edx, 1 mov BYTE PTR _y1$[ebp], dl ; 9 :
If you want to say IntegralConstant could be more intuitively (or even better) defined, great. But your approach is to assert that next/prior are definitively wrong is just off-putting, because I know it's not as black-and-white as you seem to assert.
If you have run into an actual problem, please describe it and how it has come up in your work, and we can try to look for an appropriate solution. Changing concept requirements is a serious documentation- and code-breaking change, and I wouldn't do it just because the concept seems odd to you.
The IntegralConstant requirements have just been changed. Now you have to do: typedef boost::mpl::integral_c_tag tag; How do I make my Integral Constants compatible with mpl , boost::integral_constant and std::integral_constant ? that's my main problem. Anyway I'm working on it ;-) regards Andy Little
participants (3)
-
Aleksey Gurtovoy
-
Andy Little
-
David Abrahams