I don't see any reason for them to be implementation dependent.
This is comething that I use, for the actual manipulator, create a function that returns an instance of the following helper. If you need to store the data, just store it inside the helper, some global variable, singleton, etc...
/// One argument manipulators helper
template < typename ParType >
class OneArgManip
{
ParType par;
std::ostream& (*impl)(std::ostream&, const ParType&);
public:
OneArgManip(std::ostream& (*code)(std::ostream&, const ParType&), ParType p)
: par(p), impl(code) {}
// calls the implementation
void operator()(std::ostream& stream) const
{ impl(stream,par); }
// a wrapper that allows us to use the manipulator directly
friend std::ostream& operator << (std::ostream& stream,
const OneArgManip<ParType>& manip)
{ manip(stream); return stream; }
};
Example of a manipulator based on this:
OneArgManip<unsigned> cursorMoveUp(unsigned c)
{ return OneArgManip<unsigned>(cursorMoveUpI,c); }
std::ostream& cursorMoveUpI(std::ostream& stream, const unsigned& c)
{ stream << "\033[" << c << "A"; return stream; }
For some explanation:
- u use the manipulator, that returns a new instance of the helper bound to an implementation of the helper
- stream tries to process the helper, that invokes the
<<
overload on the helper
- that invokes the
()
operator on the helper
- that invokes the real implementation of the helper with the parameter passed from the original manipulator call
If you want I can post 2 param and 3 param helpers as well. The principle is the same though.