https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123819
Bug ID: 123819
Summary: [reflection] promote_strings ->
std::define_static_array(views) -> exception:
reflect_constant failed'
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: lyubomir.filipov at amusnet dot com
Target Milestone: ---
I'm trying to implement the promote_strings function, mentioned in P3491R3
https://isocpp.org/files/papers/P3491R3.html
I'm using compiler explorer, with gcc trunk:
https://godbolt.org/z/K6z9nKdzx
I have also implemented my own string_view class with public members. The
resulting code is following:
```
#include <algorithm>
#include <meta>
#include <iostream>
#include <vector>
#include <span>
#include <string>
struct MyStringView {
constexpr MyStringView (const std::string_view& sv)
:data (sv.data())
,len (sv.size()) {}
constexpr operator std::string_view () const
{
return std::string_view (data,len);
}
std::string_view::const_pointer data;
size_t len;
};
constexpr std::vector<std::string> get_strings() {
return {"Jason", "Was", "Here"};
}
consteval auto promote_strings(std::vector<std::string> vs)
-> std::span<MyStringView const>
{
// promote the concatenated strings to static storage
std::string_view promoted = std::define_static_string(
std::ranges::fold_left(vs, std::string(), std::plus()));
// now build up all our string views into promoted
std::vector<MyStringView> views;
for (size_t offset = 0; std::string const& s : vs) {
views.emplace_back(promoted.substr (offset, s.size()));
offset += s.size();
}
// promote our array of string_views
return std::define_static_array(views);
}
int main (int argc, char** argv)
{
constexpr auto views = promote_strings(get_strings());
for (auto& view: views) {
std::string_view sv = view;
std::cout << "\t" << sv << "\n";
}
return 0;
}
```
But throws an exception at compile time:
```
<source>: In function 'int main(int, char**)':
<source>:49:57: error: uncaught exception of type 'std::meta::exception';
'what()': 'reflect_constant failed'
49 | constexpr auto views = promote_strings(get_strings());
```
The interesting part is that it throws an exception when on line 38 the offset
value is different from 0. If the offset is 0, the code compiles and fills the
resulting span with string views to the beginning of the `promoted` string. I
even can set (at line 38) the size to arbitrary large value and the code will
still compile successfully, so we can see the entire 'promoted' string and that
the `promoted` string is correctly concatenated: `JasonWasHere` - but I cannot
take a string_view from it at offset different from 0 - even offset 1 and size
1 should work, giving a string_view to the second character