読者です 読者をやめる 読者になる 読者になる

Boost.Interprocessはどこまでヘッダオンリーでできるのか

C++

Boost.InterprocessはBoost.DateTimeに依存しているライブラリなのですが、managed fileのあたりならDateTime使わないんじゃないかと思って試してみました。


ついでに、生のIPCのコードをそのまま書きたくないのでfile_mapping_containerなるものを作ってありますがまだ作りかけです。
vectorしか扱えないし、open_or_createしかできないので、まじめにやるならもう少し作り込む必要があります。

// tested compiler : Microsoft Visual C++ 2010(Windows XP)

#define BOOST_DATE_TIME_NO_LIB

#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>

#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>

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;

    template <class FileFlag>
    file_mapping_container(
            FileFlag file_flag,
            const std::string& filename,
            std::size_t filesize,
            const std::string& object_name)
        : managed_file_(file_flag, 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 {
    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)
{
    {
        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();
    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 << ' ');
    }
}
3 1 4