Add moveable_types=forward_setter option for perfect forwarding setters

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>
diff --git a/test/cpp/CMakeLists.txt b/test/cpp/CMakeLists.txt
index a6c1fd5..2403c87 100644
--- a/test/cpp/CMakeLists.txt
+++ b/test/cpp/CMakeLists.txt
@@ -95,6 +95,75 @@
 target_link_libraries(SpecificNameTest thriftnb)
 add_test(NAME SpecificNameTest COMMAND SpecificNameTest)
 
+# ForwardSetterTest - tests the forward_setter option
+set(forwardsettertestgencpp_SOURCES
+    gen-cpp-forward/gen-cpp/ThriftTest_types.cpp
+    gen-cpp-forward/gen-cpp/ThriftTest_constants.cpp
+    src/ThriftTest_extras.cpp
+)
+add_library(forwardsettertestgencpp STATIC ${forwardsettertestgencpp_SOURCES})
+target_include_directories(forwardsettertestgencpp BEFORE PRIVATE 
+    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-forward"
+    "${CMAKE_CURRENT_BINARY_DIR}"
+    "${PROJECT_SOURCE_DIR}/lib/cpp/src"
+)
+target_link_libraries(forwardsettertestgencpp thrift)
+
+add_executable(ForwardSetterTest src/ForwardSetterTest.cpp)
+target_include_directories(ForwardSetterTest BEFORE PRIVATE 
+    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-forward/gen-cpp"
+    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-forward"
+)
+target_link_libraries(ForwardSetterTest forwardsettertestgencpp ${Boost_LIBRARIES})
+target_link_libraries(ForwardSetterTest thrift)
+add_test(NAME ForwardSetterTest COMMAND ForwardSetterTest)
+
+# PrivateOptionalTest - tests the private_optional option
+set(privateoptonaltestgencpp_SOURCES
+    gen-cpp-private/gen-cpp/ThriftTest_types.cpp
+    gen-cpp-private/gen-cpp/ThriftTest_constants.cpp
+    src/ThriftTest_extras.cpp
+)
+add_library(privateoptonaltestgencpp STATIC ${privateoptonaltestgencpp_SOURCES})
+target_include_directories(privateoptonaltestgencpp BEFORE PRIVATE 
+    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private"
+    "${CMAKE_CURRENT_BINARY_DIR}"
+    "${PROJECT_SOURCE_DIR}/lib/cpp/src"
+)
+target_link_libraries(privateoptonaltestgencpp thrift)
+
+add_executable(PrivateOptionalTest src/PrivateOptionalTest.cpp)
+target_include_directories(PrivateOptionalTest BEFORE PRIVATE 
+    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private/gen-cpp"
+    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private"
+)
+target_link_libraries(PrivateOptionalTest privateoptonaltestgencpp ${Boost_LIBRARIES})
+target_link_libraries(PrivateOptionalTest thrift)
+add_test(NAME PrivateOptionalTest COMMAND PrivateOptionalTest)
+
+# EnumClassTest - tests the pure_enums=enum_class option
+set(enumclasstestgencpp_SOURCES
+    gen-cpp-enumclass/gen-cpp/ThriftTest_types.cpp
+    gen-cpp-enumclass/gen-cpp/ThriftTest_constants.cpp
+    src/ThriftTest_extras.cpp
+)
+add_library(enumclasstestgencpp STATIC ${enumclasstestgencpp_SOURCES})
+target_include_directories(enumclasstestgencpp BEFORE PRIVATE 
+    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-enumclass"
+    "${CMAKE_CURRENT_BINARY_DIR}"
+    "${PROJECT_SOURCE_DIR}/lib/cpp/src"
+)
+target_link_libraries(enumclasstestgencpp thrift)
+
+add_executable(EnumClassTest src/EnumClassTest.cpp)
+target_include_directories(EnumClassTest BEFORE PRIVATE 
+    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-enumclass/gen-cpp"
+    "${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-enumclass"
+)
+target_link_libraries(EnumClassTest enumclasstestgencpp ${Boost_LIBRARIES})
+target_link_libraries(EnumClassTest thrift)
+add_test(NAME EnumClassTest COMMAND EnumClassTest)
+
 #
 # Common thrift code generation rules
 #
@@ -103,6 +172,27 @@
     COMMAND ${THRIFT_COMPILER} --gen cpp:templates,cob_style -r ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
 )
 
+# Generate ThriftTest with forward_setter option for ForwardSetterTest
+add_custom_command(OUTPUT gen-cpp-forward/gen-cpp/ThriftTest_types.cpp gen-cpp-forward/gen-cpp/ThriftTest_types.h gen-cpp-forward/gen-cpp/ThriftTest_types.tcc gen-cpp-forward/gen-cpp/ThriftTest_constants.cpp
+    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-forward
+    COMMAND ${THRIFT_COMPILER} --gen cpp:moveable_types=forward_setter -o gen-cpp-forward ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
+    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+# Generate ThriftTest with private_optional option for PrivateOptionalTest
+add_custom_command(OUTPUT gen-cpp-private/gen-cpp/ThriftTest_types.cpp gen-cpp-private/gen-cpp/ThriftTest_types.h gen-cpp-private/gen-cpp/ThriftTest_constants.cpp
+    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-private
+    COMMAND ${THRIFT_COMPILER} --gen cpp:private_optional -o gen-cpp-private ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
+    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+# Generate ThriftTest with pure_enums=enum_class option for EnumClassTest
+add_custom_command(OUTPUT gen-cpp-enumclass/gen-cpp/ThriftTest_types.cpp gen-cpp-enumclass/gen-cpp/ThriftTest_types.h gen-cpp-enumclass/gen-cpp/ThriftTest_constants.cpp
+    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp-enumclass
+    COMMAND ${THRIFT_COMPILER} --gen cpp:pure_enums=enum_class -o gen-cpp-enumclass ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
+    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+)
+
 add_custom_command(OUTPUT gen-cpp/Service.cpp
     COMMAND ${THRIFT_COMPILER} --gen cpp ${PROJECT_SOURCE_DIR}/test/StressTest.thrift
 )