public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-5343] libstdc++: Add [[nodiscard]] to std::span members
@ 2023-11-11  0:43 Jonathan Wakely
  0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2023-11-11  0:43 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:a92a434024c59f57dc24328d946f97a5e71cee94

commit r14-5343-ga92a434024c59f57dc24328d946f97a5e71cee94
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sat Nov 4 08:30:54 2023 +0000

    libstdc++: Add [[nodiscard]] to std::span members
    
    All std::span member functions are pure functions that have no side
    effects. They are only useful for their return value, so they should all
    warn if that value is not used.
    
    libstdc++-v3/ChangeLog:
    
            * include/std/span (span, as_bytes, as_writable_bytes): Add
            [[nodiscard]] attribute on all non-void functions.
            * testsuite/23_containers/span/back_assert_neg.cc: Suppress
            nodiscard warning.
            * testsuite/23_containers/span/back_neg.cc: Likewise.
            * testsuite/23_containers/span/first_2_assert_neg.cc: Likewise.
            * testsuite/23_containers/span/first_assert_neg.cc: Likewise.
            * testsuite/23_containers/span/first_neg.cc: Likewise.
            * testsuite/23_containers/span/front_assert_neg.cc: Likewise.
            * testsuite/23_containers/span/front_neg.cc: Likewise.
            * testsuite/23_containers/span/index_op_assert_neg.cc: Likewise.
            * testsuite/23_containers/span/index_op_neg.cc: Likewise.
            * testsuite/23_containers/span/last_2_assert_neg.cc: Likewise.
            * testsuite/23_containers/span/last_assert_neg.cc: Likewise.
            * testsuite/23_containers/span/last_neg.cc: Likewise.
            * testsuite/23_containers/span/subspan_2_assert_neg.cc:
            Likewise.
            * testsuite/23_containers/span/subspan_3_assert_neg.cc:
            Likewise.
            * testsuite/23_containers/span/subspan_4_assert_neg.cc:
            Likewise.
            * testsuite/23_containers/span/subspan_5_assert_neg.cc:
            Likewise.
            * testsuite/23_containers/span/subspan_6_assert_neg.cc:
            Likewise.
            * testsuite/23_containers/span/subspan_assert_neg.cc: Likewise.
            * testsuite/23_containers/span/subspan_neg.cc: Likewise.
            * testsuite/23_containers/span/nodiscard.cc: New test.

Diff:
---
 libstdc++-v3/include/std/span                      | 26 +++++++++-
 .../23_containers/span/back_assert_neg.cc          |  2 +-
 .../testsuite/23_containers/span/back_neg.cc       |  2 +-
 .../23_containers/span/first_2_assert_neg.cc       |  2 +-
 .../23_containers/span/first_assert_neg.cc         |  2 +-
 .../testsuite/23_containers/span/first_neg.cc      |  2 +-
 .../23_containers/span/front_assert_neg.cc         |  2 +-
 .../testsuite/23_containers/span/front_neg.cc      |  2 +-
 .../23_containers/span/index_op_assert_neg.cc      |  2 +-
 .../testsuite/23_containers/span/index_op_neg.cc   |  2 +-
 .../23_containers/span/last_2_assert_neg.cc        |  2 +-
 .../23_containers/span/last_assert_neg.cc          |  2 +-
 .../testsuite/23_containers/span/last_neg.cc       |  2 +-
 .../testsuite/23_containers/span/nodiscard.cc      | 58 ++++++++++++++++++++++
 .../23_containers/span/subspan_2_assert_neg.cc     |  2 +-
 .../23_containers/span/subspan_3_assert_neg.cc     |  2 +-
 .../23_containers/span/subspan_4_assert_neg.cc     |  2 +-
 .../23_containers/span/subspan_5_assert_neg.cc     |  2 +-
 .../23_containers/span/subspan_6_assert_neg.cc     |  2 +-
 .../23_containers/span/subspan_assert_neg.cc       |  2 +-
 .../testsuite/23_containers/span/subspan_neg.cc    |  6 +--
 21 files changed, 103 insertions(+), 23 deletions(-)

diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index d5644a196a2..90d08f18d2c 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -246,20 +246,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // observers
 
+      [[nodiscard]]
       constexpr size_type
       size() const noexcept
       { return this->_M_extent._M_extent(); }
 
+      [[nodiscard]]
       constexpr size_type
       size_bytes() const noexcept
       { return this->_M_extent._M_extent() * sizeof(element_type); }
 
-      [[nodiscard]] constexpr bool
+      [[nodiscard]]
+      constexpr bool
       empty() const noexcept
       { return size() == 0; }
 
       // element access
 
+      [[nodiscard]]
       constexpr reference
       front() const noexcept
       {
@@ -267,6 +271,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return *this->_M_ptr;
       }
 
+      [[nodiscard]]
       constexpr reference
       back() const noexcept
       {
@@ -274,6 +279,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return *(this->_M_ptr + (size() - 1));
       }
 
+      [[nodiscard]]
       constexpr reference
       operator[](size_type __idx) const noexcept
       {
@@ -281,41 +287,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return *(this->_M_ptr + __idx);
       }
 
+      [[nodiscard]]
       constexpr pointer
       data() const noexcept
       { return this->_M_ptr; }
 
       // iterator support
 
+      [[nodiscard]]
       constexpr iterator
       begin() const noexcept
       { return iterator(this->_M_ptr); }
 
+      [[nodiscard]]
       constexpr iterator
       end() const noexcept
       { return iterator(this->_M_ptr + this->size()); }
 
+      [[nodiscard]]
       constexpr reverse_iterator
       rbegin() const noexcept
       { return reverse_iterator(this->end()); }
 
+      [[nodiscard]]
       constexpr reverse_iterator
       rend() const noexcept
       { return reverse_iterator(this->begin()); }
 
 #if __cplusplus > 202002L
+      [[nodiscard]]
       constexpr const_iterator
       cbegin() const noexcept
       { return begin(); }
 
+      [[nodiscard]]
       constexpr const_iterator
       cend() const noexcept
       { return end(); }
 
+      [[nodiscard]]
       constexpr const_reverse_iterator
       crbegin() const noexcept
       { return rbegin(); }
 
+      [[nodiscard]]
       constexpr const_reverse_iterator
       crend() const noexcept
       { return rend(); }
@@ -324,6 +339,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // subviews
 
       template<size_t _Count>
+	[[nodiscard]]
 	constexpr span<element_type, _Count>
 	first() const noexcept
 	{
@@ -335,6 +351,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return _Sp{ this->data(), _Count };
 	}
 
+      [[nodiscard]]
       constexpr span<element_type, dynamic_extent>
       first(size_type __count) const noexcept
       {
@@ -343,6 +360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       template<size_t _Count>
+	[[nodiscard]]
 	constexpr span<element_type, _Count>
 	last() const noexcept
 	{
@@ -354,6 +372,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  return _Sp{ this->data() + (this->size() - _Count), _Count };
 	}
 
+      [[nodiscard]]
       constexpr span<element_type, dynamic_extent>
       last(size_type __count) const noexcept
       {
@@ -362,6 +381,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       template<size_t _Offset, size_t _Count = dynamic_extent>
+	[[nodiscard]]
 	constexpr auto
 	subspan() const noexcept
 	-> span<element_type, _S_subspan_extent<_Offset, _Count>()>
@@ -393,6 +413,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    }
 	}
 
+      [[nodiscard]]
       constexpr span<element_type, dynamic_extent>
       subspan(size_type __offset, size_type __count = dynamic_extent) const
       noexcept
@@ -434,6 +455,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       -> span<remove_reference_t<ranges::range_reference_t<_Range&>>>;
 
   template<typename _Type, size_t _Extent>
+    [[nodiscard]]
     inline
     span<const byte, _Extent == dynamic_extent
 	? dynamic_extent : _Extent * sizeof(_Type)>
@@ -451,7 +473,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline
     span<byte, _Extent == dynamic_extent
        ? dynamic_extent : _Extent * sizeof(_Type)>
