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.

290 lines
8.1 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/conversion/explicit_cast.hpp (originally MTExCast.h, ::SynesisStl)
  3. *
  4. * Purpose: Class to provide explicit cast operators.
  5. *
  6. * Created: 20th September 2002
  7. * Updated: 10th August 2009
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2002-2009, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file stlsoft/conversion/explicit_cast.hpp
  40. *
  41. * \brief [C++ only] Definition of the stlsoft::explicit_cast cast class
  42. * (\ref group__library__conversion "Conversion" Library).
  43. */
  44. #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_EXPLICIT_CAST
  45. #define STLSOFT_INCL_STLSOFT_CONVERSION_HPP_EXPLICIT_CAST
  46. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  47. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_EXPLICIT_CAST_MAJOR 4
  48. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_EXPLICIT_CAST_MINOR 0
  49. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_EXPLICIT_CAST_REVISION 1
  50. # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_EXPLICIT_CAST_EDIT 36
  51. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  52. /* /////////////////////////////////////////////////////////////////////////
  53. * Includes
  54. */
  55. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  56. # include <stlsoft/stlsoft.h>
  57. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  58. /* /////////////////////////////////////////////////////////////////////////
  59. * Namespace
  60. */
  61. #ifndef _STLSOFT_NO_NAMESPACE
  62. namespace stlsoft
  63. {
  64. #endif /* _STLSOFT_NO_NAMESPACE */
  65. /* /////////////////////////////////////////////////////////////////////////
  66. * Classes
  67. */
  68. // class explicit_cast
  69. /** \brief This class is used to provide explicit casting operators.
  70. *
  71. * \ingroup group__library__conversion
  72. *
  73. * \param T The underlying type of the cast
  74. */
  75. template <ss_typename_param_k T>
  76. class explicit_cast
  77. {
  78. public:
  79. typedef T value_type;
  80. typedef explicit_cast<T> class_type;
  81. // Construction
  82. public:
  83. explicit_cast(T t)
  84. : m_t(t)
  85. {}
  86. #ifndef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
  87. // For compilers that do not support partial specialisation we need to
  88. // enforce the constraint that only basic types may be used.
  89. ~explicit_cast() stlsoft_throw_0()
  90. {
  91. union must_be_basic_type
  92. {
  93. int i;
  94. T t;
  95. };
  96. }
  97. #endif /* !STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
  98. // Conversions
  99. public:
  100. operator value_type () const
  101. {
  102. return m_t;
  103. }
  104. // Members
  105. private:
  106. T m_t;
  107. };
  108. #ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
  109. /** \brief Being able to cast to non-const references does not work, since
  110. * the compilers will refuse to apply such to a temporary.
  111. *
  112. * \ingroup group__library__conversion
  113. *
  114. * Furthermore, it is too evil to contemplate (see Effective C++ #30)
  115. * so we simply hide the constructor and conversion operator.
  116. */
  117. template <ss_typename_param_k T>
  118. class explicit_cast<T &>
  119. {
  120. public:
  121. typedef T value_type;
  122. typedef explicit_cast<T> class_type;
  123. // Construction
  124. private:
  125. explicit_cast(T &);
  126. // Conversions
  127. private:
  128. operator T & ();
  129. # if defined(STLSOFT_COMPILER_IS_GCC)
  130. public: static void f() {}
  131. # endif /* compiler */
  132. };
  133. # ifdef _STLSOFT_EXPLICIT_CAST_FORCE_ALLOW_REFERENCE_TO_CONST_UDT
  134. /* Compiler check */
  135. # if defined(STLSOFT_COMPILER_IS_BORLAND) || \
  136. defined(STLSOFT_COMPILER_IS_DMC) || \
  137. defined(STLSOFT_COMPILER_IS_GCC) || \
  138. ( defined(STLSOFT_COMPILER_IS_MSVC) && \
  139. _MSC_VER == 1310) || \
  140. defined(STLSOFT_COMPILER_IS_WATCOM)
  141. // These compilers are ok
  142. # elif defined(STLSOFT_COMPILER_IS_INTEL) || \
  143. ( defined(STLSOFT_COMPILER_IS_MSVC) && \
  144. _MSC_VER != 1310)
  145. // These are not
  146. # error The current compiler does not properly implement it
  147. # else /* ? compiler */
  148. // These are unknown
  149. # error The current compiler has not been assessed as to whether it correctly translates explicit_cast for references to non-const
  150. # endif /* compiler */
  151. template <ss_typename_param_k T>
  152. class explicit_cast<T const&>
  153. {
  154. public:
  155. typedef T value_type;
  156. typedef explicit_cast<T> class_type;
  157. // Construction
  158. public:
  159. explicit_cast(T const& t)
  160. : m_t(t)
  161. {}
  162. // Conversions
  163. public:
  164. operator T const& () const
  165. {
  166. return m_t;
  167. }
  168. // Members
  169. private:
  170. T const& m_t;
  171. };
  172. # else /* ? _STLSOFT_EXPLICIT_CAST_FORCE_ALLOW_REFERENCE_TO_CONST_UDT */
  173. # ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  174. # if defined(STLSOFT_COMPILER_IS_MSVC)
  175. # if _MSC_VER >= 1200
  176. # pragma warning(push)
  177. # endif /* _MSC_VER >= 1200 */
  178. # pragma warning(disable : 4512)
  179. # endif /* compiler */
  180. # ifndef STLSOFT_INCL_STLSOFT_INTERNAL_HPP_EXPLICIT_CAST_SPECIALISATIONS
  181. # include <stlsoft/conversion/internal/explicit_cast_specialisations.hpp>
  182. # endif /* !STLSOFT_INCL_STLSOFT_INTERNAL_HPP_EXPLICIT_CAST_SPECIALISATIONS */
  183. # if defined(STLSOFT_COMPILER_IS_MSVC)
  184. # if _MSC_VER >= 1200
  185. # pragma warning(pop)
  186. # else /* _MSC_VER */
  187. # pragma warning(disable : 4512)
  188. # endif /* _MSC_VER >= 1200 */
  189. # endif /* compiler */
  190. # endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  191. # endif /* _STLSOFT_EXPLICIT_CAST_FORCE_ALLOW_REFERENCE_TO_CONST_UDT */
  192. /** \brief Not sure I really like this one, and reserve the right to remove it
  193. * but for now it stays.
  194. *
  195. * \ingroup group__library__conversion
  196. */
  197. template <ss_typename_param_k T>
  198. class explicit_cast<T *>
  199. {
  200. public:
  201. typedef T value_type;
  202. typedef explicit_cast<T> class_type;
  203. // Construction
  204. public:
  205. explicit_cast(T *t)
  206. : m_t(t)
  207. {}
  208. // Conversions
  209. public:
  210. operator T * ()
  211. {
  212. return m_t;
  213. }
  214. // Members
  215. private:
  216. T *m_t;
  217. };
  218. # ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  219. template <ss_typename_param_k T>
  220. class explicit_cast<T const*>
  221. {
  222. public:
  223. typedef T value_type;
  224. typedef explicit_cast<T> class_type;
  225. // Construction
  226. public:
  227. explicit_cast(T const* t)
  228. : m_t(t)
  229. {}
  230. // Conversions
  231. public:
  232. operator T const* () const
  233. {
  234. return m_t;
  235. }
  236. // Members
  237. private:
  238. T const* m_t;
  239. };
  240. # endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  241. #endif // STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
  242. /* ////////////////////////////////////////////////////////////////////// */
  243. #ifndef _STLSOFT_NO_NAMESPACE
  244. } // namespace stlsoft
  245. #endif /* _STLSOFT_NO_NAMESPACE */
  246. /* ////////////////////////////////////////////////////////////////////// */
  247. #endif /* !STLSOFT_INCL_STLSOFT_CONVERSION_HPP_EXPLICIT_CAST */
  248. /* ///////////////////////////// end of file //////////////////////////// */