// -*- C++ -*-
//  Boost general library 'format'  ---------------------------
//  See http://www.boost.org for updates, documentation, and revision history.

//  (C) Samuel Krempp 2001
//                  krempp@crans.ens-cachan.fr
//  Permission to copy, use, modify, sell and
//  distribute this software is granted provided this copyright notice appears
//  in all copies. This software is provided "as is" without express or implied
//  warranty, and with no claim as to its suitability for any purpose.

// ------------------------------------------------------------------------------
// sample_formats.cc :  format の基本的な使い方の例
// ------------------------------------------------------------------------------

#include <iostream>
#include <iomanip>

#include "boost/format.hpp"

int main(){
    using namespace std;
    using boost::format;
    using boost::io::group;
    using boost::io::str;
    stringstream oss;

    
    // 並べ替え :
    cout << format("%1% %2% %3% %2% %1% \n") % "o" % "oo" % "O"; // 'シンプル'なスタイル
    //          prints  "o oo O oo o \n"
    cout << format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35;     // POSIX 版 printf のスタイル


    // No reordering :
    cout << format("writing %s,  x=%s : %d-th step \n") % "toto" % 40.23 % 50; 
    //          "writing toto,  x=40.23 : 50-th step \n" と表示する

    cout << format("(x,y) = (%+5d,%+5d) \n") % -23 % 35;
    cout << format("(x,y) = (%|+5|,%|+5|) \n") % -23 % 35;
    cout << format("(x,y) = (%|1$+5|,%|2$+5|) \n") % -23 % 35;
    //   all those are the same,  it prints  "(x,y) = (  -23,  +35) \n"
    //   すべて同じ。 "(x,y) = (  -23,  +35) \n" と表示する



    // 'group' を用いてマニピュレータを使う :
    cout << format("%2% %1% %2%\n")  % 1   % group(setfill('X'), hex, setw(4), 16+3) ;
    // "XX13 1 XX13\n" と表示


    // printf 命令の型フラグは書式化オプションを渡すのに使われることができる :
    cout <<  format("_%1$4d_ is : _%1$#4x_, _%1$#4o_, and _%1$s_ by default\n")  % 18;
    //          "_  18_ is : _0x12_, _ 022_, and _18_ by default\n" と表示する

    // 値の文字列を取り出す :
    std::string s;
    s= str( format(" %d %d ") % 11 % 22 );
    assert( s == " 11 22 ");


    // -----------------------------------------------
    //  %% は '%' と表示される

    cout << format("%%##%#x ") % 20 << endl;
    //          "%##0x14 " と表示する
 

    // -----------------------------------------------
    //    引数の正しい数を強制する

    // 多すぎる引数は、不要な引数を与えた時点で例外を送出する :
    try {
      format(" %1% %1% ") % 101 % 102;
      // 書式文字列は<b>一つの</b>引数を二回参照する。引数は二つではない。
      // したがって、二つの引数を与えることはエラーである
    }
    catch (boost::io::too_many_args& exc) { 
      cerr <<  exc.what() << "\n\t\t***Dont worry, that was planned\n";
    }

    
    // Too few arguments when requesting the result will also throw an exception :
    // 少なすぎる引数もまた、結果を要求した時点で例外を送出する :
    try {
      cerr << format(" %|3$| ") % 101; 
      // %1$ と %2$ が使われていなかったとしても、三つの引数を与えるべきである
    }
    catch (boost::io::too_few_args& exc) { 
      cerr <<  exc.what() << "\n\t\t***Dont worry, that was planned\n";
    }

    
    cerr << "\n\nEverything went OK, exiting. \n";
    return 0;
}
