diff options
-rw-r--r-- | src/libutil/fmt.cc | 14 | ||||
-rw-r--r-- | src/libutil/fmt.hh | 13 | ||||
-rw-r--r-- | src/libutil/meson.build | 1 | ||||
-rw-r--r-- | src/libutil/serialise.cc | 25 | ||||
-rw-r--r-- | src/libutil/serialise.hh | 14 |
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) { |