Scine::Sparrow  4.0.0
Library for fast and agile quantum chemical calculations with semiempirical methods.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
Common.h
Go to the documentation of this file.
1 
7 #ifndef INCLUDE_SPARROW_EMBED_COMMON_H
8 #define INCLUDE_SPARROW_EMBED_COMMON_H
9 
10 #include "boost/optional.hpp"
11 #include <algorithm>
12 #include <fstream>
13 #include <iostream>
14 #include <vector>
15 
16 inline std::ostream& sep(std::ostream& os) {
17  os << ", ";
18  return os;
19 }
20 
21 inline std::ostream& nl(std::ostream& os) {
22  os << "\n";
23  return os;
24 }
25 
26 inline std::string sp(unsigned i) {
27  return std::string(i, ' ');
28 }
29 
31  std::vector<std::string> includes;
32  std::vector<std::string> namespaces;
33  boost::optional<std::string> guard = boost::none;
34 
35  void writeHeader(std::ostream& os) {
36  /* We need to obfuscate the doxygen copyright statement from our license
37  * checker script, which allows only a single such statement in each file.
38  */
39  os << R"delim(/** * @file * @copy)delim"
40  << R"delim(right This code is licensed under the 3-clause BSD license.\n * Copyright ETH Zurich, Laboratory of Physical Chemistry, Reiher Group.\n * See LICENSE.txt for details. * * @note This file was generated by the Embed binary from runtime values. * Prefer improving the generator over editing this file whenever possible. * )delim";
41 
42  // Write some more details for cpp files
43  if (!guard) {
44  os << R"delim( * This file contains functions generating runtime values. It was * generated from runtime values of its return type. It is not intended to be * human-readable. A small guide: Return values are directly brace-initialized * in deep nesting to keep file size to a minimum. Types are annotated only when * necessary. Floating point values are represented in hexadecimal (see * std::hexfloat) to ensure serialization does not cause loss of accuracy. * * The functions defined here might be declared and called elsewhere entirely. * )delim";
45  }
46 
47  os << R"delim( */ )delim";
48 
49  if (guard) {
50  os << "#ifndef " << guard.value() << nl;
51  os << "#define " << guard.value() << nl << nl;
52  }
53 
54  for (auto& include : includes) {
55  if (include[0] == '<' || include[0] == '\"') {
56  os << "#include " << include << nl;
57  }
58  else {
59  os << "#include \"" << include << "\"" << nl;
60  }
61  }
62  os << nl;
63 
64  for (auto& name : namespaces) {
65  os << "namespace " << name << " {" << nl;
66  }
67 
68  os << nl;
69  }
70 
71  void writeFooter(std::ostream& os) {
72  os << nl;
73  for (auto iter = std::rbegin(namespaces); iter != std::rend(namespaces); ++iter) {
74  os << "} // namespace " << *iter << nl;
75  }
76 
77  if (guard) {
78  os << nl << "#endif";
79  }
80  }
81 };
82 
83 inline std::string lower(std::string a) {
84  std::transform(std::begin(a), std::end(a), std::begin(a), [](unsigned char c) { return std::tolower(c); });
85  return a;
86 }
87 
88 inline std::string upper(std::string a) {
89  std::transform(std::begin(a), std::end(a), std::begin(a), [](unsigned char c) { return std::toupper(c); });
90  return a;
91 }
92 
93 namespace detail {
94 
95 template<typename Arg>
96 void writePack(std::ostream& os, Arg arg) {
97  os << arg;
98 }
99 
100 template<typename Arg, typename... Args>
101 void writePack(std::ostream& os, Arg arg1, Args... args) {
102  os << arg1 << sep;
103  writePack(os, args...);
104 }
105 
106 template<typename Tuple, std::size_t... Inds>
107 void writeTuplePackHelper(std::ostream& os, const Tuple& tup, std::index_sequence<Inds...> /* inds */
108 ) {
109  writePack(os, std::get<Inds>(tup)...);
110 }
111 
112 template<typename Tuple>
113 void writeTuplePack(std::ostream& os, const Tuple& tup) {
114  writeTuplePackHelper(os, tup, std::make_index_sequence<std::tuple_size<Tuple>::value>{});
115 }
116 
117 } // namespace detail
118 
119 template<typename... Args>
120 struct Joiner {
121  Joiner(const Args&... args) : bound(args...) {
122  }
123 
124  std::tuple<const Args&...> bound;
125 };
126 
127 template<typename... Args>
128 auto join(const Args&... args) {
129  return Joiner<Args...>(args...);
130 }
131 
132 template<typename... Args>
133 std::ostream& operator<<(std::ostream& os, const Joiner<Args...>& join) {
134  detail::writeTuplePack(os, join.bound);
135  return os;
136 }
137 
138 /* Note: We need to wrap optionals because boost provides its own output
139  * operators that don't serve our purpose. We can't use the type directly
140  * because there's already a declaration available for it by inclusion of boost
141  * optional.
142  */
143 template<typename T>
144 struct OptionalWrapper {
145  boost::optional<T> optional;
146 };
147 
148 template<typename T>
149 auto wrapOptional(const boost::optional<T>& optional) {
150  return OptionalWrapper<T>{optional};
151 }
152 
153 template<typename T>
154 std::ostream& operator<<(std::ostream& os, const OptionalWrapper<T>& o) {
155  if (o.optional) {
156  os << o.optional.value();
157  }
158  else {
159  os << "boost::none";
160  }
161  return os;
162 }
164 #endif
165 
Definition: Common.h:163
Definition: Common.h:30
Definition: Common.h:139