shand::file_mapping_container v0.9

open_only, create_only, open_or_createに対応しました。
vector以外の選択はまた後日対応。設計はまだ考え中なので破壊的な変更が入るかもしれません。


shand/file_mapping_container.hpp

#ifndef SHAND_FILE_MAPPING_CONTAINER_INCLUDE
#define SHAND_FILE_MAPPING_CONTAINER_INCLUDE

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/vector.hpp>

namespace shand {

namespace ipc = boost::interprocess;

template <class T>
class file_mapping_container {
public:
    typedef ipc::allocator<T, ipc::managed_mapped_file::segment_manager> allocator_t;
    typedef ipc::vector<T, allocator_t> container_t;

    file_mapping_container(
            ipc::create_only_t create_only,
            const std::string& filename,
            std::size_t filesize,
            const std::string& object_name)
        : managed_file_(create_only, filename.c_str(), filesize),
          allocator_(managed_file_.get_segment_manager()),
          container_(*(managed_file_.construct<container_t>(object_name.c_str())(allocator_)))
    {}

    file_mapping_container(
            ipc::open_only_t open_only,
            const std::string& filename,
            const std::string& object_name)
        : managed_file_(open_only, filename.c_str()),
          allocator_(managed_file_.get_segment_manager()),
          container_(*(managed_file_.find<container_t>(object_name.c_str()).first))
    {
    }

    file_mapping_container(
            ipc::open_or_create_t open_or_create,
            const std::string& filename,
            std::size_t filesize,
            const std::string& object_name)
        : managed_file_(open_or_create, filename.c_str(), filesize),
          allocator_(managed_file_.get_segment_manager()),
          container_(*(managed_file_.find_or_construct<container_t>(object_name.c_str())(allocator_)))
    {}

    container_t& get() { return container_; }
    const container_t& get() const { return container_; }

private:
    ipc::managed_mapped_file managed_file_;
    allocator_t allocator_;
    container_t& container_;
};

} // namespace shand

#endif // SHAND_FILE_MAPPING_CONTAINER_INCLUDE


サンプル

#define BOOST_DATE_TIME_NO_LIB

#include <iostream>
#include <boost/range/algorithm/copy.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/lambda/lambda.hpp>
#include <shand/file_mapping_container.hpp>

namespace ipc = boost::interprocess;

namespace {
    const std::string save_file_name = "test.dat";
    const std::size_t save_file_size = 65536;
    const std::string save_object_name = "SaveData";
}

void save(const std::vector<int>& data)
{
    {
        shand::file_mapping_container<int> file(ipc::create_only, save_file_name, save_file_size, save_object_name);
//      shand::file_mapping_container<int> file(ipc::open_or_create, save_file_name, save_file_size, save_object_name);
        boost::copy(data, std::back_inserter(file.get()));
    }
    ipc::managed_mapped_file::shrink_to_fit(save_file_name.c_str());
}

void load(std::vector<int>& data)
{
    data.clear();
    shand::file_mapping_container<int> file(ipc::open_only, save_file_name, save_object_name);
//  shand::file_mapping_container<int> file(ipc::open_or_create, save_file_name, save_file_size, save_object_name);
    boost::copy(file.get(), std::back_inserter(data));
}

int main()
{
    struct shm_remove {
        shm_remove() { ipc::shared_memory_object::remove(save_object_name.c_str()); }
        ~shm_remove(){ ipc::shared_memory_object::remove(save_object_name.c_str()); }
    } remover;

    {
        const std::vector<int> v = boost::assign::list_of(3)(1)(4);
        save(v);
    }
    {
        std::vector<int> v;
        load(v);

        boost::for_each(v, std::cout << boost::lambda::_1 << ' ');
    }

    std::remove(save_file_name.c_str());
}
3 1 4