Skip to content

Commit

Permalink
add arithmetic like operators to bel_c class
Browse files Browse the repository at this point in the history
  • Loading branch information
yumetodo committed Mar 22, 2016
1 parent 1c077a1 commit 3c18048
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 15 deletions.
208 changes: 194 additions & 14 deletions dxlibex/basic_types/bel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0.
#include "dxlibex/type_traits/is_ratio.hpp"
#include "dxlibex/type_traits/enable_if.hpp"
#include <type_traits>
#include <limits>
namespace dxle {
typedef std::ratio<1, 10000> myrio;
namespace sound_units {
Expand All @@ -22,6 +23,14 @@ namespace dxle {
class bel_c;
template<typename To, typename T, typename Period, enable_if_t<is_bel_c<To>::value, nullptr_t> = nullptr>
inline DXLE_CONSTEXPR To bel_cast(const bel_c<T, Period>& o);

/// bel_c_values
template<typename _Rep> struct bel_c_values{
static DXLE_CONSTEXPR _Rep zero(){ return _Rep(0); }
static DXLE_CONSTEXPR _Rep max(){ return std::numeric_limits<_Rep>::max();}
static DXLE_CONSTEXPR _Rep min(){ return std::numeric_limits<_Rep>::lowest(); }
};

template<typename T, typename Period, enable_if_t<is_ratio<Period>::value, nullptr_t>>
class bel_c {
public:
Expand Down Expand Up @@ -53,6 +62,67 @@ namespace dxle {
DXLE_CONSTEXPR value_type count() const { return value_; }
DXLE_CONSTEXPR value_type get() const { return value_; }
DXLE_CONSTEXPR value_type operator*() const { return value_; }
DXLE_CONSTEXPR bel_c operator+() const { return *this; }
DXLE_CONSTEXPR bel_c operator-() const { return bel_c(-value_); }
bel_c& operator++()
{
++value_;
return *this;
}

bel_c operator++(int) { return bel_c(value_++); }

bel_c& operator--()
{
--value_;
return *this;
}

bel_c operator--(int) { return bel_c(value_--); }

bel_c& operator+=(const bel_c& o)
{
value_ += o.count();
return *this;
}

bel_c& operator-=(const bel_c& o)
{
value_ -= o.count();
return *this;
}

bel_c& operator*=(const T& r)
{
value_ *= r;
return *this;
}

bel_c& operator/=(const T& r)
{
value_ /= r;
return *this;
}

// DR 934.
template<typename T2 = T, std::enable_if_t<!std::is_floating_point<T2>::value, std::nullptr_t> = nullptr>
bel_c& operator%=(const T& r)
{
value_ %= r;
return *this;
}

template<typename T2 = T, std::enable_if_t<!std::is_floating_point<T2>::value, std::nullptr_t> = nullptr>
bel_c& operator%=(const bel_c& o)
{
value_ %= o.count();
return *this;
}

//special values
static DXLE_CONSTEXPR bel_c zero() { return bel_c(bel_c_values<T>::zero()); }
static DXLE_CONSTEXPR bel_c min() { return bel_c(bel_c_values<T>::min()); }
static DXLE_CONSTEXPR bel_c max() { return bel_c(bel_c_values<T>::max()); }
};
template<typename T_> struct is_bel_c : std::false_type {};
template<typename T, typename Period> struct is_bel_c<bel_c<T, Period>> : std::true_type{};
Expand Down Expand Up @@ -85,27 +155,137 @@ namespace dxle {
}
template<typename To, typename T, typename Period, enable_if_t<is_bel_c<To>::value, nullptr_t>>
inline DXLE_CONSTEXPR To bel_cast(const bel_c<T, Period>& o)
{ // convert duration to another duration
{ // convert bel_c to another bel_c
typedef std::ratio_divide<Period, typename To::period> CF;

typedef typename To::value_type ToT;
typedef std::common_type_t<ToT, T, intmax_t> CR;
return detail::bel_cast_helper<To, T, Period, CF, ToT, CR, CF::num == 1, CF::den == 1>::cast(o);
//return (CF::num == 1 && CF::den == 1
//? To(static_cast<ToT>(_Dur.count()))
//: CF::num != 1 && CF::den == 1
//? To(static_cast<ToT>(
// static_cast<CR>(
// _Dur.count()) * static_cast<CR>(CF::num)))
//: CF::num == 1 && CF::den != 1
//? To(static_cast<ToT>(
// static_cast<CR>(_Dur.count())
// / static_cast<CR>(CF::den)))
//: To(static_cast<ToT>(
// static_cast<CR>(_Dur.count()) * static_cast<CR>(CF::num)
// / static_cast<CR>(CF::den))));
}

template<typename T1, typename Period1, typename T2, typename Period2>
constexpr common_type_t<bel_c<T1, Period1>, bel_c<T2, Period2 >>
operator+(const bel_c<T1, Period1>& l, const bel_c<T2, Period2>& r)
{
typedef bel_c<T1, Period1> bel_c1;
typedef bel_c<T2, Period2> bel_c2;
typedef common_type_t<bel_c1, bel_c2> result_t;
return result_t(result_t(l).count() + result_t(r).count());
}

template<typename T1, typename Period1, typename T2, typename Period2>
constexpr common_type_t<bel_c<T1, Period1>, bel_c<T2, Period2>>
operator-(const bel_c<T1, Period1>& l, const bel_c<T2, Period2>& r)
{
typedef bel_c<T1, Period1> bel_c1;
typedef bel_c<T2, Period2> bel_c2;
typedef common_type_t<bel_c1, bel_c2> result_t;
return result_t(result_t(l).count() - result_t(r).count());
}

namespace detail {
template<typename T2, typename Result>
struct common_rep_type_impl : enable_if<std::is_convertible<T2, Result>::value, Result> {};
template<typename T1, typename T2>
struct common_rep_type : common_rep_type_impl<T2, common_type_t<T1, T2>> {};
template<typename T1, typename T2>
using common_rep_type_t = typename common_rep_type<T1, T2>::type;
}

template<typename T1, typename _Period, typename T2>
constexpr bel_c<detail::common_rep_type_t<T1, T2>, _Period>
operator*(const bel_c<T1, _Period>& b, const T2& r)
{
typedef bel_c<common_type_t<T1, T2>, _Period> result_t;
return result_t(result_t(b).count() * r);
}

template<typename T1, typename T2, typename _Period>
constexpr bel_c<detail::common_rep_type_t<T2, T1>, _Period>
operator*(const T1& r, const bel_c<T2, _Period>& b)
{
return b * r;
}

template<typename T1, typename _Period, typename T2>
constexpr bel_c<detail::common_rep_type_t<T1, enable_if_t<!is_bel_c<T2>::value, T2>>, _Period>
operator/(const bel_c<T1, _Period>& b, const T2& r)
{
typedef bel_c<common_type_t<T1, T2>, _Period> result_t;
return result_t(result_t(b).count() / r);
}

template<typename T1, typename Period1, typename T2, typename Period2>
constexpr common_type_t<T1, T2>
operator/(const bel_c<T1, Period1>& l, const bel_c<T2, Period2>& r)
{
typedef bel_c<T1, Period1> bel_c1;
typedef bel_c<T2, Period2> bel_c2;
typedef common_type_t<bel_c1, bel_c2> result_t;
return result_t(l).count() / result_t(r).count();
}

// DR 934.
template<typename T1, typename _Period, typename T2>
constexpr bel_c<detail::common_rep_type_t<T1, enable_if_t<!is_bel_c<T2>::value, T2>>, _Period>
operator%(const bel_c<T1, _Period>& b, const T2& r)
{
typedef bel_c<common_type_t<T1, T2>, _Period> result_t;
return result_t(result_t(b).count() % r);
}

template<typename T1, typename Period1, typename T2, typename Period2>
constexpr common_type_t<bel_c<T1, Period1>, bel_c<T2, Period2>>
operator%(const bel_c<T1, Period1>& l, const bel_c<T2, Period2>& r)
{
typedef bel_c<T1, Period1> bel_c1;
typedef bel_c<T2, Period2> bel_c2;
typedef common_type_t<bel_c1, bel_c2> result_t;
return result_t(result_t(l).count() % result_t(r).count());
}

// comparisons
template<typename T1, typename Period1, typename T2, typename Period2>
constexpr bool operator==(const bel_c<T1, Period1>& l, const bel_c<T2, Period2>& r)
{
typedef bel_c<T1, Period1> bel_c1;
typedef bel_c<T2, Period2> bel_c2;
typedef common_type_t<bel_c1, bel_c2> __ct;
return __ct(l).count() == __ct(r).count();
}

template<typename T1, typename Period1, typename T2, typename Period2>
constexpr bool operator<(const bel_c<T1, Period1>& l, const bel_c<T2, Period2>& r)
{
typedef bel_c<T1, Period1> bel_c1;
typedef bel_c<T2, Period2> bel_c2;
typedef common_type_t<bel_c1, bel_c2> __ct;
return __ct(l).count() < __ct(r).count();
}

template<typename T1, typename Period1, typename T2, typename Period2>
constexpr bool operator!=(const bel_c<T1, Period1>& l, const bel_c<T2, Period2>& r)
{
return !(l == r);
}

template<typename T1, typename Period1, typename T2, typename Period2>
constexpr bool operator<=(const bel_c<T1, Period1>& l, const bel_c<T2, Period2>& r)
{
return !(r < l);
}

template<typename T1, typename Period1, typename T2, typename Period2>
constexpr bool operator>(const bel_c<T1, Period1>& l, const bel_c<T2, Period2>& r)
{
return r < l;
}

template<typename T1, typename Period1, typename T2, typename Period2>
constexpr bool operator>=(const bel_c<T1, Period1>& l, const bel_c<T2, Period2>& r)
{
return !(l < r);
}

typedef bel_c<int, myrio> myrio_bel;
typedef bel_c<int, std::deci> deci_bel;
Expand Down
4 changes: 3 additions & 1 deletion samples/sound_play/sound_play/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//#include <dxlibex/Sound.h>
#include <dxlibex/Sound.h>
#include <dxlibex/basic_types/bel.hpp>
#include <Windows.h>
int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpCmdLine*/, int /*nCmdShow*/) {
Expand All @@ -8,6 +8,8 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /
constexpr auto rate = 300_dB;
constexpr auto rate2 = 4000_myrioB;
constexpr auto rate3 = dxle::bel_cast<dxle::bel>(rate);
constexpr auto rate2_2 = rate2;
#endif
constexpr dxle::deci_bel rate4(100);
constexpr dxle::myrio_bel rate5{ 20 };
}

1 comment on commit 3c18048

@yumetodo
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#51

Please sign in to comment.