Scine::Sparrow  3.1.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 <fstream>
12 #include <iostream>
13 #include <vector>
14 
15 inline std::ostream& sep(std::ostream& os) {
16  os << ", ";
17  return os;
18 }
19 
20 inline std::ostream& nl(std::ostream& os) {
21  os << "\n";
22  return os;
23 }
24 
25 inline std::string sp(unsigned i) {
26  return std::string(i, ' ');
27 }
28 
30  std::vector<std::string> includes;
31  std::vector<std::string> namespaces;
32  boost::optional<std::string> guard = boost::none;
33 
34  void writeHeader(std::ostream& os) {
35  /* We need to obfuscate the doxygen copyright statement from our license
36  * checker script, which allows only a single such statement in each file.
37  */
38  os << R"delim(/** * @file * @copy)delim"
39  << 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";
40 
41  // Write some more details for cpp files
42  if (!guard) {
43  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";
44  }
45 
46  os << R"delim( */ )delim";
47 
48  if (guard) {
49  os << "#ifndef " << guard.value() << nl;
50  os << "#define " << guard.value() << nl << nl;
51  }
52 
53  for (auto& include : includes) {
54  if (include[0] == '<' || include[0] == '\"') {
55  os << "#include " << include << nl;
56  }
57  else {
58  os << "#include \"" << include << "\"" << nl;
59  }
60  }
61  os << nl;
62 
63  for (auto& name : namespaces) {
64  os << "namespace " << name << " {" << nl;
65  }
66 
67  os << nl;
68  }
69 
70  void writeFooter(std::ostream& os) {
71  os << nl;
72  for (auto iter = std::rbegin(namespaces); iter != std::rend(namespaces); ++iter) {
73  os << "} // namespace " << *iter << nl;
74  }
75 
76  if (guard) {
77  os << nl << "#endif";
78  }
79  }
80 };
81 
82 inline std::string lower(std::string a) {
83  std::transform(std::begin(a), std::end(a), std::begin(a), [](unsigned char c) { return std::tolower(c); });
84  return a;
85 }
86 
87 inline std::string upper(std::string a) {
88  std::transform(std::begin(a), std::end(a), std::begin(a), [](unsigned char c) { return std::toupper(c); });
89  return a;
90 }
91 
92 namespace detail {
93 
94 template<typename Arg>
95 void writePack(std::ostream& os, Arg arg) {
96  os << arg;
97 }
98 
99 template<typename Arg, typename... Args>
100 void writePack(std::ostream& os, Arg arg1, Args... args) {
101  os << arg1 << sep;
102  writePack(os, args...);
103 }
104 
105 template<typename Tuple, std::size_t... Inds>
106 void writeTuplePackHelper(std::ostream& os, const Tuple& tup, std::index_sequence<Inds...> /* inds */
107 ) {
108  writePack(os, std::get<Inds>(tup)...);
109 }
110 
111 template<typename Tuple>
112 void writeTuplePack(std::ostream& os, const Tuple& tup) {
113  writeTuplePackHelper(os, tup, std::make_index_sequence<std::tuple_size<Tuple>::value>{});
114 }
115 
116 } // namespace detail
117 
118 template<typename... Args>
119 struct Joiner {
120  Joiner(const Args&... args) : bound(args...) {
121  }
122 
123  std::tuple<const Args&...> bound;
124 };
125 
126 template<typename... Args>
127 auto join(const Args&... args) {
128  return Joiner<Args...>(args...);
129 }
130 
131 template<typename... Args>
132 std::ostream& operator<<(std::ostream& os, const Joiner<Args...>& join) {
133  detail::writeTuplePack(os, join.bound);
134  return os;
135 }
136 
137 /* Note: We need to wrap optionals because boost provides its own output
138  * operators that don't serve our purpose. We can't use the type directly
139  * because there's already a declaration available for it by inclusion of boost
140  * optional.
141  */
142 template<typename T>
143 struct OptionalWrapper {
144  boost::optional<T> optional;
145 };
146 
147 template<typename T>
148 auto wrapOptional(const boost::optional<T>& optional) {
149  return OptionalWrapper<T>{optional};
150 }
151 
152 template<typename T>
153 std::ostream& operator<<(std::ostream& os, const OptionalWrapper<T>& o) {
154  if (o.optional) {
155  os << o.optional.value();
156  }
157  else {
158  os << "boost::none";
159  }
160  return os;
161 }
163 #endif
164 
Definition: Common.h:162
Definition: Common.h:29
Definition: Common.h:138