-    as_writable_bytes(span<_Type, _Extent> __sp) noexcept
+    as_writable_bytes [[nodiscard]] (span<_Type, _Extent> __sp) noexcept
     {
       auto data = reinterpret_cast<byte*>(__sp.data());
       auto size = __sp.size_bytes();
diff --git a/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc
index b42aea3b4b4..71480246fed 100644
--- a/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc
@@ -25,5 +25,5 @@
 int main()
 {
   std::span<int, std::dynamic_extent> s;
-  s.back();
+  (void) s.back();
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/back_neg.cc b/libstdc++-v3/testsuite/23_containers/span/back_neg.cc
index d3ea4f405f4..dce512aa1c8 100644
--- a/libstdc++-v3/testsuite/23_containers/span/back_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/back_neg.cc
@@ -24,7 +24,7 @@ test01(bool b)
 {
   std::span<int, 0> s;
   if (b || !s.empty())
-    s.back();
+    (void) s.back();
   return true;
 }
 
diff --git a/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc
index 876a6b773d6..d885268c96c 100644
--- a/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.first(5);
+  (void) s.first(5);
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc
index f1d8cdccb9b..829818c65c2 100644
--- a/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.first<5>();
+  (void) s.first<5>();
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/first_neg.cc b/libstdc++-v3/testsuite/23_containers/span/first_neg.cc
index 4a8cd184172..c47b8db7281 100644
--- a/libstdc++-v3/testsuite/23_containers/span/first_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/first_neg.cc
@@ -24,6 +24,6 @@ test01()
 {
   int a[4];
   std::span<int, 4> s(a);
-  s.first<5>(); // { dg-error "here" }
+  (void) s.first<5>(); // { dg-error "here" }
 }
 // { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc
index 12cbd4a80ae..5dd9c963677 100644
--- a/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc
@@ -25,5 +25,5 @@
 int main()
 {
   std::span<int, std::dynamic_extent> s;
-  s.front();
+  (void) s.front();
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/front_neg.cc b/libstdc++-v3/testsuite/23_containers/span/front_neg.cc
index b5525db8f1d..b2c5e9cae32 100644
--- a/libstdc++-v3/testsuite/23_containers/span/front_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/front_neg.cc
@@ -24,7 +24,7 @@ test01(bool b)
 {
   std::span<int, 0> s;
   if (b || !s.empty())
-    s.front();
+    (void) s.front();
   return true;
 }
 
diff --git a/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc
index c75924e5f38..9a62bdd3233 100644
--- a/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc
@@ -25,5 +25,5 @@
 int main()
 {
   std::span<int, std::dynamic_extent> s;
-  s[99];
+  (void) s[99];
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc b/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc
index 6e8cd4903b3..a2cdb8a44c7 100644
--- a/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc
@@ -24,7 +24,7 @@ test01(bool b)
 {
   std::span<int, 0> s;
   if (b || !s.empty())
-    s[99];
+    (void) s[99];
   return true;
 }
 
diff --git a/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc
index a464fa516b0..86439392e2c 100644
--- a/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.last(5);
+  (void) s.last(5);
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc
index f36db455519..a32246ada47 100644
--- a/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.last<5>();
+  (void) s.last<5>();
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/last_neg.cc b/libstdc++-v3/testsuite/23_containers/span/last_neg.cc
index 2e86233f19a..c85668ab128 100644
--- a/libstdc++-v3/testsuite/23_containers/span/last_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/last_neg.cc
@@ -24,6 +24,6 @@ test01()
 {
   int a[2];
   std::span<int, 2> s(a);
-  s.last<3>(); // { dg-error "here" }
+  (void) s.last<3>(); // { dg-error "here" }
 }
 // { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/nodiscard.cc b/libstdc++-v3/testsuite/23_containers/span/nodiscard.cc
new file mode 100644
index 00000000000..3bccd1545c3
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/nodiscard.cc
@@ -0,0 +1,58 @@
+// { dg-do compile { target c++20 } }
+
+#include <span>
+
+void
+test_observers(std::span<int> s)
+{
+  s.size(); // { dg-warning "ignoring return value" }
+  s.size_bytes(); // { dg-warning "ignoring return value" }
+  s.empty(); // { dg-warning "ignoring return value" }
+}
+
+void
+test_element_access(std::span<float> s)
+{
+  s.front(); // { dg-warning "ignoring return value" }
+  s.back(); // { dg-warning "ignoring return value" }
+  s[1]; // { dg-warning "ignoring return value" }
+  s.data(); // { dg-warning "ignoring return value" }
+}
+
+struct S { };
+
+void
+test_iterators(std::span<S> s)
+{
+  s.begin(); // { dg-warning "ignoring return value" }
+  s.end(); // { dg-warning "ignoring return value" }
+  s.rbegin(); // { dg-warning "ignoring return value" }
+  s.rend(); // { dg-warning "ignoring return value" }
+
+#if __cplusplus > 202002L
+  s.cbegin(); // { dg-warning "ignoring return value" "" { target c++23 } }
+  s.cend(); // { dg-warning "ignoring return value" "" { target c++23 } }
+  s.crbegin(); // { dg-warning "ignoring return value" "" { target c++23 } }
+  s.crend(); // { dg-warning "ignoring return value" "" { target c++23 } }
+#endif
+}
+
+void
+test_subviews(std::span<long, 20> s)
+{
+  s.first<5>(); // { dg-warning "ignoring return value" }
+  s.first(6); // { dg-warning "ignoring return value" }
+  s.last<7>(); // { dg-warning "ignoring return value" }
+  s.last(8); // { dg-warning "ignoring return value" }
+  s.subspan<1>(); // { dg-warning "ignoring return value" }
+  s.subspan<2, 3>(); // { dg-warning "ignoring return value" }
+  s.subspan(4); // { dg-warning "ignoring return value" }
+  s.subspan(5, 6); // { dg-warning "ignoring return value" }
+}
+
+void
+test_non_members(std::span<S, 20> s)
+{
+  std::as_bytes(s); // { dg-warning "ignoring return value" }
+  std::as_writable_bytes(s); // { dg-warning "ignoring return value" }
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc
index 12b79fffc5d..3151f544a24 100644
--- a/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan<2, 5>();
+  (void) s.subspan<2, 5>();
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc
index 3130a503534..4bb29fe99d6 100644
--- a/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan<2, 3>();
+  (void) s.subspan<2, 3>();
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc
index 2a57ddf48b8..eee4d558feb 100644
--- a/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan(5, 0);
+  (void) s.subspan(5, 0);
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc
index 48aaeaffbbf..705359d504e 100644
--- a/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan(2, 5);
+  (void) s.subspan(2, 5);
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc
index 2c90c5e67f8..21715a1a343 100644
--- a/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan(2, 3);
+  (void) s.subspan(2, 3);
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc
index 4873c757996..ee35e874b6d 100644
--- a/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc
@@ -26,5 +26,5 @@ int main()
 {
   int a[4];
   std::span<int, std::dynamic_extent> s(a);
-  s.subspan<5, 0>();
+  (void) s.subspan<5, 0>();
 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc
index 3c69f236755..8c1d2bbfeef 100644
--- a/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc
@@ -24,7 +24,7 @@ test01()
 {
   int a[4];
   std::span<int, 4> s(a);
-  s.subspan<5, 0>(); // { dg-error "here" }
+  (void) s.subspan<5, 0>(); // { dg-error "here" }
 }
 
 void
@@ -32,7 +32,7 @@ test02()
 {
   int a[4];
   std::span<int, 4> s(a);
-  s.subspan<3, 5>(); // { dg-error "here" }
+  (void) s.subspan<3, 5>(); // { dg-error "here" }
 }
 
 void
@@ -40,7 +40,7 @@ test03()
 {
   int a[4];
   std::span<int, 4> s(a);
-  s.subspan<3, 2>(); // { dg-error "here" }
+  (void) s.subspan<3, 2>(); // { dg-error "here" }
 }
 
 // { dg-error "static assertion failed" "" { target *-*-* } 0 }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-11-11  0:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-11  0:43 [gcc r14-5343] libstdc++: Add [[nodiscard]] to std::span members Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).