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.

513 lines
21 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: rangelib/sequence_range.hpp
  3. *
  4. * Purpose: Sequence container range adaptor.
  5. *
  6. * Created: 4th November 2003
  7. * Updated: 10th August 2009
  8. *
  9. * Thanks: To Luoyi (whom I could not thank by email), for pointing out
  10. * some gaps with the sequence_range
  11. *
  12. * Home: http://stlsoft.org/
  13. *
  14. * Copyright (c) 2003-2009, Matthew Wilson and Synesis Software
  15. * All rights reserved.
  16. *
  17. * Redistribution and use in source and binary forms, with or without
  18. * modification, are permitted provided that the following conditions are met:
  19. *
  20. * - Redistributions of source code must retain the above copyright notice, this
  21. * list of conditions and the following disclaimer.
  22. * - Redistributions in binary form must reproduce the above copyright notice,
  23. * this list of conditions and the following disclaimer in the documentation
  24. * and/or other materials provided with the distribution.
  25. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  26. * any contributors may be used to endorse or promote products derived from
  27. * this software without specific prior written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  30. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  31. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  32. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  33. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  34. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  35. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  36. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  37. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  38. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  39. * POSSIBILITY OF SUCH DAMAGE.
  40. *
  41. * ////////////////////////////////////////////////////////////////////// */
  42. /** \file rangelib/sequence_range.hpp Sequence container range adaptor */
  43. #ifndef RANGELIB_INCL_RANGELIB_HPP_SEQUENCE_RANGE
  44. #define RANGELIB_INCL_RANGELIB_HPP_SEQUENCE_RANGE
  45. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  46. # define RANGELIB_VER_RANGELIB_HPP_SEQUENCE_RANGE_MAJOR 2
  47. # define RANGELIB_VER_RANGELIB_HPP_SEQUENCE_RANGE_MINOR 12
  48. # define RANGELIB_VER_RANGELIB_HPP_SEQUENCE_RANGE_REVISION 2
  49. # define RANGELIB_VER_RANGELIB_HPP_SEQUENCE_RANGE_EDIT 62
  50. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  51. /* /////////////////////////////////////////////////////////////////////////
  52. * Auto-generation and compatibility
  53. */
  54. /*
  55. [Incompatibilies-start]
  56. STLSOFT_COMPILER_IS_DMC:
  57. STLSOFT_COMPILER_IS_MSVC: _MSC_VER < 1200
  58. STLSOFT_COMPILER_IS_MWERKS: (__MWERKS__ & 0xFF00) < 0x3000
  59. [Incompatibilies-end]
  60. */
  61. /* /////////////////////////////////////////////////////////////////////////
  62. * Includes
  63. */
  64. #ifndef RANGELIB_INCL_RANGELIB_HPP_RANGELIB
  65. # include <rangelib/rangelib.hpp>
  66. #endif /* !RANGELIB_INCL_RANGELIB_HPP_RANGELIB */
  67. #ifndef RANGELIB_INCL_RANGELIB_HPP_RANGE_CATEGORIES
  68. # include <rangelib/range_categories.hpp>
  69. #endif /* !RANGELIB_INCL_RANGELIB_HPP_RANGE_CATEGORIES */
  70. #ifndef RANGELIB_INCL_RANGELIB_HPP_OPERATOR_ADAPTORS
  71. # include <rangelib/operator_adaptors.hpp>
  72. #endif /* !RANGELIB_INCL_RANGELIB_HPP_OPERATOR_ADAPTORS */
  73. #ifndef STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES
  74. # include <stlsoft/meta/capabilities.hpp>
  75. #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_CAPABILITIES */
  76. #ifndef STLSOFT_INCL_STLSOFT_META_HPP_IS_CONST_TYPE
  77. # include <stlsoft/meta/is_const_type.hpp>
  78. #endif /* !STLSOFT_INCL_STLSOFT_META_HPP_IS_CONST_TYPE */
  79. #ifdef STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED
  80. # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_DIFFERENCE_TYPE
  81. # include <stlsoft/meta/typefixer/difference_type.hpp>
  82. # endif /* !STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_DIFFERENCE_TYPE */
  83. # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_REFERENCE
  84. # include <stlsoft/meta/typefixer/reference.hpp>
  85. # endif /* !STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_REFERENCE */
  86. # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_ITERATOR
  87. # include <stlsoft/meta/typefixer/iterator.hpp>
  88. # endif /* !STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_ITERATOR */
  89. # ifndef STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_POINTER
  90. # include <stlsoft/meta/typefixer/pointer.hpp>
  91. # endif /* !STLSOFT_INCL_STLSOFT_META_TYPEFIXER_HPP_POINTER */
  92. # ifndef STLSOFT_INCL_STLSOFT_META_HPP_MEMBER_TRAITS
  93. # include <stlsoft/meta/member_traits.hpp>
  94. # endif /* !STLSOFT_INCL_STLSOFT_META_HPP_MEMBER_TRAITS */
  95. #endif /* STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED */
  96. #ifdef STLSOFT_UNITTEST
  97. # include <algorithm>
  98. # include <deque>
  99. # include <list>
  100. # include <numeric>
  101. # include <vector>
  102. #endif /* STLSOFT_UNITTEST */
  103. /* /////////////////////////////////////////////////////////////////////////
  104. * Namespace
  105. */
  106. #ifndef RANGELIB_NO_NAMESPACE
  107. # if defined(_STLSOFT_NO_NAMESPACE) || \
  108. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  109. /* There is no stlsoft namespace, so must define ::rangelib */
  110. namespace rangelib
  111. {
  112. # else
  113. /* Define stlsoft::rangelib_project */
  114. namespace stlsoft
  115. {
  116. namespace rangelib_project
  117. {
  118. # endif /* _STLSOFT_NO_NAMESPACE */
  119. #endif /* !RANGELIB_NO_NAMESPACE */
  120. /* /////////////////////////////////////////////////////////////////////////
  121. * Classes
  122. */
  123. #if defined(STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED)
  124. /** \brief Traits class for determining the attributes of range-adapted sequence container types
  125. *
  126. * \ingroup group__library__rangelib
  127. */
  128. template< ss_typename_param_k S
  129. , bool B_CONST = false
  130. >
  131. struct sequence_range_traits
  132. {
  133. private:
  134. /// Indicates whether the parameterising sequence type has a \c reference member
  135. ///
  136. /// \note We can't use the type fixer in a fully correct way here, because
  137. /// most compilers do not detect reference / const_reference members, so we
  138. /// take a guess and use the presence/absence of the iterator membertype as
  139. /// the sign of the presence of the reference member type.
  140. #if defined(STLSOFT_COMPILER_IS_MWERKS)
  141. enum { HAS_MEMBER_REFERENCE = 0 != member_traits<S>::has_member_reference };
  142. enum { HAS_MEMBER_CONST_REFERENCE = 0 != member_traits<S>::has_member_const_reference };
  143. #else /* ? compiler */
  144. enum { HAS_MEMBER_REFERENCE = 0 != member_traits<S>::has_member_iterator };
  145. enum { HAS_MEMBER_CONST_REFERENCE = 0 != member_traits<S>::has_member_const_iterator };
  146. #endif /* compiler */
  147. enum { HAS_MEMBER_ITERATOR = 0 != member_traits<S>::has_member_iterator }; // Need to do these as member enums, otherwise GCC2.95 cries a river
  148. enum { HAS_MEMBER_CONST_ITERATOR = 0 != member_traits<S>::has_member_const_iterator }; // Need to do these as member enums, otherwise GCC2.95 cries a river
  149. enum { HAS_MEMBER_DIFFERENCE_TYPE = 0 != member_traits<S>::has_member_difference_type }; // Need to do these as member enums, otherwise GCC2.95 cries a river
  150. enum { HAS_MEMBER_POINTER = 0 != member_traits<S>::has_member_pointer };
  151. enum { HAS_MEMBER_CONST_POINTER = 0 != member_traits<S>::has_member_const_pointer };
  152. public:
  153. /// The sequence type
  154. typedef S sequence_type;
  155. /// The sequence reference type
  156. typedef S& sequence_reference_type;
  157. /// The value type
  158. typedef ss_typename_type_k sequence_type::value_type value_type;
  159. /// The mutating (non-const) iterator type
  160. typedef ss_typename_type_k select_first_type_if<ss_typename_type_k ::stlsoft::typefixer::fixer_iterator<S, HAS_MEMBER_ITERATOR>::iterator
  161. , ss_typename_type_k ::stlsoft::typefixer::fixer_const_iterator<S, HAS_MEMBER_CONST_ITERATOR>::const_iterator
  162. , HAS_MEMBER_ITERATOR
  163. >::type iterator;
  164. /// The non-mutating (const) iterator type
  165. typedef ss_typename_type_k ::stlsoft::typefixer::fixer_const_iterator<S, HAS_MEMBER_CONST_ITERATOR>::const_iterator
  166. const_iterator;
  167. /// The mutating (non-const) reference type
  168. typedef ss_typename_type_k select_first_type_if<ss_typename_type_k ::stlsoft::typefixer::fixer_reference<sequence_type, HAS_MEMBER_REFERENCE>::reference
  169. , ss_typename_type_k ::stlsoft::typefixer::fixer_const_reference<sequence_type, HAS_MEMBER_CONST_REFERENCE>::const_reference
  170. , HAS_MEMBER_REFERENCE
  171. >::type reference;
  172. /// The non-mutating (const) reference type
  173. typedef ss_typename_type_k ::stlsoft::typefixer::fixer_const_reference<S, HAS_MEMBER_CONST_REFERENCE>::const_reference
  174. const_reference;
  175. /// The mutating (non-const) pointer type
  176. typedef ss_typename_type_k select_first_type_if<ss_typename_type_k ::stlsoft::typefixer::fixer_pointer<sequence_type, HAS_MEMBER_POINTER>::pointer
  177. , ss_typename_type_k ::stlsoft::typefixer::fixer_const_pointer<sequence_type, HAS_MEMBER_CONST_POINTER>::const_pointer
  178. , HAS_MEMBER_POINTER
  179. >::type pointer;
  180. /// The non-mutating (const) pointer type
  181. typedef ss_typename_type_k ::stlsoft::typefixer::fixer_const_pointer<S, HAS_MEMBER_CONST_POINTER>::const_pointer
  182. const_pointer;
  183. /// The difference type
  184. typedef ss_typename_type_k select_first_type_if<ss_typename_type_k ::stlsoft::typefixer::fixer_difference_type<S, HAS_MEMBER_DIFFERENCE_TYPE>::difference_type
  185. , ss_ptrdiff_t
  186. , HAS_MEMBER_DIFFERENCE_TYPE
  187. >::type difference_type;
  188. /// The size type
  189. typedef ss_typename_type_k sequence_type::size_type size_type;
  190. };
  191. /** \brief Partial specialisation for constant sequences
  192. *
  193. * \ingroup group__library__rangelib
  194. */
  195. template< ss_typename_param_k S
  196. >
  197. struct sequence_range_traits<S, true>
  198. {
  199. public:
  200. /// The sequence type
  201. typedef S sequence_type;
  202. /// The sequence reference type
  203. typedef S& sequence_reference_type;
  204. /// The value type
  205. typedef ss_typename_type_k sequence_type::value_type value_type;
  206. /// The mutating (non-const) iterator type
  207. typedef ss_typename_type_k sequence_type::const_iterator iterator;
  208. /// The non-mutating (const) iterator type
  209. typedef ss_typename_type_k sequence_type::const_iterator const_iterator;
  210. /// The non-mutating (const) iterator type
  211. typedef ss_typename_type_k sequence_type::const_reference reference;
  212. /// The non-mutating (const) reference type
  213. typedef ss_typename_type_k sequence_type::const_reference const_reference;
  214. // TODO: Stick in the member-finder stuff here, so can assume ptrdiff_t if none found
  215. /// The difference type
  216. typedef ss_typename_type_k sequence_type::difference_type difference_type;
  217. /// The size type
  218. typedef ss_typename_type_k sequence_type::size_type size_type;
  219. };
  220. #else /* ? STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED */
  221. template< ss_typename_param_k S
  222. >
  223. struct sequence_range_traits
  224. {
  225. public:
  226. typedef S sequence_type;
  227. typedef S& sequence_reference_type;
  228. typedef ss_typename_type_k sequence_type::value_type value_type;
  229. typedef ss_typename_type_k sequence_type::iterator iterator;
  230. typedef ss_typename_type_k sequence_type::const_iterator const_iterator;
  231. typedef ss_typename_type_k sequence_type::reference reference;
  232. typedef ss_typename_type_k sequence_type::const_reference const_reference;
  233. typedef ss_typename_type_k sequence_type::difference_type difference_type;
  234. typedef ss_typename_type_k sequence_type::size_type size_type;
  235. };
  236. template< ss_typename_param_k S
  237. >
  238. struct const_sequence_range_traits
  239. {
  240. public:
  241. typedef S sequence_type;
  242. typedef S const& sequence_reference_type;
  243. typedef ss_typename_type_k sequence_type::value_type value_type;
  244. typedef ss_typename_type_k sequence_type::const_iterator iterator;
  245. typedef ss_typename_type_k sequence_type::const_iterator const_iterator;
  246. typedef ss_typename_type_k sequence_type::const_reference reference;
  247. typedef ss_typename_type_k sequence_type::const_reference const_reference;
  248. typedef ss_typename_type_k sequence_type::difference_type difference_type;
  249. typedef ss_typename_type_k sequence_type::size_type size_type;
  250. };
  251. template< ss_typename_param_k S
  252. >
  253. struct non_const_sequence_range_traits
  254. {
  255. public:
  256. typedef S sequence_type;
  257. typedef S const& sequence_reference_type;
  258. typedef ss_typename_type_k sequence_type::value_type value_type;
  259. typedef ss_typename_type_k sequence_type::iterator iterator;
  260. typedef ss_typename_type_k sequence_type::iterator const_iterator;
  261. typedef ss_typename_type_k sequence_type::reference reference;
  262. typedef ss_typename_type_k sequence_type::reference const_reference;
  263. typedef ss_typename_type_k sequence_type::difference_type difference_type;
  264. typedef ss_typename_type_k sequence_type::size_type size_type;
  265. };
  266. #endif /* STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED */
  267. /** \brief This class adapts an STL sequence instance into a Range
  268. *
  269. * \ingroup group__library__rangelib
  270. *
  271. * \param S The sequence class
  272. * \param T The sequence range traits, used to deduce the Range's iterator, const_iterator, reference, const_reference and value_type
  273. *
  274. * It is categoried as an Iterable Range
  275. *
  276. * It could be used as follows
  277. \code
  278. void dump_elements(std::vector<int> const& numbers)
  279. {
  280. for(sequence_range<std::vector<int> > r(numbers); r; ++r)
  281. {
  282. std::cout << &r; // Dump the current value to stdout
  283. }
  284. }
  285. \endcode
  286. */
  287. template< ss_typename_param_k S
  288. #if defined(STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED)
  289. , ss_typename_param_k T = sequence_range_traits<S, is_const_type<S>::value> // Determines whether the sequence is const
  290. #else /* ? STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED */
  291. , ss_typename_param_k T = const_sequence_range_traits<S> // Defaults to a const sequence
  292. #endif /* STLSOFT_CF_HAS_MEMBER_TYPE_SUPPORTED */
  293. >
  294. class sequence_range
  295. : public mutating_operator_adaptor<sequence_range<S, T>, T> // This provides the operator forms of the methods
  296. , public iterable_range_tag
  297. {
  298. public:
  299. /// The sequence type
  300. typedef S sequence_type;
  301. /// The traits type
  302. typedef T traits_type;
  303. /// The range category tag type
  304. typedef iterable_range_tag range_tag_type;
  305. /// The current instantiation of the type
  306. typedef sequence_range<S, T> class_type;
  307. /// The sequence reference type
  308. typedef ss_typename_type_k traits_type::sequence_reference_type sequence_reference_type;
  309. /// The value type
  310. typedef ss_typename_type_k traits_type::value_type value_type;
  311. /// The mutating (non-const) iterator type
  312. typedef ss_typename_type_k traits_type::iterator iterator;
  313. /// The non-mutating (const) iterator type
  314. typedef ss_typename_type_k traits_type::const_iterator const_iterator;
  315. /// The mutating (non-const) reference type
  316. typedef ss_typename_type_k traits_type::reference reference;
  317. /// The non-mutating (const) reference type
  318. typedef ss_typename_type_k traits_type::const_reference const_reference;
  319. /// The difference type
  320. typedef ss_typename_type_k traits_type::difference_type difference_type;
  321. /// The size type
  322. typedef ss_typename_type_k traits_type::size_type size_type;
  323. public:
  324. #if !defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) || \
  325. defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED) || \
  326. ( defined(STLSOFT_COMPILER_IS_MSVC) && \
  327. _MSC_VER == 1200)
  328. /// Constructor
  329. ///
  330. /// \param rhs The sequence which will be adapted to a range
  331. sequence_range(sequence_reference_type rhs) // The constness of this will require some thinking about. Maybe need sequence_range and const_sequence_range??
  332. : m_position(rhs.begin())
  333. , m_last(rhs.end())
  334. {}
  335. #endif /* !STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT || STLSOFT_CF_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED */
  336. #if defined(STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT) && \
  337. ( !defined(STLSOFT_COMPILER_IS_MSVC) || \
  338. _MSC_VER != 1200)
  339. /// Constructor
  340. ///
  341. /// \param rhs The sequence which will be adapted to a range
  342. template <ss_typename_param_k S1>
  343. sequence_range(S1& rhs)
  344. : m_position(rhs.begin())
  345. , m_last(rhs.end())
  346. {}
  347. #endif /* STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT */
  348. #ifdef STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT
  349. /// Constructs a range over an array
  350. template <ss_size_t N>
  351. sequence_range(S (&ar)[N])
  352. : m_position(&ar[0])
  353. , m_last(&ar[N])
  354. {}
  355. #endif /* STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT */
  356. /// Constructs from an iterator
  357. ///
  358. /// \param position The start position of the range
  359. /// \param last The end position of the range
  360. sequence_range(iterator position, iterator last)
  361. : m_position(position)
  362. , m_last(last)
  363. {}
  364. /// Copy constructor
  365. ///
  366. /// \note This has to be provided, to avoid precipitating C4217 with Visual C++
  367. sequence_range(class_type const& rhs)
  368. : m_position(rhs.m_position)
  369. , m_last(rhs.m_last)
  370. {}
  371. /// Copy assignment operator
  372. ///
  373. /// \note This has to be provided, to avoid precipitating C4217 with Visual C++
  374. class_type& operator =(class_type const& rhs)
  375. {
  376. m_position = rhs.m_position;
  377. m_last = rhs.m_last;
  378. return *this;
  379. }
  380. /// \name Notional Range methods
  381. /// @{
  382. public:
  383. /// Indicates whether the range is open
  384. ss_bool_t is_open() const
  385. {
  386. return m_position != m_last;
  387. }
  388. /// Returns the current value in the range
  389. reference current()
  390. {
  391. STLSOFT_ASSERT(is_open());
  392. return *m_position;
  393. }
  394. /// Returns the current value in the range
  395. const_reference current() const
  396. {
  397. STLSOFT_ASSERT(is_open());
  398. return *m_position;
  399. }
  400. /// Advances the current position in the range
  401. class_type& advance()
  402. {
  403. STLSOFT_MESSAGE_ASSERT("Attempting to increment the range past its end point", is_open());
  404. ++m_position;
  405. return *this;
  406. }
  407. /// @}
  408. /// \name Iterable Range methods
  409. /// @{
  410. public:
  411. /// Returns an iterator to the current position of the range
  412. iterator begin()
  413. {
  414. return m_position;
  415. }
  416. /// Returns an iterator to the end of the range
  417. iterator end()
  418. {
  419. return m_last;
  420. }
  421. /// Returns an iterator to the current position of the range
  422. const_iterator begin() const
  423. {
  424. return m_position;
  425. }
  426. /// Returns an iterator to the end of the range
  427. const_iterator end() const
  428. {
  429. return m_last;
  430. }
  431. /// @}
  432. // Members
  433. private:
  434. iterator m_position;
  435. iterator m_last;
  436. };
  437. ////////////////////////////////////////////////////////////////////////////
  438. // Functions
  439. template<ss_typename_param_k S>
  440. #ifdef STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT
  441. inline sequence_range<S> make_sequence_range(S &s)
  442. #else /* ? STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
  443. inline sequence_range<S> make_sequence_range(S const& s)
  444. #endif /* STLSOFT_CF_TEMPLATE_PARTIAL_SPECIALISATION_SUPPORT */
  445. {
  446. return sequence_range<S>(s);
  447. }
  448. ////////////////////////////////////////////////////////////////////////////
  449. // Unit-testing
  450. #ifdef STLSOFT_UNITTEST
  451. # include "./unittest/sequence_range_unittest_.h"
  452. #endif /* STLSOFT_UNITTEST */
  453. /* ////////////////////////////////////////////////////////////////////// */
  454. #ifndef RANGELIB_NO_NAMESPACE
  455. # if defined(_STLSOFT_NO_NAMESPACE) || \
  456. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  457. } // namespace rangelib
  458. # else
  459. } // namespace rangelib_project
  460. } // namespace stlsoft
  461. # endif /* _STLSOFT_NO_NAMESPACE */
  462. #endif /* !RANGELIB_NO_NAMESPACE */
  463. /* ////////////////////////////////////////////////////////////////////// */
  464. #endif /* !RANGELIB_INCL_RANGELIB_HPP_SEQUENCE_RANGE */
  465. /* ///////////////////////////// end of file //////////////////////////// */