1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2005, 2009 StatPro Italia srl
5 
6  This file is part of QuantLib, a free-software/open-source library
7  for financial quantitative analysts and developers - http://quantlib.org/
8 
9  QuantLib is free software: you can redistribute it and/or modify it
10  under the terms of the QuantLib license.  You should have received a
11  copy of the license along with this program; if not, please email
12  <quantlib-dev@lists.sf.net>. The license is also available online at
13  <http://quantlib.org/license.shtml>.
14 
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE.  See the license for more details.
18 */
19 
20 /*! \file dataformatters.hpp
21     \brief output manipulators
22 */
23 
24 #ifndef quantlib_data_formatters_hpp
25 #define quantlib_data_formatters_hpp
26 
27 #include <ql/utilities/null.hpp>
28 #include <iosfwd>
29 
30 namespace QuantLib {
31 
32     namespace detail {
33 
34         template <typename T> struct null_checker {
null_checkerQuantLib::detail::null_checker35             explicit null_checker(T value) : value(value) {}
36             T value;
37         };
38         template <typename T>
39         std::ostream& operator<<(std::ostream&, const null_checker<T>&);
40 
41         struct ordinal_holder {
ordinal_holderQuantLib::detail::ordinal_holder42             explicit ordinal_holder(Size n) : n(n) {}
43             Size n;
44         };
45         std::ostream& operator<<(std::ostream&, const ordinal_holder&);
46 
47         template <typename T> struct power_of_two_holder {
power_of_two_holderQuantLib::detail::power_of_two_holder48             explicit power_of_two_holder(T n) : n(n) {}
49             T n;
50         };
51         template <typename T>
52         std::ostream& operator<<(std::ostream&,
53                                  const power_of_two_holder<T>&);
54 
55         struct percent_holder {
percent_holderQuantLib::detail::percent_holder56             explicit percent_holder(Real value) : value(value) {}
57             Real value;
58         };
59         std::ostream& operator<<(std::ostream&, const percent_holder&);
60 
61         template <typename InputIterator> struct sequence_holder {
sequence_holderQuantLib::detail::sequence_holder62             sequence_holder(InputIterator begin, InputIterator end)
63             : begin(begin), end(end) {}
64             InputIterator begin, end;
65         };
66         template <typename I>
67         std::ostream& operator<<(std::ostream&, const sequence_holder<I>&);
68 
69     }
70 
71 
72     namespace io {
73 
74         /*! \defgroup manips Output manipulators
75 
76             Helper functions for creating formatted output.
77 
78             @{
79         */
80 
81         //! check for nulls before output
82         template <typename T>
83         detail::null_checker<T> checknull(T);
84 
85         //! outputs naturals as 1st, 2nd, 3rd...
86         detail::ordinal_holder ordinal(Size);
87 
88         //! output integers as powers of two
89         template <typename T>
90         detail::power_of_two_holder<T> power_of_two(T);
91 
92         //! output reals as percentages
93         detail::percent_holder percent(Real);
94 
95         //! output rates and spreads as percentages
96         detail::percent_holder rate(Rate);
97 
98         //! output volatilities as percentages
99         detail::percent_holder volatility(Volatility);
100 
101         //! output STL-compliant containers as space-separated sequences
102         template <class Container>
103         detail::sequence_holder<typename Container::const_iterator>
104         sequence(const Container& c);
105 
106         /*! @}  */
107 
108 
109         // inline definitions
110 
111         template <typename T>
checknull(T x)112         inline detail::null_checker<T> checknull(T x) {
113             return detail::null_checker<T>(x);
114         }
115 
ordinal(Size n)116         inline detail::ordinal_holder ordinal(Size n) {
117             return detail::ordinal_holder(n);
118         }
119 
120         template <typename T>
power_of_two(T n)121         inline detail::power_of_two_holder<T> power_of_two(T n) {
122             return detail::power_of_two_holder<T>(n);
123         }
124 
percent(Real x)125         inline detail::percent_holder percent(Real x) {
126             return detail::percent_holder(x);
127         }
128 
rate(Rate r)129         inline detail::percent_holder rate(Rate r) {
130             return detail::percent_holder(r);
131         }
132 
volatility(Volatility v)133         inline detail::percent_holder volatility(Volatility v) {
134             return detail::percent_holder(v);
135         }
136 
137         template <class Container>
138         inline detail::sequence_holder<typename Container::const_iterator>
sequence(const Container & c)139         sequence(const Container& c) {
140             return detail::sequence_holder<typename Container::const_iterator>(
141                                                            c.begin(), c.end());
142         }
143 
144     }
145 
146     namespace detail {
147 
148         template <typename T>
operator <<(std::ostream & out,const null_checker<T> & checker)149         inline std::ostream& operator<<(std::ostream& out,
150                                         const null_checker<T>& checker) {
151             if (checker.value == Null<T>())
152                 return out << "null";
153             else
154                 return out << checker.value;
155         }
156 
157         template <typename T>
operator <<(std::ostream & out,const power_of_two_holder<T> & holder)158         inline std::ostream& operator<<(std::ostream& out,
159                                         const power_of_two_holder<T>& holder) {
160             if (holder.n == Null<T>())
161                 return out << "null";
162 
163             T n = holder.n;
164             Integer power = 0;
165             if (n != 0) {
166                 while (!(n & 1UL)) {
167                     power++;
168                     n >>= 1;
169                 }
170             }
171             return out << n << "*2^" << power;
172         }
173 
174         template <typename I>
operator <<(std::ostream & out,const sequence_holder<I> & holder)175         inline std::ostream& operator<<(std::ostream& out,
176                                         const sequence_holder<I>& holder) {
177             out << "( ";
178             for (I i = holder.begin; i != holder.end; ++i)
179                 out << *i << " ";
180             out << ")";
181             return out;
182         }
183 
184     }
185 
186 }
187 
188 
189 #endif
190