Skip to content

Add moveable_types=forward_setter option for perfect forwarding setters#3292

Merged
Jens-G merged 1 commit intoapache:masterfrom
zsy056:forward_setters
Feb 8, 2026
Merged

Add moveable_types=forward_setter option for perfect forwarding setters#3292
Jens-G merged 1 commit intoapache:masterfrom
zsy056:forward_setters

Conversation

@zsy056
Copy link
Contributor

@zsy056 zsy056 commented Jan 29, 2026

Description

Adds forward_setter value to moveable_types option, generating perfect forwarding setters for complex types while preserving traditional setters for primitives. Also fixes missing operator< implementation that caused link errors when structs are used as map keys.

Generator Changes

Forward Setter Generation (compiler/cpp/src/thrift/generate/t_cpp_generator.cc):

  • Parse moveable_types=forward_setter option
  • Complex types (strings, containers, structs) → template setters with std::forward<T_>
  • Primitive types → traditional const-ref setters
  • Template implementations in .tcc file (auto-included in header)
  • Legacy moveable_types behavior unchanged

Testing

Compiler Unit Tests (compiler/cpp/tests/cpp/):

  • New test_forward_setter.thrift fixture
  • Dedicated t_cpp_generator_forward_setter_tests.cc (91 assertions, 9 test cases)
  • Verify .tcc generation and template implementations

Integration Tests (test/cpp/src/):

  • ForwardSetterTest.cpp - validates lvalue/rvalue/temporary/literal setters with move semantics
  • PrivateOptionalTest.cpp - SFINAE + static_assert verify optional fields are private
  • EnumClassTest.cpp - type_traits + static_assert verify true enum class semantics

Build System

CMakeLists.txt (test/cpp/):

  • Separate gen-cpp-{forward,private,enumclass} directories

Makefile.am (test/cpp/):

  • Library targets for each option variant
  • Proper BUILT_SOURCES dependencies
  • Include path ordering: option-specific directory before standard gen-cpp

Example

// Generated with --gen cpp:moveable_types=forward_setter

struct TestStruct {
  int32_t primitive_field;
  std::string complex_field;
  
  void __set_primitive_field(const int32_t val);  // Traditional
  
  template <typename T_>
  void __set_complex_field(T_&& val);  // Perfect forwarding
};

// In .tcc file:
template <typename T_>
void TestStruct::__set_complex_field(T_&& val) {
  this->complex_field = ::std::forward<T_>(val);
  __isset.complex_field = true;
}
  • Did you create an Apache Jira ticket? (Request account here, not required for trivial changes)
  • If a ticket exists: Does your pull request title follow the pattern "THRIFT-NNNN: describe my issue"?
  • Did you squash your changes to a single commit? (not required, but preferred)
  • Did you do your best to avoid breaking changes? If one was needed, did you label the Jira ticket with "Breaking-Change"?
  • If your change does not involve any code, include [skip ci] anywhere in the commit message to free up build resources.

@mergeable mergeable bot added c++ compiler github_actions Pull requests that update GitHub Actions code labels Jan 29, 2026
@zsy056 zsy056 force-pushed the forward_setters branch 2 times, most recently from e537cf7 to a037d53 Compare January 29, 2026 22:41
Copy link
Member

@Jens-G Jens-G left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couild you please remove the [skip ci] piece from your commit message?

Adds `forward_setter` value to `moveable_types` option, generating perfect forwarding setters for complex types while preserving traditional setters for primitives. Also fixes missing `operator<` implementation that caused link errors when structs are used as map keys.

**Forward Setter Generation** (`compiler/cpp/src/thrift/generate/t_cpp_generator.cc`):
- Parse `moveable_types=forward_setter` option
- Complex types (strings, containers, structs) → template setters with `std::forward<T_>`
- Primitive types → traditional const-ref setters
- Template implementations in `.tcc` file (auto-included in header)
- Legacy `moveable_types` behavior unchanged

**Compiler Unit Tests** (`compiler/cpp/tests/cpp/`):
- New `test_forward_setter.thrift` fixture
- Dedicated `t_cpp_generator_forward_setter_tests.cc` (91 assertions, 9 test cases)
- Verify `.tcc` generation and template implementations

**Integration Tests** (`test/cpp/src/`):
- `ForwardSetterTest.cpp` - validates lvalue/rvalue/temporary/literal setters with move semantics
- `PrivateOptionalTest.cpp` - SFINAE + static_assert verify optional fields are private
- `EnumClassTest.cpp` - type_traits + static_assert verify true enum class semantics

**CMakeLists.txt** (`test/cpp/`):
- Separate gen-cpp-{forward,private,enumclass} directories

**Makefile.am** (`test/cpp/`):
- Library targets for each option variant
- Proper `BUILT_SOURCES` dependencies
- Include path ordering: option-specific directory before standard `gen-cpp`

```cpp
// Generated with --gen cpp:moveable_types=forward_setter

struct TestStruct {
  int32_t primitive_field;
  std::string complex_field;

  void __set_primitive_field(const int32_t val);  // Traditional

  template <typename T_>
  void __set_complex_field(T_&& val);  // Perfect forwarding
};

// In .tcc file:
template <typename T_>
void TestStruct::__set_complex_field(T_&& val) {
  this->complex_field = ::std::forward<T_>(val);
  __isset.complex_field = true;
}
```

- [ ] Did you create an [Apache Jira](https://issues.apache.org/jira/projects/THRIFT/issues/) ticket?  ([Request account here](https://selfserve.apache.org/jira-account.html), not required for trivial changes)
- [ ] If a ticket exists: Does your pull request title follow the pattern "THRIFT-NNNN: describe my issue"?
- [x] Did you squash your changes to a single commit?  (not required, but preferred)
- [x] Did you do your best to avoid breaking changes?  If one was needed, did you label the Jira ticket with "Breaking-Change"?

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: zsy056 <1074382+zsy056@users.noreply.github.com>
@zsy056
Copy link
Contributor Author

zsy056 commented Feb 7, 2026

Couild you please remove the [skip ci] piece from your commit message?

thanks, pushed an update.

@Jens-G Jens-G merged commit 1e09a04 into apache:master Feb 8, 2026
83 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ compiler github_actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants