614 return InvokeWithLinearAccessesAndSizes(
616 return VisitAccessesAs<VisitorArgCount, T>(visitor, dataType, dtl, linAccessesAndSizes...);
618 lPlaneAccesses, {vpatAndSize.size_, vpatAndSizes.size_...},
619 std::make_index_sequence<
sizeof...(ACCESSES) + 1>());
626 constexpr const size_t NumAccesses = 1 +
sizeof...(ACCESSES);
627 return visitor(ScatterBlock<RefValue<T, NumAccesses>, NumAccesses>{scatterAccess, vpatAndSize.size_});
631 template <
size_t VisitorArgCount,
class T,
class VISITOR,
class... DTL,
class... ACCESSES,
632 std::enable_if_t<(VisitorArgCount ==
sizeof...(ACCESSES) + 1 ||
sizeof...(ACCESSES) == 0),
int> = 0>
633 auto VisitAccessesAs(VISITOR &&visitor, Cvb::DataType dataType, DispatchableTypeList<DTL...> dtl,
634 const VpatAndSize &vpatAndSize,
const ACCESSES &...vpatAndSizes)
636 const auto lPlaneAccesses =
637 MakeLinearAccessesIfAllAre(vpatAndSize.size_, dataType, vpatAndSize.access_, vpatAndSizes.access_...);
638 if (lPlaneAccesses[0])
640 return InvokeWithLinearAccessesAndSizes(
641 [visitor = std::forward<VISITOR>(visitor), dataType, dtl](
auto &&...linAccessesAndSizes) {
642 return VisitAccessesAs<VisitorArgCount, T>(visitor, dataType, dtl, linAccessesAndSizes...);
644 lPlaneAccesses, {vpatAndSize.size_, vpatAndSizes.size_...},
645 std::make_index_sequence<
sizeof...(ACCESSES) + 1>());
648 return std::forward<VISITOR>(visitor)(VpatPlaneBlock<T>{vpatAndSize.access_, vpatAndSize.size_},
649 VpatPlaneBlock<T>{vpatAndSizes.access_, vpatAndSizes.size_}...);
653 template <
size_t VisitorArgCount,
template <
class...>
class T,
class VISITOR,
class DT,
class... DTL,
654 class... ACCESSES, std::enable_if_t<VisitorArgCount == 1 &&
sizeof...(ACCESSES) != 0,
int> = 0>
655 auto VisitAccessesAs(VISITOR &&visitor, Cvb::DataType dataType, DispatchableTypeList<DT, DTL...> dtl,
656 const VpatAndSize &vpatAndSize,
const ACCESSES &...vpatAndSizes)
658 const auto lPlaneAccesses =
659 MakeLinearAccessesIfAllAre(vpatAndSize.size_, dataType, vpatAndSize.access_, vpatAndSizes.access_...);
660 if (lPlaneAccesses[0])
662 return InvokeWithLinearAccessesAndSizes(
663 [visitor = std::forward<VISITOR>(visitor), dataType, dtl](
auto &&...linAccessesAndSizes) {
664 return VisitAccessesAs<VisitorArgCount, T>(visitor, dataType, dtl, linAccessesAndSizes...);
666 lPlaneAccesses, {vpatAndSize.size_, vpatAndSizes.size_...},
667 std::make_index_sequence<
sizeof...(ACCESSES) + 1>());
674 constexpr const size_t NumAccesses = 1 +
sizeof...(ACCESSES);
675 return CallWithAnyOfTypes<
676 TemplatedTypeBlock<TemplatedSizedType<ScatterBlock, NumAccesses>::template type, T>::template type, DT>(
677 dataType, dtl, std::forward<VISITOR>(visitor), scatterAccess, vpatAndSize.size_);
681 template <
size_t VisitorArgCount,
template <
class...>
class T,
class VISITOR,
class DT,
class... DTL,
683 std::enable_if_t<VisitorArgCount ==
sizeof...(ACCESSES) + 1 ||
sizeof...(ACCESSES) == 0,
int> = 0>
684 auto VisitAccessesAs(VISITOR &&visitor, Cvb::DataType dataType, DispatchableTypeList<DT, DTL...> dtl,
685 const VpatAndSize &vpatAndSize,
const ACCESSES &...vpatAndSizes)
687 const auto lPlaneAccesses =
688 MakeLinearAccessesIfAllAre(vpatAndSize.size_, dataType, vpatAndSize.access_, vpatAndSizes.access_...);
689 if (lPlaneAccesses[0])
691 return InvokeWithLinearAccessesAndSizes(
692 [visitor = std::forward<VISITOR>(visitor), dataType, dtl](
auto &&...linAccessesAndSizes) {
693 return VisitAccessesAs<VisitorArgCount, T>(visitor, dataType, dtl, linAccessesAndSizes...);
695 lPlaneAccesses, {vpatAndSize.size_, vpatAndSizes.size_...},
696 std::make_index_sequence<
sizeof...(ACCESSES) + 1>());
699 return CallWithAnyOfTypes<TemplatedTypeBuilder<T>::template type, DT>(
701 [=](
auto typedThingy) {
702 visitor(typedThingy(vpatAndSize.access_, vpatAndSize.size_),
703 typedThingy(vpatAndSizes.access_, vpatAndSizes.size_)...);
709 template <
class PIXEL_TYPE,
class VISITOR,
class... DTL>
710 auto VisitAccessesAs(VISITOR &&visitor, Cvb::DataType dataType, DispatchableTypeList<DTL...>,
711 const VpatAndSize &accessAndSize)
713 Internal::BlockBuilder<PIXEL_TYPE> builder{accessAndSize.size_};
714 if (
const auto linearAccess = LinearAccess::FromVpat(accessAndSize.access_, accessAndSize.size_, dataType))
716 if (
const auto arrayAccess = ArrayAccess::FromLinearAccess(linearAccess, accessAndSize.size_))
717 return std::forward<VISITOR>(visitor)(builder(arrayAccess));
719 return std::forward<VISITOR>(visitor)(builder(linearAccess));
722 return std::forward<VISITOR>(visitor)(builder(accessAndSize.access_));
724#pragma endregion VpatVisit
727 template <
class T,
class VISITOR,
class PLANE_T,
class... PLNS,
728 std::enable_if_t<!std::is_arithmetic<T>::value,
int> = 0>
729 auto VisitPlanesAs(VISITOR &&visitor,
const PLANE_T &plane,
const PLNS &...planes)
731 using PlaneTrait = PlaneTraits<PLANE_T>;
732 constexpr const size_t ArgCount = 1 +
sizeof...(PLNS);
733 constexpr const size_t VisitorArgCount =
734 Cvb::Internal::IsCallableMParameters<VISITOR, ArgCount, Block<T, LinearAccess>>::value ? ArgCount : 1;
736 static_assert(VisitorArgCount == ArgCount || VisitorArgCount == 1,
737 "Cvb: visitor must have either one argument or as many arguments as plane arguments are given.");
739 if (!PlaneTrait::GetDataType(plane).
template Matches<ComponentOfT<T>>()
740 || !AllPlanesHaveSameDataType(plane, planes...))
741 throw std::domain_error{
"The requested planes must have all the same data type"};
743#pragma warning(push, 4)
744#pragma warning(disable : 4127)
745 if (VisitorArgCount == 1 && !AllPlanesHaveSameSize(plane, planes...))
746 throw std::domain_error{
"Planes must have same size."};
749 return VisitAccessesAs<VisitorArgCount, T>(std::forward<VISITOR>(visitor), PlaneTrait::GetDataType(plane),
750 typename PlaneTrait::TypeList{}, GetAccessAndSize(plane),
751 GetAccessAndSize(planes)...);
755 template <
class T,
class VISITOR,
class PLANE_T,
class... PLNS,
756 std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
757 auto VisitPlanesAs(VISITOR &&visitor,
const PLANE_T &plane,
const PLNS &...planes)
759 using PlaneTrait = PlaneTraits<PLANE_T>;
760 constexpr const size_t ArgCount = 1 +
sizeof...(PLNS);
761 constexpr const size_t VisitorArgCount =
762 Cvb::Internal::IsCallableMParameters<VISITOR, ArgCount, Block<T, LinearAccess>>::value ? ArgCount : 1;
764 static_assert(VisitorArgCount == ArgCount || VisitorArgCount == 1,
765 "Cvb: visitor must have either one argument or as many arguments as plane arguments are given.");
767 if (!PlaneTrait::GetDataType(plane).
template Matches<T>() || !AllPlanesHaveSameDataType(plane, planes...))
768 throw std::domain_error{
"The requested planes must have all the same data type"};
770#pragma warning(push, 4)
771#pragma warning(disable : 4127)
772 if (VisitorArgCount == 1 && !AllPlanesHaveSameSize(plane, planes...))
773 throw std::domain_error{
"Planes must have same size."};
776 return VisitAccessesAs<VisitorArgCount, T>(std::forward<VISITOR>(visitor), PlaneTrait::GetDataType(plane),
777 typename PlaneTrait::TypeList{}, GetAccessAndSize(plane),
778 GetAccessAndSize(planes)...);
782 template <
template <
class...>
class T,
class VISITOR,
class PLANE_T,
class... PLNS>
783 auto VisitPlanesAs(VISITOR &&visitor,
const PLANE_T &plane,
const PLNS &...planes)
785 using PlaneTrait = PlaneTraits<PLANE_T>;
786 constexpr const size_t ArgCount = 1 +
sizeof...(PLNS);
787 constexpr const size_t VisitorArgCount =
788 Cvb::Internal::IsCallableMParameters<
789 VISITOR, ArgCount, Block<T<typename PlaneTrait::TypeList::DefaultType>, LinearAccess>>::value
793 static_assert(VisitorArgCount == ArgCount || VisitorArgCount == 1,
794 "Cvb: visitor must have either one argument or as many arguments as plane arguments are given.");
796 if (!AllPlanesHaveSameDataType(plane, planes...))
797 throw std::domain_error{
"The requested planes must have all the same data type"};
799#pragma warning(push, 4)
800#pragma warning(disable : 4127)
801 if (VisitorArgCount == 1 && !AllPlanesHaveSameSize(plane, planes...))
802 throw std::domain_error{
"Planes must have same size."};
805 return VisitAccessesAs<VisitorArgCount, T>(std::forward<VISITOR>(visitor), PlaneTrait::GetDataType(plane),
806 typename PlaneTrait::TypeList{}, GetAccessAndSize(plane),
807 GetAccessAndSize(planes)...);
811 template <
class T,
class VISITOR,
class PLANE_T>
812 auto VisitPlanesAs(VISITOR &&visitor,
const PLANE_T &plane)
814 static_assert(Cvb::Internal::is_callable<VISITOR(Block<T, LinearAccess>)>::value,
815 "Cvb: The visitor must be visitable with a single typed block.");
817 using PlaneTrait = PlaneTraits<PLANE_T>;
818 return VisitAccessesAs<1, T>(std::forward<VISITOR>(visitor), PlaneTrait::GetDataType(plane),
819 typename PlaneTrait::TypeList{}, GetAccessAndSize(plane));
822 template <class VISITOR, class PLANE_T, std::enable_if_t<!PlaneTraits<PLANE_T>::HasVpat,
int> = 0>
823 auto VisitPlanes(VISITOR &&visitor,
const PLANE_T &plane)
825 using PlaneTrait = PlaneTraits<PLANE_T>;
826 constexpr const size_t VisitorArgCount = 1;
828 const auto dataType = PlaneTrait::GetDataType(plane);
829 return VisitAccesses<VisitorArgCount>(std::forward<VISITOR>(visitor), dataType,
typename PlaneTrait::TypeList{},
830 LinearAccessAndSize{LinearAccess::FromPlane(plane), GetBlockSize(plane)});
833 template <class VISITOR, class PLANE_T, std::enable_if_t<PlaneTraits<PLANE_T>::HasVpat,
int> = 0>
834 auto VisitPlanes(VISITOR &&visitor,
const PLANE_T &plane)
836 using PlaneTrait = PlaneTraits<PLANE_T>;
837 const auto blockSize = GetBlockSize(plane);
838 auto vpat = PlaneTrait::GetVpat(plane);
839 const Cvb::DataType dt = PlaneTrait::GetDataType(plane);
840 if (
const auto access = LinearAccess::FromVpat(vpat, blockSize, dt))
842 if (
const auto arrayAccess = ArrayAccess::FromLinearAccess(access, blockSize))
843 return CallWithAnyOfTypes<ArrayPlaneBlock, typename PlaneTrait::TypeList::DefaultType>(
844 dt,
typename PlaneTrait::TypeList{}, visitor, arrayAccess, blockSize);
846 return CallWithAnyOfTypes<LinearPlaneBlock, typename PlaneTrait::TypeList::DefaultType>(
847 dt,
typename PlaneTrait::TypeList{}, visitor, access, blockSize);
850 return CallWithAnyOfTypes<VpatPlaneBlock, typename PlaneTrait::TypeList::DefaultType>(
851 dt,
typename PlaneTrait::TypeList{}, visitor, vpat, blockSize);
854 template <
class VISITOR,
class PLANE_T,
class... PLANEARGS>
855 auto VisitPlanes(VISITOR &&visitor,
const PLANE_T &plane,
const PLANEARGS &...planes)
857 using PlaneTrait = PlaneTraits<PLANE_T>;
858 constexpr const size_t ArgCount = 1 +
sizeof...(PLANEARGS);
859 constexpr const size_t VisitorArgCount =
860 Cvb::Internal::IsCallableMParameters<VISITOR, ArgCount,
861 Block<typename PlaneTrait::TypeList::DefaultType, LinearAccess>>::value
865 static_assert(VisitorArgCount == ArgCount || VisitorArgCount == 1,
866 "Cvb: visitor must have either one argument or as many arguments as plane arguments are given.");
868 if (!AllPlanesHaveSameDataType(plane, planes...))
869 throw std::domain_error{
"Planes must have all the same data type"};
871#pragma warning(push, 4)
872#pragma warning(disable : 4127)
873 if (VisitorArgCount == 1 && !AllPlanesHaveSameSize(plane, planes...))
874 throw std::domain_error{
"Planes must have same size."};
877 return VisitAccesses<VisitorArgCount>(std::forward<VISITOR>(visitor), PlaneTrait::GetDataType(plane),
878 typename PlaneTrait::TypeList{}, GetAccessAndSize(plane),
879 GetAccessAndSize(planes)...);
884 template <
class VISITOR,
class PLANE_T,
class... PLNS,
885 std::enable_if_t<std::is_same<typename PlaneTraits<PLANE_T>::PlaneT, PLANE_T>::value,
int>>
886 auto Visit(VISITOR &&visitor,
const PLANE_T &plane,
const PLNS &...planes)
891 template <
class T,
class VISITOR,
class PLANE_T,
class... PLANEARGS,
892 std::enable_if_t<std::is_same<typename PlaneTraits<PLANE_T>::PlaneT, PLANE_T>::value,
int>>
893 auto VisitAs(VISITOR &&visitor,
const PLANE_T &plane,
const PLANEARGS &...planes)
893 auto VisitAs(VISITOR &&visitor,
const PLANE_T &plane,
const PLANEARGS &...planes) {
…}