My approach would be to control the output of that class. Set a flag of that class and overwrite the <<operator () of that class to modify the oputput to your needs. Don't touch the well tested stream classes.
Main Topics
Browse All TopicsHi all
I have a nice class for tracking units-of-measure along with numerical values.
I have a simple output method accompanying this class which I can use to make the units show whenever a value is outputted to an ostream, as shown below.
My question: instead of using the ios_base::showbase flag (which is really intended for something completely different), can I create a new flag that is guaranteed to work on all platforms, that won't clash with existing flags, and which can safely be set with the 'stream.flags()' method?
What would be the model approach here?
Any suggestions appreciated.
JP
---------------------8<---
#define DEFINE_OUTPUT_METHOD(MM,LL
inline \
std::ostream& operator <<(std::ostream &os,const Units<MM,LL,TT,KK,II> &u){ \
double d = *reinterpret_cast<const double*>(&u); \
os << d; \
os.flags() & std::ios_base::showbase && os << " " << UNITS; \
return os; \
}
DEFINE_OUTPUT_METHOD(0, 1, 0, 0, 0, "m");
DEFINE_OUTPUT_METHOD(0, 0, 1, 0, 0, "s");
DEFINE_OUTPUT_METHOD(0, 1, -1, 0, 0, "m/s");
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
You may be looking for xalloc and iword (or if you want to make it more complicated pword).
Here's a way of handling display units with a standard length class.
--------8<--------
#include <iostream>
#include <iomanip>
#include <string>
// Globals for display units
namespace display {
// Allocate our global ios_base::iword index for display units
const int index = std::ios_base::xalloc();
// Metres/Yards
enum Units {Metres,Yards};
// Get the ostream's display units
template<typename C>
inline Units get_units(std::basic_ostre
{
return static_cast<Units>(os.iwor
}
// Set the ostream's display unitys
template<typename C>
inline void set_units(std::basic_ostre
{
os.iword(index) = value;
}
// A manipulator to set the verbosity level
class units {
const Units value;
template<typename C>
friend std::basic_ostream<C>& operator<<(std::basic_ostr
{
set_units(os,u.value);
return os;
}
public:
units(Units value) : value(value) {}
};
} // display namespace
// Class for storing length
class StandardLength {
double length; // Internally stored as metres
template<typename C>
friend std::basic_ostream<C>& operator<<(std::basic_ostr
public:
StandardLength() {}
StandardLength(double standard_length) : length(standard_length) {}
// Construct a StandardLength in yards
static StandardLength Yards(double yards_length)
{
return StandardLength(yards_lengt
}
// Construct a StandardLength in metres
static StandardLength Metres(double metres_length)
{
return StandardLength(metres_leng
}
};
// Display the StandardLength
template<typename C>
std::basic_ostream<C>& operator<<(std::basic_ostr
{
return os << (display::get_units(os) == display::Yards ? distance.length*0.9144 : distance.length);
}
int main()
{
StandardLength race_length = StandardLength::Metres(100
std::cout
<< "The race is "
<< display::units(display::Ya
<< race_length
<< " yards, which is "
<< display::units(display::Me
<< race_length
<< " metres\n";
}
--------8<--------
BTW... Don't trust my metres/yards conversion - this was a quick hack :-)
Thanks for the tips you guys...
STeH, this units class which I have needs to add zero overhead to storage and arithmetic operations, so I don't think that I can use a flag on top of the Units class, unless you had some clever way of doing it with static variables or something... But even then, I might want units being output in one stream, but not in another. For example, if I have a console window with some live results, showing units, but also afile with some tab-separated values. I would want both streams to keep their correct settings.
rstaveley, that stuff looks pretty good. I'm not familiar with xalloc and iword, I'll read up on those, check out your code, and get back to you.
Thanks again
JP
> // A manipulator to set the verbosity level
That stray comment, which shouldn't be there, was left over from the facility for which I last used xalloc/iword. I had a flag which I put into the output stream to specify the verbosity of my debug.
I dug this stuff out of Standard C++ IOStreams and Locales by Langer and Kreft, which is worth flipping through, if you've got access to a library.
Actuall, i don't know why you are using 'showbase' flag:
I compiled using
#define DEFINE_OUTPUT_METHOD(MM,LL
inline \
std::ostream& operator <<(std::ostream &os,const Units<MM,LL,TT,KK,II> &u){ \
double d = *reinterpret_cast<const double*>(&u); \
os << d; \
/*os.flags() & std::ios_base::showbase && */os << " " << UNITS; \
return os; \
}
DEFINE_OUTPUT_METHOD(0, 1, 0, 0, 0, "m");
DEFINE_OUTPUT_METHOD(0, 0, 1, 0, 0, "s");
DEFINE_OUTPUT_METHOD(0, 1, -1, 0, 0, "m/s");
Velocity v = 60. * kilometre / hour;
Length x = 250. * kilometre;
Time t = x / v;
Length z = metre + metre;
Units<0, 0, 0, 0, 0> unitless = 123.4;
z = unitless * z;
cerr << "The time taken to travel " << x << " at speed " << v << " is " << t << endl;
// cerr.flags(ios_base::showb
cerr << "The car's length is " << z << endl;
not using any flag, and the output was fine:
The time taken to travel 250000 m at speed 16.6667 m/s is 15000 s
The car's length is 2 m
Regards, Alex
The idea here is to be able to safely define a flag which can be used to turn on and off the display of units. I originally thought I would dodgily re-use the 'showbase' flag usually reserved (I think) for showing 0x (or whatever it is) at the start of binary values.
I think rstaveley's approach with 'iword' is going to be the right one.
JP
I also, though that below looks simpler and runs on my VC6 system:
enum { showunit = ios_base::showbase };
#define DEFINE_OUTPUT_METHOD(MM,LL
inline \
std::ostream& operator <<(std::ostream &os,const Units<MM,LL,TT,KK,II> &u){ \
double d = *reinterpret_cast<const double*>(&u); \
os << d; \
os.flags() & showunit && os << " " << UNITS; \
return os; \
}
DEFINE_OUTPUT_METHOD(0, 1, 0, 0, 0, "m");
DEFINE_OUTPUT_METHOD(0, 0, 1, 0, 0, "s");
DEFINE_OUTPUT_METHOD(0, 1, -1, 0, 0, "m/s");
int main(int argc, char *argv[]){
Velocity v = 60. * kilometre / hour;
Length x = 250. * kilometre;
Time t = x / v;
Length z = metre + metre;
Units<0, 0, 0, 0, 0> unitless = 123.4;
z = unitless * z;
cerr << "The time taken to travel " << x << " at speed " << v << " is " << t << endl;
cerr.flags(showunit);
cerr << "The car's length is " << z << endl;
return 0;
}
Regards, Alex
The reason why the above works is:
// extract from xiosbase header
enum _Fmtflags {skipws = 0x0001, unitbuf = 0x0002,
uppercase = 0x0004, showbase = 0x0008,
showpoint = 0x0010, showpos = 0x0020,
left = 0x0040, right = 0x0080, internal = 0x0100,
dec = 0x0200, oct = 0x0400, hex = 0x0800,
scientific = 0x1000, fixed = 0x2000, boolalpha = 0x4000,
adjustfield = 0x01c0, basefield = 0x0e00,
floatfield = 0x3000, _Fmtmask = 0x7fff, _Fmtzero = 0};
...
_BITMASK(_Fmtflags, fmtflags); // ==> typedef int fmtflags;
...
fmtflags flags(fmtflags _Nf)
{fmtflags _Of = _Fmtfl;
_Fmtfl = _Nf & _Fmtmask;
return (_Of); }
By switching on and off just before and after Units elements, you could avoid influences on other output elements:
cerr << "The time taken to travel "
<< setiosflags(showunit) << x << resetiosflags(showunit)
<< " at speed " << v << " is " << t << endl;
gives the following output:
The time taken to travel 250000 m at speed 16.6667 is 15000
Regards, Alex
I doubt that you want to derive a new stream class. Only the << operator needs to be overloaded in the tracking units class.
class track {
[snip]
bool bShowUnits; // this can be either static of normal member variable: a static would be good to switch unit output for all class objects.
// whereas a normal member allows to change output for each object indiviually.
public:
friend ostream& operator<< (ostream&, track& tr1);
}
ostream& operator << (ostream& os, track& tr1)
{
if (true == track::bShowUnits) // or (true == tr1.bShowUnits) for non static member var
os << tr1.value << " " << tr1.unit;
else
os << tr1.value;
return os;
}
If it was me implementing it, I would:
create a function:
void displayunits(void)
{
if(app_globals::disp_units
else app_globals::disp_units == true;
}
And another so that you can use it:
ostream& operator <<(ostream& out, void (*func)(void) )
{
func();
return out;
}
Then, create output operators for all the types that you want to assign units to:
ostream& operator<<(ostream& out, const myType&obj)
{
if(app_globals::disp_units
{
//display with units
out << obj.value << " " << obj.units;
}
else
{
//display without units
out << obj.value;
}
return out;
}
There are some assumptions; one being that you've created an output operator for your "units" type. This would be the easiest way, IMHO. You might create disp_units as a public static member of your units class.
Guitaristx
The units class I'm using here is one modified from http://www.embedded.com/sh
you can see the code in current form at
http://cvs.sourceforge.net
The aim is to have zero runtime overhead on the units class. It's purely template related stuff which creates the output operator. Therefore there is no 'obj.units'.
Also, I want the display of units to be individually switched per stream. So I can have one stream open with units being written out, and another with no units being written.
JP
Wow....
Okay, after looking at your code, I'm going to recommend my original suggestion - overload the ostream class. However, you may run into problems, since by overloading the class, you're making a subclass of ostream. This being said, most people don't use ostream, they use subclasses of it (ofstream, ostringstream, etc).
What I'm thinking is something like this (and, unfortunately, you'll have to make overloads for all of the ostream-derived classes that you want to use, unless you want to get into multiple-inheritance):
class myofstream : public ofstream
{
protected:
bool showunits;
public:
void setShowUnits(bool set);
}
Now, make sure that you have overloaded output operators for your derived stream class(es).
Now, check out this URL:
http://www.informit.com/ar
for instructions on how to implement a stream manipulator. Manipulators are functions that operate on streams using the stream insertion operator (<<). Now, you should be able to set this up so you can do this:
myofstream str("myfile.txt");
Units x = /*some value*/;
str << showunits(true) << x << endl;
str << showunits(false) << x << endl;
Is this the end result you're looking for?
Business Accounts
Answer for Membership
by: jdpipePosted on 2004-11-21 at 23:27:41ID: 12641963
To clarify, this is how I use the above:
ase);
Length L=5 * metre;
cerr.flags(ios_base::showb
cerr << "The car's length is " << L << endl;
This would output:
The car's length is 5 m