mirror of
https://github.com/apache/thrift.git
synced 2026-10-28 16:35:10 +08:00
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:
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;
|
||||
}
|
||||
Reference in new issue
Block a user