Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
context.hh
Go to the documentation of this file.
1 #ifndef VCSN_CTX_CONTEXT_HH
2 # define VCSN_CTX_CONTEXT_HH
3 
4 # include <cassert>
5 # include <memory>
6 # include <string>
7 
8 # include <vcsn/core/join.hh>
9 # include <vcsn/core/kind.hh>
10 # include <vcsn/core/rat/fwd.hh>
11 # include <vcsn/ctx/fwd.hh>
12 # include <vcsn/misc/stream.hh>
13 # include <vcsn/misc/symbol.hh>
14 
15 namespace vcsn
16 {
17 
18  template <typename LabelSet, typename WeightSet>
19  class context
20  {
21  public:
24  using labelset_ptr = std::shared_ptr<const labelset_t>;
25  using weightset_ptr = std::shared_ptr<const weightset_t>;
26 
27  using kind_t = typename labelset_t::kind_t;
28  enum
29  {
36  };
38  using label_t = typename labelset_t::value_t;
40  using weight_t = typename weightset_t::value_t;
41 
42  context(const context& that)
43  : context(that.ls_, that.ws_)
44  {}
45 
48  context(const labelset_ptr& ls, const weightset_ptr& ws)
49  : ls_{ls}
50  , ws_{ws}
51  {}
52 
56  context(const labelset_t& ls, const weightset_t& ws = {})
57  : context(std::make_shared<const labelset_t>(ls),
58  std::make_shared<const weightset_t>(ws))
59  {}
60 
64  //
65  // Use SFINAE to avoid requiring labelset_t to define letter_t.
66  // labels_are_tuples does not define it for instance.
67  //
68  // It would be simpler to just use "= {}", but the C++ standard
69  // does not support it (and this is properly considered a
70  // defect: see http://cplusplus.github.io/LWG/lwg-active.html#2193).
71  //
72  // Gcc accepts though.
73  // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56922
74  // But clang rejects it.
75  // http://llvm.org/bugs/show_bug.cgi?id=15724
76  template <typename LabelSet2 = labelset_t>
77  context(const std::initializer_list<typename LabelSet2::letter_t>& gs,
78  const weightset_t& ws = {})
79  : context{labelset_t{gs}, ws}
80  {}
81 
83  template <typename LabelSet2 = labelset_t>
85  : context{typename std::enable_if<is_lao, labelset_t>::type{},
86  weightset_t{}}
87  {}
88 
90  {
91  if (this != &that)
92  {
93  std::swap(ls_, that.ls_);
94  std::swap(ws_, that.ws_);
95  }
96  return *this;
97  }
98 
101  static std::string sname()
102  {
103  return (labelset_t::sname()
104  + ", " + weightset_t::sname());
105  }
106 
107  std::string vname(bool full = true) const
108  {
109  return (labelset()->vname(full)
110  + ", " + weightset()->vname(full));
111  }
112 
114  static context make(std::istream& is)
115  {
116  auto ls = labelset_t::make(is);
117  eat(is, ',');
118  while (isspace(is.peek()))
119  is.ignore();
120  auto ws = weightset_t::make(is);
121  return {ls, ws};
122  }
123 
124  const labelset_ptr& labelset() const
125  {
126  return ls_;
127  }
128 
129  const weightset_ptr& weightset() const
130  {
131  return ws_;
132  }
133 
134  std::ostream&
135  print_set(std::ostream& o, symbol format = symbol{"text"}) const
136  {
137  labelset()->print_set(o, format);
138  if (format == "latex")
139  o << "\\rightarrow";
140  else
141  o << ", ";
142  return weightset()->print_set(o, format);
143  }
144 
145  static constexpr bool
147  {
148  return labelset_t::has_one();
149  }
150 
151  private:
154  };
155 
156 
158  template <typename LabelSet, typename WeightSet>
160  make_context(const LabelSet& ls, const WeightSet& ws)
161  {
162  return {ls, ws};
163  }
164 
165 
166 
167  /*-----------------.
168  | join_t, meet_t. |
169  `-----------------*/
170 
171  template <typename... ValueSets>
172  using meet_t = decltype(meet(std::declval<ValueSets>()...));
173 
174 
175  /*-------------------------.
176  | Variadic join and meet. |
177  `-------------------------*/
178 
181  template <typename ValueSet>
182  auto
183  meet(const ValueSet& vs)
184  -> ValueSet
185  {
186  return vs;
187  }
188 
189  template <typename ValueSet1, typename ValueSet2, typename ValueSet3,
190  typename... VSs>
191  auto
192  meet(const ValueSet1& vs1, const ValueSet2& vs2, const ValueSet3& vs3,
193  const VSs&... vs)
194  -> decltype(meet(meet(vs1, vs2), vs3, vs...))
195  {
196  return meet(meet(vs1, vs2), vs3, vs...);
197  }
198 
199 
200  /*-------------------------.
201  | join(context, context). |
202  `-------------------------*/
203 
204  namespace detail
205  {
207  template <typename LS1, typename WS1,
208  typename LS2, typename WS2>
209  struct join_impl<context<LS1, WS1>, context<LS2, WS2>>
210  {
214 
215  static type join(const context<LS1, WS1>& ctx1,
216  const context<LS2, WS2>& ctx2)
217  {
218  return {vcsn::join(*ctx1.labelset(), *ctx2.labelset()),
219  vcsn::join(*ctx1.weightset(), *ctx2.weightset())};
220  }
221  };
222  }
223 
224  /*-------------------------.
225  | meet(context, context). |
226  `-------------------------*/
227 
229  template <typename LhsLabelSet, typename LhsWeightSet,
230  typename RhsLabelSet, typename RhsWeightSet>
231  auto
236  {
237  auto ls = meet(*a.labelset(), *b.labelset());
238  auto ws = join(*a.weightset(), *b.weightset());
239  return {ls, ws};
240  }
241 
242 }
243 
244 #endif // !VCSN_CTX_CONTEXT_HH
LabelSet labelset_t
Definition: context.hh:22
labelset_ptr ls_
Definition: context.hh:152
static context make(std::istream &is)
Build from the description in is.
Definition: context.hh:114
decltype(join(std::declval< ValueSets >()...)) join_t
The type of the join of the ValueSets.
Definition: join.hh:61
const weightset_ptr & weightset() const
Definition: context.hh:129
static std::string sname()
The name of this context, built from its parameters.
Definition: context.hh:101
std::ostream & print_set(std::ostream &o, symbol format=symbol{"text"}) const
Definition: context.hh:135
context(const labelset_t &ls, const weightset_t &ws={})
Build a context.
Definition: context.hh:56
weightset_ptr ws_
Definition: context.hh:153
context & operator=(context &&that)
Definition: context.hh:89
std::string vname(bool full=true) const
Definition: context.hh:107
std::shared_ptr< const labelset_t > labelset_ptr
Definition: context.hh:24
context(const labelset_ptr &ls, const weightset_ptr &ws)
Definition: context.hh:48
boost::flyweight< std::string, boost::flyweights::no_tracking > symbol
An internalized string.
Definition: symbol.hh:24
std::string sname()
Definition: name.hh:31
typename weightset_t::value_t weight_t
Type of weights.
Definition: context.hh:40
context(const context &that)
Definition: context.hh:42
auto meet(const ratexpset< Ctx1 > &a, const ratexpset< Ctx2 > &b) -> ratexpset< meet_t< Ctx1, Ctx2 >>
The meet of two ratexpsets.
Definition: ratexpset.hh:480
std::istringstream is
The input stream: the specification to translate.
Definition: translate.cc:329
static type join(const context< LS1, WS1 > &ctx1, const context< LS2, WS2 > &ctx2)
Definition: context.hh:215
const labelset_ptr & labelset() const
Definition: context.hh:124
A structure that implements the computation of join(V1, V2).
Definition: join.hh:19
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:36
context(const std::initializer_list< typename LabelSet2::letter_t > &gs, const weightset_t &ws={})
Build a context.
Definition: context.hh:77
decltype(meet(std::declval< ValueSets >()...)) meet_t
Definition: context.hh:172
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:37
typename labelset_t::value_t label_t
Type of transition labels, and type of RatExp atoms.
Definition: context.hh:38
auto join(const ValueSet &vs) -> ValueSet
The join of a single valueset.
Definition: join.hh:44
std::shared_ptr< const weightset_t > weightset_ptr
Definition: context.hh:25
typename labelset_t::kind_t kind_t
Definition: context.hh:27
context()
Build a context whose labelset constructor takes no argument.
Definition: context.hh:84
Ctx make_context(const std::string &name)
Definition: make-context.hh:22
static constexpr bool has_one()
Definition: context.hh:146