mirror of
https://github.com/KingDuckZ/dindexer.git
synced 2025-07-03 14:14:11 +00:00
Support const/non-const DirIterators and SetListingViews
This commit is contained in:
parent
84a2617c24
commit
0a3e469951
3 changed files with 84 additions and 26 deletions
|
@ -23,17 +23,24 @@
|
||||||
#include <boost/iterator/iterator_facade.hpp>
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <ciso646>
|
||||||
|
|
||||||
namespace mchlib {
|
namespace mchlib {
|
||||||
|
namespace implem {
|
||||||
|
template <bool Const> class DirIterator;
|
||||||
|
} //namespace implem
|
||||||
|
|
||||||
class PathName;
|
class PathName;
|
||||||
class SetListingView;
|
template <bool Const> class SetListingView;
|
||||||
|
template <bool Const> const PathName& get_pathname ( const implem::DirIterator<Const>& parIter );
|
||||||
|
|
||||||
namespace implem {
|
namespace implem {
|
||||||
template <bool Const>
|
template <bool Const>
|
||||||
class DirIterator : public boost::iterator_facade<DirIterator<Const>, FileRecordData, boost::forward_traversal_tag> {
|
class DirIterator : public boost::iterator_facade<DirIterator<Const>, FileRecordData, boost::forward_traversal_tag> {
|
||||||
friend class mchlib::SetListingView;
|
friend class mchlib::SetListingView<Const>;
|
||||||
friend class boost::iterator_core_access;
|
friend class boost::iterator_core_access;
|
||||||
template <bool> friend class DirIterator;
|
template <bool> friend class DirIterator;
|
||||||
|
template <bool B> friend const PathName& mchlib::get_pathname ( const DirIterator<B>& parIter );
|
||||||
typedef boost::iterator_facade<DirIterator<Const>, FileRecordData, boost::random_access_traversal_tag> base_class;
|
typedef boost::iterator_facade<DirIterator<Const>, FileRecordData, boost::random_access_traversal_tag> base_class;
|
||||||
typedef typename base_class::difference_type difference_type;
|
typedef typename base_class::difference_type difference_type;
|
||||||
typedef typename base_class::reference reference;
|
typedef typename base_class::reference reference;
|
||||||
|
@ -66,12 +73,15 @@ namespace mchlib {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <bool Const>
|
||||||
class SetListingView {
|
class SetListingView {
|
||||||
|
struct enabler {};
|
||||||
public:
|
public:
|
||||||
typedef implem::DirIterator<true> const_iterator;
|
typedef implem::DirIterator<true> const_iterator;
|
||||||
typedef std::vector<FileRecordData>::const_iterator list_iterator;
|
typedef implem::DirIterator<false> iterator;
|
||||||
|
typedef typename implem::DirIterator<Const>::VecIterator list_iterator;
|
||||||
|
|
||||||
explicit SetListingView ( const const_iterator& parIter );
|
explicit SetListingView ( const implem::DirIterator<Const>& parIter );
|
||||||
SetListingView ( list_iterator parBeg, list_iterator parEnd );
|
SetListingView ( list_iterator parBeg, list_iterator parEnd );
|
||||||
SetListingView ( SetListingView&& ) = default;
|
SetListingView ( SetListingView&& ) = default;
|
||||||
~SetListingView ( void ) noexcept = default;
|
~SetListingView ( void ) noexcept = default;
|
||||||
|
@ -80,6 +90,10 @@ namespace mchlib {
|
||||||
const_iterator cbegin ( void ) const;
|
const_iterator cbegin ( void ) const;
|
||||||
const_iterator end ( void ) const;
|
const_iterator end ( void ) const;
|
||||||
const_iterator cend ( void ) const;
|
const_iterator cend ( void ) const;
|
||||||
|
template <bool B=not Const, typename R=typename std::enable_if<B, iterator>::type>
|
||||||
|
R begin ( void );
|
||||||
|
template <bool B=not Const, typename R=typename std::enable_if<B, iterator>::type>
|
||||||
|
R end ( void );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
list_iterator m_begin;
|
list_iterator m_begin;
|
||||||
|
@ -89,7 +103,7 @@ namespace mchlib {
|
||||||
class SetListing {
|
class SetListing {
|
||||||
public:
|
public:
|
||||||
typedef std::vector<FileRecordData> ListType;
|
typedef std::vector<FileRecordData> ListType;
|
||||||
typedef SetListingView::const_iterator const_iterator;
|
typedef implem::DirIterator<true> const_iterator;
|
||||||
|
|
||||||
explicit SetListing ( ListType&& parList, bool parSort=true );
|
explicit SetListing ( ListType&& parList, bool parSort=true );
|
||||||
~SetListing ( void ) noexcept;
|
~SetListing ( void ) noexcept;
|
||||||
|
@ -100,11 +114,18 @@ namespace mchlib {
|
||||||
const_iterator cend ( void ) const;
|
const_iterator cend ( void ) const;
|
||||||
|
|
||||||
//ListType descend_copy ( const const_iterator& parItem ) const;
|
//ListType descend_copy ( const const_iterator& parItem ) const;
|
||||||
SetListingView make_view ( void ) const;
|
SetListingView<false> make_view ( void );
|
||||||
|
SetListingView<true> make_view ( void ) const;
|
||||||
|
SetListingView<true> make_cview ( void ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ListType m_list;
|
ListType m_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <bool Const>
|
||||||
|
inline const PathName& get_pathname (const implem::DirIterator<Const>& parIter) {
|
||||||
|
return *parIter.m_base_path;
|
||||||
|
}
|
||||||
} //namespace mchlib
|
} //namespace mchlib
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,12 +45,6 @@ namespace mchlib {
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
namespace implem {
|
namespace implem {
|
||||||
template class DirIterator<true>;
|
|
||||||
template class DirIterator<false>;
|
|
||||||
template bool DirIterator<true>::equal ( const DirIterator<false>& ) const;
|
|
||||||
template bool DirIterator<true>::equal ( const DirIterator<true>& ) const;
|
|
||||||
template DirIterator<true>::DirIterator ( DirIterator<false>&&, enabler );
|
|
||||||
|
|
||||||
template <bool Const>
|
template <bool Const>
|
||||||
DirIterator<Const>::DirIterator (DirIterator<Const>&& parOther) :
|
DirIterator<Const>::DirIterator (DirIterator<Const>&& parOther) :
|
||||||
m_current(std::move(parOther.m_current)),
|
m_current(std::move(parOther.m_current)),
|
||||||
|
@ -137,6 +131,14 @@ namespace mchlib {
|
||||||
*/;
|
*/;
|
||||||
return is_this_end;
|
return is_this_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template class DirIterator<true>;
|
||||||
|
template class DirIterator<false>;
|
||||||
|
template bool DirIterator<true>::equal ( const DirIterator<false>& ) const;
|
||||||
|
template bool DirIterator<true>::equal ( const DirIterator<true>& ) const;
|
||||||
|
template bool DirIterator<false>::equal ( const DirIterator<false>& ) const;
|
||||||
|
template bool DirIterator<false>::equal ( const DirIterator<true>& ) const;
|
||||||
|
template DirIterator<true>::DirIterator ( DirIterator<false>&&, enabler );
|
||||||
} //namespace implem
|
} //namespace implem
|
||||||
|
|
||||||
SetListing::SetListing (ListType&& parList, bool parSort) :
|
SetListing::SetListing (ListType&& parList, bool parSort) :
|
||||||
|
@ -170,27 +172,39 @@ namespace mchlib {
|
||||||
return const_iterator(m_list.end(), m_list.end(), std::unique_ptr<PathName>());
|
return const_iterator(m_list.end(), m_list.end(), std::unique_ptr<PathName>());
|
||||||
}
|
}
|
||||||
|
|
||||||
SetListingView SetListing::make_view() const {
|
SetListingView<false> SetListing::make_view() {
|
||||||
return SetListingView(m_list.begin(), m_list.end());
|
return SetListingView<false>(m_list.begin(), m_list.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
SetListingView::SetListingView (const const_iterator& parIter) :
|
SetListingView<true> SetListing::make_view() const {
|
||||||
|
return SetListingView<true>(m_list.begin(), m_list.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
SetListingView<true> SetListing::make_cview() const {
|
||||||
|
return SetListingView<true>(m_list.begin(), m_list.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool Const>
|
||||||
|
SetListingView<Const>::SetListingView (const implem::DirIterator<Const>& parIter) :
|
||||||
m_begin(parIter.m_current),
|
m_begin(parIter.m_current),
|
||||||
m_end(parIter.m_end)
|
m_end(parIter.m_end)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SetListingView::SetListingView (list_iterator parBeg, list_iterator parEnd) :
|
template <bool Const>
|
||||||
m_begin(parBeg),
|
SetListingView<Const>::SetListingView (list_iterator parBeg, list_iterator parEnd) :
|
||||||
m_end(parEnd)
|
m_begin(std::move(parBeg)),
|
||||||
|
m_end(std::move(parEnd))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SetListingView::begin() const -> const_iterator {
|
template <bool Const>
|
||||||
|
auto SetListingView<Const>::begin() const -> const_iterator {
|
||||||
return cbegin();
|
return cbegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SetListingView::cbegin() const -> const_iterator {
|
template <bool Const>
|
||||||
|
auto SetListingView<Const>::cbegin() const -> const_iterator {
|
||||||
std::unique_ptr<PathName> base_path;
|
std::unique_ptr<PathName> base_path;
|
||||||
if (m_begin != m_end) {
|
if (m_begin != m_end) {
|
||||||
base_path.reset(new PathName(m_begin->abs_path));
|
base_path.reset(new PathName(m_begin->abs_path));
|
||||||
|
@ -198,11 +212,34 @@ namespace mchlib {
|
||||||
return const_iterator(m_begin, m_end, std::move(base_path));
|
return const_iterator(m_begin, m_end, std::move(base_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SetListingView::end() const -> const_iterator {
|
template <bool Const>
|
||||||
|
auto SetListingView<Const>::end() const -> const_iterator {
|
||||||
return cend();
|
return cend();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SetListingView::cend() const -> const_iterator {
|
template <bool Const>
|
||||||
|
auto SetListingView<Const>::cend() const -> const_iterator {
|
||||||
return const_iterator(m_end, m_end, std::unique_ptr<PathName>());
|
return const_iterator(m_end, m_end, std::unique_ptr<PathName>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <bool Const>
|
||||||
|
template <bool B, typename R>
|
||||||
|
R SetListingView<Const>::begin() {
|
||||||
|
std::unique_ptr<PathName> base_path;
|
||||||
|
if (m_begin != m_end) {
|
||||||
|
base_path.reset(new PathName(m_begin->abs_path));
|
||||||
|
}
|
||||||
|
return iterator(m_begin, m_end, std::move(base_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <bool Const>
|
||||||
|
template <bool B, typename R>
|
||||||
|
R SetListingView<Const>::end() {
|
||||||
|
return iterator(m_end, m_end, std::unique_ptr<PathName>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template class SetListingView<true>;
|
||||||
|
template class SetListingView<false>;
|
||||||
|
template SetListingView<false>::iterator SetListingView<false>::begin ( void );
|
||||||
|
template SetListingView<false>::iterator SetListingView<false>::end ( void );
|
||||||
} //namespace mchlib
|
} //namespace mchlib
|
||||||
|
|
|
@ -25,14 +25,14 @@
|
||||||
//TEST_F for class
|
//TEST_F for class
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void flatten_filelist (const mchlib::SetListingView& parContent, std::vector<std::string>& parOut) {
|
void flatten_filelist (const mchlib::SetListingView<true>& parContent, std::vector<std::string>& parOut) {
|
||||||
const auto end = parContent.end();
|
const auto end = parContent.end();
|
||||||
|
|
||||||
for (auto itcurr = parContent.cbegin(); itcurr != end; ++itcurr) {
|
for (auto itcurr = parContent.cbegin(); itcurr != end; ++itcurr) {
|
||||||
parOut.push_back(itcurr->abs_path);
|
parOut.push_back(itcurr->abs_path);
|
||||||
|
|
||||||
if (itcurr->is_directory) {
|
if (itcurr->is_directory) {
|
||||||
flatten_filelist(mchlib::SetListingView(itcurr), parOut);
|
flatten_filelist(mchlib::SetListingView<true>(itcurr), parOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ TEST(machinery, diriterator) {
|
||||||
EXPECT_EQ("BestAndBest", i->abs_path);
|
EXPECT_EQ("BestAndBest", i->abs_path);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto view = SetListingView(i);
|
auto view = SetListingView<true>(i);
|
||||||
auto i2 = view.cbegin();
|
auto i2 = view.cbegin();
|
||||||
EXPECT_EQ("BestAndBest/CD1", i2->abs_path);
|
EXPECT_EQ("BestAndBest/CD1", i2->abs_path);
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ TEST(machinery, diriterator) {
|
||||||
|
|
||||||
std::vector<std::string> flattened;
|
std::vector<std::string> flattened;
|
||||||
flattened.reserve(lengthof(expected_list));
|
flattened.reserve(lengthof(expected_list));
|
||||||
flatten_filelist(lst.make_view(), flattened);
|
flatten_filelist(lst.make_cview(), flattened);
|
||||||
EXPECT_EQ(lengthof(expected_list), flattened.size());
|
EXPECT_EQ(lengthof(expected_list), flattened.size());
|
||||||
const auto count = std::min(lengthof(expected_list), flattened.size());
|
const auto count = std::min(lengthof(expected_list), flattened.size());
|
||||||
for (std::size_t z = 0; z < count; ++z) {
|
for (std::size_t z = 0; z < count; ++z) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue