Информация об изменениях

Сообщение LRU cache, предложения и замечания от 14.04.2019 2:17

Изменено 14.04.2019 2:18 kaa.python

LRU cache, предложения и замечания
Для собственных нужд накидал LRU-cache, который вроде делает то, что мне нужно и так как мне нужно. Но так как я не часто пишу на C++ именно что библиотеки, а в то же время написание библиотек вообще сильно оттедельный навык, у меня есть некоторые сомнения в том, что все реализовано в соответствии с современными веяниями. Сам кеш тут, минимальный поддерживаемый стандарт C++11.

  ну и еще вот сюда продублирую
#ifndef CACHEW_LRU_CACHE_HPP
#define CACHEW_LRU_CACHE_HPP

#include <algorithm>
#include <list>
#include <unordered_map>

namespace cachew
{

template <class _Key, class _Tp>
class lru_cache
{
public:
    using key_type   = _Key;
    using value_type = _Tp;

    using kv_pair = std::pair<key_type, value_type>;

    template <class _Storage = std::list<kv_pair>>
    class lru_iterator
    {
    private:
        using it_type        = lru_iterator<_Storage>;
        using parent_it_type = typename _Storage::const_iterator;

        parent_it_type _it;

    public:
        lru_iterator() = default;

        lru_iterator( const it_type &it )
            : _it( it._it )
        {
        }

        explicit lru_iterator( const parent_it_type &it )
            : _it( it )
        {
        }

        bool operator==( const it_type &it ) const
        {
            return it._it == _it;
        }

        bool operator!=( const it_type &it ) const
        {
            return it._it != _it;
        }

        const it_type &operator++()
        {
            ++_it;
            return *this;
        }

        const it_type operator++( int )
        {
            it_type res( *this );
            ++( *this );
            return res;
        }

        const value_type &operator*() const
        {
            return ( _it->second );
        }

        const value_type *operator->() const
        {
            return &( _it->second );
        }
    };

    using lru_list = std::list<std::pair<key_type, value_type>>;
    using lru_map  = std::unordered_map<key_type, typename lru_list::iterator>;

    using iterator = lru_iterator<lru_list>;

    friend bool operator!=( const lru_cache &lhs, const lru_cache &rhs )
    {
        return !( rhs == lhs );
    }

    explicit lru_cache( size_t capacity ) noexcept
        : _capacity( capacity )
    {
    }

    iterator get( const key_type &key )
    {
        auto it = _map.find( key );
        if( it == _map.end() )
        {
            return iterator( _list.end() );
        }
        _list.splice( _list.begin(), _list, it->second );

        return iterator( it->second );
    }

    template <class _PutK, class _PutT>
    void put( _PutK &&key, _PutT &&value )
    {
        auto it = _map.find( key );
        if( it != _map.end() )
        {
            _list.splice( _list.begin(), _list, it->second );
            it->second->second = value;
        }
        if( _map.size() == _capacity )
        {
            auto to_del = _list.back().first;
            _list.pop_back();
            _map.erase( to_del );
        }
        _list.emplace_front( std::forward<key_type>( key ),
                             std::forward<value_type>( value ) );
        _map.emplace( std::forward<key_type>( key ), _list.begin() );
    }

    size_t capacity() const
    {
        return _capacity;
    }

    size_t size() const
    {
        return _map.size();
    }

    iterator begin() const noexcept
    {
        return iterator( _list.begin() );
    }

    iterator end() const noexcept
    {
        return iterator( _list.end() );
    }

private:
    lru_list _list;
    lru_map  _map;
    size_t   _capacity;
};

} // namespace cachew

#endif // CACHEW_LRU_CACHE_HPP
lru-cache c++11 codereview
LRU cache, предложения и замечания
Для собственных нужд накидал LRU-cache, который вроде делает то, что мне нужно и так как мне нужно. Но так как я не часто пишу на C++ именно что библиотеки, а в то же время написание библиотек вообще сильно оттедельный навык, у меня есть некоторые сомнения в том, что все реализовано в соответствии с современными веяниями. Сам кеш тут, минимальный поддерживаемый стандарт C++11. Буду благодарен за дополнения и замечания

  ну и еще вот сюда продублирую
#ifndef CACHEW_LRU_CACHE_HPP
#define CACHEW_LRU_CACHE_HPP

#include <algorithm>
#include <list>
#include <unordered_map>

namespace cachew
{

template <class _Key, class _Tp>
class lru_cache
{
public:
    using key_type   = _Key;
    using value_type = _Tp;

    using kv_pair = std::pair<key_type, value_type>;

    template <class _Storage = std::list<kv_pair>>
    class lru_iterator
    {
    private:
        using it_type        = lru_iterator<_Storage>;
        using parent_it_type = typename _Storage::const_iterator;

        parent_it_type _it;

    public:
        lru_iterator() = default;

        lru_iterator( const it_type &it )
            : _it( it._it )
        {
        }

        explicit lru_iterator( const parent_it_type &it )
            : _it( it )
        {
        }

        bool operator==( const it_type &it ) const
        {
            return it._it == _it;
        }

        bool operator!=( const it_type &it ) const
        {
            return it._it != _it;
        }

        const it_type &operator++()
        {
            ++_it;
            return *this;
        }

        const it_type operator++( int )
        {
            it_type res( *this );
            ++( *this );
            return res;
        }

        const value_type &operator*() const
        {
            return ( _it->second );
        }

        const value_type *operator->() const
        {
            return &( _it->second );
        }
    };

    using lru_list = std::list<std::pair<key_type, value_type>>;
    using lru_map  = std::unordered_map<key_type, typename lru_list::iterator>;

    using iterator = lru_iterator<lru_list>;

    friend bool operator!=( const lru_cache &lhs, const lru_cache &rhs )
    {
        return !( rhs == lhs );
    }

    explicit lru_cache( size_t capacity ) noexcept
        : _capacity( capacity )
    {
    }

    iterator get( const key_type &key )
    {
        auto it = _map.find( key );
        if( it == _map.end() )
        {
            return iterator( _list.end() );
        }
        _list.splice( _list.begin(), _list, it->second );

        return iterator( it->second );
    }

    template <class _PutK, class _PutT>
    void put( _PutK &&key, _PutT &&value )
    {
        auto it = _map.find( key );
        if( it != _map.end() )
        {
            _list.splice( _list.begin(), _list, it->second );
            it->second->second = value;
        }
        if( _map.size() == _capacity )
        {
            auto to_del = _list.back().first;
            _list.pop_back();
            _map.erase( to_del );
        }
        _list.emplace_front( std::forward<key_type>( key ),
                             std::forward<value_type>( value ) );
        _map.emplace( std::forward<key_type>( key ), _list.begin() );
    }

    size_t capacity() const
    {
        return _capacity;
    }

    size_t size() const
    {
        return _map.size();
    }

    iterator begin() const noexcept
    {
        return iterator( _list.begin() );
    }

    iterator end() const noexcept
    {
        return iterator( _list.end() );
    }

private:
    lru_list _list;
    lru_map  _map;
    size_t   _capacity;
};

} // namespace cachew

#endif // CACHEW_LRU_CACHE_HPP
c++11 codereview lru-cache