types/sized: update bits types to follow a more current style

This commit is contained in:
Danny Robson 2020-10-22 11:27:25 +10:00
parent 3fffacc19c
commit e22f4a9001
11 changed files with 120 additions and 123 deletions

View File

@ -553,7 +553,7 @@ list (
typeidx.cpp typeidx.cpp
typeidx.hpp typeidx.hpp
types.hpp types.hpp
types/bits.hpp types/sized.hpp
types/comparator.hpp types/comparator.hpp
types/description.cpp types/description.cpp
types/description.hpp types/description.hpp

View File

@ -8,7 +8,6 @@
#pragma once #pragma once
#include "types/bits.hpp"
#include "debug/assert.hpp" #include "debug/assert.hpp"
#include <type_traits> #include <type_traits>

View File

@ -17,7 +17,6 @@
#include "../tuple/value.hpp" #include "../tuple/value.hpp"
#include "../debug/assert.hpp" #include "../debug/assert.hpp"
#include "../maths.hpp" #include "../maths.hpp"
#include "../types/bits.hpp"
#include <cruft/util/preprocessor.hpp> #include <cruft/util/preprocessor.hpp>

View File

@ -9,7 +9,7 @@
#pragma once #pragma once
#include "std.hpp" #include "std.hpp"
#include "types/bits.hpp" #include "types/sized.hpp"
#include <compare> #include <compare>
#include <iosfwd> #include <iosfwd>
@ -196,8 +196,8 @@ namespace cruft {
"endian conversion is only defined for integrals currently"); "endian conversion is only defined for integrals currently");
union { union {
typename sized_type<T>::sint sint; typename types::sized::bytes<sizeof(T)>::sint sint;
typename sized_type<T>::uint uint; typename types::sized::bytes<sizeof(T)>::uint uint;
}; };
if (std::is_signed<T>::value) if (std::is_signed<T>::value)

View File

