internals.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // -*- C++ -*-
  2. // Boost general library 'format' ---------------------------
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. // (C) Samuel Krempp 2001
  5. // krempp@crans.ens-cachan.fr
  6. // Permission to copy, use, modify, sell and
  7. // distribute this software is granted provided this copyright notice appears
  8. // in all copies. This software is provided "as is" without express or implied
  9. // warranty, and with no claim as to its suitability for any purpose.
  10. // ideas taken from Rüdiger Loos's format class
  11. // and Karl Nelson's ofstream
  12. // ----------------------------------------------------------------------------
  13. // internals.hpp : internal structs. included by format.hpp
  14. // stream_format_state, and format_item
  15. // ----------------------------------------------------------------------------
  16. #ifndef BOOST_FORMAT_INTERNALS_HPP
  17. #define BOOST_FORMAT_INTERNALS_HPP
  18. #include <string>
  19. #include <sstream>
  20. namespace boost {
  21. namespace io {
  22. namespace detail {
  23. // --------------
  24. // set of params that define the format state of a stream
  25. struct stream_format_state
  26. {
  27. typedef std::ios basic_ios;
  28. std::streamsize width_;
  29. std::streamsize precision_;
  30. char fill_;
  31. std::ios::fmtflags flags_;
  32. stream_format_state() : width_(-1), precision_(-1), fill_(0), flags_(std::ios::dec) {}
  33. stream_format_state(basic_ios& os) {set_by_stream(os); }
  34. void apply_on(basic_ios & os) const; //- applies format_state to the stream
  35. template<class T> void apply_manip(T manipulator) //- modifies state by applying manipulator.
  36. { apply_manip_body<T>( *this, manipulator) ; }
  37. void reset(); //- sets to default state.
  38. void set_by_stream(const basic_ios& os); //- sets to os's state.
  39. };
  40. // --------------
  41. // format_item : stores all parameters that can be defined by directives in the format-string
  42. struct format_item
  43. {
  44. enum pad_values { zeropad = 1, spacepad =2, centered=4, tabulation = 8 };
  45. enum arg_values { argN_no_posit = -1, // non-positional directive. argN will be set later.
  46. argN_tabulation = -2, // tabulation directive. (no argument read)
  47. argN_ignored = -3 // ignored directive. (no argument read)
  48. };
  49. typedef BOOST_IO_STD ios basic_ios;
  50. typedef detail::stream_format_state stream_format_state;
  51. typedef std::string string_t;
  52. typedef BOOST_IO_STD ostringstream internal_stream_t;
  53. int argN_; //- argument number (starts at 0, eg : %1 => argN=0)
  54. // negative values are used for items that don't process
  55. // an argument
  56. string_t res_; //- result of the formatting of this item
  57. string_t appendix_; //- piece of string between this item and the next
  58. stream_format_state ref_state_;// set by parsing the format_string, is only affected by modify_item
  59. stream_format_state state_; // always same as ref_state, _unless_ modified by manipulators 'group(..)'
  60. // non-stream format-state parameters
  61. signed int truncate_; //- is >=0 for directives like %.5s (take 5 chars from the string)
  62. unsigned int pad_scheme_; //- several possible padding schemes can mix. see pad_values
  63. format_item() : argN_(argN_no_posit), truncate_(-1), pad_scheme_(0) {}
  64. void compute_states(); // sets states according to truncate and pad_scheme.
  65. };
  66. // -----------------------------------------------------------
  67. // Definitions
  68. // -----------------------------------------------------------
  69. // --- stream_format_state:: -------------------------------------------
  70. inline
  71. void stream_format_state::apply_on(basic_ios & os) const
  72. // set the state of this stream according to our params
  73. {
  74. if(width_ != -1)
  75. os.width(width_);
  76. if(precision_ != -1)
  77. os.precision(precision_);
  78. if(fill_ != 0)
  79. os.fill(fill_);
  80. os.flags(flags_);
  81. }
  82. inline
  83. void stream_format_state::set_by_stream(const basic_ios& os)
  84. // set our params according to the state of this stream
  85. {
  86. flags_ = os.flags();
  87. width_ = os.width();
  88. precision_ = os.precision();
  89. fill_ = os.fill();
  90. }
  91. template<class T> inline
  92. void apply_manip_body( stream_format_state& self,
  93. T manipulator)
  94. // modify our params according to the manipulator
  95. {
  96. BOOST_IO_STD stringstream ss;
  97. self.apply_on( ss );
  98. ss << manipulator;
  99. self.set_by_stream( ss );
  100. }
  101. inline
  102. void stream_format_state::reset()
  103. // set our params to standard's default state
  104. {
  105. width_=-1; precision_=-1; fill_=0;
  106. flags_ = std::ios::dec;
  107. }
  108. // --- format_items:: -------------------------------------------
  109. inline
  110. void format_item::compute_states()
  111. // reflect pad_scheme_ on state_ and ref_state_
  112. // because some pad_schemes has complex consequences on several state params.
  113. {
  114. if(pad_scheme_ & zeropad)
  115. {
  116. if(ref_state_.flags_ & std::ios::left)
  117. {
  118. pad_scheme_ = pad_scheme_ & (~zeropad); // ignore zeropad in left alignment
  119. }
  120. else
  121. {
  122. ref_state_.fill_='0';
  123. ref_state_.flags_ |= std::ios::internal;
  124. }
  125. }
  126. state_ = ref_state_;
  127. }
  128. } } } // namespaces boost :: io :: detail
  129. #endif // BOOST_FORMAT_INTERNALS_HPP