From c506d2537fda683486c882262210e7c87deaf7a2 Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sun, 26 Dec 2010 23:14:08 +0000 Subject: [PATCH] [boost][range] - Trac item 4226 - Implemented a safe_bool utility class that is intended to be refactored into a core area. Integrated this into iterator_range. [SVN r67463] --- include/boost/range/adaptor/strided.hpp | 4 -- include/boost/range/detail/safe_bool.hpp | 72 +++++++++++++++++++++ include/boost/range/iterator_range_core.hpp | 20 +++--- 3 files changed, 81 insertions(+), 15 deletions(-) create mode 100644 include/boost/range/detail/safe_bool.hpp diff --git a/include/boost/range/adaptor/strided.hpp b/include/boost/range/adaptor/strided.hpp index a391eef..abfad5e 100755 --- a/include/boost/range/adaptor/strided.hpp +++ b/include/boost/range/adaptor/strided.hpp @@ -15,7 +15,6 @@ #include #include #include -#include namespace boost { @@ -206,14 +205,11 @@ namespace boost private: void increment() { - std::cout << "increment() - before = " << (this->base_reference() - m_first); base_iterator& it = this->base_reference(); if ((m_last - it) > m_stride) it += m_stride; else it = m_last; - - std::cout << " after = " << (this->base_reference() - m_first) << std::endl; } void decrement() diff --git a/include/boost/range/detail/safe_bool.hpp b/include/boost/range/detail/safe_bool.hpp new file mode 100644 index 0000000..182e510 --- /dev/null +++ b/include/boost/range/detail/safe_bool.hpp @@ -0,0 +1,72 @@ +// This header intentionally has no include guards. +// +// Copyright (c) 2010 Neil Groves +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// This code utilises the experience gained during the evolution of +// +#ifndef BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP +#define BOOST_RANGE_SAFE_BOOL_INCLUDED_HPP + +#include +#include + +namespace boost +{ + namespace range_detail + { + +template +class safe_bool +{ +public: + typedef safe_bool this_type; + +#if (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570)) || defined(__CINT_) + typedef bool unspecified_bool_type; + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr) + { + return x; + } +#elif defined(_MANAGED) + static void unspecified_bool(this_type***) + { + } + typedef void(*unspecified_bool_type)(this_type***); + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr) + { + return x ? unspecified_bool : 0; + } +#elif \ + ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \ + ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \ + ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) ) + + typedef bool (this_type::*unspecified_bool_type)() const; + + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr) + { + return x ? &this_type::detail_safe_bool_member_fn : 0; + } +private: + bool detail_safe_bool_member_fn() const { return false; } +#else + typedef DataMemberPtr unspecified_bool_type; + static unspecified_bool_type to_unspecified_bool(const bool x, DataMemberPtr p) + { + return x ? p : 0; + } +#endif +private: + safe_bool(); + safe_bool(const safe_bool&); + void operator=(const safe_bool&); + ~safe_bool(); +}; + + } // namespace range_detail +} // namespace boost + +#endif // include guard diff --git a/include/boost/range/iterator_range_core.hpp b/include/boost/range/iterator_range_core.hpp index ab1e80e..7664c2e 100755 --- a/include/boost/range/iterator_range_core.hpp +++ b/include/boost/range/iterator_range_core.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -81,7 +82,6 @@ namespace boost struct range_tag { }; struct const_range_tag { }; - } // iterator range template class -----------------------------------------// @@ -106,13 +106,14 @@ namespace boost template class iterator_range { + typedef range_detail::safe_bool< IteratorT iterator_range::* > safe_bool_t; protected: // Used by sub_range //! implementation class typedef iterator_range_detail::iterator_range_impl impl; public: - //! this type typedef iterator_range type; + typedef BOOST_DEDUCED_TYPENAME safe_bool_t::unspecified_bool_type unspecified_bool_type; //BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(value_type); //! Encapsulated value type @@ -238,18 +239,15 @@ namespace boost return m_Begin == m_End; } -#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) - operator bool() const - { - return !empty(); - } -#else - typedef iterator (iterator_range::*unspecified_bool_type) () const; operator unspecified_bool_type() const { - return empty() ? 0: &iterator_range::end; + return safe_bool_t::to_unspecified_bool(m_Begin != m_End, &iterator_range::m_Begin); + } + + bool operator!() const + { + return empty(); } -#endif bool equal( const iterator_range& r ) const {