#include <iostream>

// Copyright 2013, Dmitry Ledentsov
// Released under the MIT License: http://w...content-available-to-author-only...e.org/licenses/mit-license.php
// see https://g...content-available-to-author-only...b.com/d-led/fakeformat

template <typename format>
void tryout() {
  // try your formatting here
  std::cout<<format("with 3 zeroes: {1,num=fixed,precision=3}, without: {1}").with(1.0).now()<<std::endl;
  std::cout<<format("1:{1,width=10,fill=-}\n2:{2,width=10,fill=-}\n3:{3,width=10,fill=-}")
    .with(1)
    .also_with(10)
    .also_with(1000)
    .now()
  <<std::endl;
}

#include <string>
#include <sstream>
#include <vector>
#include <map>
#include <utility>
#include <iomanip>

namespace ff {

  template <typename TChar>
  struct config {
    static const TChar scope_begin='{';
    static const TChar scope_end='}';
    static const TChar separator=',';
    static const TChar equals='=';
    static const size_t index_begin=1;
    static bool string_to_key(std::string const& to_parse,int& res) {
      std::istringstream ss(to_parse);
      ss.imbue(std::locale::classic());
      ss >> res;
      if (!ss.fail() && ss.eof())
        return true;
      return false;
    }
  };

  typedef std::map<std::string,std::string> TKeyValueMap;

  namespace detail {

    template <
    typename TString=std::string,
    typename TStream=std::stringstream
    >
    class stream {

    public:
      stream ()
      {
        flags=impl.flags();
        impl.imbue(std::locale());
      }

      stream (const stream &)
      {
        flags=impl.flags();
        impl.imbue(std::locale());
      }

      stream & operator = (const stream &) {
        return *this;
      }

    public:
      template <typename T>
      stream const& put(T const& p) const {
        impl<<p;
        return *this;
      }

      template <typename TIter>
      stream const& put(TIter first,TIter last) const {
        for (TIter it=first; it!=last; ++it)
          impl.put(*it);
        return *this;
      }

      TString str() const {
        return impl.str();
      }

      void clear() const {
        impl.str("");
        impl.flags(flags);
      }

      void configure(TKeyValueMap const& config_map) {
        for (TKeyValueMap::const_iterator it=config_map.begin();
           it!=config_map.end();
           ++it) {
             if (it->first=="num"
               || it->first=="number") {
                 if (it->second=="hex") {
                   impl<<std::hex;
                 } else if (it->second=="oct") {
                   impl<<std::oct;
                 } else if (it->second=="sci"
                      || it->second=="scientific") {
                   impl<<std::scientific;
                 } else if (it->second=="fix"
                      || it->second=="fixed") {
                   impl<<std::fixed;
                 }
             } else if (it->first=="w"
                  || it->first=="width") {
                    int width=-1;
                    if (config<char>::string_to_key(it->second,width)
                      && width>0) {
                        impl.width(width);
                    }
             } else if (it->first=="left") {
               impl<<std::left;
             } else if (it->first=="right") {
               impl<<std::right;
             } else if (it->first=="precision") {
                    int precision=-1;
                    if (config<char>::string_to_key(it->second,precision)
                      && precision>0) {
                        impl.precision(precision);
                    }
             } else if (it->first=="fill") {
                    if (it->second.length()==1) {
                        impl.fill(it->second[0]);
                    }
             }
        }
      }

    private:
      mutable TStream impl;
      std::ios_base::fmtflags flags;
    };
  }

  //////////////////PARSER BEGIN////////////////////////

static const int START_POS=-1;

struct Placeholder {
  int id;
  int length;
  TKeyValueMap config;
  Placeholder():id(START_POS),length(START_POS){}
};

typedef std::vector< std::pair<int,Placeholder> > Placeholders;

class FormatContext
{
  struct ParserState {
    std::string format_string;
    int pos;
    int last_left_brace;
    int last_key_start;
    int last_value_start;
    std::string last_key;
    Placeholder current_placeholder;
    Placeholders placeholders;
  } state;

  int string_to_key(std::string const& to_parse) {
    int res=START_POS;
    std::istringstream ss(to_parse);
    ss.imbue(std::locale::classic());
    ss >> res;
    if (!ss.fail() && ss.eof())
      return res;
    return START_POS;
  }

public:

  bool IsAtEnd() const {
    bool res=state.pos >= (static_cast<int>(state.format_string.size())-1);
    return res;
  }

