Make it easier to define comparisons available conditionally.

When concrete types are specified at `WithEqual` or `WithCompare`, define
primary comparisons with swapped parameters only if unswapped ones are defined.
Also, do not define secondary comparisons with swapped parameters for concrete
parameter types; they are provided generically.

PiperOrigin-RevId: 922146940
diff --git a/doc/record_writer_options.md b/doc/record_writer_options.md
index 4670d30..936a76f 100644
--- a/doc/record_writer_options.md
+++ b/doc/record_writer_options.md
@@ -67,7 +67,8 @@
 compression speed (higher = better density but slower).
 
 `zstd_level` must be between -131072 and 22. Level 0 is currently equivalent to
-3. Default: 3.
+
+1.  Default: 3.
 
 ### `snappy`
 
diff --git a/riegeli/base/compare.h b/riegeli/base/compare.h
index dde0185..a95d148 100644
--- a/riegeli/base/compare.h
+++ b/riegeli/base/compare.h
@@ -323,26 +323,23 @@
 
 template <typename T, typename Other>
 class WithSwappedEqual {
-  friend bool operator==(const Other& a, const T& b) { return b == a; }
+  template <typename DependentT = T,
+            std::enable_if_t<
+                compare_internal::HasEqual<DependentT, Other>::value, int> = 0>
+  friend bool operator==(const Other& a, const T& b) {
+    return b == a;
+  }
 };
 
 template <typename T, typename Other>
 class WithSwappedCompare {
+  template <
+      typename DependentT = T,
+      std::enable_if_t<compare_internal::HasCompare<DependentT, Other>::value,
+                       int> = 0>
   friend auto RIEGELI_COMPARE(const Other& a, const T& b) {
     return NegateOrdering(RIEGELI_COMPARE(b, a));
   }
-  friend bool operator<(const Other& a, const T& b) {
-    return RIEGELI_COMPARE(b, a) > 0;
-  }
-  friend bool operator>(const Other& a, const T& b) {
-    return RIEGELI_COMPARE(b, a) < 0;
-  }
-  friend bool operator<=(const Other& a, const T& b) {
-    return RIEGELI_COMPARE(b, a) >= 0;
-  }
-  friend bool operator>=(const Other& a, const T& b) {
-    return RIEGELI_COMPARE(b, a) <= 0;
-  }
 };
 
 }  // namespace compare_internal
@@ -360,11 +357,12 @@
 // If `T` supports heterogeneous comparisons against other types, use
 // `WithEqual<T, Other...>` instead, specifying the types of these parameters.
 // For each of these types, define the appropriate `==` with the first parameter
-// of type `const T&` or `T`.
+// of type `const T&` or `T`. This is applicable also if the comparison is
+// defined conditionally.
 //
-// If the other parameter does not have a concrete type because the `==` is a
-// template, do not add a template parameter of `WithEqual`. Instead, define
-// also `==` with swapped parameters, wrapped in
+// If the other parameter does not have a concrete type because the `==` is
+// a template over several other types, do not add a template parameter of
+// `WithEqual`. Instead, define also `==` with swapped parameters, wrapped in
 // `#if !__cpp_impl_three_way_comparison`.
 template <typename T, typename... Others>
 class WithEqual