615 lPlaneAccesses, {vpatAndSize.size_, vpatAndSizes.size_...},
616 std::make_index_sequence<
sizeof...(ACCESSES) + 1>());
623 constexpr const size_t NumAccesses = 1 +
sizeof...(ACCESSES);
624 return visitor(ScatterBlock<RefValue<T, NumAccesses>, NumAccesses>{scatterAccess, vpatAndSize.size_});
628 template <
size_t VisitorArgCount,
class T,
class VISITOR,
class... DTL,
class... ACCESSES,
629 std::enable_if_t<(VisitorArgCount ==
sizeof...(ACCESSES) + 1 ||
sizeof...(ACCESSES) == 0),
int> = 0>
630 auto VisitAccessesAs(VISITOR &&visitor, Cvb::DataType dataType, DispatchableTypeList<DTL...> dtl,
631 const VpatAndSize &vpatAndSize,
const ACCESSES &...vpatAndSizes)
633 const auto lPlaneAccesses =
634 MakeLinearAccessesIfAllAre(vpatAndSize.size_, dataType, vpatAndSize.access_, vpatAndSizes.access_...);
635 if (lPlaneAccesses[0])
637 return InvokeWithLinearAccessesAndSizes(
638 [visitor = std::forward<VISITOR>(visitor), dataType, dtl](
auto &&...linAccessesAndSizes) {
639 return VisitAccessesAs<VisitorArgCount, T>(visitor, dataType, dtl, linAccessesAndSizes...);
641 lPlaneAccesses, {vpatAndSize.size_, vpatAndSizes.size_...},
642 std::make_index_sequence<
sizeof...(ACCESSES) + 1>());
645 return std::forward<VISITOR>(visitor)(VpatPlaneBlock<T>{vpatAndSize.access_, vpatAndSize.size_},
646 VpatPlaneBlock<T>{vpatAndSizes.access_, vpatAndSizes.size_}...);
650 template <
size_t VisitorArgCount,
template <
class...>
class T,
class VISITOR,
class DT,
class... DTL,
651 class... ACCESSES, std::enable_if_t<VisitorArgCount == 1 &&
sizeof...(ACCESSES) != 0,
int> = 0>
652 auto VisitAccessesAs(VISITOR &&visitor, Cvb::DataType dataType, DispatchableTypeList<DT, DTL...> dtl,
653 const VpatAndSize &vpatAndSize,
const ACCESSES &...vpatAndSizes)
655 const auto lPlaneAccesses =
656 MakeLinearAccessesIfAllAre(vpatAndSize.size_, dataType, vpatAndSize.access_, vpatAndSizes.access_...);
657 if (lPlaneAccesses[0])
659 return InvokeWithLinearAccessesAndSizes(
660 [visitor = std::forward<VISITOR>(visitor), dataType, dtl](
auto &&...linAccessesAndSizes) {
661 return VisitAccessesAs<VisitorArgCount, T>(visitor, dataType, dtl, linAccessesAndSizes...);
663 lPlaneAccesses, {vpatAndSize.size_, vpatAndSizes.size_...},
664 std::make_index_sequence<
sizeof...(ACCESSES) + 1>());
671 constexpr const size_t NumAccesses = 1 +
sizeof...(ACCESSES);
672 return CallWithAnyOfTypes<
673 TemplatedTypeBlock<TemplatedSizedType<ScatterBlock, NumAccesses>::template type, T>::template type, DT>(
674 dataType, dtl, std::forward<VISITOR>(visitor), scatterAccess, vpatAndSize.size_);
678 template <
size_t VisitorArgCount,
template <
class...>
class T,
class VISITOR,
class DT,
class... DTL,
680 std::enable_if_t<VisitorArgCount ==
sizeof...(ACCESSES) + 1 ||
sizeof...(ACCESSES) == 0,
int> = 0>
681 auto VisitAccessesAs(VISITOR &&visitor, Cvb::DataType dataType, DispatchableTypeList<DT, DTL...> dtl,
682 const VpatAndSize &vpatAndSize,
const ACCESSES &...vpatAndSizes)
684 const auto lPlaneAccesses =
685 MakeLinearAccessesIfAllAre(vpatAndSize.size_, dataType, vpatAndSize.access_, vpatAndSizes.access_...);
686 if (lPlaneAccesses[0])
688 return InvokeWithLinearAccessesAndSizes(
689 [visitor = std::forward<VISITOR>(visitor), dataType, dtl](
auto &&...linAccessesAndSizes) {
690 return VisitAccessesAs<VisitorArgCount, T>(visitor, dataType, dtl, linAccessesAndSizes...);
692 lPlaneAccesses, {vpatAndSize.size_, vpatAndSizes.size_...},
693 std::make_index_sequence<
sizeof...(ACCESSES) + 1>());
696 return CallWithAnyOfTypes<TemplatedTypeBuilder<T>::template type, DT>(
698 [=](
auto typedThingy) {
699 visitor(typedThingy(vpatAndSize.access_, vpatAndSize.size_),
700 typedThingy(vpatAndSizes.access_, vpatAndSizes.size_)...);
706 template <
class PIXEL_TYPE,
class VISITOR,
class... DTL>
707 auto VisitAccessesAs(VISITOR &&visitor, Cvb::DataType dataType, DispatchableTypeList<DTL...>,
708 const VpatAndSize &accessAndSize)
710 Internal::BlockBuilder<PIXEL_TYPE> builder{accessAndSize.size_};
711 if (
const auto linearAccess = LinearAccess::FromVpat(accessAndSize.access_, accessAndSize.size_, dataType))
713 if (
const auto arrayAccess = ArrayAccess::FromLinearAccess(linearAccess, accessAndSize.size_))
714 return std::forward<VISITOR>(visitor)(builder(arrayAccess));
716 return std::forward<VISITOR>(visitor)(builder(linearAccess));
719 return std::forward<VISITOR>(visitor)(builder(accessAndSize.access_));
721#pragma endregion VpatVisit
724 template <
class T,
class VISITOR,
class PLANE_T,
class... PLNS,
725 std::enable_if_t<!std::is_arithmetic<T>::value,
int> = 0>
726 auto VisitPlanesAs(VISITOR &&visitor,
const PLANE_T &plane,
const PLNS &...planes)
728 using PlaneTrait = PlaneTraits<PLANE_T>;
729 constexpr const size_t ArgCount = 1 +
sizeof...(PLNS);
730 constexpr const size_t VisitorArgCount =
731 Cvb::Internal::IsCallableMParameters<VISITOR, ArgCount, Block<T, LinearAccess>>::value ? ArgCount : 1;
733 static_assert(VisitorArgCount == ArgCount || VisitorArgCount == 1,
734 "Cvb: visitor must have either one argument or as many arguments as plane arguments are given.");
736 if (!PlaneTrait::GetDataType(plane).
template Matches<ComponentOfT<T>>()
737 || !AllPlanesHaveSameDataType(plane, planes...))
738 throw std::domain_error{
"The requested planes must have all the same data type"};
740#pragma warning(push, 4)
741#pragma warning(disable : 4127)
742 if (VisitorArgCount == 1 && !AllPlanesHaveSameSize(plane, planes...))
743 throw std::domain_error{
"Planes must have same size."};
746 return VisitAccessesAs<VisitorArgCount, T>(std::forward<VISITOR>(visitor), PlaneTrait::GetDataType(plane),
747 typename PlaneTrait::TypeList{}, GetAccessAndSize(plane),
748 GetAccessAndSize(planes)...);
752 template <
class T,
class VISITOR,
class PLANE_T,
class... PLNS,
753 std::enable_if_t<std::is_arithmetic<T>::value,
int> = 0>
754 auto VisitPlanesAs(VISITOR &&visitor,
const PLANE_T &plane,
const PLNS &...planes)
756 using PlaneTrait = PlaneTraits<PLANE_T>;
757 constexpr const size_t ArgCount = 1 +
sizeof...(PLNS);
758 constexpr const size_t VisitorArgCount =
759 Cvb::Internal::IsCallableMParameters<VISITOR, ArgCount, Block<T, LinearAccess>>::value ? ArgCount : 1;
761 static_assert(VisitorArgCount == ArgCount || VisitorArgCount == 1,
762 "Cvb: visitor must have either one argument or as many arguments as plane arguments are given.");
764 if (!PlaneTrait::GetDataType(plane).
template Matches<T>() || !AllPlanesHaveSameDataType(plane, planes...))
765 throw std::domain_error{
"The requested planes must have all the same data type"};
767#pragma warning(push, 4)
768#pragma warning(disable : 4127)
769 if (VisitorArgCount == 1 && !AllPlanesHaveSameSize(plane, planes...))
770 throw std::domain_error{
"Planes must have same size."};
773 return VisitAccessesAs<VisitorArgCount, T>(std::forward<VISITOR>(visitor), PlaneTrait::GetDataType(plane),
774 typename PlaneTrait::TypeList{}, GetAccessAndSize(plane),
775 GetAccessAndSize(planes)...);
779 template <
template <
class...>
class T,
class VISITOR,
class PLANE_T,
class... PLNS>
780 auto VisitPlanesAs(VISITOR &&visitor,
const PLANE_T &plane,
const PLNS &...planes)
782 using PlaneTrait = PlaneTraits<PLANE_T>;
783 constexpr const size_t ArgCount = 1 +
sizeof...(PLNS);
784 constexpr const size_t VisitorArgCount =
785 Cvb::Internal::IsCallableMParameters<
786 VISITOR, ArgCount, Block<T<typename PlaneTrait::TypeList::DefaultType>, LinearAccess>>::value
790 static_assert(VisitorArgCount == ArgCount || VisitorArgCount == 1,
791 "Cvb: visitor must have either one argument or as many arguments as plane arguments are given.");
793 if (!AllPlanesHaveSameDataType(plane, planes...))
794 throw std::domain_error{
"The requested planes must have all the same data type"};
796#pragma warning(push, 4)
797#pragma warning(disable : 4127)
798 if (VisitorArgCount == 1 && !AllPlanesHaveSameSize(plane, planes...))
799 throw std::domain_error{
"Planes must have same size."};
802 return VisitAccessesAs<VisitorArgCount, T>(std::forward<VISITOR>(visitor), PlaneTrait::GetDataType(plane),
803 typename PlaneTrait::TypeList{}, GetAccessAndSize(plane),
804 GetAccessAndSize(planes)...);
808 template <
class T,
class VISITOR,
class PLANE_T>
809 auto VisitPlanesAs(VISITOR &&visitor,
const PLANE_T &plane)
811 static_assert(Cvb::Internal::is_callable<VISITOR(Block<T, LinearAccess>)>::value,
812 "Cvb: The visitor must be visitable with a single typed block.");
814 using PlaneTrait = PlaneTraits<PLANE_T>;
815 return VisitAccessesAs<1, T>(std::forward<VISITOR>(visitor), PlaneTrait::GetDataType(plane),
816 typename PlaneTrait::TypeList{}, GetAccessAndSize(plane));
819 template <class VISITOR, class PLANE_T, std::enable_if_t<!PlaneTraits<PLANE_T>::HasVpat,
int> = 0>
820 auto VisitPlanes(VISITOR &&visitor,
const PLANE_T &plane)
822 using PlaneTrait = PlaneTraits<PLANE_T>;
823 constexpr const size_t VisitorArgCount = 1;
825 const auto dataType = PlaneTrait::GetDataType(plane);
826 return VisitAccesses<VisitorArgCount>(std::forward<VISITOR>(visitor), dataType,
typename PlaneTrait::TypeList{},
827 LinearAccessAndSize{LinearAccess::FromPlane(plane), GetBlockSize(plane)});
830 template <class VISITOR, class PLANE_T, std::enable_if_t<PlaneTraits<PLANE_T>::HasVpat,
int> = 0>
831 auto VisitPlanes(VISITOR &&visitor,
const PLANE_T &plane)
833 using PlaneTrait = PlaneTraits<PLANE_T>;
834 const auto blockSize = GetBlockSize(plane);
835 auto vpat = PlaneTrait::GetVpat(plane);
836 const Cvb::DataType dt = PlaneTrait::GetDataType(plane);
837 if (
const auto access = LinearAccess::FromVpat(vpat, blockSize, dt))
839 if (
const auto arrayAccess = ArrayAccess::FromLinearAccess(access, blockSize))
840 return CallWithAnyOfTypes<ArrayPlaneBlock, typename PlaneTrait::TypeList::DefaultType>(
841 dt,
typename PlaneTrait::TypeList{}, visitor, arrayAccess, blockSize);
843 return CallWithAnyOfTypes<LinearPlaneBlock, typename PlaneTrait::TypeList::DefaultType>(
844 dt,
typename PlaneTrait::TypeList{}, visitor, access, blockSize);
847 return CallWithAnyOfTypes<VpatPlaneBlock, typename PlaneTrait::TypeList::DefaultType>(
848 dt,
typename PlaneTrait::TypeList{}, visitor, vpat, blockSize);
851 template <
class VISITOR,
class PLANE_T,
class... PLANEARGS>
852 auto VisitPlanes(VISITOR &&visitor,
const PLANE_T &plane,
const PLANEARGS &...planes)
854 using PlaneTrait = PlaneTraits<PLANE_T>;
855 constexpr const size_t ArgCount = 1 +
sizeof...(PLANEARGS);
856 constexpr const size_t VisitorArgCount =
857 Cvb::Internal::IsCallableMParameters<VISITOR, ArgCount,
858 Block<typename PlaneTrait::TypeList::DefaultType, LinearAccess>>::value
862 static_assert(VisitorArgCount == ArgCount || VisitorArgCount == 1,
863 "Cvb: visitor must have either one argument or as many arguments as plane arguments are given.");
865 if (!AllPlanesHaveSameDataType(plane, planes...))
866 throw std::domain_error{
"Planes must have all the same data type"};
868#pragma warning(push, 4)
869#pragma warning(disable : 4127)
870 if (VisitorArgCount == 1 && !AllPlanesHaveSameSize(plane, planes...))
871 throw std::domain_error{
"Planes must have same size."};
874 return VisitAccesses<VisitorArgCount>(std::forward<VISITOR>(visitor), PlaneTrait::GetDataType(plane),
875 typename PlaneTrait::TypeList{}, GetAccessAndSize(plane),
876 GetAccessAndSize(planes)...);
881 template <
class VISITOR,
class PLANE_T,
class... PLNS,
882 std::enable_if_t<std::is_same<typename PlaneTraits<PLANE_T>::PlaneT, PLANE_T>::value,
int>>
883 auto Visit(VISITOR &&visitor,
const PLANE_T &plane,
const PLNS &...planes)
888 template <
class T,
class VISITOR,
class PLANE_T,
class... PLANEARGS,
889 std::enable_if_t<std::is_same<typename PlaneTraits<PLANE_T>::PlaneT, PLANE_T>::value,
int>>
890 auto VisitAs(VISITOR &&visitor,
const PLANE_T &plane,
const PLANEARGS &...planes)