Euphoria
lrud.h
Go to the documentation of this file.
1 #pragma once
2 
3 
4 #include <optional>
5 
6 
7 
8 #include "base/string_io.h"
9 #include "base/stringutils.h"
10 #include "base/default_parse.h"
11 
12 
13 namespace eu
14 {
18  template<typename T>
19  struct Lrud
20  {
21  using Self = Lrud<T>;
22 
23  T left;
24  T right;
25  T up;
26  T down;
27 
28  explicit Lrud(const T& t)
29  : left(t)
30  , right(t)
31  , up(t)
32  , down(t)
33  {
34  }
35 
38  [[nodiscard]]
39  static
40  Self
41  from_lrud(const T& lr, const T& ud)
42  {
43  return {lr, lr, ud, ud};
44  }
45 
48  [[nodiscard]]
49  static
50  Self
51  from_lrud(const T& l, const T& r, const T& u, const T& d)
52  {
53  return {l, r, u, d};
54  }
55 
56  private:
57  Lrud
58  (
59  const T& l,
60  const T& r,
61  const T& u,
62  const T& d
63  )
64  : left(l)
65  , right(r)
66  , up(u)
67  , down(d)
68  {
69  }
70  };
71 
72 
73  template<typename T>
74  bool
75  operator==(const Lrud<T>& lhs, const Lrud<T>& rhs)
76  {
77  return
78  lhs.left == rhs.left &&
79  lhs.right == rhs.right &&
80  lhs.up == rhs.up &&
81  lhs.down == rhs.down
82  ;
83  }
84 
85 
86  template<typename T>
87  bool
88  operator!=(const Lrud<T>& lhs, const Lrud<T>& rhs)
89  {
90  return !(lhs == rhs);
91  }
92 
93 
97  template<typename T>
98  struct StringParser<Lrud<T>>
99  {
100  enum { value = 1 };
101 
102  using Self = Lrud<T>;
103 
104  static constexpr char separator = '/';
105 
106  static
107  std::string
108  to_string(const Self& fw)
109  {
110  return fmt::format
111  (
112  "{1}{0}{2}{0}{3}{0}{4}",
113  separator,
118  );
119  }
120 
121  static
123  parse(const std::string& value)
124  {
125  using R = Result<Self>;
126  auto parse = [](const std::string& v)
127  {
128  return default_parse_function<T>(v);
129  };
130  const auto values = split(value, separator);
131  switch(values.size())
132  {
133  case 1:
134  {
135  const auto val = parse(values[0]);
136 
137  if(!val) { return R::create_error(val.get_error()); }
138 
139  return R::create_value(Self{*val});
140  }
141  case 2:
142  {
143  const auto vvert = values[0];
144  const auto vhor = values[1];
145 
146  const auto vert = parse(vvert);
147  const auto hor = parse(vhor);
148 
149  if(!hor) { return R::create_error(fmt::format("invalid hor({}): {}", vhor, hor.get_error())); }
150  if(!vert) { return R::create_error(fmt::format("invalid vert({}): {}", vvert, vert.get_error())); }
151 
152  return R::create_value(Self::from_lrud(*hor, *vert));
153  }
154  case 4:
155  {
156  const auto vup = values[0];
157  const auto vright = values[1];
158  const auto vdown = values[2];
159  const auto vleft = values[3];
160 
161  const auto up = parse(vup);
162  const auto right = parse(vright);
163  const auto down = parse(vdown);
164  const auto left = parse(vleft);
165 
166  if(!left) { return R::create_error(fmt::format("invalid left({}): {}", vleft, left.get_error())); }
167  if(!right) { return R::create_error(fmt::format("invalid right({}): {}", vright, right.get_error())); }
168  if(!up) { return R::create_error(fmt::format("invalid up({}): {}", vup, up.get_error())); }
169  if(!down) { return R::create_error(fmt::format("invalid down({}): {}", vdown, down.get_error())); }
170 
171  return R::create_value(Self::from_lrud
172  (
173  *left,
174  *right,
175  *up,
176  *down
177  ));
178  }
179  default:
180  {
181  return R::create_error("wrong number of splits in fourway");
182  }
183  }
184  }
185  };
186 
187 }
188 
189 
190 template<typename T>
191 struct fmt::formatter<eu::Lrud<T>> : formatter<std::string>
192 {
193  template <typename FormatContext>
194  auto format(const eu::Lrud<T>& fw, FormatContext& ctx) const
195  {
196  return formatter<string_view>::format
197  (
198  fmt::format("({} {} {} {})", fw.up, fw.right, fw.down, fw.left),
199  ctx
200  );
201  }
202 };
std::vector< std::string > split(const std::string &s, char delim)
Definition: stringutils.cc:431
Definition: assert.h:90
bool operator==(const Lrud< T > &lhs, const Lrud< T > &rhs)
Definition: lrud.h:75
bool operator!=(const Lrud< T > &lhs, const Lrud< T > &rhs)
Definition: lrud.h:88
std::string from_default_value_to_string(const T &t)
String utility functions.
Generic version of a CSS like padding type.
Definition: lrud.h:20
static Self from_lrud(const T &lr, const T &ud)
Create a new fourway from left-righ and up-down.
Definition: lrud.h:41
T right
Definition: lrud.h:24
T left
Definition: lrud.h:23
Lrud< T > Self
Definition: lrud.h:21
Lrud(const T &t)
Definition: lrud.h:28
T up
Definition: lrud.h:25
static Self from_lrud(const T &l, const T &r, const T &u, const T &d)
Create a new fourway from left right up and down.
Definition: lrud.h:51
T down
Definition: lrud.h:26
static std::string to_string(const Self &fw)
Definition: lrud.h:108
static Result< Self > parse(const std::string &value)
Definition: lrud.h:123
auto format(const eu::Lrud< T > &fw, FormatContext &ctx) const
Definition: lrud.h:194