Add template classes
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 30/100
Línea de trabajo
No se nombran archivos fuente, pruebas ni puntos de entrada. Empieza revisando el esquema XML propuesto de templateclass/templateparam y la implementación de C++ y los ejemplos de bindings generados; se considera terminado cuando se pueden declarar clases genéricas y se generan sus stubs de implementación y bindings para las instanciaciones mostradas.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Currently ACT does not support generic classes (aka template classes) which makes it hard to define certain types such as (type-safe) generic containers and algorithms.
For example, to define types like Map<int,IFoo*>, Map<string,IBar*>, and Map<int,double> in the API today, you would need to define the following:
<class name="Map" abstract="true">
<!-- Base methods that do not use the value type (Size, IsEmpty, etc.) -->
</class>
<class name="IntFooMap" parent="Map">
<!-- Methods with key type="int32" and value type="class" class="Foo" -->
</class>
<class name="StringBarMap">
<!-- Same methods copy-pasted, but with key type="string" and value type="class" class="Bar" -->
</class>
<class name="IntDoubleMap">
<!-- Same methods copy-pasted, but with key type="int32" and value type="double" -->
</class>
This quickly becomes unmaintainable as for N instantiations you need to:
- Copy-paste and adjust the method definitions N times
- Maintain N implementation classes by:
- Writing the same code N times, or
- Writing a generic
Mapclass yourself and inheriting from that N times (something likeclass StringBarMap : public Map<std::string, IBar*>)
Instead, ACT could provide support for generic classes, and it could look something like this (following previous discussions with @martinweismann and @alexanderoster):
<templateclass name="Map">
<!--
template<typename TKey, typename TValue>
-->
<templateparam name="TKey" description="" />
<templateparam name="TValue" description="" />
<!-- template methods -->
<templatemethod name="Add" description="adds an entry to the map.">
<param name="Key" type="template" templateparam="TKey" pass="in" description="Key String."/>
<param name="Value" type="template" templateparam="TValue" pass="in" description="Value to store."/>
</templatemethod>
<templatemethod name="Get" description="returns an entry of the map.">
<param name="Key" type="template" templateparam="TKey" pass="in" description="Key String."/>
<param name="Instance" type="template" templateparam="TValue" pass="return" description="Class Instance."/>
</templatemethod>
<templatemethod name="GetOut" description="returns an entry of the map.">
<param name="Key" type="template" templateparam="TKey" pass="in" description="Key String."/>
<param name="Instance" type="template" templateparam="TValue" pass="out" description="Class Instance."/>
</templatemethod>
<!-- non-template methods -->
<method name="Clear" description="clears the map." />
<method name="Count" description="returns the entry count of the map.">
<param name="Count" type="uint32" pass="return" description="Entry count of the map."/>
</method>
</templateclass>
<class name="IntFooMap" parent="Map">
<templatearg param="TKey" type="int32"/>
<templatearg param="TValue" type="class" class="Foo" />
</class>
<class name="StringBarMap" parent="Map">
<templatearg param="TKey" type="string"/>
<templatearg param="TValue" type="class" class="Bar" />
</class>
<class name="IntDoubleMap" parent="Map">
<templatearg param="TKey" type="int32"/>
<templatearg param="TValue" type="double" />
</class>
The implementation stubs could then be generated as follows:
// Implementation Stubs
namespace Component { namespace Impl {
template <typename TKey, typename TValue>
class CMap
{
public:
virtual void Add(TKey Key, TValue Value);
virtual TValue Get(TKey Key);
virtual void GetOut(TKey Key, TValue *pValue);
virtual void Clear();
virtual Component_uint32 Count();
};
class IntFooMap : public CMap<Component_int32, IFoo *>
{
/* instantiates to:
virtual void Add(Component_int32 Key, IFoo * Value);
virtual IFoo * Get(Component_int32 Key);
virtual void GetOut(Component_int32 Key, IFoo **pValue);
virtual void Clear();
virtual Component_uint32 Count();
*/
};
class StringBarMap : public CMap<String *, IBar *>
{
/* instantiates to:
virtual void Add(String * Key, IBar * Value);
virtual IBar * Get(String * Key);
virtual void GetOut(String * Key, IBar **pValue);
virtual void Clear();
virtual Component_uint32 Count();
*/
};
class IntDoubleMap : public CMap<Component_int32, double>
{
/* instantiates to:
virtual void Add(Component_int32 Key, double Value);
virtual double Get(Component_int32 Key);
virtual void GetOut(Component_int32 Key, double *pValue);
virtual void Clear();
virtual Component_uint32 Count();
*/
};
}} // namespace Component::Impl
And the bindings:
// Bindings
namespace Component { namespace Binding {
class CMap
{
public:
virtual void Clear();
virtual Component_uint32 Count();
};
class IntFooMap : public CMap
{
virtual void Add(Component_int32 Key, IFoo * Value);
virtual IFoo * Get(Component_int32 Key);
virtual void GetOut(Component_int32 Key, IFoo **pValue);
};
class StringBarMap : public CMap
{
virtual void Add(String * Key, IBar * Value);
virtual IBar * Get(String * Key);
virtual void GetOut(String * Key, IBar **pValue);
};
class IntDoubleMap : public CMap
{
virtual void Add(Component_int32 Key, double Value);
virtual double Get(Component_int32 Key);
virtual void GetOut(Component_int32 Key, double *pValue);
};
}} // namespace Component::Binding
The API author would then only need to implement the template class CMap once.
Notes:
- Only works with strings if they're wrapped in a class
- Already a need for string wrapper class
- Can't support string without wrapper class because of different in/out/return types (
const std::string&/std::string &/std::string)- Template class signatures would differ from the simple / class types, won't work.
- Ref counting, need to check if type is a pointer or not to decide whether or not to call IncRefCount/DecRefCount.
- Provide a helper function with specializations for class / simple types
- Concepts
- Example: key type for map, how to compare?
pLhs->Compare(pRhs)?pLhs < pRhs?
- Leave it up to the API author, C++ (pre C++20) didn't have support for Concepts either and relied on documentation
- API author can choose to write template functions with specializations like (ACT could document an example)
template <typename T, typename = void> struct compare_helper { static int compare(T lhs, T rhs); }; template <typename Comparable> struct compare_helper<Comparable, std::enable_if_t<std::is_base_of_v<IBase, std::remove_pointer_t<Comparable>>>> { static int compare(Comparable pLhs, Comparable pRhs) { static_assert(std::is_member_function_pointer<decltype(&std::remove_pointer_t<Comparable>::Compare)>::value, "Type does not implement Comparable concept (Comparable::Compare is not a member function)."); return pLhs->Compare(pRhs); } }; template <typename Comparable> struct compare_helper<Comparable, std::enable_if_t<std::is_arithmetic_v<Comparable>>> { static int compare(Comparable lhs, Comparable rhs) { return lhs - rhs; } }; template <typename T> int compare(T lhs, T rhs) { return compare_helper<T>::compare(lhs,rhs); } // compare(pObject1, pObject2) => compiles only if pObject1 has Compare method // compare(1,2)
- API author can choose to write template functions with specializations like (ACT could document an example)
- Example: key type for map, how to compare?
- Lenguaje dominante
- Go
- Estrellas
- 54
- Forks
- 26
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de Autodesk/AutomaticComponentToolkit
-
Autodesk/AutomaticComponentToolkit#226 · 5 comentarios · 3 reacciones · 3 asignados ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 45/100
Autodesk/AutomaticComponentToolkit#213 · 1 comentario · 2 reacciones ·
-
XML namespaces are not observed Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
Autodesk/AutomaticComponentToolkit#188 · 1 comentario ·
-
Why isn't JNI already a target? Abierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 20/100
Autodesk/AutomaticComponentToolkit#183 · 1 comentario ·
-
stringoutclass issues Abierto
Autodesk/AutomaticComponentToolkit#162 · 1 reacción · 2 asignados ·
Todos los issues de Autodesk/AutomaticComponentToolkit
Issues similares
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 60/100
github/gh-aw-mcpg#13748 ·
-
agentic-workflows
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
-
needs-triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
googleapis/librarian#7670 · 2 comentarios ·