owlcpp  v0.3.3~
C++ library for working with OWL ontologies
 All Classes Namespaces Files Functions Macros Pages
node_literal.hpp
Go to the documentation of this file.
1 
6 #ifndef NODE_LITERAL_HPP_
7 #define NODE_LITERAL_HPP_
8 #include <string>
9 #include "boost/functional/hash.hpp"
10 #include "boost/lexical_cast.hpp"
11 
12 #include "owlcpp/rdf/node.hpp"
13 #include "owlcpp/rdf/exception.hpp"
14 #include "owlcpp/node_id.hpp"
17 #include "owlcpp/rdf/node_fwd.hpp"
19 
20 namespace owlcpp{
21 
24 class Node_literal : public Node {
25 public:
26  Node_id datatype() const {return datatype_impl();}
27  std::string value_str() const {return value_str_impl();}
28 private:
29  virtual Node_id datatype_impl() const =0;
30  virtual std::string value_str_impl() const =0;
31  Ns_id ns_id_impl() const { return terms::empty::id(); }
32 };
33 
34 namespace detail{
35 
38 template<class Dt> class Node_literal_impl : public Node_literal {
40  typedef typename Dt::default_datatype default_datatype;
41 
42 public:
43  typedef typename Dt::value_type value_type;
44 
45  template<class In> static value_type convert(In const& in, const Node_id dt) {
46  try{
47  return Dt::convert(in, dt);
48  } catch(std::bad_cast const&) {
49  BOOST_THROW_EXCEPTION(
50  Rdf_err()
51  << Rdf_err::msg_t("error converting to " + Dt::name_str(dt))
52  << Rdf_err::str1_t("\"" + boost::lexical_cast<std::string>(in) + "\"")
53  );
54  }
55  }
56 
57  template<class T> explicit Node_literal_impl(
58  T const& val,
59  const Node_id dt = default_datatype::id()
60  )
61  : val_(convert<T>(val, dt)), dt_(dt)
62  {}
63 
64  explicit Node_literal_impl(
65  char const* val,
66  const Node_id dt = default_datatype::id()
67  )
68  : val_(convert(std::string(val), dt)), dt_(dt)
69  {}
70 
71  explicit Node_literal_impl(
72  std::string const& val,
73  const Node_id dt = default_datatype::id()
74  )
75  : val_(convert(val, dt)), dt_(dt)
76  {}
77 
78  value_type value() const {return val_;}
79 
80 private:
81  value_type val_;
82  Node_id dt_;
83 
84  OWLCPP_VISITABLE
85 
86  std::string value_str_impl() const {return Dt::to_string(val_, dt_);}
87 
88  Node_id datatype_impl() const {return dt_;}
89 
90  bool equal_impl(const Node& n) const {
91  //todo: use typeid()?
92  if( self_type const*const p = dynamic_cast<self_type const*>(&n) ) {
93  return dt_ == p->dt_ && val_ == p->val_;
94  }
95  return false;
96  }
97 
98  std::size_t hash_impl() const {
99  std::size_t h = 0;
100  boost::hash_combine(h, val_);
101  boost::hash_combine(h, dt_);
102  return h;
103  }
104 
105  Node* clone_impl() const {return new self_type(*this);}
106 
107 };
108 
111 template<> class Node_literal_impl<Datatype_string> : public Node_literal {
113  typedef Datatype_string::default_datatype default_datatype;
114 
115  static std::size_t _hash(std::string const& val, const Node_id dt, std::string const& lang) {
116  std::size_t h = 0;
117  boost::hash_combine(h, val);
118  boost::hash_combine(h, lang);
119  boost::hash_combine(h, dt);
120  return h;
121  }
122 
123 public:
124  typedef Datatype_string::value_type value_type;
125 
126  explicit Node_literal_impl(
127  std::string const& val,
128  const Node_id dt,
129  std::string const& lang = ""
130  )
131  : val_(val), lang_(lang), hash_(_hash(val, dt, lang)), dt_(dt)
132  {}
133 
134  explicit Node_literal_impl(
135  std::string const& val,
136  std::string const& lang = ""
137  )
138  : val_(val),
139  lang_(lang),
140  hash_(_hash(val, default_datatype::id(), lang)),
141  dt_(default_datatype::id())
142  {}
143 
144  std::string const& language() const {return lang_;}
145  std::string const& value() const {return val_;}
146 
147 private:
148  std::string val_;
149  std::string lang_;
150  std::size_t hash_;
151  Node_id dt_;
152 
153  OWLCPP_VISITABLE
154 
155  Node_id datatype_impl() const {return dt_;}
156 
157  std::string value_str_impl() const {return val_;}
158 
159  bool empty_impl() const { return val_.empty() && lang_.empty() && is_empty(dt_); }
160 
161  bool equal_impl(const Node& n) const {
162  //todo: use typeid()?
163  if( self_type const*const p = dynamic_cast<self_type const*>(&n) ) {
164  return dt_ == p->dt_ && lang_ == p->lang_ && val_ == p->val_;
165  }
166  return false;
167  }
168 
169  std::size_t hash_impl() const {return hash_;}
170 
171  Node* clone_impl() const {return new self_type(*this);}
172 };
173 
174 }//namespace detail
175 }//namespace owlcpp
176 #endif /* NODE_LITERAL_HPP_ */