aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libutil/fmt.cc14
-rw-r--r--src/libutil/fmt.hh13
-rw-r--r--src/libutil/meson.build1
-rw-r--r--src/libutil/serialise.cc25
-rw-r--r--src/libutil/serialise.hh14
5 files changed, 52 insertions, 15 deletions
diff --git a/src/libutil/fmt.cc b/src/libutil/fmt.cc
new file mode 100644
index 000000000..400fb7ea0
--- /dev/null
+++ b/src/libutil/fmt.cc
@@ -0,0 +1,14 @@
+#include "fmt.hh" // IWYU pragma: keep
+
+template class boost::basic_format<char>;
+
+namespace nix {
+
+// Explicit instantiation saves about 30 cpu-seconds of compile time
+template HintFmt::HintFmt(const std::string &, const Uncolored<std::string> &s);
+template HintFmt::HintFmt(const std::string &, const std::string &s);
+template HintFmt::HintFmt(const std::string &, const uint64_t &, const char * const &);
+
+HintFmt::HintFmt(const std::string & literal) : HintFmt("%s", Uncolored(literal)) {}
+
+}
diff --git a/src/libutil/fmt.hh b/src/libutil/fmt.hh
index d015f7e5f..7589e51e2 100644
--- a/src/libutil/fmt.hh
+++ b/src/libutil/fmt.hh
@@ -3,7 +3,6 @@
#include <iostream>
#include <string>
-#include <optional>
#include <boost/format.hpp>
// Darwin and FreeBSD stdenv do not define _GNU_SOURCE but do have _Unwind_Backtrace.
#if __APPLE__ || __FreeBSD__
@@ -12,6 +11,9 @@
#include <boost/stacktrace.hpp>
#include "ansicolor.hh"
+// Explicit instantiation in fmt.cc
+extern template class boost::basic_format<char>;
+
namespace nix {
/**
@@ -157,7 +159,9 @@ public:
* Format the given string literally, without interpolating format
* placeholders.
*/
- HintFmt(const std::string & literal) : HintFmt("%s", Uncolored(literal)) {}
+ // Moved out of line because it was instantiating the template below in
+ // every file in the project.
+ HintFmt(const std::string & literal);
/**
* Interpolate the given arguments into the format string.
@@ -193,6 +197,11 @@ public:
}
};
+// Explicit instantiations in fmt.cc
+extern template HintFmt::HintFmt(const std::string &, const Uncolored<std::string> &s);
+extern template HintFmt::HintFmt(const std::string &, const std::string &s);
+extern template HintFmt::HintFmt(const std::string &, const uint64_t &, const char * const &);
+
std::ostream & operator<<(std::ostream & os, const HintFmt & hf);
}
diff --git a/src/libutil/meson.build b/src/libutil/meson.build
index 7c0e45e4b..e7f986363 100644
--- a/src/libutil/meson.build
+++ b/src/libutil/meson.build
@@ -17,6 +17,7 @@ libutil_sources = files(
'experimental-features.cc',
'file-descriptor.cc',
'file-system.cc',
+ 'fmt.cc',
'git.cc',
'hash.cc',
'hilite.cc',
diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc
index a6dd7e200..4eda1b7e7 100644
--- a/src/libutil/serialise.cc
+++ b/src/libutil/serialise.cc
@@ -9,6 +9,31 @@
namespace nix {
+template<typename T>
+T readNum(Source & source)
+{
+ unsigned char buf[8];
+ source(charptr_cast<char *>(buf), sizeof(buf));
+
+ auto n = readLittleEndian<uint64_t>(buf);
+
+ if (n > (uint64_t) std::numeric_limits<T>::max())
+ throw SerialisationError("serialised integer %d is too large for type '%s'", n, typeid(T).name());
+
+ return (T) n;
+}
+
+template bool readNum<bool>(Source & source);
+
+template unsigned char readNum<unsigned char>(Source & source);
+
+template unsigned int readNum<unsigned int>(Source & source);
+
+template unsigned long readNum<unsigned long>(Source & source);
+template long readNum<long>(Source & source);
+
+template unsigned long long readNum<unsigned long long>(Source & source);
+template long long readNum<long long>(Source & source);
void BufferedSink::operator () (std::string_view data)
{
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
index d6a22b3e9..9ad8018d0 100644
--- a/src/libutil/serialise.hh
+++ b/src/libutil/serialise.hh
@@ -450,19 +450,7 @@ inline Sink & operator<<(Sink & sink, const Error & ex)
MakeError(SerialisationError, Error);
template<typename T>
-T readNum(Source & source)
-{
- unsigned char buf[8];
- source(charptr_cast<char *>(buf), sizeof(buf));
-
- auto n = readLittleEndian<uint64_t>(buf);
-
- if (n > (uint64_t) std::numeric_limits<T>::max())
- throw SerialisationError("serialised integer %d is too large for type '%s'", n, typeid(T).name());
-
- return (T) n;
-}
-
+T readNum(Source & source);
inline unsigned int readInt(Source & source)
{