[common-sln]: base增加唯一标识管理类

来源:互联网 发布:泛雅网络教学平台答案 编辑:程序博客网 时间:2024/05/22 08:12

目的:创建某种场景下的唯一标识,就好像文件描述符那种
#ifndef COMMON_BASE_HANDLE_MANAGER_H#define COMMON_BASE_HANDLE_MANAGER_H#include <deque>#include <algorithm>#include <functional>#include "base_common.h"#include "base_uncopy.h"#include "base_locker.h"#include "base_guard.hpp"NAMESPACE_COMMON_BEGINtemplate <typename HandleType, typename LockerType = NullLocker>class YRK_EXPORT_DLL HandleManager : public BaseUncopy{public:    HandleManager(HandleType min, HandleType max);public:    bool acquire(HandleType & handle);    bool release(HandleType handle);private:    const HandleType         m_min_handle;    const HandleType         m_max_handle;    HandleType               m_next_handle;    std::deque<HandleType>   m_unused_handle;    LockerType               m_locker;};template <typename HandleType, typename LockerType>HandleManager<HandleType, LockerType>::HandleManager(    HandleType min, HandleType max)    : m_min_handle(min)    , m_max_handle(max)    , m_next_handle(min)    , m_unused_handle()    , m_locker(){}template <typename HandleType, typename LockerType>bool HandleManager<HandleType, LockerType>::acquire(HandleType & handle){    BaseGuard<LockerType> guard(m_locker);    if (!m_unused_handle.empty())    {        handle = m_unused_handle.back();        m_unused_handle.pop_back();        return(true);    }    if (m_next_handle >= m_max_handle)    {        return(false);    }    handle = m_next_handle++;    return(true);}template <typename HandleType, typename LockerType>bool HandleManager<HandleType, LockerType>::release(HandleType handle){    BaseGuard<LockerType> guard(m_locker);    if (handle <  m_min_handle ||         handle >= m_next_handle)    {        return(false);    }    if (m_unused_handle.end() !=         std::find(m_unused_handle.begin(), m_unused_handle.end(), handle))    {        return(false);    }    if (handle + 1 == m_next_handle)    {        m_next_handle = handle;    }    else    {        m_unused_handle.push_back(handle);        std::sort(m_unused_handle.begin(), m_unused_handle.end(),                   std::greater<HandleType>());    }    typename std::deque<HandleType>::iterator iter = m_unused_handle.begin();    while (m_unused_handle.end() != iter)    {        if (*iter + 1 == m_next_handle)        {            m_next_handle = *iter++;        }        else        {            break;        }    }    m_unused_handle.erase(m_unused_handle.begin(), iter);    return(true);}NAMESPACE_COMMON_END#endif // COMMON_BASE_HANDLE_MANAGER_H

测试:
#include <cassert>#include <iostream>#include "base_handle_manager.hpp"USING_NAMESPACE_COMMONint main(int argc, char * argv[]){    int min = 0;    int max = 20;    HandleManager<int, NullLocker> manager(min, max);    if (!manager.release(min))    {        std::cout << "as i known, release " << min << " failed" << std::endl;    }    else    {        assert(false);    }    int handle = 0;    while (manager.acquire(handle))    {        std::cout << "acquire " << handle << std::endl;    }    for (int i = min; i < max; i += 2)    {        manager.release(i);        std::cout << "release " << i << std::endl;    }    if (!manager.release(min))    {        std::cout << "as i known, release " << min << " failed" << std::endl;    }    else    {        assert(false);    }    if (manager.acquire(handle))    {        std::cout << "acquire " << handle << std::endl;        manager.release(handle);        std::cout << "release " << handle << std::endl;    }    for (int i = max - 1; i > min; i -= 2)    {        manager.release(i);        std::cout << "release " << i << std::endl;    }    if (!manager.release(min))    {        std::cout << "as i known, release " << min << " failed" << std::endl;    }    else    {        assert(false);    }    if (manager.acquire(handle) && min == handle)    {        std::cout << "acquire " << handle << std::endl;    }    else    {        assert(false);    }    return(0);}


原创粉丝点击