THRIFT-6377: Grow a list<bool> with push_back so generated C++ builds as C++11

Client: cpp

std::vector<bool> has no emplace_back() before C++14, so code generated for a
list<bool> field, directly or through a typedef, did not compile as C++11 against
libc++. Other element types keep emplace_back().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sylwester LachiewiczandClaude Opus 5.5 authored and Jens Geyer committed 2026-10-01 02:13:30 +02:00
1 parent 269d35b4e8
commit b581cb84e3
3 files changed
+94 -1

No files matched your search

@@ -4544,8 +4544,13 @@ void t_cpp_generator::generate_deserialize_list_element(ostream& out,
} else {
// The vector's capacity was reserved (capped) from the declared count, so grow it one element
// at a time and read into the element just appended, rather than indexing into a full resize.
// std::vector<bool> has no emplace_back() before C++14, so a list of bool uses push_back().
(void)index;
indent(out) << prefix << ".emplace_back();" << '\n';
if (tlist->get_elem_type()->get_true_type()->is_bool()) {
indent(out) << prefix << ".push_back(false);" << '\n';
} else {
indent(out) << prefix << ".emplace_back();" << '\n';
}
t_field felem(tlist->get_elem_type(), prefix + ".back()");
generate_deserialize_field(out, &felem);
}
@@ -0,0 +1,59 @@
// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "t_cpp_generator_test_utils.h"
using std::string;
using std::map;
using cpp_generator_test_utils::read_file;
using cpp_generator_test_utils::source_dir;
using cpp_generator_test_utils::join_path;
using cpp_generator_test_utils::parse_thrift_for_test;
// std::vector<bool> has emplace_back() only from C++14 on, and the generated code has to build as
// C++11, so a list of bool (directly or through a typedef) must be grown with push_back().
TEST_CASE("t_cpp_generator grows a list<bool> with push_back, not emplace_back", "[functional]")
{
string path = join_path(source_dir(), "test_list_bool.thrift");
string name = "test_list_bool";
map<string, string> parsed_options;
string option_string = "";
std::unique_ptr<t_program> program(new t_program(path, name));
parse_thrift_for_test(program.get());
std::unique_ptr<t_generator> gen(
t_generator_registry::get_generator(program.get(), "cpp", parsed_options, option_string));
REQUIRE(gen != nullptr);
REQUIRE_NOTHROW(gen->generate_program());
string generated = read_file("gen-cpp/test_list_bool_types.cpp");
REQUIRE(!generated.empty());
REQUIRE(generated.find("this->flags.push_back(false);") != string::npos);
REQUIRE(generated.find("this->typedef_flags.push_back(false);") != string::npos);
REQUIRE(generated.find("this->flags.emplace_back();") == string::npos);
REQUIRE(generated.find("this->typedef_flags.emplace_back();") == string::npos);
// The outer list holds vectors, so it keeps emplace_back(); its elements are lists of bool.
REQUIRE(generated.find("this->nested_flags.emplace_back();") != string::npos);
REQUIRE(generated.find("this->nested_flags.back().push_back(false);") != string::npos);
REQUIRE(generated.find("this->nested_flags.back().emplace_back();") == string::npos);
// Every other element type is unchanged.
REQUIRE(generated.find("this->numbers.emplace_back();") != string::npos);
}
@@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
namespace cpp test.list_bool
typedef bool Flag
struct ListBool {
1: list<bool> flags;
2: list<Flag> typedef_flags;
3: list<list<bool>> nested_flags;
4: list<i32> numbers;
}