
Martin wrote:
In our applications, we can't predict the currency of a money variable at compile-time, and the overhead of the currencies is acceptable due to the very lean implementation (only 4 bytes, single comparison for checks).
Yes, that was one of the reasons I removed the currencyid from the type but I didn't find any good way to specify the currency for individual objects.
Do you have it as a constructor argument or is it a property?
ctor. Either directly: money m( 42, "EUR" ); or indirectly through a predefined currency to prevent typos and make it even more efficient: const currency EUR( "EUR" ) // Only once in some global project header money m( 42, EUR ); additionally, you can use: decimal d = m.amount(); // getter m.amount( d ); // setter currency c = m.currency(); // getter m.currency( c ); // setter to access the parts.
In your implementation decimal_traits<decimal64> and decimal_traits<decimalBCD> need to have the same interface so what's the difference.
Don't get me wrong here. I am usually in favour of traits classes but in this case I don't see the point.
The point is that when I want to use a new underlying type for calculations, I have a single point of customization, about 100-200 lines. The specialization of decimal_traits<T> for that type T and the typedef for decimal. I don't have to touch the 300.000+ lines of code that use it. What do you prefer?
Can we combine our work? I like your run-time currency and maybe you can convince me about the traits but I assume your solution is part of your work so it can't be used in boost.
The folks in my company are basically in favor of boost, so I hope they allow me to take some of the stuff here. Even if they don't allow it, I can still take my knowledge of general programming techniques (where lots of them come from boost!) and implement the classes from scratch. It'll just take a bit longer. To combine our work, I think it's best to separate it. As I said, decimal64 might be a candidate for basic_decimal<T>'s T. As I write this, I realize that I can describe basic_decimal as a helper for basic_money<T> (and the application as a whole) to decouple from T's interface. Maybe this helps to understand why basic_decimal is there. I'll ask about using the company's basic_decimal/basic_money/currency as a template for the boost implementation tomorrow and we can then discuss it independently of decimal64. I think it's most useful if you work on decimal64 independently of money/currency issues. Make it a cool new float-point type and basic_decimal will be able to use it :) Another benefit of the indirection through basic_decimal<T>: FWIW, there is one thing that my classes don't do right now and which I always dreamed of: "Correct" epsilon handling. Like operator== respects a given epsilon native_less(a,b) like the current operator< for the underlying type a!=b -> !(a==b) a<b -> native_less(a,b) && a!=b a>b -> native_less(b,a) && a!=b a<=b -> native_less(a,b) || a==b a>=b -> native_less(b,a) || a==b But we could encapsulate that in the decimal_traits<T>, too, so you can switch your application from no epsilon to different epsilons in a single place. Wouldn't that be cool? :o) Regards, Daniel