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.

1118 lines
28 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/util/must_init.hpp
  3. *
  4. * Purpose: Simple class that wraps a fundamental type and forces its
  5. * explicit initialisation.
  6. *
  7. * Thanks: To Josh Kelley, whose blog prompted me to fix docs, and
  8. * newsgroup request prompted me to put it under test and
  9. * code coverage.
  10. *
  11. * Created: 18th June 2006
  12. * Updated: 10th August 2009
  13. *
  14. * Home: http://stlsoft.org/
  15. *
  16. * Copyright (c) 2006-2009, Matthew Wilson and Synesis Software
  17. * All rights reserved.
  18. *
  19. * Redistribution and use in source and binary forms, with or without
  20. * modification, are permitted provided that the following conditions are met:
  21. *
  22. * - Redistributions of source code must retain the above copyright notice, this
  23. * list of conditions and the following disclaimer.
  24. * - Redistributions in binary form must reproduce the above copyright notice,
  25. * this list of conditions and the following disclaimer in the documentation
  26. * and/or other materials provided with the distribution.
  27. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  28. * any contributors may be used to endorse or promote products derived from
  29. * this software without specific prior written permission.
  30. *
  31. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  32. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  34. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  35. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  36. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  37. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  38. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  39. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41. * POSSIBILITY OF SUCH DAMAGE.
  42. *
  43. * ////////////////////////////////////////////////////////////////////////// */
  44. /** \file stlsoft/util/must_init.hpp
  45. *
  46. * \brief [C++ only] Definition of stlsoft::must_init class template
  47. * (\ref group__library__utility "Utility" Library).
  48. */
  49. #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_MUST_INIT
  50. #define STLSOFT_INCL_STLSOFT_UTIL_HPP_MUST_INIT
  51. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  52. # define STLSOFT_VER_STLSOFT_UTIL_HPP_MUST_INIT_MAJOR 1
  53. # define STLSOFT_VER_STLSOFT_UTIL_HPP_MUST_INIT_MINOR 1
  54. # define STLSOFT_VER_STLSOFT_UTIL_HPP_MUST_INIT_REVISION 4
  55. # define STLSOFT_VER_STLSOFT_UTIL_HPP_MUST_INIT_EDIT 17
  56. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  57. /* /////////////////////////////////////////////////////////////////////////
  58. * Includes
  59. */
  60. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  61. # include <stlsoft/stlsoft.h>
  62. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  63. #ifdef STLSOFT_UNITTEST
  64. # include <string>
  65. #endif /* STLSOFT_UNITTEST */
  66. /* /////////////////////////////////////////////////////////////////////////
  67. * Namespace
  68. */
  69. #ifndef _STLSOFT_NO_NAMESPACE
  70. namespace stlsoft
  71. {
  72. #endif /* _STLSOFT_NO_NAMESPACE */
  73. /* /////////////////////////////////////////////////////////////////////////
  74. * Algorithms
  75. */
  76. /** \brief Wraps a variable and forces its explicit initialisation by the
  77. * user.
  78. *
  79. * \param T The base type, e.g. \c int, \c std::wstring
  80. *
  81. * \ingroup group__library__utility
  82. *
  83. * <b>Problem:</b>
  84. *
  85. \code
  86. int i1; // Not initialised. Compiler doesn't care!
  87. int res = 2 * i1; // Result is undefined!
  88. \endcode
  89. *
  90. * <b>Solution:</b>
  91. *
  92. \code
  93. must_init<int> i1; // Not initialised. Compiler error
  94. \endcode
  95. *
  96. * The user is required to explicitly initialise <code>i1</code>:
  97. *
  98. \code
  99. must_init<int> i1(0); // Initialised. Everybody's happy
  100. int res = 2 * i1.get(); // Result is defined
  101. \endcode
  102. */
  103. //STLSOFT_PRAGMA_PACK_PUSH(1)
  104. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  105. template <ss_typename_param_k T>
  106. class must_init_builtin
  107. {
  108. /// \name Member Types
  109. /// @{
  110. public:
  111. /// \brief The wrapped type
  112. typedef T value_type;
  113. /// \brief The current instantiation of the type
  114. typedef must_init_builtin<T> class_type;
  115. /// The reference type
  116. typedef T& reference;
  117. /// The non-mutating (const) reference type
  118. typedef T const& const_reference;
  119. /// @}
  120. /// \name Construction
  121. /// @{
  122. public:
  123. /// \brief Constructor
  124. ss_explicit_k must_init_builtin(T t)
  125. : value(t)
  126. {}
  127. /// \brief Implicit conversion to the wrapped type
  128. operator value_type () const
  129. {
  130. return value;
  131. }
  132. class_type& operator =(const value_type rhs)
  133. {
  134. value = rhs;
  135. return *this;
  136. }
  137. /// @}
  138. /// \name Members
  139. /// @{
  140. public:
  141. /// Provides non-mutating (const) access to the base type value
  142. const_reference base_type_value() const
  143. {
  144. return value;
  145. }
  146. /// Provides mutating access to the base type value
  147. reference base_type_value()
  148. {
  149. return value;
  150. }
  151. /// Provides non-mutating (const) access to the base type value
  152. const_reference get() const
  153. {
  154. return base_type_value();
  155. }
  156. /// Provides mutating access to the base type value
  157. reference get()
  158. {
  159. return base_type_value();
  160. }
  161. /// @}
  162. /// \name Members
  163. /// @{
  164. public:
  165. /// \brief The underlying value
  166. ///
  167. /// \remarks Since the purpose of must_init is to guard against a
  168. /// forgotten initialisation in composition involving fundamental
  169. /// types, rather than encapsulation in any wider sense, the member
  170. /// value is public, to simplify manipulation of the actual value by
  171. /// its encapsulating class, thereby avoiding all the
  172. /// (compiler-dependent) hassles attendant with implicit conversion to
  173. /// reference types.
  174. value_type value;
  175. /// @}
  176. };
  177. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  178. template <ss_typename_param_k T>
  179. class must_init
  180. {
  181. /// \name Member Types
  182. /// @{
  183. public:
  184. /// \brief The wrapped type
  185. typedef T value_type;
  186. /// \brief The current instantiation of the type
  187. typedef must_init<T> class_type;
  188. /// The reference type
  189. typedef T& reference;
  190. /// The non-mutating (const) reference type
  191. typedef T const& const_reference;
  192. /// @}
  193. /// \name Construction
  194. /// @{
  195. public:
  196. /// \brief Constructor
  197. ss_explicit_k must_init(T t)
  198. : value(t)
  199. {}
  200. /// \brief Implicit conversion to the wrapped type
  201. operator value_type const& () const
  202. {
  203. return value;
  204. }
  205. class_type& operator =(value_type const &rhs)
  206. {
  207. value = rhs;
  208. return *this;
  209. }
  210. /// @}
  211. /// \name Members
  212. /// @{
  213. public:
  214. /// Provides non-mutating (const) access to the base type value
  215. const_reference base_type_value() const
  216. {
  217. return value;
  218. }
  219. /// Provides mutating access to the base type value
  220. reference base_type_value()
  221. {
  222. return value;
  223. }
  224. /// Provides non-mutating (const) access to the base type value
  225. const_reference get() const
  226. {
  227. return base_type_value();
  228. }
  229. /// Provides mutating access to the base type value
  230. reference get()
  231. {
  232. return base_type_value();
  233. }
  234. /// @}
  235. /// \name Members
  236. /// @{
  237. public:
  238. /// \brief The underlying value
  239. ///
  240. /// \remarks Since the purpose of must_init is to guard against a
  241. /// forgotten initialisation in composition involving fundamental
  242. /// types, rather than encapsulation in any wider sense, the member
  243. /// value is public, to simplify manipulation of the actual value by
  244. /// its encapsulating class, thereby avoiding all the
  245. /// (compiler-dependent) hassles attendant with implicit conversion to
  246. /// reference types.
  247. value_type value;
  248. /// @}
  249. };
  250. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  251. # define STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(type) \
  252. \
  253. STLSOFT_TEMPLATE_SPECIALISATION \
  254. class must_init<type> \
  255. : public must_init_builtin<type> \
  256. { \
  257. public: \
  258. typedef must_init<type> class_type; \
  259. public: \
  260. explicit must_init(type value) \
  261. : must_init_builtin<type>(value) \
  262. {} \
  263. class_type& operator =(const value_type rhs) \
  264. { \
  265. value = rhs; \
  266. return *this; \
  267. } \
  268. }
  269. # ifdef STLSOFT_CF_NATIVE_BOOL_SUPPORT
  270. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(bool);
  271. # endif /* STLSOFT_CF_NATIVE_BOOL_SUPPORT */
  272. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(char);
  273. # ifdef STLSOFT_CF_NATIVE_WCHAR_T_SUPPORT
  274. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(wchar_t);
  275. # endif /* STLSOFT_CF_NATIVE_WCHAR_T_SUPPORT */
  276. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(signed char);
  277. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(unsigned char);
  278. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(short);
  279. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(unsigned short);
  280. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(int);
  281. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(unsigned int);
  282. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(long);
  283. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(unsigned long);
  284. #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  285. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(ss_sint64_t);
  286. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(ss_uint64_t);
  287. #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  288. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(float);
  289. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(double);
  290. STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_(long double);
  291. # undef STLSOFT_UTIL_MUST_INIT_DEFINE_BUILTIN_
  292. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  293. //STLSOFT_PRAGMA_PACK_POP()
  294. ////////////////////////////////////////////////////////////////////////////
  295. // Specialisations
  296. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>bool</code>.
  297. *
  298. * \ingroup group__library__utility
  299. */
  300. typedef must_init<bool> bool_init_t;
  301. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>char</code>.
  302. *
  303. * \ingroup group__library__utility
  304. */
  305. typedef must_init<char> char_init_t;
  306. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>wchar_t</code>.
  307. *
  308. * \ingroup group__library__utility
  309. */
  310. typedef must_init<wchar_t> wchar_t_init_t;
  311. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>signed char</code>.
  312. *
  313. * \ingroup group__library__utility
  314. */
  315. typedef must_init<signed char> signed_char_init_t;
  316. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>unsigned char</code>.
  317. *
  318. * \ingroup group__library__utility
  319. */
  320. typedef must_init<unsigned char> unsigned_char_init_t;
  321. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>short</code>.
  322. *
  323. * \ingroup group__library__utility
  324. */
  325. typedef must_init<short> short_init_t;
  326. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>unsigned short</code>.
  327. *
  328. * \ingroup group__library__utility
  329. */
  330. typedef must_init<unsigned short> unsigned_short_init_t;
  331. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>int</code>.
  332. *
  333. * \ingroup group__library__utility
  334. */
  335. typedef must_init<int> int_init_t;
  336. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>unsigned int</code>.
  337. *
  338. * \ingroup group__library__utility
  339. */
  340. typedef must_init<unsigned int> unsigned_int_init_t;
  341. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>long</code>.
  342. *
  343. * \ingroup group__library__utility
  344. */
  345. typedef must_init<long> long_init_t;
  346. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>unsigned long</code>.
  347. *
  348. * \ingroup group__library__utility
  349. */
  350. typedef must_init<unsigned long> unsigned_long_init_t;
  351. #ifdef STLSOFT_CF_64BIT_INT_SUPPORT
  352. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>ss_sint64_t</code>.
  353. *
  354. * \ingroup group__library__utility
  355. */
  356. typedef must_init<ss_sint64_t> sint64_init_t;
  357. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>ss_uint64_t</code>.
  358. *
  359. * \ingroup group__library__utility
  360. */
  361. typedef must_init<ss_uint64_t> uint64_init_t;
  362. #endif /* STLSOFT_CF_64BIT_INT_SUPPORT */
  363. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>float</code>.
  364. *
  365. * \ingroup group__library__utility
  366. */
  367. typedef must_init<float> float_init_t;
  368. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>double</code>.
  369. *
  370. * \ingroup group__library__utility
  371. */
  372. typedef must_init<double> double_init_t;
  373. /** \brief Specialisation of \link stlsoft::must_init must_init\endlink for <code>long double</code>.
  374. *
  375. * \ingroup group__library__utility
  376. */
  377. typedef must_init<long double> long_double_init_t;
  378. /* /////////////////////////////////////////////////////////////////////////
  379. * Operators
  380. */
  381. inline bool operator !(bool_init_t const& b)
  382. {
  383. return !b.value;
  384. }
  385. // Pre-increment
  386. template< ss_typename_param_k T
  387. >
  388. inline must_init<T>& operator ++(must_init<T> &v)
  389. {
  390. ++v.base_type_value();
  391. return v;
  392. }
  393. // Post-increment
  394. template< ss_typename_param_k T
  395. >
  396. inline must_init<T> const operator ++(must_init<T> &v, int)
  397. {
  398. must_init<T> r(v);
  399. v.base_type_value()++;
  400. return r;
  401. }
  402. // Pre-decrement
  403. template< ss_typename_param_k T
  404. >
  405. inline must_init<T>& operator --(must_init<T> &v)
  406. {
  407. --v.base_type_value();
  408. return v;
  409. }
  410. // Post-decrement
  411. template< ss_typename_param_k T
  412. >
  413. inline must_init<T> const operator --(must_init<T> &v, int)
  414. {
  415. must_init<T> r(v);
  416. v.base_type_value()--;
  417. return r;
  418. }
  419. // operator ==
  420. template< ss_typename_param_k T
  421. >
  422. inline ss_bool_t operator ==(must_init<T> const& lhs, must_init<T> const& rhs)
  423. {
  424. return lhs.base_type_value() == rhs.base_type_value();
  425. }
  426. template< ss_typename_param_k T
  427. >
  428. inline ss_bool_t operator ==(must_init<T> const& lhs, T const& rhs)
  429. {
  430. return lhs.base_type_value() == rhs;
  431. }
  432. template< ss_typename_param_k T
  433. >
  434. inline ss_bool_t operator ==(T const& lhs, must_init<T> const& rhs)
  435. {
  436. return lhs == rhs.base_type_value();
  437. }
  438. // operator !=
  439. template< ss_typename_param_k T
  440. >
  441. inline ss_bool_t operator !=(must_init<T> const& lhs, must_init<T> const& rhs)
  442. {
  443. return ! operator ==(lhs, rhs);
  444. }
  445. template< ss_typename_param_k T
  446. >
  447. inline ss_bool_t operator !=(must_init<T> const& lhs, T const& rhs)
  448. {
  449. return ! operator ==(lhs, rhs);
  450. }
  451. template< ss_typename_param_k T
  452. >
  453. inline ss_bool_t operator !=(T const& lhs, must_init<T> const& rhs)
  454. {
  455. return ! operator ==(lhs, rhs);
  456. }
  457. // operator <
  458. template< ss_typename_param_k T
  459. >
  460. inline ss_bool_t operator <(must_init<T> const& lhs, must_init<T> const& rhs)
  461. {
  462. return lhs.base_type_value() < rhs.base_type_value();
  463. }
  464. template< ss_typename_param_k T
  465. >
  466. inline ss_bool_t operator <(must_init<T> const& lhs, T const& rhs)
  467. {
  468. return lhs.base_type_value() < rhs;
  469. }
  470. template< ss_typename_param_k T
  471. >
  472. inline ss_bool_t operator <(T const& lhs, must_init<T> const& rhs)
  473. {
  474. return lhs < rhs.base_type_value();
  475. }
  476. // operator <=
  477. template< ss_typename_param_k T
  478. >
  479. inline ss_bool_t operator <=(must_init<T> const& lhs, must_init<T> const& rhs)
  480. {
  481. return lhs.base_type_value() <= rhs.base_type_value();
  482. }
  483. template< ss_typename_param_k T
  484. >
  485. inline ss_bool_t operator <=(must_init<T> const& lhs, T const& rhs)
  486. {
  487. return lhs.base_type_value() <= rhs;
  488. }
  489. template< ss_typename_param_k T
  490. >
  491. inline ss_bool_t operator <=(T const& lhs, must_init<T> const& rhs)
  492. {
  493. return lhs <= rhs.base_type_value();
  494. }
  495. // operator >
  496. template< ss_typename_param_k T
  497. >
  498. inline ss_bool_t operator >(must_init<T> const& lhs, must_init<T> const& rhs)
  499. {
  500. return lhs.base_type_value() > rhs.base_type_value();
  501. }
  502. #ifdef __SYNSOFT_DBS_COMPILER_SUPPORTS_PRAGMA_MESSAGE
  503. # pragma message(_sscomp_fileline_message("This had to be changed to T + T2, so as to allow comparison between different integral types"))
  504. #endif /* __SYNSOFT_DBS_COMPILER_SUPPORTS_PRAGMA_MESSAGE */
  505. template< ss_typename_param_k T
  506. , ss_typename_param_k T2
  507. >
  508. inline ss_bool_t operator >(must_init<T> const& lhs, T2 const& rhs)
  509. {
  510. return lhs.base_type_value() > rhs;
  511. }
  512. template< ss_typename_param_k T
  513. >
  514. inline ss_bool_t operator >(T const& lhs, must_init<T> const& rhs)
  515. {
  516. return lhs > rhs.base_type_value();
  517. }
  518. // operator >=
  519. template< ss_typename_param_k T
  520. >
  521. inline ss_bool_t operator >=(must_init<T> const& lhs, must_init<T> const& rhs)
  522. {
  523. return lhs.base_type_value() >= rhs.base_type_value();
  524. }
  525. template< ss_typename_param_k T
  526. >
  527. inline ss_bool_t operator >=(must_init<T> const& lhs, T const& rhs)
  528. {
  529. return lhs.base_type_value() >= rhs;
  530. }
  531. template< ss_typename_param_k T
  532. >
  533. inline ss_bool_t operator >=(T const& lhs, must_init<T> const& rhs)
  534. {
  535. return lhs >= rhs.base_type_value();
  536. }
  537. // operator +
  538. #if 0
  539. template< ss_typename_param_k T
  540. >
  541. inline must_init<T> operator +(must_init<T> const& lhs, must_init<T> const& rhs)
  542. {
  543. return must_init<T>(lhs.base_type_value() + rhs.base_type_value());
  544. }
  545. #endif /* 0 */
  546. #if 0
  547. template< ss_typename_param_k T
  548. >
  549. inline must_init<T> operator +(must_init<T> const& lhs, T const& rhs)
  550. {
  551. return must_init<T>(lhs.base_type_value() + rhs);
  552. }
  553. #else /* ? 0 */
  554. template< ss_typename_param_k T
  555. , ss_typename_param_k T2
  556. >
  557. inline must_init<T> operator +(must_init<T> const& lhs, T2 const& rhs)
  558. {
  559. return must_init<T>(lhs.base_type_value() + rhs);
  560. }
  561. #endif /* 0 */
  562. #if 0
  563. template< ss_typename_param_k T
  564. >
  565. inline must_init<T> operator +(T const& lhs, must_init<T> const& rhs)
  566. {
  567. return must_init<T>(lhs + rhs.base_type_value());
  568. }
  569. #else /* ? 0 */
  570. template< ss_typename_param_k T
  571. , ss_typename_param_k T2
  572. >
  573. inline must_init<T> operator +(T const& lhs, must_init<T> const& rhs)
  574. {
  575. return must_init<T>(lhs + rhs.base_type_value());
  576. }
  577. #endif /* 0 */
  578. // operator -
  579. template< ss_typename_param_k T
  580. >
  581. inline must_init<T> operator -(must_init<T> const& lhs, must_init<T> const& rhs)
  582. {
  583. return must_init<T>(lhs.base_type_value() - rhs.base_type_value());
  584. }
  585. template< ss_typename_param_k T
  586. >
  587. inline must_init<T> operator -(must_init<T> const& lhs, T const& rhs)
  588. {
  589. return must_init<T>(lhs.base_type_value() - rhs);
  590. }
  591. template< ss_typename_param_k T
  592. >
  593. inline must_init<T> operator -(T const& lhs, must_init<T> const& rhs)
  594. {
  595. return must_init<T>(lhs - rhs.base_type_value());
  596. }
  597. // operator *
  598. template< ss_typename_param_k T
  599. >
  600. inline must_init<T> operator *(must_init<T> const& lhs, must_init<T> const& rhs)
  601. {
  602. return must_init<T>(lhs.base_type_value() * rhs.base_type_value());
  603. }
  604. template< ss_typename_param_k T
  605. >
  606. inline must_init<T> operator *(must_init<T> const& lhs, T const& rhs)
  607. {
  608. return must_init<T>(lhs.base_type_value() * rhs);
  609. }
  610. template< ss_typename_param_k T
  611. >
  612. inline must_init<T> operator *(T const& lhs, must_init<T> const& rhs)
  613. {
  614. return must_init<T>(lhs * rhs.base_type_value());
  615. }
  616. // operator /
  617. template< ss_typename_param_k T
  618. >
  619. inline must_init<T> operator /(must_init<T> const& lhs, must_init<T> const& rhs)
  620. {
  621. return must_init<T>(lhs.base_type_value() / rhs.base_type_value());
  622. }
  623. template< ss_typename_param_k T
  624. >
  625. inline must_init<T> operator /(must_init<T> const& lhs, T const& rhs)
  626. {
  627. return must_init<T>(lhs.base_type_value() / rhs);
  628. }
  629. template< ss_typename_param_k T
  630. >
  631. inline must_init<T> operator /(T const& lhs, must_init<T> const& rhs)
  632. {
  633. return must_init<T>(lhs / rhs.base_type_value());
  634. }
  635. // operator %
  636. template< ss_typename_param_k T
  637. >
  638. inline must_init<T> operator %(must_init<T> const& lhs, must_init<T> const& rhs)
  639. {
  640. return must_init<T>(lhs.base_type_value() % rhs.base_type_value());
  641. }
  642. template< ss_typename_param_k T
  643. >
  644. inline must_init<T> operator %(must_init<T> const& lhs, T const& rhs)
  645. {
  646. return must_init<T>(lhs.base_type_value() % rhs);
  647. }
  648. template< ss_typename_param_k T
  649. >
  650. inline must_init<T> operator %(T const& lhs, must_init<T> const& rhs)
  651. {
  652. return must_init<T>(lhs % rhs.base_type_value());
  653. }
  654. // operator ^
  655. template< ss_typename_param_k T
  656. >
  657. inline must_init<T> operator ^(must_init<T> const& lhs, must_init<T> const& rhs)
  658. {
  659. return must_init<T>(lhs.base_type_value() ^ rhs.base_type_value());
  660. }
  661. template< ss_typename_param_k T
  662. >
  663. inline must_init<T> operator ^(must_init<T> const& lhs, T const& rhs)
  664. {
  665. return must_init<T>(lhs.base_type_value() ^ rhs);
  666. }
  667. template< ss_typename_param_k T
  668. >
  669. inline must_init<T> operator ^(T const& lhs, must_init<T> const& rhs)
  670. {
  671. return must_init<T>(lhs ^ rhs.base_type_value());
  672. }
  673. // operator ~
  674. template< ss_typename_param_k T
  675. >
  676. inline must_init<T> operator ~(must_init<T> const& v)
  677. {
  678. return must_init<T>(~v.base_type_value());
  679. }
  680. // operator <<
  681. template< ss_typename_param_k T
  682. >
  683. inline must_init<T> operator <<(must_init<T> const& lhs, must_init<T> const& rhs)
  684. {
  685. return must_init<T>(lhs.base_type_value() << rhs.base_type_value());
  686. }
  687. template< ss_typename_param_k T
  688. >
  689. inline must_init<T> operator <<(must_init<T> const& lhs, T const& rhs)
  690. {
  691. return must_init<T>(lhs.base_type_value() << rhs);
  692. }
  693. template< ss_typename_param_k T
  694. >
  695. inline must_init<T> operator <<(T const& lhs, must_init<T> const& rhs)
  696. {
  697. return must_init<T>(lhs << rhs.base_type_value());
  698. }
  699. // operator >>
  700. template< ss_typename_param_k T
  701. >
  702. inline must_init<T> operator >>(must_init<T> const& lhs, must_init<T> const& rhs)
  703. {
  704. return must_init<T>(lhs.base_type_value() >> rhs.base_type_value());
  705. }
  706. template< ss_typename_param_k T
  707. >
  708. inline must_init<T> operator >>(must_init<T> const& lhs, T const& rhs)
  709. {
  710. return must_init<T>(lhs.base_type_value() >> rhs);
  711. }
  712. template< ss_typename_param_k T
  713. >
  714. inline must_init<T> operator >>(T const& lhs, must_init<T> const& rhs)
  715. {
  716. return must_init<T>(lhs >> rhs.base_type_value());
  717. }
  718. // operator &
  719. template< ss_typename_param_k T
  720. >
  721. inline must_init<T> operator &(must_init<T> const& lhs, must_init<T> const& rhs)
  722. {
  723. return must_init<T>(lhs.base_type_value() & rhs.base_type_value());
  724. }
  725. template< ss_typename_param_k T
  726. >
  727. inline must_init<T> operator &(must_init<T> const& lhs, T const& rhs)
  728. {
  729. return must_init<T>(lhs.base_type_value() & rhs);
  730. }
  731. template< ss_typename_param_k T
  732. >
  733. inline must_init<T> operator &(T const& lhs, must_init<T> const& rhs)
  734. {
  735. return must_init<T>(lhs & rhs.base_type_value());
  736. }
  737. // operator |
  738. template< ss_typename_param_k T
  739. >
  740. inline must_init<T> operator |(must_init<T> const& lhs, must_init<T> const& rhs)
  741. {
  742. return must_init<T>(lhs.base_type_value() | rhs.base_type_value());
  743. }
  744. template< ss_typename_param_k T
  745. >
  746. inline must_init<T> operator |(must_init<T> const& lhs, T const& rhs)
  747. {
  748. return must_init<T>(lhs.base_type_value() | rhs);
  749. }
  750. template< ss_typename_param_k T
  751. >
  752. inline must_init<T> operator |(T const& lhs, must_init<T> const& rhs)
  753. {
  754. return must_init<T>(lhs | rhs.base_type_value());
  755. }
  756. // operator +=
  757. template< ss_typename_param_k T
  758. >
  759. inline must_init<T> const& operator +=(must_init<T> &v, T const& rhs)
  760. {
  761. v.base_type_value() += rhs;
  762. return v;
  763. }
  764. template< ss_typename_param_k T
  765. >
  766. inline must_init<T> const& operator +=(must_init<T> &v, must_init<T> const& rhs)
  767. {
  768. v.base_type_value() += rhs.base_type_value();
  769. return v;
  770. }
  771. // operator -=
  772. template< ss_typename_param_k T
  773. >
  774. inline must_init<T> const& operator -=(must_init<T> &v, T const& rhs)
  775. {
  776. v.base_type_value() -= rhs;
  777. return v;
  778. }
  779. template< ss_typename_param_k T
  780. >
  781. inline must_init<T> const& operator -=(must_init<T> &v, must_init<T> const& rhs)
  782. {
  783. v.base_type_value() -= rhs.base_type_value();
  784. return v;
  785. }
  786. // operator *=
  787. template< ss_typename_param_k T
  788. >
  789. inline must_init<T> const& operator *=(must_init<T> &v, T const& rhs)
  790. {
  791. v.base_type_value() *= rhs;
  792. return v;
  793. }
  794. template< ss_typename_param_k T
  795. >
  796. inline must_init<T> const& operator *=(must_init<T> &v, must_init<T> const& rhs)
  797. {
  798. v.base_type_value() *= rhs.base_type_value();
  799. return v;
  800. }
  801. // operator /=
  802. template< ss_typename_param_k T
  803. >
  804. inline must_init<T> const& operator /=(must_init<T> &v, T const& rhs)
  805. {
  806. v.base_type_value() /= rhs;
  807. return v;
  808. }
  809. template< ss_typename_param_k T
  810. >
  811. inline must_init<T> const& operator /=(must_init<T> &v, must_init<T> const& rhs)
  812. {
  813. v.base_type_value() /= rhs.base_type_value();
  814. return v;
  815. }
  816. // operator %=
  817. template< ss_typename_param_k T
  818. >
  819. inline must_init<T> const& operator %=(must_init<T> &v, T const& rhs)
  820. {
  821. v.base_type_value() %= rhs;
  822. return v;
  823. }
  824. template< ss_typename_param_k T
  825. >
  826. inline must_init<T> const& operator %=(must_init<T> &v, must_init<T> const& rhs)
  827. {
  828. v.base_type_value() %= rhs.base_type_value();
  829. return v;
  830. }
  831. // operator ^=
  832. template< ss_typename_param_k T
  833. >
  834. inline must_init<T> const& operator ^=(must_init<T> &v, T const& rhs)
  835. {
  836. v.base_type_value() ^= rhs;
  837. return v;
  838. }
  839. template< ss_typename_param_k T
  840. >
  841. inline must_init<T> const& operator ^=(must_init<T> &v, must_init<T> const& rhs)
  842. {
  843. v.base_type_value() ^= rhs.base_type_value();
  844. return v;
  845. }
  846. // operator <<=
  847. template< ss_typename_param_k T
  848. >
  849. inline must_init<T> const& operator <<=(must_init<T> &v, T const& rhs)
  850. {
  851. v.base_type_value() <<= rhs;
  852. return v;
  853. }
  854. template< ss_typename_param_k T
  855. >
  856. inline must_init<T> const& operator <<=(must_init<T> &v, must_init<T> const& rhs)
  857. {
  858. v.base_type_value() <<= rhs.base_type_value();
  859. return v;
  860. }
  861. // operator >>=
  862. template< ss_typename_param_k T
  863. >
  864. inline must_init<T> const& operator >>=(must_init<T> &v, T const& rhs)
  865. {
  866. v.base_type_value() >>= rhs;
  867. return v;
  868. }
  869. template< ss_typename_param_k T
  870. >
  871. inline must_init<T> const& operator >>=(must_init<T> &v, must_init<T> const& rhs)
  872. {
  873. v.base_type_value() >>= rhs.base_type_value();
  874. return v;
  875. }
  876. // operator &=
  877. template< ss_typename_param_k T
  878. >
  879. inline must_init<T> const& operator &=(must_init<T> &v, T const& rhs)
  880. {
  881. v.base_type_value() &= rhs;
  882. return v;
  883. }
  884. template< ss_typename_param_k T
  885. >
  886. inline must_init<T> const& operator &=(must_init<T> &v, must_init<T> const& rhs)
  887. {
  888. v.base_type_value() &= rhs.base_type_value();
  889. return v;
  890. }
  891. // operator |=
  892. template< ss_typename_param_k T
  893. >
  894. inline must_init<T> const& operator |=(must_init<T> &v, T const& rhs)
  895. {
  896. v.base_type_value() |= rhs;
  897. return v;
  898. }
  899. template< ss_typename_param_k T
  900. >
  901. inline must_init<T> const& operator |=(must_init<T> &v, must_init<T> const& rhs)
  902. {
  903. v.base_type_value() |= rhs.base_type_value();
  904. return v;
  905. }
  906. ////////////////////////////////////////////////////////////////////////////
  907. // Unit-testing
  908. #ifdef STLSOFT_UNITTEST
  909. # include "./unittest/must_init_unittest_.h"
  910. #endif /* STLSOFT_UNITTEST */
  911. /* ////////////////////////////////////////////////////////////////////// */
  912. #ifndef _STLSOFT_NO_NAMESPACE
  913. } // namespace stlsoft
  914. #endif /* _STLSOFT_NO_NAMESPACE */
  915. /* ////////////////////////////////////////////////////////////////////// */
  916. #endif /* !STLSOFT_INCL_STLSOFT_UTIL_HPP_MUST_INIT */
  917. /* ///////////////////////////// end of file //////////////////////////// */