86 lines
2.2 KiB
C++
86 lines
2.2 KiB
C++
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||
|
|
||
|
#if !defined(CPPLINQ_LINQ_LAST_HPP)
|
||
|
#define CPPLINQ_LINQ_LAST_HPP
|
||
|
#pragma once
|
||
|
|
||
|
namespace cpplinq {
|
||
|
|
||
|
template <class Cursor>
|
||
|
typename Cursor::element_type
|
||
|
linq_last_(Cursor c, onepass_cursor_tag)
|
||
|
{
|
||
|
if (c.empty()) { throw std::logic_error("last() out of bounds"); }
|
||
|
typename Cursor::element_type elem = c.get();
|
||
|
for(;;) {
|
||
|
c.inc();
|
||
|
if (c.empty()) break;
|
||
|
elem = c.get();
|
||
|
}
|
||
|
return elem;
|
||
|
}
|
||
|
|
||
|
// TODO: bidirectional iterator in constant time
|
||
|
|
||
|
template <class Cursor>
|
||
|
typename Cursor::reference_type
|
||
|
linq_last_(Cursor c, forward_cursor_tag)
|
||
|
{
|
||
|
if (c.empty()) { throw std::logic_error("last() out of bounds"); }
|
||
|
Cursor best = c;
|
||
|
for(;;) {
|
||
|
c.inc();
|
||
|
if (c.empty()) break;
|
||
|
best = c;
|
||
|
}
|
||
|
return best.get();
|
||
|
}
|
||
|
|
||
|
template <class Cursor>
|
||
|
typename Cursor::reference_type
|
||
|
linq_last_(Cursor c, random_access_cursor_tag)
|
||
|
{
|
||
|
if (c.empty()) { throw std::logic_error("last() out of bounds"); }
|
||
|
c.skip(c.size()-1);
|
||
|
return c.get();
|
||
|
}
|
||
|
|
||
|
template <class Cursor>
|
||
|
typename Cursor::element_type
|
||
|
linq_last_or_default_(Cursor c, onepass_cursor_tag)
|
||
|
{
|
||
|
typename Cursor::element_type elem;
|
||
|
while(!c.empty()) {
|
||
|
elem = c.get();
|
||
|
c.inc();
|
||
|
}
|
||
|
return elem;
|
||
|
}
|
||
|
|
||
|
template <class Cursor>
|
||
|
typename Cursor::element_type
|
||
|
linq_last_or_default_(Cursor c, forward_cursor_tag)
|
||
|
{
|
||
|
if (c.empty()) { throw std::logic_error("last() out of bounds"); }
|
||
|
Cursor best = c;
|
||
|
for(;;) {
|
||
|
c.inc();
|
||
|
if (c.empty()) break;
|
||
|
best = c;
|
||
|
}
|
||
|
return best.get();
|
||
|
}
|
||
|
|
||
|
template <class Cursor>
|
||
|
typename Cursor::element_type
|
||
|
linq_last_or_default_(Cursor c, random_access_cursor_tag)
|
||
|
{
|
||
|
if (c.empty()) { return typename Cursor::element_type(); }
|
||
|
c.skip(c.size()-1);
|
||
|
return c.get();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif // CPPLINQ_LINQ_LAST_HPP
|