7979# define bit_HAVE_BYTESWAP 0
8080#endif
8181
82+ // Provide bit functions in namespace nonstd :
83+
8284namespace nonstd
8385{
8486 using std::bit_cast;
@@ -104,6 +106,85 @@ namespace nonstd
104106 using std::endian;
105107}
106108
109+ //
110+ // Provide bit extensions (at bottom), unless omitted:
111+ //
112+
113+ #if ! bit_CONFIG_STRICT
114+
115+ // Additional includes needed for extensions:
116+
117+ #include < climits> // CHAR_BIT
118+
119+ // Macros needed for extensions:
120+
121+ #define bit_noexcept noexcept
122+
123+ #ifdef _MSC_VER
124+ # include < cstdlib>
125+ # define bit_byteswap16 _byteswap_ushort
126+ # define bit_byteswap32 _byteswap_ulong
127+ # define bit_byteswap64 _byteswap_uint64
128+ #else
129+ # define bit_byteswap16 __builtin_bswap16
130+ # define bit_byteswap32 __builtin_bswap32
131+ # define bit_byteswap64 __builtin_bswap64
132+ #endif
133+
134+ // Detail needed for extensions:
135+
136+ namespace nonstd {
137+ namespace bit {
138+
139+ // C++11 emulation:
140+
141+ namespace std11 {
142+
143+ using std::uint8_t ;
144+ using std::uint16_t ;
145+ using std::uint32_t ;
146+ using std::uint64_t ;
147+
148+ using std::integral_constant;
149+ using std::true_type;
150+ using std::false_type;
151+
152+ using std::is_trivial;
153+ using std::is_trivially_copyable;
154+ using std::is_copy_constructible;
155+ using std::is_move_constructible;
156+ using std::is_unsigned;
157+ using std::is_same;
158+
159+ } // namespace std11
160+
161+ // Detail appearing for extensions both with std::bit and nonstd::bit:
162+
163+ // make sure all unsigned types are covered, see
164+ // http://ithare.com/c-on-using-int_t-as-overload-and-template-parameters/
165+
166+ template < size_t N > struct uint_by_size ;
167+ template <> struct uint_by_size < 8 > { typedef std11::uint8_t type; };
168+ template <> struct uint_by_size <16 > { typedef std11::uint16_t type; };
169+ template <> struct uint_by_size <32 > { typedef std11::uint32_t type; };
170+ #if bit_CPP11_OR_GREATER
171+ template <> struct uint_by_size <64 > { typedef std11::uint64_t type; };
172+ #endif
173+
174+ template < typename T >
175+ struct normalized_uint_type
176+ {
177+ typedef typename uint_by_size< CHAR_BIT * sizeof ( T ) >::type type;
178+
179+ static_assert ( std::is_integral<T>::value, " integral type required." );
180+ static_assert ( std11::is_unsigned<type>::value, " unsigned type result expected." );
181+ static_assert ( sizeof ( type ) == sizeof ( T ), " size of determined type differs from type derived from." );
182+ };
183+
184+ }} // namespace nonstd::bit
185+
186+ #endif // bit_CONFIG_STRICT
187+
107188#else // bit_USES_STD_BIT
108189
109190// half-open range [lo..hi):
@@ -788,7 +869,36 @@ class endian
788869} // namespace nonstd
789870
790871//
791- // Extensions: endian conversions
872+ // Make type available in namespace nonstd:
873+ //
874+
875+ namespace nonstd
876+ {
877+ using bit::bit_cast;
878+
879+ using bit::has_single_bit;
880+ using bit::bit_ceil;
881+ using bit::bit_floor;
882+ using bit::bit_width;
883+
884+ using bit::rotl;
885+ using bit::rotr;
886+
887+ using bit::countl_zero;
888+ using bit::countl_one;
889+ using bit::countr_zero;
890+ using bit::countr_one;
891+ using bit::popcount;
892+
893+ using bit::byteswap;
894+
895+ using bit::endian;
896+ }
897+
898+ #endif // bit_USES_STD_BIT
899+
900+ //
901+ // Extensions (unless omitted): endian conversions
792902//
793903
794904#if !bit_CONFIG_STRICT
@@ -949,32 +1059,9 @@ inline T as_native_endian( T v ) bit_noexcept
9491059#endif // !bit_CONFIG_STRICT
9501060
9511061//
952- // Make type available in namespace nonstd:
1062+ // Make extensions available in namespace nonstd:
9531063//
9541064
955- namespace nonstd
956- {
957- using bit::bit_cast;
958-
959- using bit::has_single_bit;
960- using bit::bit_ceil;
961- using bit::bit_floor;
962- using bit::bit_width;
963-
964- using bit::rotl;
965- using bit::rotr;
966-
967- using bit::countl_zero;
968- using bit::countl_one;
969- using bit::countr_zero;
970- using bit::countr_one;
971- using bit::popcount;
972-
973- using bit::byteswap;
974-
975- using bit::endian;
976- }
977-
9781065#if !bit_CONFIG_STRICT
9791066
9801067namespace nonstd
@@ -994,6 +1081,4 @@ namespace nonstd
9941081
9951082#endif // !bit_CONFIG_STRICT
9961083
997- #endif // bit_USES_STD_BIT
998-
9991084#endif // NONSTD_BIT_LITE_HPP
0 commit comments