Boost logo

Boost :

From: James S. Adelman (j.adelman_at_[hidden])
Date: 2002-02-09 18:11:59

It's manipulator-like; it can work for user-defined types. Currently,
though, it is expensive. It needs a seperator between units, because in
general there is no way to know what is and is not a manipulator. Pretty
much safe. It's only meant to be a proof of concept at present. Any

// -- test.cpp --

#include "format.hpp"

#include <iostream>
#include <string>
#include <complex>

int main()
  int x=6;
  double y=5;
  std::complex<double> y2(5,0.5);
  std::string s="foo";
  std::cout<<format<char>("%1 %0 ")<<y2<<endi<<y<<endi<<x<<endf<<"\n";
  std::cout<<"back to normal"<<std::endl;
  std::cout<<format<char>("%1 %2 %0")<<y2<<endi<<y<<endf<<std::endl;

// -- end
// -- format.hpp --

#ifndef JSA_FORMAT_H
#define JSA_FORMAT_H

#include <streambuf>
#include <string>
#include <ostream>
#include <vector>
#include <cctype>
#include <iostream>
#include <cstddef>

template <typename Ch,typename Tr=std::char_traits<Ch> >
struct format
  format(const std::basic_string<Ch,Tr>&s):

  std::basic_string<Ch,Tr> s_;

template <typename Ch, typename Tr=std::char_traits<Ch> >
struct formatbuf: std::basic_streambuf<Ch,Tr>

  formatbuf(std::basic_ostream<Ch,Tr>* os,
            std::basic_streambuf<Ch,Tr>* old,
            const format<Ch,Tr>& s):
    std::basic_string<Ch,Tr>::const_iterator p=s.s_.begin(),q=s.s_.end(),r=p;
      if(*p!='%') continue;
      std::size_t j=0;
      while((p!=q)&&std::isdigit(*p)) j=j*10+*p++-'0';
      if(j>=order_.size()) order_.resize(j+1);
      if(*p=='$') ++p;
      if(*p!='%') order_[j]=howm_++;
      if(p==q) break;

  formatbuf* shutdown()
    for(std::vector<std::basic_string<Ch,Tr> >::iterator
        p!=q; ++p)
    return this;

  void next()
    if(which_==howm_) {std::cerr<<"^y^";shutdown();}


  std::streamsize xsputn(const Ch* p, std::streamsize n)
    return n;

  typename Tr::int_type overflow(typename Tr::int_type c=Tr::eof())
      return c;
    return Tr::not_eof(c);


  std::basic_ostream<Ch,Tr> *os_;
  std::basic_streambuf<Ch,Tr> *osb_;
  std::vector<std::basic_string<Ch,Tr> > out_;
  std::vector<int> order_;
  bool shutdown_;
  int which_,howm_;

template <typename Ch,typename Tr>
std::basic_ostream<Ch,Tr>& operator<<(std::basic_ostream<Ch,Tr>&os,
  const format<Ch,Tr>& ft)
  os.rdbuf(new formatbuf<Ch,Tr>(&os,os.rdbuf(),ft));
  return os;

template <typename Ch,typename Tr>
std::basic_ostream<Ch,Tr>& endi(std::basic_ostream<Ch,Tr>& os)
  if(formatbuf<Ch,Tr>* p=dynamic_cast<formatbuf<Ch,Tr>*>(os.rdbuf()))
  return os;

template <typename Ch,typename Tr>
std::basic_ostream<Ch,Tr>& endf(std::basic_ostream<Ch,Tr>& os)
  if(formatbuf<Ch,Tr>* p=dynamic_cast<formatbuf<Ch,Tr>*>(os.rdbuf())) delete
  return os;


// -- end

James S. Adelman

Boost list run by bdawes at, gregod at, cpdaniel at, john at