CVB++ 15.0
Loading...
Searching...
No Matches
decl_object.hpp
1#pragma once
2
3#include "../../affine_matrix_2d.hpp"
4#include "../../affine_matrix_3d.hpp"
5#include "../../angle.hpp"
6#include "../../circle.hpp"
7#include "../../composite.hpp"
8#include "../../cuboid.hpp"
9#include "../../data_type.hpp"
10#include "../../dense_point_cloud.hpp"
11#include "../../driver/buffer_image.hpp"
12#include "../../driver/composite_stream.hpp"
13#include "../../driver/emu_image.hpp"
14#include "../../driver/genicam_device.hpp"
15#include "../../driver/image_stream.hpp"
16#include "../../driver/multi_part_image.hpp"
17#include "../../driver/point_cloud_stream.hpp"
18#include "../../driver/video_image.hpp"
19#include "../../genapi/boolean_node.hpp"
20#include "../../genapi/category_node.hpp"
21#include "../../genapi/command_node.hpp"
22#include "../../genapi/enum_entry_node.hpp"
23#include "../../genapi/enumeration_node.hpp"
24#include "../../genapi/float_node.hpp"
25#include "../../genapi/float_reg_node.hpp"
26#include "../../genapi/int_reg_node.hpp"
27#include "../../genapi/integer_node.hpp"
28#include "../../genapi/node_map.hpp"
29#include "../../genapi/node_map_enumerator.hpp"
30#include "../../genapi/string_node.hpp"
31#include "../../genapi/string_reg_node.hpp"
32#include "../../image.hpp"
33#include "../../line_2d.hpp"
34#include "../../matrix_2d.hpp"
35#include "../../matrix_3d.hpp"
36#include "../../matrix_3d_h.hpp"
37#include "../../pfnc_buffer.hpp"
38#include "../../plane.hpp"
39#include "../../plane_3d.hpp"
40#include "../../point_2d.hpp"
41#include "../../point_3d.hpp"
42#include "../../point_3d_h.hpp"
43#include "../../rect.hpp"
44#include "../../rect_lt.hpp"
45#include "../../sparse_point_cloud.hpp"
46#include "../py_script.hpp"
47
48#include <memory>
49#include <type_traits>
50
51namespace Cvb
52{
53 CVB_BEGIN_INLINE_NS
54
55 template <>
56 inline HandleGuard<PyScript::Object>::HandleGuard(void *handle) noexcept
57 : HandleGuard<PyScript::Object>(handle, [](void *handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
58 {
59 }
60
61 namespace PyScript
62 {
63 namespace Private
64 {
65 template <typename T>
66 struct IsPod : std::false_type
67 {
68 };
69
70 template <>
71 struct IsPod<bool> : std::true_type
72 {
73 using StorageType = bool;
74 static constexpr auto TypeId = CExports::CVPYSOTY_Bool;
75 static constexpr size_t Size = sizeof(bool);
76 };
77
78 template <>
79 struct IsPod<int8_t> : std::true_type
80 {
81 using StorageType = int64_t;
82 static constexpr auto TypeId = CExports::CVPYSOTY_Int64;
83 static constexpr size_t Size = sizeof(int64_t);
84 };
85
86 template <>
87 struct IsPod<uint8_t> : std::true_type
88 {
89 using StorageType = uint64_t;
90 static constexpr auto TypeId = CExports::CVPYSOTY_UInt64;
91 static constexpr size_t Size = sizeof(uint64_t);
92 };
93
94 template <>
95 struct IsPod<int16_t> : std::true_type
96 {
97 using StorageType = int64_t;
98 static constexpr auto TypeId = CExports::CVPYSOTY_Int64;
99 static constexpr size_t Size = sizeof(int64_t);
100 };
101
102 template <>
103 struct IsPod<uint16_t> : std::true_type
104 {
105 using StorageType = uint64_t;
106 static constexpr auto TypeId = CExports::CVPYSOTY_UInt64;
107 static constexpr size_t Size = sizeof(uint64_t);
108 };
109
110 template <>
111 struct IsPod<int32_t> : std::true_type
112 {
113 using StorageType = int64_t;
114 static constexpr auto TypeId = CExports::CVPYSOTY_Int64;
115 static constexpr size_t Size = sizeof(int64_t);
116 };
117
118 template <>
119 struct IsPod<uint32_t> : std::true_type
120 {
121 using StorageType = uint64_t;
122 static constexpr auto TypeId = CExports::CVPYSOTY_UInt64;
123 static constexpr size_t Size = sizeof(uint64_t);
124 };
125
126 template <>
127 struct IsPod<int64_t> : std::true_type
128 {
129 using StorageType = int64_t;
130 static constexpr auto TypeId = CExports::CVPYSOTY_Int64;
131 static constexpr size_t Size = sizeof(int64_t);
132 };
133
134 template <>
135 struct IsPod<uint64_t> : std::true_type
136 {
137 using StorageType = uint64_t;
138 static constexpr auto TypeId = CExports::CVPYSOTY_UInt64;
139 static constexpr size_t Size = sizeof(uint64_t);
140 };
141
142 template <>
143 struct IsPod<float> : std::true_type
144 {
145 using StorageType = double;
146 static constexpr auto TypeId = CExports::CVPYSOTY_Float64;
147 static constexpr size_t Size = sizeof(double);
148 };
149
150 template <>
151 struct IsPod<double> : std::true_type
152 {
153 using StorageType = double;
154 static constexpr auto TypeId = CExports::CVPYSOTY_Float64;
155 static constexpr size_t Size = sizeof(double);
156 };
157
158 template <typename T>
159 struct IsHandleType : std::false_type
160 {
161 };
162
163 template <>
164 struct IsHandleType<Composite> : std::true_type
165 {
166 static constexpr auto TypeId = CExports::CVPYSOTY_Composite;
167 };
168
169 template <>
170 struct IsHandleType<DensePointCloud> : std::true_type
171 {
172 static constexpr auto TypeId = CExports::CVPYSOTY_DensePointCloud;
173 };
174
175 template <>
176 struct IsHandleType<Image> : std::true_type
177 {
178 static constexpr auto TypeId = CExports::CVPYSOTY_Image;
179 };
180
181 template <>
182 struct IsHandleType<MultiPartImage> : std::true_type
183 {
184 static constexpr auto TypeId = CExports::CVPYSOTY_MultiPartImage;
185 };
186
187 template <>
188 struct IsHandleType<PFNCBuffer> : std::true_type
189 {
190 static constexpr auto TypeId = CExports::CVPYSOTY_PfncBuffer;
191 };
192
193 template <>
194 struct IsHandleType<Plane> : std::true_type
195 {
196 static constexpr auto TypeId = CExports::CVPYSOTY_Plane;
197 };
198
199 template <>
200 struct IsHandleType<SparsePointCloud> : std::true_type
201 {
202 static constexpr auto TypeId = CExports::CVPYSOTY_SparsePointCloud;
203 };
204
205 template <>
206 struct IsHandleType<GenICamDevice> : std::true_type
207 {
208 static constexpr auto TypeId = CExports::CVPYSOTY_GenICamDevice;
209 };
210
211 template <>
212 struct IsHandleType<CompositeStream> : std::true_type
213 {
214 static constexpr auto TypeId = CExports::CVPYSOTY_CompositeStream;
215 };
216
217 template <>
218 struct IsHandleType<ImageStream> : std::true_type
219 {
220 static constexpr auto TypeId = CExports::CVPYSOTY_ImageStream;
221 };
222
223 template <>
224 struct IsHandleType<PointCloudStream> : std::true_type
225 {
226 static constexpr auto TypeId = CExports::CVPYSOTY_PointCloudStream;
227 };
228
229 template <>
230 struct IsHandleType<BooleanNode> : std::true_type
231 {
232 static constexpr auto TypeId = CExports::CVPYSOTY_BooleanNode;
233 };
234
235 template <>
236 struct IsHandleType<CategoryNode> : std::true_type
237 {
238 static constexpr auto TypeId = CExports::CVPYSOTY_CategoryNode;
239 };
240
241 template <>
242 struct IsHandleType<CommandNode> : std::true_type
243 {
244 static constexpr auto TypeId = CExports::CVPYSOTY_CommandNode;
245 };
246
247 template <>
248 struct IsHandleType<EnumEntryNode> : std::true_type
249 {
250 static constexpr auto TypeId = CExports::CVPYSOTY_EnumEntryNode;
251 };
252
253 template <>
254 struct IsHandleType<EnumerationNode> : std::true_type
255 {
256 static constexpr auto TypeId = CExports::CVPYSOTY_EnumerationNode;
257 };
258
259 template <>
260 struct IsHandleType<FloatNode> : std::true_type
261 {
262 static constexpr auto TypeId = CExports::CVPYSOTY_FloatNode;
263 };
264
265 template <>
266 struct IsHandleType<FloatRegNode> : std::true_type
267 {
268 static constexpr auto TypeId = CExports::CVPYSOTY_FloatRegNode;
269 };
270
271 template <>
272 struct IsHandleType<IntRegNode> : std::true_type
273 {
274 static constexpr auto TypeId = CExports::CVPYSOTY_IntRegNode;
275 };
276
277 template <>
278 struct IsHandleType<IntegerNode> : std::true_type
279 {
280 static constexpr auto TypeId = CExports::CVPYSOTY_IntegerNode;
281 };
282
283 template <>
284 struct IsHandleType<NodeMap> : std::true_type
285 {
286 static constexpr auto TypeId = CExports::CVPYSOTY_NodeMap;
287 };
288
289 template <>
290 struct IsHandleType<NodeMapEnumerator> : std::true_type
291 {
292 static constexpr auto TypeId = CExports::CVPYSOTY_NodeMapEnumerator;
293 };
294
295 template <>
296 struct IsHandleType<StringNode> : std::true_type
297 {
298 static constexpr auto TypeId = CExports::CVPYSOTY_StringNode;
299 };
300
301 template <>
302 struct IsHandleType<StringRegNode> : std::true_type
303 {
304 static constexpr auto TypeId = CExports::CVPYSOTY_StringRegNode;
305 };
306
307 template <typename T>
308 struct IsCvbType : std::false_type
309 {
310 };
311
312 template <>
313 struct IsCvbType<DataType> : std::true_type
314 {
315 static constexpr auto TypeId = CExports::CVPYSOTY_DataType;
316 };
317
318 template <>
319 struct IsCvbType<Circle> : std::true_type
320 {
321 static constexpr auto TypeId = CExports::CVPYSOTY_Circle;
322 };
323
324 template <>
325 struct IsCvbType<AffineMatrix2D> : std::true_type
326 {
327 static constexpr auto TypeId = CExports::CVPYSOTY_AffineMatrix2D;
328 };
329
330 template <>
331 struct IsCvbType<AffineMatrix3D> : std::true_type
332 {
333 static constexpr auto TypeId = CExports::CVPYSOTY_AffineMatrix3D;
334 };
335
336 template <>
337 struct IsCvbType<Angle> : std::true_type
338 {
339 static constexpr auto TypeId = CExports::CVPYSOTY_Angle;
340 };
341
342 template <>
343 struct IsCvbType<Cuboid> : std::true_type
344 {
345 static constexpr auto TypeId = CExports::CVPYSOTY_Cuboid;
346 };
347
348 template <>
349 struct IsCvbType<Line2D> : std::true_type
350 {
351 static constexpr auto TypeId = CExports::CVPYSOTY_Line2D;
352 };
353
354 template <>
355 struct IsCvbType<Matrix2D> : std::true_type
356 {
357 static constexpr auto TypeId = CExports::CVPYSOTY_Matrix2D;
358 };
359
360 template <>
361 struct IsCvbType<Matrix3DH> : std::true_type
362 {
363 static constexpr auto TypeId = CExports::CVPYSOTY_Matrix3DH;
364 };
365
366 template <>
367 struct IsCvbType<Matrix3D> : std::true_type
368 {
369 static constexpr auto TypeId = CExports::CVPYSOTY_Matrix3D;
370 };
371
372 template <>
373 struct IsCvbType<Plane3D> : std::true_type
374 {
375 static constexpr auto TypeId = CExports::CVPYSOTY_Plane3D;
376 };
377
378 template <>
379 struct IsCvbType<Point2D<double>> : std::true_type
380 {
381 static constexpr auto TypeId = CExports::CVPYSOTY_Point2D;
382 };
383
384 template <>
385 struct IsCvbType<Point3D<double>> : std::true_type
386 {
387 static constexpr auto TypeId = CExports::CVPYSOTY_Point3D;
388 };
389
390 template <>
391 struct IsCvbType<Point3DH<double>> : std::true_type
392 {
393 static constexpr auto TypeId = CExports::CVPYSOTY_Point3DH;
394 };
395
396 template <>
397 struct IsCvbType<Rect<double>> : std::true_type
398 {
399 static constexpr auto TypeId = CExports::CVPYSOTY_Rect;
400 };
401
402 template <>
403 struct IsCvbType<RectLT<double>> : std::true_type
404 {
405 static constexpr auto TypeId = CExports::CVPYSOTY_RectLT;
406 };
407
408 template <>
409 struct IsCvbType<Size2D<double>> : std::true_type
410 {
411 static constexpr auto TypeId = CExports::CVPYSOTY_Size2D;
412 };
413
414 template <>
415 struct IsCvbType<ValueRange<double>> : std::true_type
416 {
417 static constexpr auto TypeId = CExports::CVPYSOTY_ValueRange;
418 };
419
420 template <typename T>
421 struct CanCastCvbType : std::false_type
422 {
423 };
424
425 template <>
426 struct CanCastCvbType<Point2D<int>> : std::true_type
427 {
428 using StorageType = Point2D<double>;
429 };
430
431 template <>
432 struct CanCastCvbType<Point3D<int>> : std::true_type
433 {
434 using StorageType = Point3D<double>;
435 };
436
437 template <>
438 struct CanCastCvbType<Rect<int>> : std::true_type
439 {
440 using StorageType = Rect<double>;
441 };
442
443 template <>
444 struct CanCastCvbType<RectLT<int>> : std::true_type
445 {
446 using StorageType = RectLT<double>;
447 };
448
449 template <>
450 struct CanCastCvbType<Size2D<int>> : std::true_type
451 {
452 using StorageType = Size2D<double>;
453 };
454
455 template <typename T>
456 struct CanHandleUpCastType : std::false_type
457 {
458 };
459
460 template <>
461 struct CanHandleUpCastType<Image> : std::true_type
462 {
463 using StorageType = Image;
464 };
465
466 template <>
467 struct CanHandleUpCastType<RingBufferImage> : std::true_type
468 {
469 using StorageType = Image;
470 };
471
472 template <>
473 struct CanHandleUpCastType<BufferImage> : std::true_type
474 {
475 using StorageType = Image;
476 };
477
478 template <>
479 struct CanHandleUpCastType<StreamImage> : std::true_type
480 {
481 using StorageType = Image;
482 };
483
484 template <>
485 struct CanHandleUpCastType<WrappedImage> : std::true_type
486 {
487 using StorageType = Image;
488 };
489
490 template <>
491 struct CanHandleUpCastType<VinImage> : std::true_type
492 {
493 using StorageType = Image;
494 };
495
496 template <>
497 struct CanHandleUpCastType<VideoImage> : std::true_type
498 {
499 using StorageType = Image;
500 };
501
502 template <>
503 struct CanHandleUpCastType<EmuImage> : std::true_type
504 {
505 using StorageType = Image;
506 };
507
508 template <>
509 struct CanHandleUpCastType<DeviceImage> : std::true_type
510 {
511 using StorageType = Image;
512 };
513
514 template <>
515 struct CanHandleUpCastType<IntegerNode> : std::true_type
516 {
517 using StorageType = IntegerNode;
518 };
519
520 template <>
521 struct CanHandleUpCastType<FloatNode> : std::true_type
522 {
523 using StorageType = FloatNode;
524 };
525
526 template <>
527 struct CanHandleUpCastType<StringNode> : std::true_type
528 {
529 using StorageType = StringNode;
530 };
531
532 template <class... T>
533 struct DownCastList
534 {
535 };
536
537 template <typename T>
538 struct CanHandleDownCastType : std::false_type
539 {
540 };
541
542 template <>
543 struct CanHandleDownCastType<Image> : std::true_type
544 {
545 using List = DownCastList<MultiPartImage>;
546 };
547
548 template <>
549 struct CanHandleDownCastType<StreamImage> : std::true_type
550 {
551 using List = DownCastList<MultiPartImage>;
552 };
553
554 template <>
555 struct CanHandleDownCastType<Node> : std::true_type
556 {
557 using List = DownCastList<BooleanNode, CategoryNode, CommandNode, EnumerationNode, EnumEntryNode, FloatRegNode,
558 FloatNode, IntRegNode, IntegerNode, StringRegNode, StringNode>;
559 };
560
561 template <>
562 struct CanHandleDownCastType<ValueNode> : std::true_type
563 {
564 using List = DownCastList<BooleanNode, CategoryNode, CommandNode, EnumerationNode, EnumEntryNode, FloatRegNode,
565 FloatNode, IntRegNode, IntegerNode, StringRegNode, StringNode>;
566 };
567
568 template <>
569 struct CanHandleDownCastType<SelectorNode> : std::true_type
570 {
571 using List = DownCastList<EnumerationNode, IntRegNode, IntegerNode>;
572 };
573
574 template <>
575 struct CanHandleDownCastType<FloatNode> : std::true_type
576 {
577 using List = DownCastList<FloatRegNode>;
578 };
579
580 template <>
581 struct CanHandleDownCastType<IntegerNode> : std::true_type
582 {
583 using List = DownCastList<IntRegNode>;
584 };
585
586 template <>
587 struct CanHandleDownCastType<StringNode> : std::true_type
588 {
589 using List = DownCastList<StringRegNode>;
590 };
591
592 template <>
593 struct CanHandleDownCastType<PointCloud> : std::true_type
594 {
595 using List = DownCastList<SparsePointCloud, DensePointCloud>;
596 };
597
598 } // namespace Private
599
601
613 class Object final
614 {
615 struct PrivateTag
616 {
617 };
618
619 public:
620 using GuardType = HandleGuard<Object>;
621
622 static ObjectPtr FromHandle(HandleGuard<Object> &&guard)
623 {
624 return std::make_shared<Object>(std::move(guard), PrivateTag{});
625 }
626
627 template <class T>
628 static ObjectPtr FromHandle(HandleGuard<Object> &&guard)
629 {
630 return FromHandle(std::move(guard));
631 }
632
634
641 template <class T>
642 static std::shared_ptr<Object> Create(const T &value)
643 {
644 return CreateImpl(value, SelectCategory<T>{});
645 }
646
647 template <class T>
649 {
650 static_assert(Private::IsHandleType<T>::value || Private::CanHandleUpCastType<T>::value
651 || Private::CanHandleDownCastType<T>::value,
652 "T must be a handle type or castable");
653
654 return Create(*value);
655 }
656
657 static ObjectPtr Create(const char *value);
658
659 static ObjectPtr Create(const wchar_t *value);
660
662
670 static ObjectPtr MakeVoidTuple(size_t size);
671
673
681 template <typename... T>
682 static ObjectPtr MakeTuple(T &&...args)
683 {
684 auto tuple = MakeVoidTuple(sizeof...(T));
685 size_t index = 0;
686 tuple->ImplMakeTuple(index, std::forward<T>(args)...);
687 return tuple;
688 }
689
691
699 static std::shared_ptr<Object> MakeVoidList(size_t size);
700
701 Object(HandleGuard<Object> &&guard, PrivateTag) noexcept
702 : handle_(std::move(guard))
703 {
704 }
705 Object(const Object &other) = delete;
706 Object &operator=(const Object &other) = delete;
707 Object(Object &&other) = delete;
708 Object &operator=(Object &&other) = delete;
709 ~Object() = default;
710
712
719 ObjectPtr Attribute(const Cvb::String &attributeName)
720 {
721 return Internal::DoResCallShareOut<Object>([this, &attributeName](void *&handle) {
722 return CVB_CALL_CAPI(CVPYSObjGetAttributeTyped(handle_.Handle(), attributeName.c_str(), handle));
723 });
724 }
725
727
732 ObjectPtr Run(const Object &args)
733 {
734 return Internal::DoResCallShareOut<Object>([this, &args](void *&handle) {
735 return CVB_CALL_CAPI(CVPYSObjRun(handle_.Handle(), args.Handle(), handle));
736 });
737 }
738
740
745 {
746 return Internal::DoResCallShareOut<Object>(
747 [this](void *&handle) { return CVB_CALL_CAPI(CVPYSObjRun(handle_.Handle(), nullptr, handle)); });
748 }
749
751
757 size_t ElementCount() const
758 {
759 size_t elementCount = 0;
760 CVB_CALL_CAPI_CHECKED(CVPYSObjElementCount(handle_.Handle(), elementCount));
761 return elementCount;
762 }
763
765
772 void Set(size_t index, const Object &obj)
773 {
774 CVB_CALL_CAPI_CHECKED(CVPYSObjElementSet(handle_.Handle(), index, obj.Handle()));
775 }
776
778
785 ObjectPtr Get(size_t index) const
786 {
787 return Internal::DoResCallShareOut<Object>([this, index](void *&handle) {
788 return CVB_CALL_CAPI(CVPYSObjElementGet(handle_.Handle(), index, handle));
789 });
790 }
791
793
800 template <class T>
801 T As() const
802 {
803 return AsImpl<T>::Run(*this, SelectCategory<T>{});
804 }
805
807
812 void *Handle() const noexcept
813 {
814 return handle_.Handle();
815 }
816
817 private:
818 template <class LAST>
819 void ImplMakeTuple(size_t &index, LAST &&last)
820 {
821 auto obj = Create(last);
822 Set(index, *obj);
823 }
824
825 template <class FIRST, class... T>
826 void ImplMakeTuple(size_t &index, FIRST &&first, T &&...args)
827 {
828 auto obj = Create(first);
829 Set(index, *obj);
830 index++;
831 ImplMakeTuple(index, std::forward<T>(args)...);
832 }
833
834 struct PodTag
835 {
836 };
837 struct HandleTag
838 {
839 };
840 struct HandleDownCastTag
841 {
842 };
843 struct HandleUpCastTag
844 {
845 };
846 struct EnumTag
847 {
848 };
849 struct CvbTag
850 {
851 };
852 struct CanCastCvbTag
853 {
854 };
855 struct DefaultTag
856 {
857 };
858
859 // Attention the order partly mattes
860 // for casting
861 // 1. down cast (HandleDownCastTag)
862 // 2. upcast (HandleUpCastTag)
863 // 3. direct use (HandleTag)
864 template <class T>
865 using SelectCategory = typename std::conditional<
866 Private::IsPod<T>::value, PodTag,
867 typename std::conditional<
868 std::is_enum<T>::value, EnumTag,
869 typename std::conditional<
870 Private::IsCvbType<T>::value, CvbTag,
871 typename std::conditional<
872 Private::CanCastCvbType<T>::value, CanCastCvbTag,
873 typename std::conditional<
874 Private::CanHandleDownCastType<T>::value, HandleDownCastTag,
875 typename std::conditional<Private::CanHandleUpCastType<T>::value, HandleUpCastTag,
876 typename std::conditional<Private::IsHandleType<T>::value,
877 HandleTag, DefaultTag>::type>::type>::
878 type>::type>::type>::type>::type;
879
880 // tag dispatch is not enough we need partial specialization
881 template <class T>
882 struct AsImpl
883 {
884 static T Run(const Object &object, PodTag)
885 {
886 CExports::CVPYSObjType type = Private::IsPod<T>::TypeId;
887 typename Private::IsPod<T>::StorageType value = {};
888 size_t size = Private::IsPod<T>::Size;
889 CVB_CALL_CAPI_CHECKED(CVPYSObjToBuffer(object.Handle(), type, &value, size));
890 return static_cast<T>(value);
891 }
892
893 static T Run(const Object &object, EnumTag)
894 {
895 return static_cast<T>(object.As<int64_t>());
896 }
897
898 static T Run(const Object &object, CvbTag)
899 {
900 CExports::CVPYSObjType type = Private::IsCvbType<T>::TypeId;
901 T value = {};
902 size_t size = sizeof(T);
903 CVB_CALL_CAPI_CHECKED(CVPYSObjToBuffer(object.Handle(), type, &value, size));
904 return value;
905 }
906
907 static T Run(const Object &object, CanCastCvbTag)
908 {
909 return Cvb::Round(AsImpl<typename Private::CanCastCvbType<T>::StorageType>::Run(object, CvbTag{}));
910 }
911 };
912
913 template <class T>
914 struct AsImpl<std::shared_ptr<T>>
915 {
916 static std::shared_ptr<T> Run(const Object &object, DefaultTag)
917 {
918 static_assert(Private::IsHandleType<T>::value, "T must be a handle type");
919 return Internal::DoResCallShareOut<T>([&object](void *&handle) {
920 CExports::CVPYSObjType type = Private::IsHandleType<T>::TypeId;
921 size_t size = sizeof(void *);
922 return CVPYSObjToBuffer(object.Handle(), type, &handle, size);
923 });
924 }
925 };
926
927
928 template <class T>
929 static ObjectPtr CreateImpl(const T &value, PodTag);
930
931 template <class T>
932 static std::shared_ptr<Object> CreateImpl(const T &value, HandleTag);
933
934 template <class T>
935 static std::shared_ptr<Object> CreateImpl(const T &value, EnumTag);
936
937 template <class T>
938 static std::shared_ptr<Object> CreateImpl(const T &value, CvbTag);
939
940 template <class T>
941 static std::shared_ptr<Object> CreateImpl(const T &value, CanCastCvbTag)
942 {
943 return CreateImpl(static_cast<typename Private::CanCastCvbType<T>::StorageType>(value), CvbTag{});
944 }
945
946 template <class T>
947 static std::shared_ptr<Object> CreateImpl(const T &value, HandleUpCastTag)
948 {
949 return CreateImpl(dynamic_cast<const typename Private::CanHandleUpCastType<T>::StorageType &>(value),
950 HandleTag{});
951 }
952
953
954
955 template <class T>
956 static std::shared_ptr<Object> CreateImpl(const T &value, HandleDownCastTag)
957 {
958 return CreateImpl(value, typename Private::CanHandleDownCastType<T>::List{});
959 }
960
961 template <class T, class DCT_FIRST, class... DCT_TAIL>
962 static std::shared_ptr<Object> CreateImpl(const T &value, Private::DownCastList<DCT_FIRST, DCT_TAIL...>)
963 {
964 if (auto *ptr = dynamic_cast<const DCT_FIRST *>(&value))
965 return CreateImpl(*ptr, HandleTag{});
966 else
967 return CreateImpl(value, Private::DownCastList<DCT_TAIL...>{});
968 }
969
970#ifdef _WIN32
971# pragma warning(push)
972# pragma warning(disable : 4702)
973#endif
974 template <class T, class DCT_LAST>
975 static std::shared_ptr<Object> CreateImpl(const T &value, Private::DownCastList<DCT_LAST>)
976 {
977 // C++ 17 contexpr if would prevent the unreachable code
978 // but we want to stay at C++ 14 for now.
979 if (auto *ptr = dynamic_cast<const DCT_LAST *>(&value))
980 return CreateImpl(*ptr, HandleTag{});
981 else
982 return CreateImpl(value, HandleUpCastTag{});
983 }
984#ifdef _WIN32
985# pragma warning(pop)
986#endif
987
988 HandleGuard<Object> handle_;
989 };
990
991 template <>
992 struct Object::AsImpl<std::shared_ptr<Image>>
993 {
994 static std::shared_ptr<Image> Run(const Object &object, DefaultTag)
995 {
996 CExports::CVPYSObjType type = CExports::CVPYSOTY_Image;
997 void *handle = nullptr;
998 size_t size = sizeof(void *);
999 CVB_CALL_CAPI_CHECKED(CVPYSObjToBuffer(object.Handle(), type, &handle, size));
1000 switch (type)
1001 {
1002 default:
1003 throw std::runtime_error("invalid image");
1004
1005 case CExports::CVPYSOTY_Image:
1006 return Image::FromHandle<Image>(HandleGuard<Image>(handle));
1007 case CExports::CVPYSOTY_MultiPartImage:
1008 return MultiPartImage::FromHandle<MultiPartImage>(HandleGuard<Image>(handle));
1009 }
1010 }
1011 };
1012
1013 template <>
1014 struct Object::AsImpl<std::shared_ptr<Node>>
1015 {
1016 static std::shared_ptr<Node> Run(const Object &object, DefaultTag)
1017 {
1018 CExports::CVPYSObjType type = CExports::CVPYSOTY_Node;
1019 void *handle = nullptr;
1020 size_t size = sizeof(void *);
1021 CVB_CALL_CAPI_CHECKED(CVPYSObjToBuffer(object.Handle(), type, &handle, size));
1022 switch (type)
1023 {
1024 default:
1025 throw std::runtime_error("invalid node");
1026
1027 case CExports::CVPYSOTY_BooleanNode:
1028 return BooleanNode::FromHandle<BooleanNode>(HandleGuard<Node>(handle));
1029 case CExports::CVPYSOTY_CategoryNode:
1030 return CategoryNode::FromHandle<CategoryNode>(HandleGuard<Node>(handle));
1031 case CExports::CVPYSOTY_CommandNode:
1032 return CommandNode::FromHandle<CommandNode>(HandleGuard<Node>(handle));
1033 case CExports::CVPYSOTY_EnumerationNode:
1034 return EnumerationNode::FromHandle<EnumerationNode>(HandleGuard<Node>(handle));
1035 case CExports::CVPYSOTY_EnumEntryNode:
1036 return EnumEntryNode::FromHandle<EnumEntryNode>(HandleGuard<Node>(handle));
1037 case CExports::CVPYSOTY_FloatRegNode:
1038 return FloatRegNode::FromHandle<FloatRegNode>(HandleGuard<Node>(handle));
1039 case CExports::CVPYSOTY_FloatNode:
1040 return FloatNode::FromHandle<FloatNode>(HandleGuard<Node>(handle));
1041 case CExports::CVPYSOTY_IntRegNode:
1042 return IntRegNode::FromHandle<IntRegNode>(HandleGuard<Node>(handle));
1043 case CExports::CVPYSOTY_IntegerNode:
1044 return IntegerNode::FromHandle<IntegerNode>(HandleGuard<Node>(handle));
1045 case CExports::CVPYSOTY_StringRegNode:
1046 return StringRegNode::FromHandle<StringRegNode>(HandleGuard<Node>(handle));
1047 case CExports::CVPYSOTY_StringNode:
1048 return StringNode::FromHandle<StringNode>(HandleGuard<Node>(handle));
1049 }
1050 }
1051 };
1052
1053 template <>
1054 struct Object::AsImpl<std::shared_ptr<ValueNode>>
1055 {
1056 static std::shared_ptr<ValueNode> Run(const Object &object, DefaultTag tag)
1057 {
1058 auto node = std::dynamic_pointer_cast<ValueNode>(AsImpl<std::shared_ptr<Node>>::Run(object, tag));
1059 if (!node)
1060 throw std::runtime_error("no valid value node");
1061 return node;
1062 }
1063 };
1064
1065 template <>
1066 struct Object::AsImpl<std::shared_ptr<FloatNode>>
1067 {
1068 static std::shared_ptr<FloatNode> Run(const Object &object, DefaultTag tag)
1069 {
1070 auto node = std::dynamic_pointer_cast<FloatNode>(AsImpl<std::shared_ptr<Node>>::Run(object, tag));
1071 if (!node)
1072 throw std::runtime_error("no valid float node");
1073 return node;
1074 }
1075 };
1076
1077 template <>
1078 struct Object::AsImpl<std::shared_ptr<IntegerNode>>
1079 {
1080 static std::shared_ptr<IntegerNode> Run(const Object &object, DefaultTag tag)
1081 {
1082 auto node = std::dynamic_pointer_cast<IntegerNode>(AsImpl<std::shared_ptr<Node>>::Run(object, tag));
1083 if (!node)
1084 throw std::runtime_error("no valid integer node");
1085 return node;
1086 }
1087 };
1088
1089 template <>
1090 struct Object::AsImpl<std::shared_ptr<SelectorNode>>
1091 {
1092 static std::shared_ptr<SelectorNode> Run(const Object &object, DefaultTag tag)
1093 {
1094 auto node = std::dynamic_pointer_cast<SelectorNode>(AsImpl<std::shared_ptr<Node>>::Run(object, tag));
1095 if (!node)
1096 throw std::runtime_error("no valid selector node");
1097 return node;
1098 }
1099 };
1100
1101 template <>
1102 struct Object::AsImpl<std::shared_ptr<StringNode>>
1103 {
1104 static std::shared_ptr<StringNode> Run(const Object &object, DefaultTag tag)
1105 {
1106 auto node = std::dynamic_pointer_cast<StringNode>(AsImpl<std::shared_ptr<Node>>::Run(object, tag));
1107 if (!node)
1108 throw std::runtime_error("no valid string node");
1109 return node;
1110 }
1111 };
1112
1113 template <>
1114 struct Object::AsImpl<std::shared_ptr<PointCloud>>
1115 {
1116 static std::shared_ptr<PointCloud> Run(const Object &object, DefaultTag)
1117 {
1118 CExports::CVPYSObjType type = CExports::CVPYSOTY_PointCloud;
1119 void *handle = nullptr;
1120 size_t size = sizeof(void *);
1121 CVB_CALL_CAPI_CHECKED(CVPYSObjToBuffer(object.Handle(), type, &handle, size));
1122 switch (type)
1123 {
1124 default:
1125 throw std::runtime_error("invalid point cloud");
1126
1127 case CExports::CVPYSOTY_DensePointCloud:
1128 return DensePointCloud::FromHandle<DensePointCloud>(HandleGuard<PointCloud>(handle));
1129 case CExports::CVPYSOTY_SparsePointCloud:
1130 return SparsePointCloud::FromHandle<SparsePointCloud>(HandleGuard<PointCloud>(handle));
1131 }
1132 }
1133 };
1134
1135 // will never be called but needed for code generation
1136 template <>
1137 [[noreturn]] inline std::shared_ptr<Object> Object::CreateImpl<Node>(const Node &value, HandleUpCastTag)
1138 {
1139 (void)value;
1140 throw std::runtime_error("cannot create from Cvb::Node");
1141 }
1142
1143 // will never be called but needed for code generation
1144 template <>
1145 [[noreturn]] inline std::shared_ptr<Object> Object::CreateImpl<ValueNode>(const ValueNode &value, HandleUpCastTag)
1146 {
1147 (void)value;
1148 throw std::runtime_error("cannot create from Cvb::ValueNode");
1149 }
1150
1151 // will never be called but needed for code generation
1152 template <>
1153 [[noreturn]] inline std::shared_ptr<Object> Object::CreateImpl<SelectorNode>(const SelectorNode &value,
1154 HandleUpCastTag)
1155 {
1156 (void)value;
1157 throw std::runtime_error("cannot create from Cvb::SelectorNode");
1158 }
1159
1160 // will never be called but needed for code generation
1161 template <>
1162 [[noreturn]] inline std::shared_ptr<Object> Object::CreateImpl<PointCloud>(const PointCloud &value, HandleUpCastTag)
1163 {
1164 (void)value;
1165 throw std::runtime_error("cannot create from Cvb::PointClouds");
1166 }
1167
1168 } // namespace PyScript
1169 CVB_END_INLINE_NS
1170
1171} // namespace Cvb
static std::unique_ptr< Image > FromHandle(HandleGuard< Image > &&guard)
Creates an image from a classic API handle.
Definition decl_image.hpp:160
Variant like python object.
Definition decl_object.hpp:614
ObjectPtr Get(size_t index) const
Get an element from this object.
Definition decl_object.hpp:785
ObjectPtr Run(const Object &args)
Runs the object as callable.
Definition decl_object.hpp:732
void Set(size_t index, const Object &obj)
Set an element in this object.
Definition decl_object.hpp:772
static ObjectPtr MakeTuple(T &&...args)
Creates tuple with the given types.
Definition decl_object.hpp:682
static std::shared_ptr< Object > MakeVoidList(size_t size)
Creates list with a specified size.
Definition detail_object.hpp:21
ObjectPtr Attribute(const Cvb::String &attributeName)
Gets an attribute of the object as object.
Definition decl_object.hpp:719
static std::shared_ptr< Object > Create(const T &value)
Creates a object form any supported type.
Definition decl_object.hpp:642
T As() const
Get an type from this object.
Definition decl_object.hpp:801
ObjectPtr Run()
Runs the object as callable.
Definition decl_object.hpp:744
size_t ElementCount() const
Number of elements in this object.
Definition decl_object.hpp:757
void * Handle() const noexcept
Classic API buffer handle.
Definition decl_object.hpp:812
static ObjectPtr MakeVoidTuple(size_t size)
Creates tuple with a specified size.
Definition detail_object.hpp:14
T forward(T... args)
cvbbool_t ReleaseObject(OBJ &Object)
T make_shared(T... args)
T move(T... args)
@ Size
Area of the blob in pixels.
Definition blob.hpp:56
Namespace for the python scripting package.
Definition decl_context.hpp:21
std::shared_ptr< Object > ObjectPtr
Convenience shared pointer for Object.
Definition py_script.hpp:127
@ DataType
Definition spectral.hpp:148
Root namespace for the Image Manager interface.
Definition version.hpp:11
std::string String
String for wide characters or unicode characters.
Definition string.hpp:49
Point2D< int > Round(const Point2D< T > &rhs) noexcept
Round to an integer point.
Definition point_2d.hpp:371