@ -6,10 +6,9 @@
* Copyright 2011-2014 Danny Robson <danny@nerdcruft.net> * Copyright 2011-2014 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_FIXED_HPP #pragma once
#define __UTIL_FIXED_HPP
#include "types/bits.hpp" #include "types/sized.hpp"
#include "maths.hpp" #include "maths.hpp"
#include <iosfwd> #include <iosfwd>
@ -30,8 +29,8 @@ namespace cruft {
static_assert (E > 0); static_assert (E > 0);
static_assert ((I + E) % 8 == 0); static_assert ((I + E) % 8 == 0);
using sint_t = typename bits_type<I+E>::sint; using sint_t = typename types::sized::bits<I+E>::sint;
using uint_t = typename bits_type<I+E>::uint; using uint_t = typename types::sized::bits<I+E>::uint;
using native_type = typename std::conditional< using native_type = typename std::conditional<
std::is_signed<T>::value, std::is_signed<T>::value,
@ -40,8 +39,8 @@ namespace cruft {
using integer_type = typename std::conditional< using integer_type = typename std::conditional<
std::is_signed<T>::value, std::is_signed<T>::value,
typename bits_type<divup (I, 8u) * 8u>::sint, typename types::sized::bits<divup (I, 8u) * 8u>::sint,
typename bits_type<divup (I, 8u) * 8u>::uint typename types::sized::bits<divup (I, 8u) * 8u>::uint
>::type; >::type;
explicit fixed (double); explicit fixed (double);
@ -112,5 +111,3 @@ namespace cruft {
template <typename T, unsigned I, unsigned E> template <typename T, unsigned I, unsigned E>
std::ostream& operator<< (std::ostream&, fixed<T,I,E>); std::ostream& operator<< (std::ostream&, fixed<T,I,E>);
} }
#endif // __UTIL_FIXED_HPP

View File

@ -22,7 +22,7 @@ ieee_float<E, S>::ieee_float (void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <unsigned int E, unsigned int S> template <unsigned int E, unsigned int S>
ieee_float<E, S>::ieee_float (floating_t _floating): ieee_float<E, S>::ieee_float (real_t _floating):
m_floating (_floating) m_floating (_floating)
{ ; } { ; }
@ -72,16 +72,31 @@ ieee_float<E, S>::is_nan (void) const {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
namespace {
template <std::size_t BitsV, typename = void>
struct has_float : public std::false_type { };
template <std::size_t BitsV>
struct has_float<
BitsV,
std::void_t<
typename cruft::types::sized::bits<BitsV>::real
>
> : public std::true_type { };
}
//-----------------------------------------------------------------------------
template <unsigned int E, unsigned int S> template <unsigned int E, unsigned int S>
bool bool
ieee_float<E, S>::operator==(floating_t _floating) const { ieee_float<E, S>::operator==(real_t _floating) const {
// TODO: This method really shouldn't be generated if there's no // TODO: This method really shouldn't be generated if there's no
// representative native floating point type. But I'm sick of // representative native floating point type. But I'm sick of
// C++'s template bullshit for tonight. // C++'s template bullshit for tonight.
CHECK (bits_type<TOTAL_BITS>::has_floating); CHECK (has_float<TOTAL_BITS>::value);
union { union {
floating_t _floating; real_t _floating;
uint_t _uint; uint_t _uint;
} convertor; } convertor;
@ -94,8 +109,8 @@ ieee_float<E, S>::operator==(floating_t _floating) const {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <unsigned int E, unsigned int S> template <unsigned int E, unsigned int S>
bool bool
ieee_float<E, S>::almost_equal (floating_t a, ieee_float<E, S>::almost_equal (real_t a,
floating_t b) real_t b)
{ {
return almost_equal (a, b, 128u); return almost_equal (a, b, 128u);
} }
@ -105,8 +120,8 @@ ieee_float<E, S>::almost_equal (floating_t a,
// Based on the Cygnus `AlmostEqual2sComplement` function // Based on the Cygnus `AlmostEqual2sComplement` function
template <unsigned int E, unsigned int S> template <unsigned int E, unsigned int S>
bool bool
ieee_float<E, S>::almost_equal (floating_t _a, ieee_float<E, S>::almost_equal (real_t _a,
floating_t _b, real_t _b,
unsigned ulps) unsigned ulps)
{ {
// Ensure ULPs is small enough that the default NaNs won't compare as // Ensure ULPs is small enough that the default NaNs won't compare as
@ -114,7 +129,7 @@ ieee_float<E, S>::almost_equal (floating_t _a,
CHECK_LE (ulps, 4 * 1024 * 1024u); CHECK_LE (ulps, 4 * 1024 * 1024u);
union { union {
floating_t f; real_t f;
sint_t s; sint_t s;
uint_t u; uint_t u;
} a, b; } a, b;
@ -132,9 +147,9 @@ ieee_float<E, S>::almost_equal (floating_t _a,
// Re-base negative floats to be continuous against +ve/-ve 0 // Re-base negative floats to be continuous against +ve/-ve 0
static const union { static const union {
floating_t f; real_t f;
sint_t s; sint_t s;
} NEG_ZERO { -floating_t {0} }; } NEG_ZERO { -real_t {0} };
if (a.s < 0) if (a.s < 0)
a.s = NEG_ZERO.s - a.s; a.s = NEG_ZERO.s - a.s;
@ -149,6 +164,6 @@ ieee_float<E, S>::almost_equal (floating_t _a,
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template class cruft::ieee_float< 5, 10>; // ieee_half //template class cruft::ieee_float< 5, 10>; // ieee_half
template class cruft::ieee_float< 8, 23>; // ieee_single; template class cruft::ieee_float< 8, 23>; // ieee_single;
template class cruft::ieee_float<11, 52>; // ieee_double; template class cruft::ieee_float<11, 52>; // ieee_double;

View File

@ -9,7 +9,7 @@
#ifndef __FLOAT_HPP #ifndef __FLOAT_HPP
#define __FLOAT_HPP #define __FLOAT_HPP
#include "types/bits.hpp" #include "types/sized.hpp"
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -24,14 +24,14 @@ namespace cruft {
static const unsigned int BIAS = (1 << (EXPONENT - 1)) - 1; static const unsigned int BIAS = (1 << (EXPONENT - 1)) - 1;
typedef typename bits_type<TOTAL_BITS>::sint sint_t; using sint_t = typename types::sized::bits<TOTAL_BITS>::sint;
typedef typename bits_type<TOTAL_BITS>::uint uint_t; using uint_t = typename types::sized::bits<TOTAL_BITS>::uint;
typedef typename bits_type<TOTAL_BITS>::floating floating_t; using real_t = typename types::sized::bits<TOTAL_BITS>::real;
protected: protected:
union { union {
uint_t m_bits; uint_t m_bits;
floating_t m_floating; real_t m_floating;
struct { struct {
uint_t sign : 1; uint_t sign : 1;
@ -42,7 +42,7 @@ namespace cruft {
public: public:
ieee_float (void); ieee_float (void);
ieee_float (floating_t _floating); ieee_float (real_t _floating);
ieee_float (const ieee_float &rhs); ieee_float (const ieee_float &rhs);
static unsigned int bias (void) static unsigned int bias (void)
@ -58,22 +58,22 @@ namespace cruft {
bool is_subnormal (void) const; bool is_subnormal (void) const;
bool is_inifinity (void) const; bool is_inifinity (void) const;
bool is_nan (void) const; bool is_nan (void) const;
bool operator== (floating_t) const; bool operator== (real_t) const;
static bool almost_equal (floating_t, floating_t); static bool almost_equal (real_t, real_t);
static bool almost_equal (floating_t, floating_t, unsigned ulps); static bool almost_equal (real_t, real_t, unsigned ulps);
}; };
typedef ieee_float< 5, 10> ieee_half; //typedef ieee_float< 5, 10> ieee_half;
typedef ieee_float< 8, 23> ieee_single; typedef ieee_float< 8, 23> ieee_single;
typedef ieee_float<11, 52> ieee_double; typedef ieee_float<11, 52> ieee_double;
extern template class ieee_float< 5,10>; //extern template class ieee_float< 5,10>;
extern template class ieee_float< 8,23>; extern template class ieee_float< 8,23>;
extern template class ieee_float<11,52>; extern template class ieee_float<11,52>;
static_assert (sizeof(ieee_half ) == 2, "ieee_half must be 2 bytes"); //static_assert (sizeof(ieee_half ) == 2, "ieee_half must be 2 bytes");
static_assert (sizeof(ieee_single ) == 4, "ieee_single must be 4 bytes"); static_assert (sizeof(ieee_single ) == 4, "ieee_single must be 4 bytes");
static_assert (sizeof(ieee_double ) == 8, "ieee_double must be 8 bytes"); static_assert (sizeof(ieee_double ) == 8, "ieee_double must be 8 bytes");
} }

View File

@ -26,9 +26,14 @@ namespace cruft::geom::sample {
/// Approximate a poisson disc sampling through the "Mitchell's Best /// Approximate a poisson disc sampling through the "Mitchell's Best
/// Candidate" algorithm. /// Candidate" algorithm.
/// ///
/// Try to keep adding a new point to a set. Each new point is the /// We try to keep adding a new point to an output set.
/// best of a set of candidates. The 'best' is the point that is /// * Generate `candidates_count` new points
/// furthest from all selected points. /// * Remove any point that fails AcceptT
/// * Order the points by minimum distance to the output set
/// * Remove any point with a distance less than DistanceT
/// * Select the point with the highest distance
///
/// Keep iterating until no point is added to the output set.
/// ///
/// \tparam SamplerT A surface sampler /// \tparam SamplerT A surface sampler
/// \tparam DistanceT The type of point-to-point distances /// \tparam DistanceT The type of point-to-point distances

View File

@ -6,10 +6,9 @@
* Copyright 2010-2016 Danny Robson <danny@nerdcruft.net> * Copyright 2010-2016 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_HASH_FLETCHER_HPP #pragma once
#define __UTIL_HASH_FLETCHER_HPP
#include "../types/bits.hpp" #include "../types/sized.hpp"
#include "../view.hpp" #include "../view.hpp"
#include <cstdint> #include <cstdint>
@ -22,7 +21,7 @@ namespace cruft::hash {
class fletcher { class fletcher {
public: public:
using digest_t = DigestT; using digest_t = DigestT;
using part_t = typename bytes_type<sizeof (digest_t) / 2>::uint; using part_t = typename types::sized::bytes<sizeof (digest_t) / 2>::uint;
fletcher (part_t modulus, part_t a, part_t b); fletcher (part_t modulus, part_t a, part_t b);
@ -38,7 +37,3 @@ namespace cruft::hash {
const state_t m_initial; const state_t m_initial;
}; };
} }
#endif

View File

@ -1,72 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __UTIL_TYPES_BITS_HPP
#define __UTIL_TYPES_BITS_HPP
#include <cstdint>
#include <cstddef>
namespace cruft {
template <size_t BITS>
struct bits_type;
template <> struct bits_type< 8u> {
static const bool has_floating = false;
typedef uint8_t uint;
typedef int8_t sint;
typedef uint8_t floating;
};
template <> struct bits_type<16u> {
static const bool has_floating = false;
typedef uint16_t uint;
typedef int16_t sint;
typedef uint16_t floating;
};
template <> struct bits_type<32u> {
static const bool has_floating = true;
typedef uint32_t uint;
typedef int32_t sint;
typedef float floating;
};
template <> struct bits_type<64u> {
static const bool has_floating = true;
typedef uint64_t uint;
typedef int64_t sint;
typedef double floating;
};
template <size_t BYTES>
struct bytes_type : public bits_type<BYTES * 8u>
{ };
template <typename T>
struct sized_type : public bits_type<sizeof(T) * 8u>
{ };
template <std::size_t Size>
using bits_uint_t = typename bits_type<Size>::uint;
template <std::size_t Size>
using bytes_uint_t = typename bytes_type<Size>::uint;
}
#endif

59
types/sized.hpp Normal file
View File

@ -0,0 +1,59 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2011-2020 Danny Robson <danny@nerdcruft.net>
*/
#pragma once
#include "../std.hpp"
#include <cstddef>
namespace cruft::types::sized {
template <size_t BITS>
struct bits;
template <>
struct bits< 8u> {
using uint = u08;
using sint = i08;
};
template <>
struct bits<16u> {
using uint = u16;
using sint = i16;
};
template <>
struct bits<32u> {
using uint = u32;
using sint = i32;
using real = f32;
};
template <>
struct bits<64u> {
using uint = u64;
using sint = i64;
using real = f64;
};
template <std::size_t BytesV>
struct bytes : public bits<BytesV * 8u>
{ };
template <typename BaseT>
struct sized_type : public bits<sizeof(BaseT) * 8u>
{ };
}