8 #include "boost/assert.hpp"
10 #include "boost/multi_index_container.hpp"
11 #include "boost/multi_index/hashed_index.hpp"
12 #include "boost/multi_index/mem_fun.hpp"
13 #include "boost/multi_index/member.hpp"
14 #include "boost/range.hpp"
15 #include "boost/foreach.hpp"
19 #include "owlcpp/detail/id_tracker.hpp"
21 #include "owlcpp/detail/member_iterator.hpp"
30 struct Doc_meta_wrap {
34 std::string
const& path,
37 : dm_(ontology_iri, version_iri, path), id_(doc)
40 Node_id ontology_iri()
const {
return dm_.ontology_iri;}
41 Node_id version_iri()
const {
return dm_.version_iri;}
42 std::string
const& path()
const {
return dm_.path;}
47 typedef boost::multi_index_container<
49 boost::multi_index::indexed_by<
50 boost::multi_index::hashed_unique<
51 boost::multi_index::tag<struct id_tag>,
52 boost::multi_index::member<
53 Doc_meta_wrap,
Doc_id, &Doc_meta_wrap::id_
56 boost::multi_index::hashed_non_unique<
57 boost::multi_index::tag<struct iri_tag>,
58 boost::multi_index::const_mem_fun<
59 Doc_meta_wrap,
Node_id, &Doc_meta_wrap::ontology_iri
62 boost::multi_index::hashed_non_unique<
63 boost::multi_index::tag<struct version_tag>,
64 boost::multi_index::const_mem_fun<
65 Doc_meta_wrap,
Node_id, &Doc_meta_wrap::version_iri
68 boost::multi_index::hashed_non_unique<
69 boost::multi_index::tag<struct path_tag>,
70 boost::multi_index::const_mem_fun<
71 Doc_meta_wrap, std::string
const&, &Doc_meta_wrap::path
77 typedef map_t::index<id_tag>::type id_index_t;
78 typedef map_t::index<path_tag>::type path_index_t;
79 typedef map_t::index<iri_tag>::type iri_index_t;
80 typedef map_t::index<version_tag>::type version_index_t;
83 typedef Member_iterator<
84 map_t::const_iterator,
88 typedef const_iterator iterator;
90 typedef Member_iterator<
91 path_index_t::const_iterator,
95 typedef boost::iterator_range<path_iterator> path_range;
97 typedef Member_iterator<
98 iri_index_t::const_iterator,
102 typedef boost::iterator_range<iri_iterator> iri_range;
104 typedef Member_iterator<
105 version_index_t::const_iterator,
109 typedef boost::iterator_range<version_iterator> version_range;
113 std::size_t size()
const {
return m_.size();}
114 const_iterator begin()
const {
return m_.begin();}
115 const_iterator end()
const {
return m_.end();}
117 Doc_meta
const& operator[](
const Doc_id did)
const {
118 id_index_t
const& index = m_.get<id_tag>();
119 const id_index_t::const_iterator iter = index.find(did);
120 BOOST_ASSERT( iter != index.end() );
124 Doc_meta
const& at(
const Doc_id did)
const {
125 id_index_t
const& index = m_.get<id_tag>();
126 const id_index_t::const_iterator iter = index.find(did);
127 if( iter == index.end() ) BOOST_THROW_EXCEPTION(
129 << Err::msg_t(
"invalid document ID")
130 << Err::int1_t(did())
135 Doc_meta
const* find(
const Doc_id did)
const {
136 id_index_t
const& index = m_.get<id_tag>();
137 const id_index_t::const_iterator iter = index.find(did);
138 if( iter == index.end() )
return 0;
147 return m_.get<iri_tag>().equal_range(iri_id);
155 return m_.get<version_tag>().equal_range(version_id);
158 path_range find_path(std::string
const& path)
const {
159 return m_.get<path_tag>().equal_range(path);
186 std::string
const& path =
"",
187 const Node_id vers = terms::empty_::id()
189 if( iri == terms::empty_::id() ) BOOST_THROW_EXCEPTION(
191 << Err::msg_t(
"empty ontologyIRI is not allowed")
194 if( iri == vers ) BOOST_THROW_EXCEPTION(
196 << Err::msg_t(
"ontologyIRI and versionIRI are same")
200 Doc_id const* did = check_existing(iri, vers, path);
201 if( did )
return std::make_pair(*did,
false);
202 const Doc_id id = idt_.get();
203 m_.insert(Doc_meta_wrap(iri, vers, path,
id));
204 return std::make_pair(
id,
true);
209 idt_ = detail::Id_tracker<Doc_id>();
214 detail::Id_tracker<Doc_id> idt_;
216 Doc_id
const* check_existing(
219 std::string
const& path
221 BOOST_ASSERT( ! is_empty(iri) );
222 Doc_id
const* idp = 0;
225 if( ! is_empty(vers) ) {
227 Doc_meta_wrap
const& dmw,
228 m_.get<version_tag>().equal_range(vers)
230 BOOST_ASSERT( ! is_empty(dmw.ontology_iri()) );
231 if( dmw.ontology_iri() != iri ) BOOST_THROW_EXCEPTION(
233 << Err::msg_t(
"document with same versionIRI and "
234 "different ontologyIRI exists")
235 << Err::int1_t(dmw.id_())
237 if( path == dmw.path() ) idp = &dmw.id_;
242 if( ! path.empty() ) {
244 Doc_meta_wrap
const& dmw,
245 m_.get<path_tag>().equal_range(path)
247 if( dmw.ontology_iri() != iri || dmw.version_iri() != vers )
248 BOOST_THROW_EXCEPTION(
250 << Err::msg_t(
"different versionIRI or ontologyIRI is "
251 "recorded for same document")
253 << Err::int1_t(dmw.id_())
259 if( is_empty(vers) && path.empty() ) {
260 if(
const iri_range r =
find_iri(iri) ) {
262 BOOST_ASSERT( distance(r) == 1 );