Vcsn  2.3a
Be Rational
tags.hh
Go to the documentation of this file.
1 #pragma once
2 
4 #include <vcsn/algos/standard.hh>
6 #include <vcsn/misc/static-if.hh>
7 #include <vcsn/misc/symbol.hh>
8 
9 namespace vcsn
10 {
11  /*------------------.
12  | tags definitions |
13  `------------------*/
14 
16  struct auto_tag {};
17 
19  struct deterministic_tag {};
20 
22  struct general_tag
23  {
24  static symbol sname()
25  {
26  static auto res = symbol{"general_tag"};
27  return res;
28  }
29  };
30 
32  struct standard_tag
33  {
34  static symbol sname()
35  {
36  static auto res = symbol{"standard_tag"};
37  return res;
38  }
39  };
40 
41  namespace detail
42  {
44  template <Automaton... Aut, typename Operation>
45  auto
46  dispatch_tags(std::string algo, Operation op, Aut&&... auts)
47  {
48  // Whether all the labelsets are free. Requirement to call
49  // determinize/is_deterministic.
50  constexpr bool are_free
51  = all_<labelset_t_of<decltype(auts)>::is_free()...>();
52 
53  if (algo == "auto")
54  {
55  // Applies to both GCC and Clang. Cannot be done inside a
56  // statement.
57 #if defined __GNUC__
58 # pragma GCC diagnostic push
59 # pragma GCC diagnostic ignored "-Wunused-parameter"
60 #endif
61  if (all(is_standard(std::forward<Aut>(auts))...))
62  algo = "standard";
63  else if (static_if<are_free>
64  ([](auto&&... as){ return all(is_deterministic(as)...); },
65 #if (defined __clang__ && __clang_major__ == 3 && __clang_minor__ < 6 \
66  || defined __GNUC__ && !defined __clang__ && __GNUC__ < 5)
67  // Clang 3.5 and GCC 4.9 require that we name the argument.
68  [](auto&&... as){ return false; }
69 #else
70  [](auto&&...){ return false; }
71 #endif
72  )
73  (std::forward<Aut>(auts)...))
74  algo = "deterministic";
75  else
76  algo = "general";
77 #if defined __GNUC__
78 # pragma GCC diagnostic pop
79 #endif
80  }
81 
82  if (algo == "general")
83  return op(general_tag{});
84  else if (algo == "standard")
85  return op(standard_tag{});
86  else
87  {
88  using res_t = decltype(op(standard_tag{}));
89  res_t res = nullptr;
90  if (algo == "deterministic")
91  static_if<are_free>([&res](auto&& op)
92  { res = op(deterministic_tag{}); })(op);
93  require(res, "invalid algorithm: ", str_escape(algo));
94  return res;
95  }
96  }
97 
99  template <Automaton... Auts>
100  auto
102  // SFINAE
103  -> decltype(join_automata(std::forward<Auts>(auts)...))
104  {
105  return join_automata(std::forward<Auts>(auts)...);
106  }
107 
110  template <Automaton... Auts>
111  auto
113  // SFINAE
114  -> decltype(nullable_join_automata(std::forward<Auts>(auts)...))
115  {
116  return nullable_join_automata(std::forward<Auts>(auts)...);
117  }
118 
120  template <Automaton... Auts>
121  auto
123  // SFINAE
124  -> decltype(join_automata(std::forward<Auts>(auts)...))
125  {
126  return join_automata(std::forward<Auts>(auts)...);
127  }
128  }
129 
132  struct boolean_tag
133  {
134  static symbol sname()
135  {
136  static auto res = symbol{"boolean_tag"};
137  return res;
138  }
139  };
140 
144  struct dijkstra_tag {};
145 
150  {
151  static symbol sname()
152  {
153  static auto res = symbol{"weighted_tag"};
154  return res;
155  }
156  };
157 }
bool is_standard(const Aut &a)
Whether a is standard.
Definition: standard.hh:28
Tag for operations on all automata.
Definition: tags.hh:22
Tag for operations on standard automata.
Definition: tags.hh:32
Definition: a-star.hh:8
bool is_deterministic(const Aut &aut, state_t_of< Aut > s)
Whether state s is deterministic in aut.
return res
Definition: multiply.hh:398
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:91
auto dispatch_tags(std::string algo, Operation op, Aut &&...auts)
Dispatch an operation between automata depending on their nature.
Definition: tags.hh:46
Dijkstra implementation.
Definition: tags.hh:144
static symbol sname()
Definition: tags.hh:134
Tag to request the most appropriate version of an algorithm.
Definition: tags.hh:16
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
Definition: symbol.hh:23
bool all(Bool &&...values)
Whether all the values evaluate as true.
Definition: tuple.hh:446
std::ostream & str_escape(std::ostream &os, const std::string &str, const char *special=nullptr)
Output a string, escaping special characters.
Definition: escape.cc:51
Tag for operations on deterministic automata.
Definition: tags.hh:19
Request the Boolean specialization for determinization (B and F2).
Definition: tags.hh:132
auto make_join_automaton(deterministic_tag, Auts &&...auts) -> decltype(join_automata(std::forward< Auts >(auts)...))
Make an empty automaton which is a supertype of others.
Definition: tags.hh:101
static symbol sname()
Definition: tags.hh:151
auto nullable_join_automata(Auts &&...auts) -> decltype(pass(auts->null_state()...), make_mutable_automaton(nullable_join_context(auts...)))
An automaton whose type is the nullable join between those of auts.
Request for the weighted version of an algorithm.
Definition: tags.hh:149
auto join_automata(Auts &&...auts) -> decltype(pass(auts->null_state()...), make_mutable_automaton(join(auts->context()...)))
An automaton whose type is the join between those of auts.
static symbol sname()
Definition: tags.hh:24
#define Automaton
Definition: automaton.hh:23
static symbol sname()
Definition: tags.hh:34