@@ -645,7 +645,7 @@ template <class BidirectionalIterator, class Compare>
645
645
#include " support/ibm/support.h"
646
646
#endif
647
647
#if defined(_LIBCPP_COMPILER_MSVC)
648
- #include " support/win32/msvc_builtin_support.h "
648
+ #include < intrin.h >
649
649
#endif
650
650
651
651
#include < __undef_min_max>
@@ -783,51 +783,132 @@ struct __debug_less
783
783
784
784
// Precondition: __x != 0
785
785
inline _LIBCPP_INLINE_VISIBILITY
786
- unsigned
787
- __ctz (unsigned __x)
788
- {
786
+ unsigned __ctz (unsigned __x) {
787
+ #ifndef _LIBCPP_COMPILER_MSVC
789
788
return static_cast <unsigned >(__builtin_ctz (__x));
789
+ #else
790
+ static_assert (sizeof (unsigned ) == sizeof (unsigned long ), " " );
791
+ static_assert (sizeof (unsigned long ) == 4 , " " );
792
+ unsigned long where;
793
+ // Search from LSB to MSB for first set bit.
794
+ // Returns zero if no set bit is found.
795
+ if (_BitScanForward (&where, mask))
796
+ return where;
797
+ return 32 ;
798
+ #endif
790
799
}
791
800
792
801
inline _LIBCPP_INLINE_VISIBILITY
793
- unsigned long
794
- __ctz (unsigned long __x)
795
- {
802
+ unsigned long __ctz (unsigned long __x) {
803
+ #ifndef _LIBCPP_COMPILER_MSVC
796
804
return static_cast <unsigned long >(__builtin_ctzl (__x));
805
+ #else
806
+ static_assert (sizeof (unsigned long ) == sizeof (unsigned ), " " );
807
+ return __ctz (static_cast <unsigned >(__x));
808
+ #endif
797
809
}
798
810
799
811
inline _LIBCPP_INLINE_VISIBILITY
800
- unsigned long long
801
- __ctz (unsigned long long __x)
802
- {
812
+ unsigned long long __ctz (unsigned long long __x) {
813
+ #ifndef _LIBCPP_COMPILER_MSVC
803
814
return static_cast <unsigned long long >(__builtin_ctzll (__x));
815
+ #else
816
+ unsigned long where;
817
+ // Search from LSB to MSB for first set bit.
818
+ // Returns zero if no set bit is found.
819
+ #if defined(_LIBCPP_HAS_BITSCAN64)
820
+ (defined (_M_AMD64) || defined (__x86_64__))
821
+ if (_BitScanForward64 (&where, mask))
822
+ return static_cast <int >(where);
823
+ #else
824
+ // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
825
+ // Scan the Low Word.
826
+ if (_BitScanForward (&where, static_cast <unsigned long >(mask)))
827
+ return where;
828
+ // Scan the High Word.
829
+ if (_BitScanForward (&where, static_cast <unsigned long >(mask >> 32 )))
830
+ return where + 32 ; // Create a bit offset from the LSB.
831
+ #endif
832
+ return 64 ;
833
+ #endif // _LIBCPP_COMPILER_MSVC
804
834
}
805
835
806
836
// Precondition: __x != 0
807
837
inline _LIBCPP_INLINE_VISIBILITY
808
- unsigned
809
- __clz (unsigned __x)
810
- {
838
+ unsigned __clz (unsigned __x) {
839
+ #ifndef _LIBCPP_COMPILER_MSVC
811
840
return static_cast <unsigned >(__builtin_clz (__x));
841
+ #else
842
+ static_assert (sizeof (unsigned ) == sizeof (unsigned long ), " " );
843
+ static_assert (sizeof (unsigned long ) == 4 , " " );
844
+ unsigned long where;
845
+ // Search from LSB to MSB for first set bit.
846
+ // Returns zero if no set bit is found.
847
+ if (_BitScanReverse (&where, mask))
848
+ return 31 - where;
849
+ return 32 ; // Undefined Behavior.
850
+ #endif
812
851
}
813
852
814
853
inline _LIBCPP_INLINE_VISIBILITY
815
- unsigned long
816
- __clz (unsigned long __x)
817
- {
854
+ unsigned long __clz (unsigned long __x) {
855
+ #ifndef _LIBCPP_COMPILER_MSVC
818
856
return static_cast <unsigned long >(__builtin_clzl (__x));
857
+ #else
858
+ static_assert (sizeof (unsigned ) == sizeof (unsigned long ), " " );
859
+ return __clz (static_cast <unsigned >(__x));
860
+ #endif
819
861
}
820
862
821
863
inline _LIBCPP_INLINE_VISIBILITY
822
- unsigned long long
823
- __clz (unsigned long long __x)
824
- {
864
+ unsigned long long __clz (unsigned long long __x) {
865
+ #ifndef _LIBCPP_COMPILER_MSVC
825
866
return static_cast <unsigned long long >(__builtin_clzll (__x));
867
+ #else
868
+ unsigned long where;
869
+ // BitScanReverse scans from MSB to LSB for first set bit.
870
+ // Returns 0 if no set bit is found.
871
+ #if defined(_LIBCPP_HAS_BITSCAN64)
872
+ if (_BitScanReverse64 (&where, mask))
873
+ return static_cast <int >(63 - where);
874
+ #else
875
+ // Scan the high 32 bits.
876
+ if (_BitScanReverse (&where, static_cast <unsigned long >(mask >> 32 )))
877
+ return 63 - (where + 32 ); // Create a bit offset from the MSB.
878
+ // Scan the low 32 bits.
879
+ if (_BitScanReverse (&where, static_cast <unsigned long >(mask)))
880
+ return 63 - where;
881
+ #endif
882
+ return 64 ; // Undefined Behavior.
883
+ #endif // _LIBCPP_COMPILER_MSVC
884
+ }
885
+
886
+ inline _LIBCPP_INLINE_VISIBILITY int __pop_count (unsigned __x) {
887
+ #ifndef _LIBCPP_COMPILER_MSVC
888
+ return __builtin_popcount (__x);
889
+ #else
890
+ static_assert (sizeof (unsigned ) == 4 , " " );
891
+ return __popcnt (__x);
892
+ #endif
893
+ }
894
+
895
+ inline _LIBCPP_INLINE_VISIBILITY int __pop_count (unsigned long __x) {
896
+ #ifndef _LIBCPP_COMPILER_MSVC
897
+ return __builtin_popcountl (__x);
898
+ #else
899
+ static_assert (sizeof (unsigned long ) == 4 , " " );
900
+ return __popcnt (__x);
901
+ #endif
826
902
}
827
903
828
- inline _LIBCPP_INLINE_VISIBILITY int __pop_count (unsigned __x) {return __builtin_popcount (__x);}
829
- inline _LIBCPP_INLINE_VISIBILITY int __pop_count (unsigned long __x) {return __builtin_popcountl (__x);}
830
- inline _LIBCPP_INLINE_VISIBILITY int __pop_count (unsigned long long __x) {return __builtin_popcountll (__x);}
904
+ inline _LIBCPP_INLINE_VISIBILITY int __pop_count (unsigned long long __x) {
905
+ #ifndef _LIBCPP_COMPILER_MSVC
906
+ return __builtin_popcountll (__x);
907
+ #else
908
+ static_assert (sizeof (unsigned long long ) == 8 , " " );
909
+ return __popcnt64 (__x);
910
+ #endif
911
+ }
831
912
832
913
// all_of
833
914
0 commit comments