[Boost.Range][Boost.Iterators] - iterator as pointer
Hi folks, I wonder if it is possible to determine if an iterator or a boost.range can be handled like a pointer to contiguous memory using an iterator/range trait? I need to enable functions if the given range is convertible to a c-array like pointer range. Best regards, Christoph
I tried to roll my own solution but I'm failing to see how to enable the specialization for certain iterator types. What I have done is to create a generic metafunction that applies unless a specialization is found template<class Iterator> struct is_contingous_in_memory : boost::mpl::false_ {}; Now, when dealing with std::vector<int> I can declare template<> struct is_contingous_in_memory<std::vector<int>::iterator> : boost::mpl::true_ {}; template<> struct is_contingous_in_memory<std::vector<int>::iterator> : boost::mpl::true_ {}; That way I would need to declare several variants for all integral and floating point types. So I thought, that I could write template<class T> struct is_contingous_in_memory< typename std::vector<T>::iterator > : boost::mpl::true_ {}; but that fails to compile with "template parameter not used or deducible in partial specialization 'specialization'". How to deal with that (on MSVC 9)? Best regards, Christoph
Christoph, Just a guess since I don't have access to that compiler, but keep in mind that std::vector has two parameters -- they type T and an allocator (defaults to std::allocator<T>). Try adding that to the partial specialization: template<class T, class A> struct is_contingous_in_memory< typename std::vector<T, A>::iterator > : boost::mpl::true_ {}; HTH, Nate On Mon, Aug 15, 2011 at 4:13 AM, Christoph Heindl <christoph.heindl@gmail.com> wrote:
I tried to roll my own solution but I'm failing to see how to enable the specialization for certain iterator types. What I have done is to create a generic metafunction that applies unless a specialization is found
template<class Iterator> struct is_contingous_in_memory : boost::mpl::false_ {};
Now, when dealing with std::vector<int> I can declare
template<> struct is_contingous_in_memory<std::vector<int>::iterator> : boost::mpl::true_ {}; template<> struct is_contingous_in_memory<std::vector<int>::iterator> : boost::mpl::true_ {};
That way I would need to declare several variants for all integral and floating point types. So I thought, that I could write
template<class T> struct is_contingous_in_memory< typename std::vector<T>::iterator > : boost::mpl::true_ {};
but that fails to compile with "template parameter not used or deducible in partial specialization 'specialization'". How to deal with that (on MSVC 9)?
Best regards, Christoph _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On Mon, Aug 15, 2011 at 6:48 PM, Nathan Crookston <nathan.crookston@gmail.com> wrote:
Try adding that to the partial specialization:
template<class T, class A> struct is_contingous_in_memory< typename std::vector<T, A>::iterator > : boost::mpl::true_ {};
Thanks for the hint, but unfortunately that didn't help. now the error occurs for both template arguments. Best regards, Christoph
On Aug 15, 2011, at 6:13 AM, Christoph Heindl <christoph.heindl@gmail.com> wrote:
template<class T> struct is_contingous_in_memory< typename std::vector<T>::iterator > : boost::mpl::true_ {};
I've gotten bitten by this. You can't put a type nesting into a partial specialization pattern because e.g. the compiler can't infer that the iterator type T* came from a vector. You've already lost the container information at that point; T* could be the ::iterator of any number of classes. Seems like the error message could be more helpful! If you still have the container type at the place where you're trying to deduce is_continuous, I think that would be the way to go. (Apologies if my terminology is a little off; hope this gets the idea across.) Cheers Gordon
On Mon, Aug 15, 2011 at 7:22 PM, Gordon Woodhull <gordon@woodhull.com> wrote:
If you still have the container type at the place where you're trying to deduce is_continuous, I think that would be the way to go.
Unfortunately I don't have access to the container type, because my iterator comes from any boost.range compatible type. I'm doing something along the lines of /** Some policy */ struct error { /** Test if range iterator can be handled like a pointer to continuous memory */ template<class Range> inline bool operator()(const Range &r) const { // If your compiler traps here, you probably used the memory_policies::error // policy and failed to supply an appropriate is_continuous_in_memory for your // range argument. BOOST_STATIC_ASSERT((is_continuous_in_memory<boost::range_iterator<Range>::type>::value)); return true; } }; Best regards, Christoph
On Aug 15, 2011, at 1:44 PM, Christoph Heindl <christoph.heindl@gmail.com> wrote:
On Mon, Aug 15, 2011 at 7:22 PM, Gordon Woodhull <gordon@woodhull.com> wrote:
If you still have the container type at the place where you're trying to deduce is_continuous, I think that would be the way to go.
Unfortunately I don't have access to the container type, because my iterator comes from any boost.range compatible type.
Right. I don't think you can determine from its type if an iterator came from a vector. You could determine if the iterator is random access but then you'd be screwed if someone passed you a deque iterator, if you really need contiguity. Maybe I'm missing something. I know you can't ever deduce T from dependent<T>::nested though. Sorry, Gordon
participants (3)
-
Christoph Heindl
-
Gordon Woodhull
-
Nathan Crookston