summaryrefslogblamecommitdiffstatshomepage
path: root/src/lib/netlist/plib/ptypes.h
blob: d34651b9f7005f95c50c9fc2ee4b12f3b708ac7b (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                               



                 



                  

                    
                 


                      
                                                       

                                           
                                               
                                                      
                                                        



                                                      
 

              


                                                                                       
                                                                 




                                                                                       
                                                       





                                                
                                                      




                                                    
 
                                                                      




                                                                      


                                                                               
                                                                          


                                              



                           

                                                                       


                                          

                                                                   


                                                                      
                                         
                                                                      
                                
                                                   
 




                                                                      
         



                                                                                        






                                                                                                
                         






                                                                                                  
                         





                                                       
                              










                                                                                       
                              







                                                                                          
 


                                                              
 







                                                                                                 
 
                   
// license:GPL-2.0+
// copyright-holders:Couriersud

#ifndef PTYPES_H_
#define PTYPES_H_

///
/// \file ptypes.h
///

#include "pconfig.h"

#include <limits>
#include <string>
#include <type_traits>

// noexcept on move operator -> issue with macosx clang
#define COPYASSIGNMOVE(name, def)  \
		name(const name &) = def; \
		name(name &&) noexcept = def; \
		name &operator=(const name &) = def; \
		name &operator=(name &&) noexcept = def;

#define COPYASSIGN(name, def)  \
		name(const name &) = def; \
		name &operator=(const name &) = def; \

namespace plib
{
	template<typename T> struct is_integral : public std::is_integral<T> { };
	template<typename T> struct numeric_limits : public std::numeric_limits<T> { };

	// 128 bit support at least on GCC is not fully supported
#if PHAS_INT128
	template<> struct is_integral<UINT128> { static constexpr bool value = true; };
	template<> struct is_integral<INT128> { static constexpr bool value = true; };
	template<> struct numeric_limits<UINT128>
	{
		static constexpr UINT128 max() noexcept
		{
			return ~((UINT128)0);
		}
	};
	template<> struct numeric_limits<INT128>
	{
		static constexpr INT128 max() noexcept
		{
			return (~((UINT128)0)) >> 1;
		}
	};
#endif

	//============================================================
	// prevent implicit copying
	//============================================================

	struct nocopyassignmove
	{
		nocopyassignmove(const nocopyassignmove &) = delete;
		nocopyassignmove(nocopyassignmove &&) = delete;
		nocopyassignmove &operator=(const nocopyassignmove &) = delete;
		nocopyassignmove &operator=(nocopyassignmove &&) = delete;
	protected:
		nocopyassignmove() = default;
		~nocopyassignmove() = default;
	};

	struct nocopyassign
	{
		nocopyassign(const nocopyassign &) = delete;
		nocopyassign &operator=(const nocopyassign &) = delete;
	protected:
		nocopyassign() = default;
		~nocopyassign() = default;
		nocopyassign(nocopyassign &&) = default;
		nocopyassign &operator=(nocopyassign &&) = default;
	};

	//============================================================
	// Avoid unused variable warnings
	//============================================================
	template<typename... Ts>
	inline void unused_var(Ts&&...) noexcept {}

	//============================================================
	// is_pow2
	//============================================================
	template <typename T>
	constexpr bool is_pow2(T v) noexcept
	{
		static_assert(is_integral<T>::value, "is_pow2 needs integer arguments");
		return !(v & (v-1));
	}

	//============================================================
	// abs, lcd, gcm
	//============================================================

	template<typename T>
	constexpr
	typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value, T>::type
	abs(T v) noexcept
	{
		return v < 0 ? -v : v;
	}

	template<typename T>
	constexpr
	typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, T>::type
	abs(T v) noexcept
	{
		return v;
	}

	template<typename M, typename N>
	constexpr typename std::common_type<M, N>::type
	gcd(M m, N n) noexcept
	{
		static_assert(std::is_integral<M>::value, "gcd: M must be an integer");
		static_assert(std::is_integral<N>::value, "gcd: N must be an integer");

		return m == 0 ? plib::abs(n)
			 : n == 0 ? plib::abs(m)
			 : gcd(n, m % n);
	}

	template<typename M, typename N>
	constexpr typename std::common_type<M, N>::type
	lcm(M m, N n) noexcept
	{
		static_assert(std::is_integral<M>::value, "lcm: M must be an integer");
		static_assert(std::is_integral<N>::value, "lcm: N must be an integer");

		return (m != 0 && n != 0) ? (plib::abs(m) / gcd(m, n)) * plib::abs(n) : 0;
	}

} // namespace plib

//============================================================
// Define a "has member" trait.
//============================================================

#define PDEFINE_HAS_MEMBER(name, member)                                        \
	template <typename T> class name                                            \
	{                                                                           \
		template <typename U> static long test(decltype(&U:: member));          \
		template <typename U> static char  test(...);                           \
	public:                                                                     \
		static constexpr const bool value = sizeof(test<T>(nullptr)) == sizeof(long);   \
	}

#endif // PTYPES_H_