Skip to content

Commit

Permalink
Cpp: use references for non-trivial types in accessors
Browse files Browse the repository at this point in the history
The generated accessors used by-value return and parameter
types even for non-trivial types. This change is intended
to improve the situation by introducing usage of reference
for the mentioned non-trivial types.

This change:
 - introduces usage of const references for non-trivial types
   in getters defined via accessors attribute for structures
   when it is called on l-value
 - introduces usage of by-value type for non-trivial types
   in getters defined via accessors attribute for structures
   when it is called on r-value
 - introduces usage of const references for non-trivial types
   in setters
 - strips constness and references from type used to select a hash
   in 'StructHashImpl.mustache' because std::hash<T> does not
   accept references/constness for T
 - updates output of smoke tests to show, that since this commit
   the generated accessors use const references for non-trivial
   types

Signed-off-by: Patryk Wrobel <[email protected]>
  • Loading branch information
pwrobeldev committed Oct 25, 2024
1 parent 51a9c4b commit f914c76
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased
### Bug fixes:
* C++: Fixed generation of getters and setters for accessors attribute -- non-trivial types use references now.
* Added missing generation of conversion functions for lambdas defined in structs for Swift.

## 13.9.5
Expand Down
13 changes: 10 additions & 3 deletions gluecodium/src/main/resources/templates/cpp/CppStruct.mustache
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{!!
!
! Copyright (C) 2016-2020 HERE Europe B.V.
! Copyright (C) 2016-2024 HERE Europe B.V.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -51,10 +51,17 @@ public:
}}{{#if attributes.cpp.accessors}}
{{#set structElement=this}}{{#fields}}
{{prefixPartial "cpp/CppFieldDoc" " "}}
{{resolveName typeRef}} {{resolveName this "" "getter"}}( ) const { return {{resolveName}}; }{{!!
{{#ifPredicate typeRef "needsRefSuffix"}}const {{resolveName typeRef}}&{{!!
}} {{resolveName this "" "getter"}}( ) const & { return {{resolveName}}; }
{{resolveName typeRef}} {{resolveName this "" "getter"}}( ) const && { return {{resolveName}}; }{{/ifPredicate}}{{!!
}}{{#unlessPredicate typeRef "needsRefSuffix"}}{{resolveName typeRef}}{{!!
}} {{resolveName this "" "getter"}}( ) const { return {{resolveName}}; }{{/unlessPredicate}}{{!!
}}{{#unless structElement.attributes.immutable}}
{{prefixPartial "cpp/CppFieldDoc" " "}}
void {{resolveName this "" "setter"}}( {{resolveName typeRef}} value_ ) { {{resolveName}} = value_; }{{!!
void {{resolveName this "" "setter"}}( {{!!
}}{{#ifPredicate typeRef "needsRefSuffix"}}const {{resolveName typeRef}}&{{/ifPredicate}}{{!!
}}{{#unlessPredicate typeRef "needsRefSuffix"}}{{resolveName typeRef}}{{/unlessPredicate}}{{!!
}} value_ ) { {{resolveName}} = value_; }{{!!
}}{{/unless}}
{{/fields}}{{/set}}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{!!
!
! Copyright (C) 2016-2020 HERE Europe B.V.
! Copyright (C) 2016-2024 HERE Europe B.V.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
Expand All @@ -23,8 +23,8 @@ hash< {{resolveName "FQN"}} >::operator( )( const {{resolveName "FQN"}}& t ) con
{
size_t hash_value = 43;
{{#if attributes.cpp.accessors}}
{{#resolveName "FQN"}}{{#set structName=this}}{{#fields}}hash_value = (hash_value ^ {{>common/InternalNamespace}}hash< decltype({{!!
}}std::declval<{{structName}}>().{{resolveName this "" "getter"}}()) >()(t.{{resolveName this "" "getter"}}())) << 1;
{{#resolveName "FQN"}}{{#set structName=this}}{{#fields}}hash_value = (hash_value ^ {{>common/InternalNamespace}}hash< std::remove_cv_t< std::remove_reference_t< decltype({{!!
}}std::declval<{{structName}}>().{{resolveName this "" "getter"}}()) > > >()(t.{{resolveName this "" "getter"}}())) << 1;
{{/fields}}{{/set}}{{/resolveName}}
{{/if}}{{#unless attributes.cpp.accessors}}
{{#fields}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,43 @@
// -------------------------------------------------------------------------------------------------
//

//
// -------------------------------------------------------------------------------------------------

#include "smoke/EquatableStructWithAccessors.h"
#include <utility>

namespace smoke {

EquatableStructWithAccessors::EquatableStructWithAccessors( )
: foo_field{ }
{
}

EquatableStructWithAccessors::EquatableStructWithAccessors( ::std::string foo_field )
: foo_field( std::move( foo_field ) )
{
}

bool EquatableStructWithAccessors::operator==( const EquatableStructWithAccessors& rhs ) const
{
return foo_field == rhs.foo_field;
}

bool EquatableStructWithAccessors::operator!=( const EquatableStructWithAccessors& rhs ) const
{
return !( *this == rhs );
}


}

namespace gluecodium {
std::size_t
hash< ::smoke::EquatableStructWithAccessors >::operator( )( const ::smoke::EquatableStructWithAccessors& t ) const
{
size_t hash_value = 43;
hash_value = (hash_value ^ ::gluecodium::hash< decltype(std::declval<::smoke::EquatableStructWithAccessors>().get_foo_field()) >()(t.get_foo_field())) << 1;
hash_value = (hash_value ^ ::gluecodium::hash< std::remove_cv_t< std::remove_reference_t< decltype(std::declval<::smoke::EquatableStructWithAccessors>().get_foo_field()) > > >()(t.get_foo_field())) << 1;
return hash_value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,14 @@ class _GLUECODIUM_CPP_EXPORT Structs {

double get_trivial_double_field( ) const { return trivial_double_field; }

::std::string get_nontrivial_string_field( ) const { return nontrivial_string_field; }
const ::std::string& get_nontrivial_string_field( ) const & { return nontrivial_string_field; }
::std::string get_nontrivial_string_field( ) const && { return nontrivial_string_field; }

::smoke::Structs::Point get_nontrivial_point_field( ) const { return nontrivial_point_field; }
const ::smoke::Structs::Point& get_nontrivial_point_field( ) const & { return nontrivial_point_field; }
::smoke::Structs::Point get_nontrivial_point_field( ) const && { return nontrivial_point_field; }

std::optional< ::smoke::Structs::Point > get_nontrivial_optional_point( ) const { return nontrivial_optional_point; }
const std::optional< ::smoke::Structs::Point >& get_nontrivial_optional_point( ) const & { return nontrivial_optional_point; }
std::optional< ::smoke::Structs::Point > get_nontrivial_optional_point( ) const && { return nontrivial_optional_point; }

};

Expand All @@ -142,17 +145,20 @@ class _GLUECODIUM_CPP_EXPORT Structs {

void set_trivial_double_field( double value_ ) { trivial_double_field = value_; }

::std::string get_nontrivial_string_field( ) const { return nontrivial_string_field; }
const ::std::string& get_nontrivial_string_field( ) const & { return nontrivial_string_field; }
::std::string get_nontrivial_string_field( ) const && { return nontrivial_string_field; }

void set_nontrivial_string_field( ::std::string value_ ) { nontrivial_string_field = value_; }
void set_nontrivial_string_field( const ::std::string& value_ ) { nontrivial_string_field = value_; }

::smoke::Structs::Point get_nontrivial_point_field( ) const { return nontrivial_point_field; }
const ::smoke::Structs::Point& get_nontrivial_point_field( ) const & { return nontrivial_point_field; }
::smoke::Structs::Point get_nontrivial_point_field( ) const && { return nontrivial_point_field; }

void set_nontrivial_point_field( ::smoke::Structs::Point value_ ) { nontrivial_point_field = value_; }
void set_nontrivial_point_field( const ::smoke::Structs::Point& value_ ) { nontrivial_point_field = value_; }

std::optional< ::smoke::Structs::Point > get_nontrivial_optional_point( ) const { return nontrivial_optional_point; }
const std::optional< ::smoke::Structs::Point >& get_nontrivial_optional_point( ) const & { return nontrivial_optional_point; }
std::optional< ::smoke::Structs::Point > get_nontrivial_optional_point( ) const && { return nontrivial_optional_point; }

void set_nontrivial_optional_point( std::optional< ::smoke::Structs::Point > value_ ) { nontrivial_optional_point = value_; }
void set_nontrivial_optional_point( const std::optional< ::smoke::Structs::Point >& value_ ) { nontrivial_optional_point = value_; }

};

Expand Down

0 comments on commit f914c76

Please sign in to comment.