Program Listing for File strings.hpp
↰ Return to documentation for file (include/ecl/formatters/strings.hpp
)
/*****************************************************************************
** Ifdefs
*****************************************************************************/
#ifndef ECL_FORMATTERS_STRINGS_HPP_
#define ECL_FORMATTERS_STRINGS_HPP_
/*****************************************************************************
** Includes
*****************************************************************************/
#include <string>
#include <ecl/exceptions/standard_exception.hpp>
#include "common.hpp"
#include "macros.hpp"
/*****************************************************************************
** Namespaces
*****************************************************************************/
namespace ecl {
/*****************************************************************************
** Format Interface [String types]
*****************************************************************************/
template <>
class ecl_formatters_PUBLIC Format<std::string> {
public:
/******************************************
** C&D's
*******************************************/
Format(int w = -1, Alignment a = NoAlign) : width_(w),alignment_(a) {}
virtual ~Format() {}
/******************************************
** Set
*******************************************/
Format<std::string>& width(int w) { width_ = w; return *this; }
Format<std::string>& align(Alignment a) { alignment_ = a; return *this; }
/******************************************
* Set Format Combinations
******************************************/
Format<std::string>& operator ()(int w, Alignment a);
/******************************************
** Format a value
*******************************************/
Format<std::string>& operator() (const std::string &input_string);
/******************************************
** Common format usages
*******************************************/
Format<std::string>& operator() (const std::string &input_string, int w);
Format<std::string>& operator() (const std::string &input_string, int w, Alignment a);
/******************************************
** Insert the formatter into a stream
*******************************************/
template <typename OutputStream> friend OutputStream& operator << (OutputStream& ostream, Format<std::string>& formatter);
private:
/******************************************
** Parameters
*******************************************/
int width_;
Alignment alignment_;
bool ready_to_format;
std::string s;
/******************************************
** Padding
*******************************************/
template <typename OutputStream> void pad(int n, OutputStream &ostream) const;
template <typename OutputStream> void prePad(int n, OutputStream &ostream) const;
template <typename OutputStream> void postPad(int n, OutputStream &ostream) const;
/******************************************
** Formatter Functions
*******************************************/
template <typename OutputStream> void format(OutputStream &ostream) const;
};
/*****************************************************************************
** Implementation [Format<string>][Templates]
*****************************************************************************/
template <typename OutputStream>
void Format<std::string>::format(OutputStream &ostream) const
{
int size = s.size();
prePad(width_ - (size),ostream); // previously had (size+2) here...why?
ostream << s;
postPad(width_ - (size),ostream);
}
template <typename OutputStream>
void Format<std::string>::prePad(int n, OutputStream &ostream) const
{
if ( n <= 0 ) { return; }
switch ( alignment_ )
{
case ( NoAlign ) : { break; }
case ( LeftAlign ) : { break; }
case ( RightAlign ) : { pad(n,ostream); break; }
case ( CentreAlign ) : { pad(n/2+ n%2,ostream); break; } // Add the remainder
default : break;
}
}
template <typename OutputStream>
void Format<std::string>::postPad(int n, OutputStream &ostream) const
{
if ( n <= 0 ) { return; }
switch ( alignment_ )
{
case ( NoAlign ) : { break; }
case ( LeftAlign ) : { pad(n,ostream); break; }
case ( RightAlign ) : { break; }
case ( CentreAlign ) : { pad(n/2,ostream); break; } // Do not add the remainder
default : break;
}
}
template <typename OutputStream>
void Format<std::string>::pad(int n, OutputStream &ostream) const
{
for (int i = n; i > 0; --i )
{
ostream << ' ';
}
}
/*****************************************************************************
* Implementation [streaming]
*****************************************************************************/
template <typename OutputStream>
OutputStream& operator << (OutputStream &ostream, Format<std::string>& formatter )
{
bool ready = formatter.ready_to_format;
ecl_assert_throw(ready, StandardException(LOC,UsageError,"The formatter cannot print any data - "
"either there is no data available, or you have tried to use the "
"formatter more than once in a single streaming operation. "
"C++ produces unspecified results when functors are used multiply "
"in the same stream sequence, so this is not permitted here.") );
if ( ready ) {
formatter.format(ostream);
formatter.ready_to_format = false;
}
return ostream;
}
} // namespace ecl
#endif /*ECL_FORMATTERS_STRINGS_HPP_*/