Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Gluecodium project Release Notes

## Unreleased
* C++: introduced the new 'EnumValues' attribute, which allows uses to instruct the C++ generator to create helper function for the given enumeration. The mentioned function returns an array of unique enumerator values.

## 14.1.1
Release date 2026-03-03
* C++: fixed a bug related to redundant 'using' statements generation for derived classes. We generate using statment to avoid warning/error related to method shadowing, when base and derived classes have method overload with the same name.
Expand Down
1 change: 1 addition & 0 deletions docs/lime_attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ quotes need to be backslash-escaped, as in the example.
in C++ generated code. For example, `@Cpp(Type="std::chrono::steady_clock::time_point") Date` will use monotonic clock
time point type, instead of the system clock time point type which is used by default.
* **ToString**: marks an enumeration to have a helper `to_string()` function generated, mapping the enum to string.
* **EnumValues**: marks an enumeration to have a helper `<ENUM_NAME>_enumerators()` function generated. It returns array of unique enum values.
* **Skip** \[**=** **"**_CustomTag_**"** \]: marks an element to be skipped (not generated) in C++. Can be applied to
`field constuctor` or `const` elements only. Optionally, if custom tag is specified, the element is only skipped if
that tag was defined (see `@Skip` above).
Expand Down
16 changes: 16 additions & 0 deletions functional-tests/functional/cpp/tests/EnumTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// -------------------------------------------------------------------------------------------------

#include "test/EnumWithToStringHelper.h"
#include "test/EnumWithAccessibleValues.h"

#include <gmock/gmock.h>

Expand All @@ -34,4 +35,19 @@ TEST( EnumTest, to_string_returns_proper_values )
EXPECT_EQ(to_string(EnumWithToStringHelper::SECOND), "EnumWithToStringHelper::SECOND");
}

TEST( EnumTest, enum_values_attribute )
{
// Only unique values are returned.
const auto enumerators = EnumWithAccessibleValues_enumerators();
ASSERT_EQ(3u, enumerators.size());

// Values have the same order as defined.
EXPECT_EQ(EnumWithAccessibleValues::FOO, enumerators[0]);
EXPECT_EQ(EnumWithAccessibleValues::BAR, enumerators[1]);
EXPECT_EQ(EnumWithAccessibleValues::BAZ, enumerators[2]);

// Aliasing enumerator is present -- because its original version is in the container.
EXPECT_EQ(EnumWithAccessibleValues::FOO_ALIAS, enumerators[0]);
}

} // test
8 changes: 8 additions & 0 deletions functional-tests/functional/input/lime/Enums.lime
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,11 @@ enum EnumWithToStringHelper {
FIRST,
SECOND
}

