You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

312 lines
10 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: pantheios/inserters/real.hpp
  3. *
  4. * Purpose: String inserters for fundamental types
  5. *
  6. * Created: 21st June 2005
  7. * Updated: 14th February 2010
  8. *
  9. * Home: http://www.pantheios.org/
  10. *
  11. * Copyright (c) 2005-2010, Matthew Wilson and Synesis Software
  12. * Copyright (c) 1999-2005, Synesis Software and Matthew Wilson
  13. * All rights reserved.
  14. *
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions are
  17. * met:
  18. *
  19. * - Redistributions of source code must retain the above copyright notice,
  20. * this list of conditions and the following disclaimer.
  21. * - Redistributions in binary form must reproduce the above copyright
  22. * notice, this list of conditions and the following disclaimer in the
  23. * documentation and/or other materials provided with the distribution.
  24. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the
  25. * names of any contributors may be used to endorse or promote products
  26. * derived from this software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  29. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  30. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  31. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  32. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  33. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  34. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  35. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  36. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  37. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * ////////////////////////////////////////////////////////////////////// */
  41. /** \file pantheios/inserters/real.hpp
  42. *
  43. * [C++ only] Definition of the pantheios::real string inserter for
  44. * for floating-point built-in types.
  45. */
  46. #ifndef PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_REAL
  47. #define PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_REAL
  48. /* /////////////////////////////////////////////////////////////////////////
  49. * Version information
  50. */
  51. #ifndef PANTHEIOS_DOCUMENTATION_SKIP_SECTION
  52. # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_REAL_MAJOR 2
  53. # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_REAL_MINOR 3
  54. # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_REAL_REVISION 4
  55. # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_REAL_EDIT 26
  56. #endif /* !PANTHEIOS_DOCUMENTATION_SKIP_SECTION */
  57. /* /////////////////////////////////////////////////////////////////////////
  58. * Includes
  59. */
  60. #ifndef PANTHEIOS_INCL_PANTHEIOS_H_PANTHEIOS
  61. # include <pantheios/pantheios.h>
  62. #endif /* !PANTHEIOS_INCL_PANTHEIOS_H_PANTHEIOS */
  63. #ifndef PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_FMT
  64. # include <pantheios/inserters/fmt.hpp>
  65. #endif /* !PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_FMT */
  66. #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_STRING_H_FWD
  67. # include <stlsoft/shims/access/string/fwd.h>
  68. #endif /* !STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_STRING_H_FWD */
  69. /* /////////////////////////////////////////////////////////////////////////
  70. * Namespace
  71. */
  72. #if !defined(PANTHEIOS_NO_NAMESPACE)
  73. namespace pantheios
  74. {
  75. #endif /* !PANTHEIOS_NO_NAMESPACE */
  76. /* /////////////////////////////////////////////////////////////////////////
  77. * Inserter classes
  78. */
  79. /** Class for inserting floating-point types into Pantheios diagnostic
  80. * logging statements.
  81. *
  82. * \ingroup group__application_layer_interface__inserters
  83. *
  84. * This class converts a floating-point variable into a string, thereby enabling it to be
  85. * inserted into a logging statement. Consider the following statement
  86. *
  87. * \code
  88. double d = 123.456;
  89. char s[] = "abc";
  90. std::string str("def");
  91. pantheios::log(pantheios::notice, "s=", s, ", d=", pantheios::real(d), ", str=", str);
  92. * \endcode
  93. *
  94. * This will produce the output:
  95. *
  96. * &nbsp;&nbsp;&nbsp;&nbsp;<b>s=abc, d=123.456, str=def</b>
  97. *
  98. * \note Currently, Pantheios does not support the implicit insertion of
  99. * floating-point types in diagnostic logging statements, due to the various
  100. * ambiguities inherent in the C++ language. (See chapters 14, 15, 19, 24 of
  101. * <a href = "http://imperfectcplusplus.com" target="_blank">Imperfect C++</a>
  102. * for discussions of these issues.) It is possible that a future version of
  103. * the library will be able to incorporate them directly, so long as that does
  104. * not sacrifice Pantheios's central claim of not paying for what you don't use.
  105. */
  106. class real
  107. {
  108. public:
  109. /// This type
  110. typedef real class_type;
  111. public:
  112. /// Construct from a float value
  113. ///
  114. /// \param value The value to be inserted
  115. /// \param widthAndFormat Not currently used
  116. explicit real(float value, int widthAndFormat = 0);
  117. /// Construct from a double value
  118. ///
  119. /// \param value The value to be inserted
  120. /// \param widthAndFormat Not currently used
  121. explicit real(double value, int widthAndFormat = 0);
  122. /// Construct from a long double value
  123. ///
  124. /// \param value The value to be inserted
  125. /// \param widthAndFormat Not currently used
  126. explicit real(long double value, int widthAndFormat = 0);
  127. private:
  128. explicit real(int); // Prevents implicit conversion from an integer
  129. public:
  130. /// A possibly non-nul-terminated non-null pointer to the c-style string representation of the floating-point number
  131. pan_char_t const* data() const;
  132. /// A nul-terminated non-null pointer to the c-style string representation of the floating-point number
  133. pan_char_t const* c_str() const;
  134. /// The length of the c-style string representation of the floating-point number
  135. size_t length() const;
  136. private:
  137. void construct_() const;
  138. void construct_();
  139. private:
  140. enum RealSize
  141. {
  142. typeIsFloat = -1
  143. , typeIsDouble = -2
  144. , typeIsLongDouble = -3
  145. };
  146. union u
  147. {
  148. float fValue;
  149. double dValue;
  150. long double ldValue;
  151. };
  152. u m_value; // The value, copied for lazy conversion
  153. size_t m_len; // Length, and marker for type: 1 == float; 2 == double; 3 == long double
  154. pan_char_t m_sz[256]; // Marker for converted, if m_sz[0] == '\0'
  155. const int m_widthAndFormat;
  156. private:
  157. #if !defined(STLSOFT_COMPILER_IS_GCC)
  158. real(class_type const&);
  159. #endif /* compiler */
  160. class_type& operator =(class_type const&);
  161. };
  162. /* /////////////////////////////////////////////////////////////////////////
  163. * String Access Shims
  164. */
  165. #ifndef PANTHEIOS_DOCUMENTATION_SKIP_SECTION
  166. # if !defined(PANTHEIOS_NO_NAMESPACE)
  167. namespace shims
  168. {
  169. # endif /* !PANTHEIOS_NO_NAMESPACE */
  170. /** \overload c_str_data_a(real const&) */
  171. # ifdef PANTHEIOS_USE_WIDE_STRINGS
  172. inline wchar_t const* c_str_data_w(real const& r)
  173. # else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  174. inline char const* c_str_data_a(real const& r)
  175. # endif /* PANTHEIOS_USE_WIDE_STRINGS */
  176. {
  177. return r.data();
  178. }
  179. /** \overload c_str_data(real const&) */
  180. inline pan_char_t const* c_str_data(real const& r)
  181. {
  182. return r.data();
  183. }
  184. /** \overload c_str_len_a(real const&) */
  185. # ifdef PANTHEIOS_USE_WIDE_STRINGS
  186. inline size_t c_str_len_w(real const& r)
  187. # else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  188. inline size_t c_str_len_a(real const& r)
  189. # endif /* PANTHEIOS_USE_WIDE_STRINGS */
  190. {
  191. return r.length();
  192. }
  193. /** \overload c_str_len(real const&) */
  194. inline size_t c_str_len(real const& r)
  195. {
  196. return r.length();
  197. }
  198. /** \overload c_str_ptr_a(real const&) */
  199. # ifdef PANTHEIOS_USE_WIDE_STRINGS
  200. inline wchar_t const* c_str_ptr_w(real const& r)
  201. # else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  202. inline char const* c_str_ptr_a(real const& r)
  203. # endif /* PANTHEIOS_USE_WIDE_STRINGS */
  204. {
  205. return r.c_str();
  206. }
  207. /** \overload c_str_ptr(real const&) */
  208. inline pan_char_t const* c_str_ptr(real const& r)
  209. {
  210. return r.c_str();
  211. }
  212. # if !defined(PANTHEIOS_NO_NAMESPACE)
  213. } /* namespace shims */
  214. # if defined(STLSOFT_COMPILER_IS_GCC)
  215. /* GCC does not seem to correctly handle the phases of
  216. * processing of C++ templates, so we need to 'use' the
  217. * shims into the same namespace as the inserter class
  218. * in order that ADL can suffice instead.
  219. */
  220. # ifdef PANTHEIOS_USE_WIDE_STRINGS
  221. using ::pantheios::shims::c_str_data_w;
  222. using ::pantheios::shims::c_str_len_w;
  223. using ::pantheios::shims::c_str_ptr_w;
  224. # else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  225. using ::pantheios::shims::c_str_data_a;
  226. using ::pantheios::shims::c_str_len_a;
  227. using ::pantheios::shims::c_str_ptr_a;
  228. # endif /* PANTHEIOS_USE_WIDE_STRINGS */
  229. using ::pantheios::shims::c_str_data;
  230. using ::pantheios::shims::c_str_len;
  231. using ::pantheios::shims::c_str_ptr;
  232. # endif /* compiler */
  233. # endif /* !PANTHEIOS_NO_NAMESPACE */
  234. #endif /* !PANTHEIOS_DOCUMENTATION_SKIP_SECTION */
  235. /* /////////////////////////////////////////////////////////////////////////
  236. * Namespace
  237. */
  238. #if !defined(PANTHEIOS_NO_NAMESPACE)
  239. } /* namespace pantheios */
  240. namespace stlsoft
  241. {
  242. // 'Export' the string access shims into the STLSoft namespace
  243. //
  244. // c_str_ptr(_a) is not necessary for version 1.0 of Pantheios, but it's
  245. // defined and exported in order to allow for the case where someone
  246. // may find a legitimate use for the conversion classes additional to
  247. // the type-tunneling of the Pantheios API.
  248. # ifdef PANTHEIOS_USE_WIDE_STRINGS
  249. using ::pantheios::shims::c_str_data_w;
  250. using ::pantheios::shims::c_str_len_w;
  251. using ::pantheios::shims::c_str_ptr_w;
  252. # else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  253. using ::pantheios::shims::c_str_data_a;
  254. using ::pantheios::shims::c_str_len_a;
  255. using ::pantheios::shims::c_str_ptr_a;
  256. # endif /* PANTHEIOS_USE_WIDE_STRINGS */
  257. using ::pantheios::shims::c_str_data;
  258. using ::pantheios::shims::c_str_len;
  259. using ::pantheios::shims::c_str_ptr;
  260. }
  261. #endif /* !PANTHEIOS_NO_NAMESPACE */
  262. /* /////////////////////////////////////////////////////////////////////////
  263. * Inclusion
  264. */
  265. #ifdef STLSOFT_PPF_pragma_once_SUPPORT
  266. # pragma once
  267. #endif /* STLSOFT_PPF_pragma_once_SUPPORT */
  268. /* ////////////////////////////////////////////////////////////////////// */
  269. #endif /* !PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_REAL */
  270. /* ///////////////////////////// end of file //////////////////////////// */