/* Copyright 2015, 2016, Michele Santullo * This file is part of "dindexer". * * "dindexer" is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * "dindexer" is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with "dindexer". If not, see . */ #ifndef id040FEEC20F7B4F65A3EF67BA6460E737 #define id040FEEC20F7B4F65A3EF67BA6460E737 #include "dindexer-machinery/recorddata.hpp" #include "kakoune/safe_ptr.hh" #include #include #include #include #include #include namespace mchlib { namespace implem { template class DirIterator; } //namespace implem class PathName; template class SetListingView; template implem::DirIterator first_file ( const SetListingView& parList ); template implem::DirIterator first_file ( SetListingView& parList ); typedef FileRecordData SetListingItemType; namespace implem { template class DirIterator : public boost::iterator_facade, SetListingItemType, boost::forward_traversal_tag> { friend class mchlib::SetListingView; friend class boost::iterator_core_access; template friend class DirIterator; typedef boost::iterator_facade, SetListingItemType, boost::forward_traversal_tag> base_class; struct enabler {}; public: typedef typename std::conditional< Const, std::vector::const_iterator, std::vector::iterator >::type VecIterator; typedef typename base_class::difference_type difference_type; typedef typename base_class::value_type value_type; typedef typename base_class::pointer pointer; typedef typename base_class::reference reference; typedef typename base_class::iterator_category iterator_category; DirIterator ( DirIterator&& parOther ); DirIterator ( const DirIterator& parOther ); template DirIterator ( DirIterator&& parOther, typename std::enable_if::VecIterator, VecIterator>::value, enabler>::type = enabler() ); DirIterator ( VecIterator parBegin, VecIterator parEnd, const PathName* parBasePath, std::size_t parLevelOffset ); ~DirIterator ( void ) noexcept; DirIterator& operator= ( DirIterator&& parOther ); DirIterator& operator= ( const DirIterator& parOther ); template DirIterator& operator= ( typename std::enable_if::VecIterator, VecIterator>::value, DirIterator>::type&& parOther ); template DirIterator& operator= ( const typename std::enable_if::VecIterator, VecIterator>::value, DirIterator>::type& parOther ); private: void increment ( void ); difference_type distance_to ( const DirIterator& parOther ) const; template bool equal ( const DirIterator& parOther ) const; reference dereference ( void ) const; bool is_end ( void ) const; VecIterator m_current; VecIterator m_end; Kakoune::SafePtr m_base_path; std::size_t m_level_offset; }; }; template class SetListingView { struct enabler {}; public: typedef implem::DirIterator const_iterator; typedef implem::DirIterator iterator; typedef typename implem::DirIterator::VecIterator list_iterator; explicit SetListingView ( const implem::DirIterator& parIter ); SetListingView ( list_iterator parBeg, list_iterator parEnd, std::size_t parLevelOffset ); SetListingView ( list_iterator parBeg, list_iterator parEnd, std::size_t parLevelOffset, const std::shared_ptr& parBasePath ); template >::type> SetListingView ( const Other& parOther ); SetListingView ( SetListingView&& ) = default; ~SetListingView ( void ) noexcept = default; const_iterator begin ( void ) const; const_iterator cbegin ( void ) const; const_iterator end ( void ) const; const_iterator cend ( void ) const; template ::type> R begin ( void ); template ::type> R end ( void ); private: list_iterator m_begin; list_iterator m_end; std::shared_ptr m_base_path; std::size_t m_level_offset; }; using MutableSetListingView = SetListingView; using ConstSetListingView = SetListingView; class SetListing { public: typedef std::vector ListType; typedef implem::DirIterator const_iterator; explicit SetListing ( ListType&& parList, bool parSort=true ); ~SetListing ( void ) noexcept; const_iterator begin ( void ) const; const_iterator cbegin ( void ) const; const_iterator end ( void ) const; const_iterator cend ( void ) const; //ListType descend_copy ( const const_iterator& parItem ) const; SetListingView make_view ( void ); SetListingView make_view ( void ) const; SetListingView make_cview ( void ) const; bool empty ( void ) const; std::size_t size ( void ) const; std::size_t files_count ( void ) const; std::size_t dir_count ( void ) const; const ListType& sorted_list ( void ) const; static void sort_list ( ListType& parList ); static ListType::iterator lower_bound ( ListType& parList, const char* parPath, uint16_t parLevel, bool parIsDir ); private: ListType m_list; std::shared_ptr m_base_path; }; template inline implem::DirIterator first_file (const SetListingView& parList) { auto end = parList.end(); for (auto it = parList.begin(); it != end; ++it) { if (not it->is_directory) return it; } return parList.end(); } template inline implem::DirIterator first_file (SetListingView& parList) { auto end = parList.end(); for (auto it = parList.begin(); it != end; ++it) { if (not it->is_directory) return it; } return parList.end(); } } //namespace mchlib #endif