@Cpp(EnumValues)
enum EnumWithAccessibleValues {
FOO,
BAR,
BAZ,
FOO_ALIAS = FOO
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.here.gluecodium.generator.common.Include
import com.here.gluecodium.model.lime.LimeAttributeType.ASYNC
import com.here.gluecodium.model.lime.LimeAttributeType.CPP
import com.here.gluecodium.model.lime.LimeAttributeType.OPTIMIZED
import com.here.gluecodium.model.lime.LimeAttributeValueType.ENUM_VALUES
import com.here.gluecodium.model.lime.LimeAttributeValueType.TO_STRING
import com.here.gluecodium.model.lime.LimeBasicType
import com.here.gluecodium.model.lime.LimeBasicType.TypeId
Expand Down Expand Up @@ -72,7 +73,8 @@ internal class CppIncludeResolver(
is LimeLambda -> cppIncludesCache.resolveIncludes(limeElement) + CppLibraryIncludes.FUNCTIONAL
is LimeNamedElement ->
cppIncludesCache.resolveIncludes(limeElement) +
listOfNotNull(CppLibraryIncludes.STRING_VIEW.takeIf { limeElement.attributes.have(CPP, TO_STRING) })
listOfNotNull(CppLibraryIncludes.STRING_VIEW.takeIf { limeElement.attributes.have(CPP, TO_STRING) }) +
listOfNotNull(CppLibraryIncludes.ARRAY.takeIf { limeElement.attributes.have(CPP, ENUM_VALUES) })
else -> emptyList()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.here.gluecodium.model.lime.LimeBasicType.TypeId
import com.here.gluecodium.model.lime.LimeTypeRef

object CppLibraryIncludes {
val ARRAY = Include.createSystemInclude("array")
val INT_TYPES = Include.createSystemInclude("cstdint")
val MAP = Include.createSystemInclude("unordered_map")
val MEMORY = Include.createSystemInclude("memory")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@ enum class {{>cpp/CppAttributesInline}}{{resolveName}} {
std::string_view
{{>cpp/CppExportMacro}}to_string({{resolveName}} enumeration);
{{/if}}

{{#if attributes.cpp.enumvalues}}
std::array<{{resolveName}}, {{uniqueEnumerators.size}}>
{{>cpp/CppExportMacro}}{{resolveName}}_enumerators();
{{/if}}
{{/unless}}
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,18 @@ static_assert(
return "<unknown>";
}
{{/if}}

{{#if attributes.cpp.enumvalues}}
std::array<{{resolveName}}, {{uniqueEnumerators.size}}>
{{resolveName}}_enumerators() {
return std::array<{{resolveName}}, {{uniqueEnumerators.size}}>{
{
{{#set thisEnum=this}}{{#thisEnum}}{{!!
}}{{#uniqueEnumerators}}
{{resolveName thisEnum}}::{{resolveName}}{{#if iter.hasNext}},{{/if}}
{{/uniqueEnumerators}}{{!!
}}{{/thisEnum}}{{/set}}
}
};
}
{{/if}}
8 changes: 8 additions & 0 deletions gluecodium/src/test/resources/smoke/enums/input/Enums.lime
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,11 @@ enum EnumWithToStringHelper {
FIRST,
SECOND
}

@Cpp(EnumValues)
enum EnumWithAccessibleValues {
FOO,
BAR,
BAZ,
FOO_ALIAS = FOO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// -------------------------------------------------------------------------------------------------
//

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

#pragma once

#include "gluecodium/ExportGluecodiumCpp.h"
#include <array>
#include <cstdint>

namespace smoke {
enum class EnumWithAccessibleValues {
FOO,
BAR,
BAZ,
FOO_ALIAS = ::smoke::EnumWithAccessibleValues::FOO
};


std::array<EnumWithAccessibleValues, 3>
_GLUECODIUM_CPP_EXPORT EnumWithAccessibleValues_enumerators();


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// -------------------------------------------------------------------------------------------------
//

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

#include "smoke/EnumWithAccessibleValues.h"

namespace smoke {


std::array<EnumWithAccessibleValues, 3>
EnumWithAccessibleValues_enumerators() {
return std::array<EnumWithAccessibleValues, 3>{
{
EnumWithAccessibleValues::FOO,
EnumWithAccessibleValues::BAR,
EnumWithAccessibleValues::BAZ
}
};
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ internal object AntlrLimeConverter {
"Const" -> LimeAttributeValueType.CONST
"Default" -> LimeAttributeValueType.DEFAULT
"EnableIf" -> LimeAttributeValueType.ENABLE_IF
"EnumValues" -> LimeAttributeValueType.ENUM_VALUES
"FullName" -> LimeAttributeValueType.FULL_NAME
"FunctionName" -> LimeAttributeValueType.FUNCTION_NAME
"Internal" -> LimeAttributeValueType.INTERNAL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum class LimeAttributeValueType(private val tag: String) {
CONST("Const"),
DEFAULT("Default"),
ENABLE_IF("EnableIf"),
ENUM_VALUES("EnumValues"),
FULL_NAME("FullName"),
FUNCTION_NAME("FunctionName"),
FUNCTION("Function"),
Expand Down
Loading