  char Step() {
    if (IsAtEnd())
      return '\0';

    state.pos++;
    return state.format_string[state.pos];
  }

  void ResetPlaceholderState() {
    state.last_value_start=state.last_key_start=state.last_left_brace=START_POS;
  }

  void SetString(std::string const& _) {
    state.format_string=_;
    state.pos=START_POS;
    ResetPlaceholderState();
  }

  void TryAddPlaceholder() {
    if (state.current_placeholder.id!=START_POS) {
      state.current_placeholder.length=state.pos-state.last_left_brace+1;
      state.placeholders.push_back(std::make_pair(state.last_left_brace,state.current_placeholder));
    }
  }

public:


  void StartCollectingPlaceholder() {
    state.current_placeholder=Placeholder();
    state.last_left_brace=state.pos;
    state.last_key_start=state.last_value_start=START_POS;
    state.last_key="";
  }

  void ParsePlaceholder() {
    int id=string_to_key(std::string(state.format_string.begin()+state.last_left_brace+1,state.format_string.begin()+state.pos));
    state.current_placeholder.id=id;
  }

  void AddValue() {
    state.current_placeholder.config[state.last_key]=
      std::string(state.format_string.begin()+state.last_value_start+1,state.format_string.begin()+state.pos);
    state.last_key_start=state.pos;
    state.last_value_start=START_POS;
  }

  void StartKey() {
    state.last_key_start=state.pos;
    state.last_value_start=START_POS;
    state.last_key="";
  }

  void AddKey() {
    if ( (state.pos-state.last_key_start) < 1 )
      return;
    state.last_key=std::string(state.format_string.begin()+state.last_key_start+1,state.format_string.begin()+state.pos);
    state.current_placeholder.config[state.last_key]="";
  }

  void ContinueCollectingKeys() {
    state.last_key_start=state.pos;
  }

  void StartAddingValue() {
    state.last_key_start=START_POS;
    state.last_value_start=state.pos;
  }

  void FinishCollectingPlaceholder() {
    if (state.last_key_start!=START_POS)
      AddKey();

    if (state.last_left_brace!=START_POS
      && (state.pos-state.last_left_brace) > 1) {
        TryAddPlaceholder();
    }

    ResetPlaceholderState();
  }

  void Continue() {
  }

  void FSMError(const char*, const char*) {
  }

  Placeholders Get() {
    return state.placeholders;
  }


};


// Forward Declarations

class FormatParser;

//----------------------------------------------
// FormatParserState: The base state class
//----------------------------------------------
class FormatParserState
{
  public:
    virtual const char* StateName() const = 0;
    virtual void ReadEqualsSign( FormatParser& );
    virtual void ReadRightBrace( FormatParser& );
    virtual void ReadLeftBrace( FormatParser& );
    virtual void ReadComma( FormatParser& );
};

//----------------------------------------------
// State: ReadingKey
//----------------------------------------------
class FormatParserReadingKeyState : public FormatParserState
{
  public:
    virtual const char* StateName() const
        { return "ReadingKey"; }
    virtual void ReadEqualsSign( FormatParser& );
    virtual void ReadComma( FormatParser& );
    virtual void ReadLeftBrace( FormatParser& );
    virtual void ReadRightBrace( FormatParser& );
};
//----------------------------------------------
// State: General
//----------------------------------------------
class FormatParserGeneralState : public FormatParserState
{
  public:
    virtual const char* StateName() const
        { return "General"; }
    virtual void ReadLeftBrace( FormatParser& );
};
//----------------------------------------------
// State: ReadingPlaceholder
//----------------------------------------------
class FormatParserReadingPlaceholderState : public FormatParserState
{
  public:
    virtual const char* StateName() const
        { return "ReadingPlaceholder"; }
    virtual void ReadLeftBrace( FormatParser& );
    virtual void ReadRightBrace( FormatParser& );
    virtual void ReadComma( FormatParser& );
};
//----------------------------------------------
// State: ReadingValue
//----------------------------------------------
class FormatParserReadingValueState : public FormatParserState
{
  public:
    virtual const char* StateName() const
        { return "ReadingValue"; }
    virtual void ReadRightBrace( FormatParser& );
    virtual void ReadLeftBrace( FormatParser& );
    virtual void ReadComma( FormatParser& );
};
//----------------------------------------------
// FormatParser: The Finite State Machine class
//----------------------------------------------
class FormatParser: public FormatContext
{
  public:
    // Static State variables
    static FormatParserReadingKeyState ReadingKey;
    static FormatParserGeneralState General;
    static FormatParserReadingPlaceholderState ReadingPlaceholder;
    static FormatParserReadingValueState ReadingValue;

