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.

316 lines
10 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/obsolete/first_class_promoter.hpp
  3. *
  4. * Purpose: Class template that allows built-in & aggregate types to be treated as 1st-class types.
  5. *
  6. * Created: 8th 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/obsolete/first_class_promoter.hpp
  40. ///
  41. /// Class template that allows built-in & aggregate types to be treated as 1st-class types.
  42. #ifndef STLSOFT_INCL_STLSOFT_OBSOLETE_HPP_FIRST_CLASS_PROMOTER
  43. #define STLSOFT_INCL_STLSOFT_OBSOLETE_HPP_FIRST_CLASS_PROMOTER
  44. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  45. # define STLSOFT_VER_STLSOFT_OBSOLETE_HPP_FIRST_CLASS_PROMOTER_MAJOR 4
  46. # define STLSOFT_VER_STLSOFT_OBSOLETE_HPP_FIRST_CLASS_PROMOTER_MINOR 0
  47. # define STLSOFT_VER_STLSOFT_OBSOLETE_HPP_FIRST_CLASS_PROMOTER_REVISION 4
  48. # define STLSOFT_VER_STLSOFT_OBSOLETE_HPP_FIRST_CLASS_PROMOTER_EDIT 51
  49. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  50. /* /////////////////////////////////////////////////////////////////////////
  51. * Includes
  52. */
  53. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  54. # include <stlsoft/stlsoft.h>
  55. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  56. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_CONSTRAINTS
  57. # include <stlsoft/util/constraints.hpp>
  58. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_CONSTRAINTS */
  59. #ifndef STLSOFT_INCL_STLSOFT_META_HPP_YESNO
  60. # include <stlsoft/meta/yesno.hpp> // for yes_type, no_type
  61. #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_YESNO */
  62. #ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_FUNDAMENTAL_TYPE
  63. # include <stlsoft/meta/is_fundamental_type.hpp>
  64. #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_IS_FUNDAMENTAL_TYPE */
  65. #ifndef STLSOFT_INCL_H_STRING
  66. # define STLSOFT_INCL_H_STRING
  67. # include <string.h> // for memset()
  68. #endif /* !STLSOFT_INCL_H_STRING */
  69. /* /////////////////////////////////////////////////////////////////////////
  70. * Namespace
  71. */
  72. #ifndef _STLSOFT_NO_NAMESPACE
  73. namespace stlsoft
  74. {
  75. #endif /* _STLSOFT_NO_NAMESPACE */
  76. /* /////////////////////////////////////////////////////////////////////////
  77. * TMP worker classes / functions
  78. */
  79. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  80. #ifndef _STLSOFT_NO_NAMESPACE
  81. namespace first_class_promotion
  82. {
  83. #endif /* _STLSOFT_NO_NAMESPACE */
  84. template<ss_bool_t INIT>
  85. struct first_class_promoter_init_traits
  86. {
  87. typedef yes_type type;
  88. };
  89. STLSOFT_TEMPLATE_SPECIALISATION
  90. struct first_class_promoter_init_traits<false>
  91. {
  92. typedef no_type type;
  93. };
  94. template<ss_typename_param_k T>
  95. inline void first_class_promotion_do_init(T *t, yes_type, yes_type)
  96. {
  97. *t = T();
  98. }
  99. template<ss_typename_param_k T>
  100. inline void first_class_promotion_do_init(T *t, yes_type, no_type)
  101. {
  102. ::memset(t, 0, sizeof(T));
  103. }
  104. template<ss_typename_param_k T>
  105. inline void first_class_promotion_do_init(T *, no_type, yes_type)
  106. {}
  107. template<ss_typename_param_k T>
  108. inline void first_class_promotion_do_init(T *, no_type, no_type)
  109. {}
  110. template< ss_typename_param_k T
  111. , ss_bool_t INIT
  112. >
  113. struct first_class_promoter_traits
  114. {
  115. typedef ss_typename_type_k first_class_promoter_init_traits<INIT>::type do_init_yesno_type;
  116. #if defined(STLSOFT_COMPILER_IS_BORLAND) && \
  117. __BORLANDC__ < 0x0564
  118. enum { val = is_fundamental_type<T>::value };
  119. typedef first_class_promoter_init_traits<val>::type is_fundamental_yesno_type;
  120. #else /* ? compiler */
  121. typedef ss_typename_type_k first_class_promoter_init_traits<is_fundamental_type<T>::value>::type is_fundamental_yesno_type;
  122. #endif /* compiler */
  123. static void initialise(T *value)
  124. {
  125. first_class_promotion_do_init(value, do_init_yesno_type(), is_fundamental_yesno_type());
  126. }
  127. };
  128. #ifndef _STLSOFT_NO_NAMESPACE
  129. } // namespace first_class_promotion
  130. #endif /* _STLSOFT_NO_NAMESPACE */
  131. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  132. /* /////////////////////////////////////////////////////////////////////////
  133. * Classes
  134. */
  135. // class first_class_promoter
  136. /** \brief Promotes a basic type to a first-class type
  137. *
  138. * \ingroup group__library__obsolete
  139. *
  140. * This type can be used to promote a basic type (e.g. <code>int</code>) or a type that
  141. * cannot be used as the base of an inheritance relationship (such as a union)
  142. * to first class status.
  143. *
  144. * \param T The basic type
  145. *
  146. */
  147. template< ss_typename_param_k T
  148. , ss_bool_t INIT = false
  149. >
  150. class first_class_promoter
  151. {
  152. public:
  153. /// The value type
  154. typedef T value_type;
  155. /// The type of the current parameterisation
  156. typedef first_class_promoter<T> class_type;
  157. /// The pointer type
  158. typedef T* pointer;
  159. /// The non-mutating (const) pointer type
  160. typedef T const* const_pointer;
  161. /// The reference type
  162. typedef T& reference;
  163. /// The non-mutating (const) reference type
  164. typedef T const& const_reference;
  165. // Construction
  166. public:
  167. /// Default constructor
  168. ///
  169. /// \note The internal member of the \c value_type is <i><b>not</b></i>
  170. /// initialised, for efficiency, if INIT is false (the default)
  171. first_class_promoter()
  172. {
  173. #ifndef _STLSOFT_NO_NAMESPACE
  174. using namespace first_class_promotion;
  175. #endif /* _STLSOFT_NO_NAMESPACE */
  176. first_class_promoter_traits<T, INIT>::initialise(&m_value);
  177. }
  178. /// Copy constructor
  179. first_class_promoter(class_type const& rhs)
  180. : m_value(rhs.m_value)
  181. {}
  182. /// Initialise an instance from an instance of the promoted type
  183. #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  184. template <ss_typename_param_k U>
  185. ss_explicit_k first_class_promoter(U& value)
  186. : m_value(value)
  187. {}
  188. #else /* ? STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
  189. ss_explicit_k first_class_promoter(value_type const& value)
  190. : m_value(value)
  191. {}
  192. #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
  193. /// Destructor
  194. ~first_class_promoter() stlsoft_throw_0()
  195. {
  196. // This class shouldn't be used for 1st class types, so constrain to
  197. // non-class types, or trivial class types.
  198. //
  199. // It is put in a static assert merely to persuade recalcitrant
  200. // compilers to desist
  201. stlsoft_constraint_must_be_pod(value_type);
  202. // Check the assumption that this veneer is of zero size. The runtime
  203. // assert is included for those compilers that do not implement
  204. // compile-time asserts.
  205. STLSOFT_STATIC_ASSERT(sizeof(class_type) == sizeof(value_type));
  206. #if defined(STLSOFT_COMPILER_IS_WATCOM)
  207. STLSOFT_ASSERT(sizeof(class_type) == sizeof(value_type));
  208. #else /* ? compiler */
  209. STLSOFT_MESSAGE_ASSERT("first_class_promoter used for inappropriate type", sizeof(class_type) == sizeof(value_type));
  210. #endif /* compiler */
  211. }
  212. /// Copy assignment operator
  213. class_type& operator =(class_type const& rhs)
  214. {
  215. m_value = rhs.m_value;
  216. return *this;
  217. }
  218. /// Assignment operator, taking an instance of the promoted type
  219. class_type& operator =(value_type const& value)
  220. {
  221. m_value = value;
  222. return *this;
  223. }
  224. // Accessors
  225. public:
  226. /// Provides a non-mutable (const) reference to the promoted type member
  227. const_reference base_type_value() const
  228. {
  229. return m_value;
  230. }
  231. /// Provides a mutable reference to the promoted type member
  232. reference base_type_value()
  233. {
  234. return m_value;
  235. }
  236. // Operators
  237. public:
  238. /// Implicit conversion operator to a reference to the promoted type member
  239. operator reference()
  240. {
  241. return m_value;
  242. }
  243. /// Implicit conversion operator to a non-mutable (const) reference to the promoted type member
  244. operator const_reference() const
  245. {
  246. return m_value;
  247. }
  248. /// Address-of operator, providing pointer access to the promoted type member
  249. pointer operator &()
  250. {
  251. return &m_value;
  252. }
  253. /// Address-of operator, providing non-mutable (const) pointer access to the promoted type member
  254. const_pointer operator &() const
  255. {
  256. return &m_value;
  257. }
  258. // Members
  259. private:
  260. T m_value;
  261. };
  262. /* ////////////////////////////////////////////////////////////////////// */
  263. #ifndef _STLSOFT_NO_NAMESPACE
  264. } // namespace stlsoft
  265. #endif /* _STLSOFT_NO_NAMESPACE */
  266. /* ////////////////////////////////////////////////////////////////////// */
  267. #endif /* !STLSOFT_INCL_STLSOFT_OBSOLETE_HPP_FIRST_CLASS_PROMOTER */
  268. /* ///////////////////////////// end of file //////////////////////////// */