plot
Header-only C++ SVG charts — heatmap, line, scatter — GR-style API + Solarized themes
Loading...
Searching...
No Matches
utils.hpp
1/* Copyright (c) 2026 Steven Varga, Toronto, ON, Canada
2 * MIT License — see LICENSE
3 *
4 * Small SVG helpers: HTML/XML text escaping, a C++17 is_base_of replacement,
5 * and a label-width helper for axis layout. Ported from plot:: into
6 * plot::. Dependency-free (standard library only).
7 */
8#ifndef PLOT_UTILS_HPP
9#define PLOT_UTILS_HPP
10
11#include <string>
12#include <vector>
13#include <algorithm>
14#include <type_traits>
15#include <cstddef>
16
17namespace plot::util {
18 inline std::string html_escape( const std::string& data ){
19 std::string buffer;
20 buffer.reserve(data.size());
21 for(std::size_t pos = 0; pos != data.size(); ++pos) {
22 switch(data[pos]) {
23 case '&': buffer.append("&amp;"); break;
24 case '\"': buffer.append("&quot;"); break;
25 case '\'': buffer.append("&apos;"); break;
26 case '<': buffer.append("&lt;"); break;
27 case '>': buffer.append("&gt;"); break;
28 default: buffer.append(&data[pos], 1); break;
29 }
30 }
31 return buffer;
32 }
33}
34namespace plot::util::details {
35 template <typename Base> std::true_type is_base_of_test_func(Base*);
36 template <typename Base> std::false_type is_base_of_test_func(void*);
37 template <typename Base, typename Derived>
38 using pre_is_base_of = decltype(is_base_of_test_func<Base>(std::declval<Derived*>()));
39
40 template <typename Base, typename Derived, typename = void>
41 struct pre_is_base_of2 : public std::true_type { };
42 // note std::void_t is a C++17 feature
43 template <typename Base, typename Derived>
44 struct pre_is_base_of2<Base, Derived, std::void_t<pre_is_base_of<Base, Derived>>> :
45 public pre_is_base_of<Base, Derived> { };
46}
47
48namespace plot::util {
49template <typename Base, typename Derived>
50struct is_base_of :
51 public std::conditional_t<
52 std::is_class<Base>::value && std::is_class<Derived>::value,
53 details::pre_is_base_of2<Base, Derived>,
54 std::false_type
55 > { };
56}
57
58namespace plot::utils {
59 inline std::size_t size_of_max_value( const std::vector<std::string>& lbl ){
60 auto it = std::max_element( std::begin(lbl), std::end(lbl),
61 [](const auto& a, const auto& b) -> bool {
62 return a.size() < b.size();
63 });
64 return it->size();
65 }
66}
67#endif