@@ -151,6 +151,12 @@ namespace xsimd
151151 template <class Mode = aligned_mode>
152152 XSIMD_INLINE void store (T* mem, batch_bool<T, A> mask, Mode = {}) const noexcept ;
153153
154+ // Head/tail: contiguous prefix/suffix variants of the runtime-mask store.
155+ XSIMD_INLINE void store_head (T* mem, std::size_t n, aligned_mode) const noexcept ;
156+ XSIMD_INLINE void store_head (T* mem, std::size_t n, unaligned_mode) const noexcept ;
157+ XSIMD_INLINE void store_tail (T* mem, std::size_t n, aligned_mode) const noexcept ;
158+ XSIMD_INLINE void store_tail (T* mem, std::size_t n, unaligned_mode) const noexcept ;
159+
154160 template <class U >
155161 XSIMD_NO_DISCARD static XSIMD_INLINE batch load_aligned (U const * mem) noexcept ;
156162 template <class U >
@@ -168,6 +174,12 @@ namespace xsimd
168174 template <class U >
169175 XSIMD_NO_DISCARD static XSIMD_INLINE batch load (U const * mem, stream_mode) noexcept ;
170176
177+ // Head/tail: contiguous prefix/suffix variants of the runtime-mask load.
178+ XSIMD_NO_DISCARD static XSIMD_INLINE batch load_head (T const * mem, std::size_t n, aligned_mode) noexcept ;
179+ XSIMD_NO_DISCARD static XSIMD_INLINE batch load_head (T const * mem, std::size_t n, unaligned_mode) noexcept ;
180+ XSIMD_NO_DISCARD static XSIMD_INLINE batch load_tail (T const * mem, std::size_t n, aligned_mode) noexcept ;
181+ XSIMD_NO_DISCARD static XSIMD_INLINE batch load_tail (T const * mem, std::size_t n, unaligned_mode) noexcept ;
182+
171183 template <class U , class V >
172184 XSIMD_NO_DISCARD static XSIMD_INLINE batch gather (U const * src, batch<V, arch_type> const & index) noexcept ;
173185 template <class U , class V >
@@ -794,6 +806,106 @@ namespace xsimd
794806 kernel::store_masked<A>(mem, *this , mask, mode, A {});
795807 }
796808
809+ template <class T , class A >
810+ XSIMD_INLINE batch<T, A> batch<T, A>::load_head(T const * mem, std::size_t n, aligned_mode) noexcept
811+ {
812+ detail::static_check_supported_config<T, A>();
813+ if (n == 0 )
814+ return broadcast<T>(0 );
815+ if (n >= size)
816+ return load_aligned (mem);
817+ return kernel::load_head<A>(mem, n, aligned_mode {}, A {});
818+ }
819+
820+ template <class T , class A >
821+ XSIMD_INLINE batch<T, A> batch<T, A>::load_head(T const * mem, std::size_t n, unaligned_mode) noexcept
822+ {
823+ detail::static_check_supported_config<T, A>();
824+ if (n == 0 )
825+ return broadcast<T>(0 );
826+ if (n >= size)
827+ return load_unaligned (mem);
828+ return kernel::load_head<A>(mem, n, unaligned_mode {}, A {});
829+ }
830+
831+ template <class T , class A >
832+ XSIMD_INLINE batch<T, A> batch<T, A>::load_tail(T const * mem, std::size_t n, aligned_mode) noexcept
833+ {
834+ detail::static_check_supported_config<T, A>();
835+ if (n == 0 )
836+ return broadcast<T>(0 );
837+ if (n >= size)
838+ return load_aligned (mem);
839+ return kernel::load_tail<A>(mem, n, aligned_mode {}, A {});
840+ }
841+
842+ template <class T , class A >
843+ XSIMD_INLINE batch<T, A> batch<T, A>::load_tail(T const * mem, std::size_t n, unaligned_mode) noexcept
844+ {
845+ detail::static_check_supported_config<T, A>();
846+ if (n == 0 )
847+ return broadcast<T>(0 );
848+ if (n >= size)
849+ return load_unaligned (mem);
850+ return kernel::load_tail<A>(mem, n, unaligned_mode {}, A {});
851+ }
852+
853+ template <class T , class A >
854+ XSIMD_INLINE void batch<T, A>::store_head(T* mem, std::size_t n, aligned_mode) const noexcept
855+ {
856+ detail::static_check_supported_config<T, A>();
857+ if (n == 0 )
858+ return ;
859+ if (n >= size)
860+ {
861+ store_aligned (mem);
862+ return ;
863+ }
864+ kernel::store_head<A>(mem, n, *this , aligned_mode {}, A {});
865+ }
866+
867+ template <class T , class A >
868+ XSIMD_INLINE void batch<T, A>::store_head(T* mem, std::size_t n, unaligned_mode) const noexcept
869+ {
870+ detail::static_check_supported_config<T, A>();
871+ if (n == 0 )
872+ return ;
873+ if (n >= size)
874+ {
875+ store_unaligned (mem);
876+ return ;
877+ }
878+ kernel::store_head<A>(mem, n, *this , unaligned_mode {}, A {});
879+ }
880+
881+ template <class T , class A >
882+ XSIMD_INLINE void batch<T, A>::store_tail(T* mem, std::size_t n, aligned_mode) const noexcept
883+ {
884+ detail::static_check_supported_config<T, A>();
885+ if (n == 0 )
886+ return ;
887+ if (n >= size)
888+ {
889+ store_aligned (mem);
890+ return ;
891+ }
892+ kernel::store_tail<A>(mem, n, *this , aligned_mode {}, A {});
893+ }
894+
895+ template <class T , class A >
896+ XSIMD_INLINE void batch<T, A>::store_tail(T* mem, std::size_t n, unaligned_mode) const noexcept
897+ {
898+ detail::static_check_supported_config<T, A>();
899+ if (n == 0 )
900+ return ;
901+ if (n >= size)
902+ {
903+ store_unaligned (mem);
904+ return ;
905+ }
906+ kernel::store_tail<A>(mem, n, *this , unaligned_mode {}, A {});
907+ }
908+
797909 template <class T , class A >
798910 template <class U >
799911 XSIMD_INLINE batch<T, A> batch<T, A>::load(U const * mem, stream_mode) noexcept
0 commit comments