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.

1470 lines
48 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: stlsoft/properties/method_properties.hpp
  3. *
  4. * Purpose: Method-based properties.
  5. *
  6. * Created: 6th October 2003
  7. * Updated: 10th August 2009
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2003-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/properties/method_properties.hpp
  40. *
  41. * \brief [C++ only] Definition of the method property implementation
  42. * class templates:
  43. * stlsoft::method_property_get,
  44. * stlsoft::method_property_set,
  45. * stlsoft::method_property_getset,
  46. * stlsoft::method_property_get_external,
  47. * stlsoft::method_property_set_external,
  48. * stlsoft::method_property_getset_external,
  49. * stlsoft::static_method_property_get,
  50. * stlsoft::static_method_property_set
  51. * stlsoft::static_method_property_getset,
  52. * stlsoft::static_method_property_get_external,
  53. * stlsoft::static_method_property_set_external
  54. * and
  55. * stlsoft::static_method_property_getset_external
  56. * (\ref group__library__properties "Properties" Library).
  57. */
  58. #ifndef STLSOFT_INCL_STLSOFT_PROPERTIES_HPP_METHOD_PROPERTIES
  59. #define STLSOFT_INCL_STLSOFT_PROPERTIES_HPP_METHOD_PROPERTIES
  60. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  61. # define STLSOFT_VER_STLSOFT_PROPERTIES_HPP_METHOD_PROPERTIES_MAJOR 4
  62. # define STLSOFT_VER_STLSOFT_PROPERTIES_HPP_METHOD_PROPERTIES_MINOR 0
  63. # define STLSOFT_VER_STLSOFT_PROPERTIES_HPP_METHOD_PROPERTIES_REVISION 3
  64. # define STLSOFT_VER_STLSOFT_PROPERTIES_HPP_METHOD_PROPERTIES_EDIT 57
  65. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  66. /* /////////////////////////////////////////////////////////////////////////
  67. * Compatibility
  68. */
  69. /*
  70. [Incompatibilies-start]
  71. STLSOFT_COMPILER_IS_GCC: __GNUC__ == 3 && defined(__APPLE__)
  72. STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
  73. STLSOFT_COMPILER_IS_WATCOM:
  74. [Incompatibilies-end]
  75. */
  76. /* /////////////////////////////////////////////////////////////////////////
  77. * Includes
  78. */
  79. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  80. # include <stlsoft/stlsoft.h>
  81. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  82. #if defined(STLSOFT_COMPILER_IS_MSVC) && \
  83. _MSC_VER < 1200
  84. # error stlsoft/properties/method_properties.hpp is not compatible with Visual C++ 5.0 or earlier
  85. #endif /* compiler */
  86. /* /////////////////////////////////////////////////////////////////////////
  87. * Compatibility
  88. */
  89. /* Don't want all the nasty crud for handling backwards compilers included in
  90. * the documentation
  91. */
  92. #if defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  93. # define STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  94. #endif /* STLSOFT_DOCUMENTATION_SKIP_SECTION */
  95. /* Certain compilers are too hopeless to help in any conceivable way. */
  96. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  97. /* Compatible */
  98. #elif ( defined(STLSOFT_COMPILER_IS_MSVC) && \
  99. _MSC_VER < 1200)
  100. # error Compiler is not compatible with method properties
  101. #endif /* compiler */
  102. /* /////////////////////////////////////////////////////////////////////////
  103. * Namespace
  104. */
  105. #ifndef _STLSOFT_NO_NAMESPACE
  106. namespace stlsoft
  107. {
  108. #endif /* _STLSOFT_NO_NAMESPACE */
  109. /* /////////////////////////////////////////////////////////////////////////
  110. * Macros
  111. */
  112. #define STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P) \
  113. \
  114. P##_prop_offset_##C
  115. /** \def STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET
  116. *
  117. * \ingroup group__library__properties
  118. *
  119. * \param C The containing class type
  120. * \param P The property name
  121. */
  122. #define STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P) \
  123. \
  124. static stlsoft_ns_qual(ss_ptrdiff_t) STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P)() \
  125. { \
  126. return STLSOFT_RAW_OFFSETOF(C, P); \
  127. }
  128. /** \def STLSOFT_METHOD_PROPERTY_GET
  129. *
  130. * \ingroup group__library__properties
  131. *
  132. * \param V The value type
  133. * \param R The value reference type
  134. * \param C The containing class type
  135. * \param GM The property get accessor method
  136. * \param P The property name
  137. *
  138. * TODO: EXAMPLE HERE
  139. */
  140. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  141. # define STLSOFT_METHOD_PROPERTY_GET(V, R, C, GM, P) \
  142. \
  143. STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P) \
  144. \
  145. stlsoft_ns_qual(method_property_get)< V \
  146. , R \
  147. , C \
  148. , &C::STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P) \
  149. , &C::GM \
  150. > P
  151. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  152. # define STLSOFT_METHOD_PROPERTY_GET(V, R, C, GM, P) \
  153. \
  154. STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P) \
  155. \
  156. stlsoft_ns_qual(method_property_get)< V \
  157. , R \
  158. , C \
  159. , &C::STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P) \
  160. > P
  161. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  162. /** \def STLSOFT_METHOD_PROPERTY_SET
  163. *
  164. * \ingroup group__library__properties
  165. *
  166. * \param V The value type
  167. * \param R The value reference type
  168. * \param C The containing class type
  169. * \param SM The property set accessor method
  170. * \param P The property name
  171. *
  172. * TODO: EXAMPLE HERE
  173. */
  174. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  175. # define STLSOFT_METHOD_PROPERTY_SET(V, R, C, SM, P) \
  176. \
  177. STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P) \
  178. \
  179. stlsoft_ns_qual(method_property_set)< V \
  180. , R \
  181. , C \
  182. , &C::STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P) \
  183. , &C::SM \
  184. > P
  185. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  186. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  187. /** \def STLSOFT_METHOD_PROPERTY_GETSET
  188. *
  189. * \ingroup group__library__properties
  190. *
  191. * \param V The value type
  192. * \param RG The get reference type
  193. * \param RS The set reference type
  194. * \param C The containing class type
  195. * \param GM The property get accessor method
  196. * \param SM The property set accessor method
  197. * \param P The property name
  198. *
  199. * TODO: EXAMPLE HERE
  200. */
  201. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  202. # define STLSOFT_METHOD_PROPERTY_GETSET(V, RG, RS, C, GM, SM, P) \
  203. \
  204. STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P) \
  205. \
  206. stlsoft_ns_qual(method_property_getset)< V \
  207. , RG \
  208. , RS \
  209. , C \
  210. , &C::STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P) \
  211. , &C::GM \
  212. , &C::SM \
  213. > P
  214. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  215. # define STLSOFT_METHOD_PROPERTY_GETSET(V, RG, RS, C, GM, SM, P) \
  216. \
  217. STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P) \
  218. \
  219. stlsoft_ns_qual(method_property_getset)< V \
  220. , RG \
  221. , RS \
  222. , C \
  223. , &C::STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P) \
  224. > P
  225. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  226. /** \def STLSOFT_METHOD_PROPERTY_GET_EXTERNAL
  227. *
  228. * \ingroup group__library__properties
  229. *
  230. * \param R The value reference type
  231. * \param C The containing class type
  232. * \param GM The property get accessor method
  233. * \param P The property name
  234. *
  235. * TODO: EXAMPLE HERE
  236. */
  237. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  238. # define STLSOFT_METHOD_PROPERTY_GET_EXTERNAL_PROP(R, C, GM, P) \
  239. \
  240. stlsoft_ns_qual(method_property_get_external)< R \
  241. , C \
  242. , &C::STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P) \
  243. , &C::GM \
  244. > P
  245. # define STLSOFT_METHOD_PROPERTY_GET_EXTERNAL(R, C, GM, P) \
  246. \
  247. STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P) \
  248. STLSOFT_METHOD_PROPERTY_GET_EXTERNAL_PROP(R, C, GM, P)
  249. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  250. # define STLSOFT_METHOD_PROPERTY_GET_EXTERNAL(R, C, GM, P) \
  251. \
  252. STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P) \
  253. \
  254. stlsoft_ns_qual(method_property_get_external)< R \
  255. , C \
  256. , &C::STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P) \
  257. > P
  258. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  259. /** \def STLSOFT_METHOD_PROPERTY_SET_EXTERNAL
  260. *
  261. * \ingroup group__library__properties
  262. *
  263. * \param R The value reference type
  264. * \param C The containing class type
  265. * \param SM The property set accessor method
  266. * \param P The property name
  267. *
  268. * TODO: EXAMPLE HERE
  269. */
  270. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  271. # define STLSOFT_METHOD_PROPERTY_SET_EXTERNAL_PROP(R, C, SM, P) \
  272. \
  273. stlsoft_ns_qual(method_property_set_external)< R \
  274. , C \
  275. , &C::STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P) \
  276. , &C::SM \
  277. > P
  278. # define STLSOFT_METHOD_PROPERTY_SET_EXTERNAL(R, C, SM, P) \
  279. \
  280. STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P) \
  281. STLSOFT_METHOD_PROPERTY_SET_EXTERNAL_PROP(R, C, SM, P)
  282. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  283. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  284. /** \def STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL
  285. *
  286. * \ingroup group__library__properties
  287. *
  288. * \param RG The get reference type
  289. * \param RS The set reference type
  290. * \param C The containing class type
  291. * \param GM The property get accessor method
  292. * \param SM The property set accessor method
  293. * \param P The property name
  294. *
  295. * TODO: EXAMPLE HERE
  296. */
  297. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  298. # define STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL_PROP(RG, RS, C, GM, SM, P) \
  299. \
  300. stlsoft_ns_qual(method_property_getset_external)< RG \
  301. , RS \
  302. , C \
  303. , &C::STLSOFT_METHOD_PROPERTY_OFFSET_NAME(C, P) \
  304. , &C::GM \
  305. , &C::SM \
  306. > P
  307. # define STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL(RG, RS, C, GM, SM, P) \
  308. \
  309. STLSOFT_METHOD_PROPERTY_DEFINE_OFFSET(C, P) \
  310. STLSOFT_METHOD_PROPERTY_GETSET_EXTERNAL_PROP(RG, RS, C, GM, SM, P)
  311. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  312. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  313. /* /////////////////////////////////////////////////////////////////////////
  314. * Classes
  315. */
  316. /* Designates a property
  317. */
  318. struct property_tag
  319. {};
  320. struct internal_property_tag
  321. : public property_tag
  322. {
  323. enum { is_internal = 1 };
  324. enum { is_external = 0 };
  325. };
  326. struct external_property_tag
  327. : public property_tag
  328. {
  329. enum { is_internal = 0 };
  330. enum { is_external = 1 };
  331. };
  332. /** Designates an internal property
  333. */
  334. template< int R
  335. , int W
  336. , int S
  337. >
  338. struct internal_property
  339. : public internal_property_tag
  340. {
  341. enum { is_read = R };
  342. enum { is_write = W };
  343. enum { is_static = S };
  344. };
  345. /** Designates an external property
  346. */
  347. template< int R
  348. , int W
  349. , int S
  350. >
  351. struct external_property
  352. : public external_property_tag
  353. {
  354. enum { is_read = R };
  355. enum { is_write = W };
  356. enum { is_static = S };
  357. };
  358. /* /////////////////////////////////////////////////////////////////////////
  359. * Internal method property classes
  360. */
  361. // Some compilers store member functions as very large quantities, e.g Borland
  362. // uses 12-bytes on Win32, so the pointer to member is stored in a static method
  363. // of a unique type, whose users are required to call its constructor before
  364. // accessing its static method
  365. /** \brief Provides static storage and access to a get member function of a
  366. * given type.
  367. *
  368. * \ingroup group__library__properties
  369. */
  370. template< ss_typename_param_k T /* The outer class, used to provide uniqueness */
  371. , ss_typename_param_k R /* The reference type */
  372. , ss_typename_param_k C /* The enclosing class */
  373. >
  374. struct member_get_pointer
  375. {
  376. private:
  377. member_get_pointer(R (C::*pfn)() const)
  378. {
  379. function(pfn, NULL, NULL);
  380. }
  381. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(T);
  382. static R get(C *pC)
  383. {
  384. R r;
  385. function(NULL, pC, &r);
  386. return r;
  387. }
  388. private:
  389. static void function(R (C::*pfn)() const , C *pC, R *pR)
  390. {
  391. static R (C::*s_pfn)() const = pfn;
  392. STLSOFT_MESSAGE_ASSERT("member_get_pointer called before being initialised!", NULL != s_pfn);
  393. if(NULL != pC)
  394. {
  395. *pR = (pC->*s_pfn)();
  396. }
  397. }
  398. };
  399. /** \brief Provides static storage and access to a set member function of a
  400. * given type.
  401. *
  402. * \ingroup group__library__properties
  403. */
  404. template< ss_typename_param_k T /* The outer class, used to provide uniqueness */
  405. , ss_typename_param_k R /* The reference type */
  406. , ss_typename_param_k C /* The enclosing class */
  407. >
  408. struct member_set_pointer
  409. {
  410. private:
  411. member_set_pointer(void (C::*pfn)(R ))
  412. {
  413. function(pfn, NULL, NULL);
  414. }
  415. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(T);
  416. static void set(C *pC, R *pR)
  417. {
  418. function(NULL, pC, pR);
  419. }
  420. private:
  421. static void function(void (C::*pfn)(R ) , C *pC, R *pR)
  422. {
  423. static void (C::*s_pfn)(R ) = pfn;
  424. STLSOFT_MESSAGE_ASSERT("member_set_pointer called before being initialised!", NULL != s_pfn);
  425. if(NULL != pC)
  426. {
  427. (pC->*s_pfn)(*pR);
  428. }
  429. }
  430. };
  431. /** \brief This class provides method-based read-only property access
  432. *
  433. * \ingroup group__library__properties
  434. *
  435. * The containing class defines a get method. It also defines a static method
  436. * that contains the offset of the given property from within the container.
  437. * Then the template is parameterised with the value type, the reference type,
  438. * the container type, the member function and the offset function.
  439. */
  440. template< ss_typename_param_k V /* The actual property value type */
  441. , ss_typename_param_k R /* The reference type */
  442. , ss_typename_param_k C /* The enclosing class */
  443. , ss_ptrdiff_t (*PFnOff)() /* Pointer to function providing offset of property within container */
  444. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  445. , R (C::*PFnGet)() const /* Pointer to a const member function returning R */
  446. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  447. >
  448. class method_property_get
  449. : public internal_property<1, 0, 0>
  450. {
  451. /// \name Member Types
  452. /// @{
  453. public:
  454. typedef V value_type;
  455. typedef R reference_type;
  456. typedef C container_type;
  457. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  458. typedef method_property_get<V, R, C, PFnOff, PFnGet> class_type;
  459. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  460. typedef method_property_get<V, R, C, PFnOff> class_type;
  461. typedef member_get_pointer<class_type, R, C> member_pointer_type;
  462. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  463. # if defined(STLSOFT_COMPILER_IS_DMC)
  464. /// @}
  465. /// \name Construction
  466. /// @{
  467. public:
  468. # else
  469. private:
  470. # endif /* compiler */
  471. method_property_get()
  472. {}
  473. private:
  474. ss_explicit_k method_property_get(reference_type value)
  475. : m_value(value)
  476. {}
  477. #ifndef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  478. private:
  479. typedef member_pointer_type PFnGet;
  480. private:
  481. method_property_get(reference_type (C::*pfn)() const)
  482. {
  483. PFnGet f(pfn);
  484. }
  485. #endif /* !STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  486. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
  487. /// @}
  488. /// \name Accessors
  489. /// @{
  490. public:
  491. /// Provides read-only access to the property
  492. operator reference_type() const
  493. {
  494. ss_ptrdiff_t offset = (*PFnOff)();
  495. container_type *pC = (container_type*)((ss_byte_t*)this - offset);
  496. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  497. return (pC->*PFnGet)();
  498. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  499. return PFnGet::get(pC);
  500. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  501. }
  502. /// @}
  503. /// \name Members
  504. /// @{
  505. private:
  506. value_type m_value;
  507. /// @}
  508. /// \name Not to be implemented
  509. /// @{
  510. private:
  511. /// This method is hidden in order to prevent users of this class from
  512. /// becoming familiar with using operator = on the property instances
  513. /// from within the containing class, since doing so with
  514. /// method_property_getset<> would result in an infinite loop.
  515. class_type& operator =(reference_type value);
  516. /// @}
  517. };
  518. /** \brief This class provides method-based write-only property access
  519. *
  520. * \ingroup group__library__properties
  521. *
  522. * The containing class defines a set method. It also defines a static method
  523. * that contains the offset of the given property from within the container.
  524. * Then the template is parameterised with the value type, the reference type,
  525. * the container type, the member function and the offset function.
  526. */
  527. template< ss_typename_param_k V /* The actual property value type */
  528. , ss_typename_param_k R /* The reference type */
  529. , ss_typename_param_k C /* The enclosing class */
  530. , ss_ptrdiff_t (*PFnOff)() /* Pointer to function providing offset of property within container */
  531. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  532. , void (C::*PFnSet)(R ) /* Pointer to a member function taking R */
  533. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  534. >
  535. class method_property_set
  536. : public internal_property<0, 1, 0>
  537. {
  538. /// \name Member Types
  539. /// @{
  540. private:
  541. typedef V value_type;
  542. typedef R reference_type;
  543. typedef C container_type;
  544. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  545. typedef method_property_set<V, R, C, PFnOff, PFnSet> class_type;
  546. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  547. typedef method_property_set<V, R, C, PFnOff> class_type;
  548. typedef member_set_pointer<class_type, R, C> member_pointer_type;
  549. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  550. /// @}
  551. /// \name Construction
  552. /// @{
  553. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  554. # if defined(STLSOFT_COMPILER_IS_DMC)
  555. public:
  556. # else /* ? compiler */
  557. private:
  558. # endif /* compiler */
  559. method_property_set()
  560. {}
  561. private:
  562. ss_explicit_k method_property_set(reference_type value)
  563. : m_value(value)
  564. {}
  565. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  566. private:
  567. typedef member_pointer_type PFnSet;
  568. private:
  569. ss_explicit_k method_property_set(void (C::*pfn)(reference_type ))
  570. {
  571. PFnSet f(pfn);
  572. }
  573. method_property_set(void (C::*pfn)(reference_type ), reference_type value)
  574. : m_value(value)
  575. {
  576. PFnSet f(pfn);
  577. }
  578. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  579. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
  580. /// @}
  581. /// \name Accessors
  582. /// @{
  583. public:
  584. /// Provides write-only access to the property
  585. class_type& operator =(reference_type value)
  586. {
  587. ss_ptrdiff_t offset = (*PFnOff)();
  588. container_type *pC = (container_type*)((ss_byte_t*)this - offset);
  589. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  590. (pC->*PFnSet)(value);
  591. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  592. PFnSet::set(pC, &value);
  593. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  594. return *this;
  595. }
  596. /// @}
  597. /// \name Members
  598. /// @{
  599. private:
  600. value_type m_value;
  601. /// @}
  602. };
  603. /** \brief This class provides method-based read/write property access
  604. *
  605. * \ingroup group__library__properties
  606. *
  607. * The containing class defines get and set methods. It also defines a static
  608. * method that contains the offset of the given property from within the container.
  609. * Then the template is parameterised with the value type, the set reference type,
  610. * the get reference type, the container type, the member functions and the offset
  611. * function.
  612. */
  613. template< ss_typename_param_k V /* The actual property value type */
  614. , ss_typename_param_k RG /* The get reference type */
  615. , ss_typename_param_k RS /* The set reference type */
  616. , ss_typename_param_k C /* The enclosing class */
  617. , ss_ptrdiff_t (*PFnOff)() /* Pointer to function providing offset of property within container */
  618. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  619. , RG (C::*PFnGet)() const /* Pointer to a const member function returning R */
  620. , void (C::*PFnSet)(RS) /* Pointer to a member function taking R */
  621. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  622. >
  623. class method_property_getset
  624. : public internal_property<1, 1, 0>
  625. {
  626. /// \name Member Types
  627. /// @{
  628. private:
  629. typedef V value_type;
  630. typedef RG get_reference_type;
  631. typedef RS set_reference_type;
  632. typedef C container_type;
  633. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  634. typedef method_property_getset<V, RG, RS, C, PFnOff, PFnGet, PFnSet> class_type;
  635. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  636. typedef method_property_getset<V, RG, RS, C, PFnOff> class_type;
  637. typedef member_get_pointer<class_type, RG, C> get_member_pointer_type;
  638. typedef member_set_pointer<class_type, RS, C> set_member_pointer_type;
  639. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  640. /// @}
  641. /// \name Construction
  642. /// @{
  643. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  644. # if defined(STLSOFT_COMPILER_IS_DMC)
  645. public:
  646. # else /* ? compiler */
  647. private:
  648. # endif /* compiler */
  649. method_property_getset()
  650. {}
  651. private:
  652. ss_explicit_k method_property_getset(set_reference_type value)
  653. : m_value(value)
  654. {}
  655. #else
  656. private:
  657. typedef get_member_pointer_type PFnGet;
  658. typedef set_member_pointer_type PFnSet;
  659. private:
  660. method_property_getset(get_reference_type (C::*pfnGet)() const, void (C::*pfnSet)(set_reference_type ))
  661. {
  662. PFnGet fg(pfnGet);
  663. PFnSet fs(pfnSet);
  664. }
  665. method_property_getset(get_reference_type (C::*pfnGet)() const, void (C::*pfnSet)(set_reference_type ), set_reference_type value)
  666. : m_value(value)
  667. {
  668. PFnGet fg(pfnGet);
  669. PFnSet fs(pfnSet);
  670. }
  671. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  672. /// @}
  673. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
  674. /// \name Accessors
  675. /// @{
  676. public:
  677. /// Provides read-only access to the property
  678. operator get_reference_type () const
  679. {
  680. ss_ptrdiff_t offset = (*PFnOff)();
  681. container_type *pC = (container_type*)((ss_byte_t*)this - offset);
  682. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  683. return (pC->*PFnGet)();
  684. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  685. return PFnGet::get(pC);
  686. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  687. }
  688. /// Provides write-only access to the property
  689. class_type& operator =(set_reference_type value)
  690. {
  691. ss_ptrdiff_t offset = (*PFnOff)();
  692. container_type *pC = (container_type*)((ss_byte_t*)this - offset);
  693. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  694. (pC->*PFnSet)(value);
  695. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  696. PFnSet::set(pC, &value);
  697. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  698. return *this;
  699. }
  700. /// @}
  701. /// \name Members
  702. /// @{
  703. private:
  704. value_type m_value;
  705. /// @}
  706. };
  707. /* /////////////////////////////////////////////////////////////////////////
  708. * External method property classes
  709. */
  710. /**\brief This class provides indirect method-based read-only property access
  711. *
  712. * \ingroup group__library__properties
  713. *
  714. * The containing class defines a get method. It also defines a static method
  715. * that contains the offset of the given property from within the container.
  716. * Then the template is parameterised with the the reference type, the
  717. * container type, the member function and the offset function.
  718. */
  719. template< ss_typename_param_k R /* The reference type */
  720. , ss_typename_param_k C /* The enclosing class */
  721. , ss_ptrdiff_t (*PFnOff)() /* Pointer to function providing offset of property within container */
  722. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  723. , R (C::*PFnGet)() const /* Pointer to a const member function returning R */
  724. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  725. >
  726. class method_property_get_external
  727. : public external_property<1, 0, 0>
  728. {
  729. /// \name Member Types
  730. /// @{
  731. public:
  732. typedef R reference_type;
  733. typedef C container_type;
  734. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  735. typedef method_property_get_external<R, C, PFnOff, PFnGet> class_type;
  736. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  737. typedef method_property_get_external<R, C, PFnOff> class_type;
  738. typedef member_get_pointer<class_type, R, C> member_pointer_type;
  739. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  740. #ifndef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  741. /// @}
  742. /// \name Construction
  743. /// @{
  744. private:
  745. method_property_get_external(R (C::*pfn)() const)
  746. {
  747. PFnGet f(pfn);
  748. }
  749. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
  750. private:
  751. typedef member_pointer_type PFnGet;
  752. #endif /* !STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  753. /// @}
  754. /// \name Operators
  755. /// @{
  756. public:
  757. /// Provides read-only access to the property
  758. operator reference_type () const
  759. {
  760. ss_ptrdiff_t offset = (*PFnOff)();
  761. container_type *pC = (container_type*)((ss_byte_t*)this - offset);
  762. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  763. return (pC->*PFnGet)();
  764. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  765. return PFnGet::get(pC);
  766. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  767. }
  768. /// @}
  769. /// \name Not to be implemented
  770. /// @{
  771. private:
  772. /// This method is hidden in order to prevent users of this class from
  773. /// becoming familiar with using operator = on the property instances
  774. /// from within the containing class, since doing so with
  775. /// method_property_getset<> would result in an infinite loop.
  776. class_type& operator =(reference_type value);
  777. /// @}
  778. };
  779. /** \brief This class provides indirect method-based write-only property access
  780. *
  781. * \ingroup group__library__properties
  782. *
  783. * The containing class defines a set method. It also defines a static method
  784. * that contains the offset of the given property from within the container.
  785. * Then the template is parameterised with the reference type, the container
  786. * type, the member function and the offset function.
  787. */
  788. template< ss_typename_param_k R /* The reference type */
  789. , ss_typename_param_k C /* The enclosing class */
  790. , ss_ptrdiff_t (*PFnOff)() /* Pointer to function providing offset of property within container */
  791. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  792. , void (C::*PFnSet)(R ) /* Pointer to a member function taking R */
  793. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  794. >
  795. class method_property_set_external
  796. : public external_property<0, 1, 0>
  797. {
  798. /// \name Member Types
  799. /// @{
  800. public:
  801. typedef R reference_type;
  802. typedef C container_type;
  803. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  804. typedef method_property_set_external<R, C, PFnOff, PFnSet> class_type;
  805. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  806. typedef method_property_set_external<R, C, PFnOff> class_type;
  807. typedef member_set_pointer<class_type, R, C> member_pointer_type;
  808. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  809. #ifndef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  810. /// @}
  811. /// \name Construction
  812. /// @{
  813. private:
  814. method_property_set_external(void (C::*pfn)(R ))
  815. {
  816. PFnSet f(pfn);
  817. }
  818. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
  819. private:
  820. typedef member_pointer_type PFnSet;
  821. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  822. /// @}
  823. /// \name Operators
  824. /// @{
  825. public:
  826. /// Provides read-only access to the property
  827. method_property_set_external& operator =(reference_type value)
  828. {
  829. ss_ptrdiff_t offset = (*PFnOff)();
  830. container_type *pC = (container_type*)((ss_byte_t*)this - offset);
  831. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  832. (pC->*PFnSet)(value);
  833. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  834. PFnSet::set(pC, &value);
  835. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  836. return *this;
  837. }
  838. /// @}
  839. };
  840. /** \brief This class provides indirect method-based read/write property access
  841. *
  842. * \ingroup group__library__properties
  843. *
  844. * The containing class defines get and set methods. It also defines a static
  845. * method that contains the offset of the given property from within the container.
  846. * Then the template is parameterised with the set reference type, the get
  847. * reference type, the container type, the member functions and the offset function.
  848. */
  849. template< ss_typename_param_k RG /* The reference type */
  850. , ss_typename_param_k RS /* The reference type */
  851. , ss_typename_param_k C /* The enclosing class */
  852. , ss_ptrdiff_t (*PFnOff)() /* Pointer to function providing offset of property within container */
  853. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  854. , RG (C::*PFnGet)() const /* Pointer to a const member function returning R */
  855. , void (C::*PFnSet)(RS ) /* Pointer to a member function taking R */
  856. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  857. >
  858. class method_property_getset_external
  859. : public external_property<1, 1, 0>
  860. {
  861. /// \name Member Types
  862. /// @{
  863. public:
  864. typedef RG get_reference_type;
  865. typedef RS set_reference_type;
  866. typedef C container_type;
  867. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  868. typedef method_property_getset_external<RG, RS, C, PFnOff, PFnGet, PFnSet> class_type;
  869. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  870. typedef method_property_getset_external<RG, RS, C, PFnOff> class_type;
  871. typedef member_get_pointer<class_type, RG, C> get_member_pointer_type;
  872. typedef member_set_pointer<class_type, RS, C> set_member_pointer_type;
  873. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  874. #ifndef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  875. /// @}
  876. /// \name Construction
  877. /// @{
  878. private:
  879. method_property_getset_external(get_reference_type (C::*pfnGet)() const, void (C::*pfnSet)(set_reference_type ))
  880. {
  881. PFnGet fg(pfnGet);
  882. PFnSet fs(pfnSet);
  883. }
  884. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
  885. private:
  886. typedef get_member_pointer_type PFnGet;
  887. typedef set_member_pointer_type PFnSet;
  888. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  889. /// @}
  890. /// \name Operators
  891. /// @{
  892. public:
  893. /// Provides read-only access to the property
  894. operator get_reference_type () const
  895. {
  896. ss_ptrdiff_t offset = (*PFnOff)();
  897. container_type *pC = (container_type*)((ss_byte_t*)this - offset);
  898. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  899. return (pC->*PFnGet)();
  900. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  901. return PFnGet::get(pC);
  902. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  903. }
  904. /// Provides read-only access to the property
  905. class_type& operator =(set_reference_type value)
  906. {
  907. ss_ptrdiff_t offset = (*PFnOff)();
  908. container_type *pC = (container_type*)((ss_byte_t*)this - offset);
  909. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  910. (pC->*PFnSet)(value);
  911. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  912. PFnSet::set(pC, &value);
  913. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  914. return *this;
  915. }
  916. /// @}
  917. };
  918. /* /////////////////////////////////////////////////////////////////////////
  919. * Internal static method property classes
  920. */
  921. /** \brief Implements static read-only Method Property
  922. *
  923. * \ingroup group__library__properties
  924. */
  925. template< ss_typename_param_k V
  926. , ss_typename_param_k R /* The reference type */
  927. , ss_typename_param_k C
  928. , R (*PFn)(void)
  929. >
  930. class static_method_property_get
  931. : public internal_property<1, 0, 1>
  932. {
  933. /// \name Member Types
  934. /// @{
  935. public:
  936. typedef V value_type;
  937. typedef R reference_type;
  938. typedef C container_type;
  939. typedef static_method_property_get<V, R, C, PFn> class_type;
  940. /// @}
  941. /// \name Construction
  942. /// @{
  943. public:
  944. static_method_property_get()
  945. {}
  946. ss_explicit_k static_method_property_get(reference_type value)
  947. : m_value(value)
  948. {}
  949. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
  950. /// @}
  951. /// \name Operators
  952. /// @{
  953. public:
  954. operator reference_type() const
  955. {
  956. return (*PFn)();
  957. }
  958. /// @}
  959. /// \name Members
  960. /// @{
  961. private:
  962. value_type m_value;
  963. /// @}
  964. /// \name Not to be implemented
  965. /// @{
  966. private:
  967. /// This method is hidden in order to prevent users of this class from
  968. /// becoming familiar with using operator = on the property instances
  969. /// from within the containing class, since doing so with
  970. /// method_property_getset<> would result in an infinite loop.
  971. class_type& operator =(reference_type value);
  972. /// @}
  973. };
  974. /** \brief Implements static write-only Method Property
  975. *
  976. * \ingroup group__library__properties
  977. */
  978. template< ss_typename_param_k V
  979. , ss_typename_param_k R /* The reference type */
  980. , ss_typename_param_k C
  981. , void (*PFn)(R )
  982. >
  983. class static_method_property_set
  984. : public internal_property<0, 1, 1>
  985. {
  986. /// \name Member Types
  987. /// @{
  988. public:
  989. typedef V value_type;
  990. typedef R reference_type;
  991. typedef C container_type;
  992. typedef static_method_property_set<V, R, C, PFn> class_type;
  993. /// @}
  994. /// \name Construction
  995. /// @{
  996. public:
  997. static_method_property_set()
  998. {}
  999. ss_explicit_k static_method_property_set(reference_type value)
  1000. : m_value(value)
  1001. {}
  1002. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
  1003. /// @}
  1004. /// \name Operators
  1005. /// @{
  1006. public:
  1007. static_method_property_set& operator =(reference_type value)
  1008. {
  1009. (*PFn)(value);
  1010. return *this;
  1011. }
  1012. /// @}
  1013. /// \name Members
  1014. /// @{
  1015. private:
  1016. value_type m_value;
  1017. /// @}
  1018. };
  1019. /** \brief Implements static read-write Method Property
  1020. *
  1021. * \ingroup group__library__properties
  1022. */
  1023. template< ss_typename_param_k V
  1024. , ss_typename_param_k RG
  1025. , ss_typename_param_k RS
  1026. , ss_typename_param_k C
  1027. , RG (*PFnGet)(void)
  1028. , void (*PFnSet)(RS )
  1029. >
  1030. class static_method_property_getset
  1031. : public internal_property<1, 1, 1>
  1032. {
  1033. /// \name Member Types
  1034. /// @{
  1035. public:
  1036. typedef V value_type;
  1037. typedef RG get_reference_type;
  1038. typedef RS set_reference_type;
  1039. typedef C container_type;
  1040. typedef static_method_property_getset<V, RG, RS, C, PFnGet, PFnSet> class_type;
  1041. STLSOFT_DECLARE_TEMPLATE_PARAM_AS_FRIEND(C);
  1042. /// @}
  1043. /// \name Construction
  1044. /// @{
  1045. public:
  1046. static_method_property_getset()
  1047. {}
  1048. ss_explicit_k static_method_property_getset(set_reference_type value)
  1049. : m_value(value)
  1050. {}
  1051. /// @}
  1052. /// \name Operators
  1053. /// @{
  1054. public:
  1055. operator get_reference_type() const
  1056. {
  1057. return (*PFnGet)();
  1058. }
  1059. static_method_property_getset& operator =(set_reference_type value)
  1060. {
  1061. (*PFnSet)(value);
  1062. return *this;
  1063. }
  1064. /// @}
  1065. /// \name Members
  1066. /// @{
  1067. private:
  1068. value_type m_value;
  1069. /// @}
  1070. };
  1071. /* /////////////////////////////////////////////////////////////////////////
  1072. * External static method property classes
  1073. */
  1074. /** \brief Implements External static read-only Method Property
  1075. *
  1076. * \ingroup group__library__properties
  1077. */
  1078. template< ss_typename_param_k R /* The reference type */
  1079. , R (*PFn)(void)
  1080. >
  1081. class static_method_property_get_external
  1082. : public external_property<1, 0, 1>
  1083. {
  1084. /// \name Member Types
  1085. /// @{
  1086. public:
  1087. typedef R reference_type;
  1088. typedef static_method_property_get_external<R, PFn> class_type;
  1089. /// @}
  1090. /// \name Operators
  1091. /// @{
  1092. public:
  1093. #if !defined(STLSOFT_COMPILER_IS_MSVC) || \
  1094. _MSC_VER > 1200
  1095. operator reference_type() const
  1096. {
  1097. return (*PFn)();
  1098. }
  1099. #else /* ? compiler */
  1100. operator R() const
  1101. {
  1102. R (*pfn)() = PFn;
  1103. return (*pfn)();
  1104. }
  1105. #endif /* compiler */
  1106. /// @}
  1107. /// \name Not to be implemented
  1108. /// @{
  1109. private:
  1110. /// This method is hidden in order to prevent users of this class from
  1111. /// becoming familiar with using operator = on the property instances
  1112. /// from within the containing class, since doing so with
  1113. /// method_property_getset<> would result in an infinite loop.
  1114. class_type& operator =(reference_type value);
  1115. /// @}
  1116. };
  1117. /** \brief Implements External static write-only Method Property.
  1118. */
  1119. template< ss_typename_param_k R /* The reference type */
  1120. , void (*PFn)(R )
  1121. >
  1122. class static_method_property_set_external
  1123. : public external_property<0, 1, 1>
  1124. {
  1125. /// \name Member Types
  1126. /// @{
  1127. public:
  1128. typedef R reference_type;
  1129. typedef static_method_property_set_external<R, PFn> class_type;
  1130. /// @}
  1131. /// \name Operators
  1132. /// @{
  1133. public:
  1134. static_method_property_set_external& operator =(reference_type value)
  1135. {
  1136. (*PFn)(value);
  1137. return *this;
  1138. }
  1139. /// @}
  1140. };
  1141. /** \brief Implements External static read-write Method Property
  1142. *
  1143. * \ingroup group__library__properties
  1144. */
  1145. template< ss_typename_param_k RG
  1146. , ss_typename_param_k RS
  1147. , RG (*PFnGet)(void)
  1148. , void (*PFnSet)(RS )
  1149. >
  1150. class static_method_property_getset_external
  1151. : public external_property<1, 1, 1>
  1152. {
  1153. /// \name Member Types
  1154. /// @{
  1155. public:
  1156. typedef RG get_reference_type;
  1157. typedef RS set_reference_type;
  1158. typedef static_method_property_getset_external<RG, RS, PFnGet, PFnSet> class_type;
  1159. /// @}
  1160. /// \name Operators
  1161. /// @{
  1162. public:
  1163. operator get_reference_type() const
  1164. {
  1165. return (*PFnGet)();
  1166. }
  1167. static_method_property_getset_external& operator =(set_reference_type value)
  1168. {
  1169. (*PFnSet)(value);
  1170. return *this;
  1171. }
  1172. /// @}
  1173. };
  1174. /* /////////////////////////////////////////////////////////////////////////
  1175. * IOStream compatibility
  1176. */
  1177. // method_property_getset
  1178. template< ss_typename_param_k V
  1179. , ss_typename_param_k RG
  1180. , ss_typename_param_k RS
  1181. , ss_typename_param_k C
  1182. , ss_ptrdiff_t (*PFnOff)()
  1183. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  1184. , RG (C::*PFnGet)() const
  1185. , void (C::*PFnSet)(RS)
  1186. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1187. , ss_typename_param_k S
  1188. >
  1189. inline S& operator <<( S& s
  1190. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  1191. , method_property_getset<V, RG, RS, C, PFnOff, PFnGet, PFnSet> const& prop)
  1192. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1193. , method_property_getset<V, RG, RS, C, PFnOff> const& prop)
  1194. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1195. {
  1196. s << static_cast<RG>(prop);
  1197. return s;
  1198. }
  1199. // method_property_get
  1200. template< ss_typename_param_k V
  1201. , ss_typename_param_k R
  1202. , ss_typename_param_k C
  1203. , ss_ptrdiff_t (*PFnOff)()
  1204. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  1205. , R (C::*PFnGet)() const
  1206. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1207. , ss_typename_param_k S
  1208. >
  1209. inline S& operator <<( S& s
  1210. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  1211. , method_property_get<V, R, C, PFnOff, PFnGet> const& prop)
  1212. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1213. , method_property_get<V, R, C, PFnOff> const& prop)
  1214. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1215. {
  1216. s << static_cast<R>(prop);
  1217. return s;
  1218. }
  1219. // method_property_getset_external
  1220. template< ss_typename_param_k RG
  1221. , ss_typename_param_k RS
  1222. , ss_typename_param_k C
  1223. , ss_ptrdiff_t (*PFnOff)()
  1224. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  1225. , RG (C::*PFnGet)() const
  1226. , void (C::*PFnSet)(RS )
  1227. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1228. , ss_typename_param_k S
  1229. >
  1230. inline S& operator <<( S& s
  1231. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  1232. , method_property_getset_external<RG, RS, C, PFnOff, PFnGet, PFnSet> const& prop)
  1233. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1234. , method_property_getset_external<RG, RS, C, PFnOff> const& prop)
  1235. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1236. {
  1237. s << static_cast<RG>(prop);
  1238. return s;
  1239. }
  1240. // method_property_get_external
  1241. template< ss_typename_param_k R
  1242. , ss_typename_param_k C
  1243. , ss_ptrdiff_t (*PFnOff)()
  1244. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  1245. , R (C::*PFnGet)() const
  1246. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1247. , ss_typename_param_k S
  1248. >
  1249. inline S& operator <<( S& s
  1250. #ifdef STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT
  1251. , method_property_get_external<R, C, PFnOff, PFnGet> const& prop)
  1252. #else /* ? STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1253. , method_property_get_external<R, C, PFnOff> const& prop)
  1254. #endif /* STLSOFT_CF_MEM_FUNC_AS_TEMPLATE_PARAM_SUPPORT */
  1255. {
  1256. s << static_cast<R>(prop);
  1257. return s;
  1258. }
  1259. /* ////////////////////////////////////////////////////////////////////// */
  1260. #ifndef _STLSOFT_NO_NAMESPACE
  1261. } // namespace stlsoft
  1262. #endif /* _STLSOFT_NO_NAMESPACE */
  1263. /* ////////////////////////////////////////////////////////////////////// */
  1264. #endif /* !STLSOFT_INCL_STLSOFT_PROPERTIES_HPP_METHOD_PROPERTIES */
  1265. /* ///////////////////////////// end of file //////////////////////////// */