    FormatParser(); // default Constructor

    // Event functions
    virtual void ReadEqualsSign() { itsState->ReadEqualsSign( *this ); }
    virtual void ReadRightBrace() { itsState->ReadRightBrace( *this ); }
    virtual void ReadLeftBrace() { itsState->ReadLeftBrace( *this ); }
    virtual void ReadComma() { itsState->ReadComma( *this ); }

    // State Accessor functions
    void SetState( FormatParserState& theState ) { itsState = &theState; }
    FormatParserState& GetState() const { return *itsState; }

    const char* GetCurrentStateName() const { return itsState->StateName(); }
    const char* GetVersion() const;

  private:
    FormatParserState* itsState;
};

  //////////////////PARSER END//////////////////////////


  typedef detail::stream<std::string,std::stringstream> TStream;
  typedef std::string TString;
  typedef size_t TPos;
  typedef std::string TParam;
  typedef std::map<TPos,TParam> TParameters;
  typedef config<char> TConfig;

  template <
  typename TConfig
  >
  class formatter {

  public:
    formatter(TString fmt):
    format_string(fmt),
    pos(TConfig::index_begin)
    {
      parse_format_string();
    }

  public:

    template <typename T>
    formatter& with(T const& param) {
      size_t count=placeholders.size();
      for (size_t it=0;
        it<count;
        it++) {
          stream.clear();
          if (placeholders[it].second.id==pos) {
            stream.configure(placeholders[it].second.config);
            stream.put(param);
            parameters[it]=stream.str();
          }
      }
      pos++;
      return *this;
    }

    template <typename T>
    formatter& also_with(T const& param) {
      return with(param);
    }

    TString now() const {
      size_t param_count=parameters.size();

      if (param_count==0) {
        return format_string;
      } else {
        return assemble_string();
      }
    }

    void clear_parameters() {
      parameters.clear();
      pos=TConfig::index_begin;
    }

   private:

    TString assemble_string() const {
      std::string res(format_string);

      for (TParameters::const_reverse_iterator it=parameters.rbegin();
         it!=parameters.rend();
         ++it) {
           std::pair<int,Placeholder> const& pl=placeholders[it->first];
           res.replace(pl.first,pl.second.length,it->second);
      }

      return res;
    }

  private:
    void parse_format_string() {
      FormatParser f;
      f.SetString(format_string);

      while (!f.IsAtEnd()) {
        char c=f.Step();
        switch (c) {
        case TConfig::scope_begin: f.ReadLeftBrace(); break;
        case TConfig::scope_end: f.ReadRightBrace(); break;
        case TConfig::separator: f.ReadComma(); break;
        case TConfig::equals: f.ReadEqualsSign(); break;
        default : f.Continue(); break;
        }
      }
      placeholders=f.Get();
    }

  private:
    TString format_string;
    Placeholders placeholders;
    TParameters parameters;
    TPos pos;

    TStream stream; // Caution: the stream is shared within the implementation!
  };

  typedef formatter< config<char> > format;

}

