Add template classes
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 30/100
Hướng nghiên cứu
Không có tệp mã nguồn, bài kiểm thử hoặc entry point nào được nêu tên. Hãy bắt đầu bằng việc xem xét schema XML templateclass/templateparam được đề xuất và phần triển khai C++ cùng các ví dụ binding được tạo; công việc được coi là hoàn tất khi có thể khai báo các lớp generic và tạo các stub triển khai cùng binding của chúng cho các instantiation được minh họa.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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?
- Ngôn ngữ chính
- Go
- Star
- 54
- Fork
- 26
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của Autodesk/AutomaticComponentToolkit
-
Autodesk/AutomaticComponentToolkit#226 · 5 bình luận · 3 reaction · 3 người được giao ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 45/100
Autodesk/AutomaticComponentToolkit#213 · 1 bình luận · 2 reaction ·
-
XML namespaces are not observed Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
Autodesk/AutomaticComponentToolkit#188 · 1 bình luận ·
-
Why isn't JNI already a target? Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 20/100
Autodesk/AutomaticComponentToolkit#183 · 1 bình luận ·
-
stringoutclass issues Đang mở
Autodesk/AutomaticComponentToolkit#162 · 1 reaction · 2 người được giao ·
Tất cả issue của Autodesk/AutomaticComponentToolkit
Issue tương tự
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 60/100
github/gh-aw-mcpg#13748 ·
-
agentic-workflows
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
-
needs-triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
googleapis/librarian#7670 · 2 bình luận ·