summaryrefslogtreecommitdiff
path: root/boost/poly_collection/detail/any_iterator.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/poly_collection/detail/any_iterator.hpp')
-rw-r--r--boost/poly_collection/detail/any_iterator.hpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/boost/poly_collection/detail/any_iterator.hpp b/boost/poly_collection/detail/any_iterator.hpp
new file mode 100644
index 0000000000..a51ae86b61
--- /dev/null
+++ b/boost/poly_collection/detail/any_iterator.hpp
@@ -0,0 +1,92 @@
+/* Copyright 2016 Joaquin M Lopez Munoz.
+ * 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)
+ *
+ * See http://www.boost.org/libs/poly_collection for library home page.
+ */
+
+#ifndef BOOST_POLY_COLLECTION_DETAIL_ANY_ITERATOR_HPP
+#define BOOST_POLY_COLLECTION_DETAIL_ANY_ITERATOR_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/type_erasure/any_cast.hpp>
+#include <type_traits>
+#include <utility>
+
+namespace boost{
+
+namespace poly_collection{
+
+namespace detail{
+
+/* type_erasure::any<Concept>* adaptor convertible to pointer to wrapped
+ * entity.
+ */
+
+template<typename Any>
+class any_iterator:public boost::iterator_adaptor<any_iterator<Any>,Any*>
+{
+public:
+ any_iterator()=default;
+ explicit any_iterator(Any* p)noexcept:any_iterator::iterator_adaptor_{p}{}
+ any_iterator(const any_iterator&)=default;
+ any_iterator& operator=(const any_iterator&)=default;
+
+ template<
+ typename NonConstAny,
+ typename std::enable_if<
+ std::is_same<Any,const NonConstAny>::value>::type* =nullptr
+ >
+ any_iterator(const any_iterator<NonConstAny>& x)noexcept:
+ any_iterator::iterator_adaptor_{x.base()}{}
+
+ template<
+ typename NonConstAny,
+ typename std::enable_if<
+ std::is_same<Any,const NonConstAny>::value>::type* =nullptr
+ >
+ any_iterator& operator=(const any_iterator<NonConstAny>& x)noexcept
+ {
+ this->base_reference()=x.base();
+ return *this;
+ }
+
+ /* interoperability with Any* */
+
+ any_iterator& operator=(Any* p)noexcept
+ {this->base_reference()=p;return *this;}
+ operator Any*()const noexcept{return this->base();}
+
+ /* interoperability with Concrete* */
+
+ template<
+ typename Concrete,
+ typename std::enable_if<
+ /* can't compile-time check concept compliance */
+ !std::is_const<Any>::value||std::is_const<Concrete>::value
+ >::type* =nullptr
+ >
+ explicit operator Concrete*()const noexcept
+ {
+ return const_cast<Concrete*>(
+ static_cast<typename std::remove_const<Concrete>::type*>(
+ type_erasure::any_cast<void*>(this->base())));
+ }
+
+private:
+ template<typename>
+ friend class any_iterator;
+};
+
+} /* namespace poly_collection::detail */
+
+} /* namespace poly_collection */
+
+} /* namespace boost */
+
+#endif