namespace ff {
//----------------------------------------------
// format.cpp
// FSM:       FormatParser
// Context:   FormatContext
// Version:
// Generated: Samstag 09/21/2013 at 16:23:34 MESZ
//


static char _versID[]  = "";



//----------------------------------------------
// Definitions of static state objects

//----------------------------------------------
FormatParserReadingKeyState FormatParser::ReadingKey;
FormatParserGeneralState FormatParser::General;
FormatParserReadingPlaceholderState FormatParser::ReadingPlaceholder;
FormatParserReadingValueState FormatParser::ReadingValue;

//----------------------------------------------
// Default Event Functions

//----------------------------------------------

void FormatParserState::ReadEqualsSign(FormatParser& s)
  { s.FSMError("ReadEqualsSign", s.GetState().StateName()); }

void FormatParserState::ReadRightBrace(FormatParser& s)
  { s.FSMError("ReadRightBrace", s.GetState().StateName()); }

void FormatParserState::ReadLeftBrace(FormatParser& s)
  { s.FSMError("ReadLeftBrace", s.GetState().StateName()); }

void FormatParserState::ReadComma(FormatParser& s)
  { s.FSMError("ReadComma", s.GetState().StateName()); }

//----------------------------------------------
// The States and their Transitions
//----------------------------------------------

//----------------------------------------------
// ReadingKey Actions and Transitions
//----------------------------------------------

// Starting State: ReadingKey
// Event:          ReadEqualsSign
//
void FormatParserReadingKeyState::ReadEqualsSign( FormatParser& s )
{

    s.AddKey();
    s.StartAddingValue();

    // Change the state
    s.SetState(FormatParser::ReadingValue);
}

// Starting State: ReadingKey
// Event:          ReadComma
//
void FormatParserReadingKeyState::ReadComma( FormatParser& s )
{

    s.AddKey();
    s.ContinueCollectingKeys();

    // Change the state
    s.SetState(FormatParser::ReadingKey);
}

// Starting State: ReadingKey
// Event:          ReadLeftBrace
//
void FormatParserReadingKeyState::ReadLeftBrace( FormatParser& s )
{

    s.StartCollectingPlaceholder();

    // Change the state
    s.SetState(FormatParser::ReadingPlaceholder);
}

// Starting State: ReadingKey
// Event:          ReadRightBrace
//
void FormatParserReadingKeyState::ReadRightBrace( FormatParser& s )
{

    s.FinishCollectingPlaceholder();

    // Change the state
    s.SetState(FormatParser::General);
}

//----------------------------------------------
// General Actions and Transitions
//----------------------------------------------

// Starting State: General
// Event:          ReadLeftBrace
//
void FormatParserGeneralState::ReadLeftBrace( FormatParser& s )
{

    s.StartCollectingPlaceholder();

    // Change the state
    s.SetState(FormatParser::ReadingPlaceholder);
}

//----------------------------------------------
// ReadingPlaceholder Actions and Transitions
//----------------------------------------------

// Starting State: ReadingPlaceholder
// Event:          ReadLeftBrace
//
void FormatParserReadingPlaceholderState::ReadLeftBrace( FormatParser& s )
{

    s.StartCollectingPlaceholder();

    // Change the state
    s.SetState(FormatParser::ReadingPlaceholder);
}

// Starting State: ReadingPlaceholder
// Event:          ReadRightBrace
//
void FormatParserReadingPlaceholderState::ReadRightBrace( FormatParser& s )
{

    s.ParsePlaceholder();
    s.FinishCollectingPlaceholder();

    // Change the state
    s.SetState(FormatParser::General);
}

// Starting State: ReadingPlaceholder
// Event:          ReadComma
//
void FormatParserReadingPlaceholderState::ReadComma( FormatParser& s )
{

    s.ParsePlaceholder();
    s.StartKey();

    // Change the state
    s.SetState(FormatParser::ReadingKey);
}

//----------------------------------------------
// ReadingValue Actions and Transitions
//----------------------------------------------

// Starting State: ReadingValue
// Event:          ReadRightBrace
//
void FormatParserReadingValueState::ReadRightBrace( FormatParser& s )
{

    s.AddValue();
    s.FinishCollectingPlaceholder();

    // Change the state
    s.SetState(FormatParser::General);
}

// Starting State: ReadingValue
// Event:          ReadLeftBrace
//
void FormatParserReadingValueState::ReadLeftBrace( FormatParser& s )
{

    s.StartCollectingPlaceholder();

    // Change the state
    s.SetState(FormatParser::ReadingPlaceholder);
}

// Starting State: ReadingValue
// Event:          ReadComma
//
void FormatParserReadingValueState::ReadComma( FormatParser& s )
{

    s.AddValue();

    // Change the state
    s.SetState(FormatParser::ReadingKey);
}

//----------------------------------------------
// State Machine Constructor: FormatParser
//  set Initial State to: General
//
//----------------------------------------------
FormatParser::FormatParser() : itsState(&General)
{
    // Entry functions for: General
}

//  Get version information
//
const char* FormatParser::GetVersion() const
{ return _versID; }

}

template <typename T1>
std::string Format (std::string const& format_string,T1 p1) {
 return ff::format(format_string).with(p1).now();
}

int main() {
  tryout<ff::format>();
  std::cout<<Format("test={1}",42)<<std::endl;
  return 0;
}
