json_view: no byte range in exceptions about a removed value

#5990 dropped the found flag from diagnostics(), reasoning that a value
value_path() does not find leaves no tokens, like the root. But the node
of a value that is no longer part of the document still holds the bytes
it had in the source, so with JSON_DIAGNOSTICS and
JSON_DIAGNOSTIC_POSITIONS its exceptions gained "(bytes 1-4)" for text
that is no longer there. The test #5997 added for exactly this case
(unit-json_view_positions.cpp, "views of values that are no longer part
of the document") has failed on develop since both were merged.

Restore the flag: a value that is not found gets no context, the root
keeps its byte range.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
diff --git a/include/nlohmann/detail/view/errors.hpp b/include/nlohmann/detail/view/errors.hpp
index 3c97cef..1006394 100644
--- a/include/nlohmann/detail/view/errors.hpp
+++ b/include/nlohmann/detail/view/errors.hpp
@@ -230,7 +230,8 @@
 
 /// the context basic_json puts in front of the message of an exception about
 /// a value: "(/path) " with JSON_DIAGNOSTICS (none for the root), then
-/// "(bytes a-b) " with JSON_DIAGNOSTIC_POSITIONS (also for the root)
+/// "(bytes a-b) " with JSON_DIAGNOSTIC_POSITIONS (also for the root); with
+/// JSON_DIAGNOSTICS, nothing for a value that is no longer part of the document
 ///
 /// This and the throw helpers that take an error_site are templates, so that
 /// the path and range code is instantiated only where an exception can be
@@ -251,8 +252,14 @@
     std::string context;
 #if JSON_DIAGNOSTICS
     std::vector<std::string> tokens;
-    // a value that is not found leaves no tokens, like the root
-    static_cast<void>(edited ? value_path<true>(d, site.value(), tokens) : value_path<false>(d, site.value(), tokens));
+    // a value that is no longer part of the document has no path, and its
+    // node still holds the bytes it had in the source: no context at all
+    const bool found = edited ? value_path<true>(d, site.value(), tokens) : value_path<false>(d, site.value(), tokens);
+    if (!found)
+    {
+        // context is still empty; returning it keeps the copy elided (-Wnrvo)
+        return context;
+    }
     if (!tokens.empty())
     {
         // the root value has no path, but still has a byte range
diff --git a/single_include/nlohmann/json_view.hpp b/single_include/nlohmann/json_view.hpp
index ea04acd..db26ed2 100644
--- a/single_include/nlohmann/json_view.hpp
+++ b/single_include/nlohmann/json_view.hpp
@@ -5059,7 +5059,8 @@
 
 /// the context basic_json puts in front of the message of an exception about
 /// a value: "(/path) " with JSON_DIAGNOSTICS (none for the root), then
-/// "(bytes a-b) " with JSON_DIAGNOSTIC_POSITIONS (also for the root)
+/// "(bytes a-b) " with JSON_DIAGNOSTIC_POSITIONS (also for the root); with
+/// JSON_DIAGNOSTICS, nothing for a value that is no longer part of the document
 ///
 /// This and the throw helpers that take an error_site are templates, so that
 /// the path and range code is instantiated only where an exception can be
@@ -5080,8 +5081,14 @@
     std::string context;
 #if JSON_DIAGNOSTICS
     std::vector<std::string> tokens;
-    // a value that is not found leaves no tokens, like the root
-    static_cast<void>(edited ? value_path<true>(d, site.value(), tokens) : value_path<false>(d, site.value(), tokens));
+    // a value that is no longer part of the document has no path, and its
+    // node still holds the bytes it had in the source: no context at all
+    const bool found = edited ? value_path<true>(d, site.value(), tokens) : value_path<false>(d, site.value(), tokens);
+    if (!found)
+    {
+        // context is still empty; returning it keeps the copy elided (-Wnrvo)
+        return context;
+    }
     if (!tokens.empty())
     {
         // the root value has no path, but still has a byte range