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