Last active
March 9, 2023 15:52
-
-
Save shawndooley/23ca121afb4fb1caf50c7383b45e3271 to your computer and use it in GitHub Desktop.
Template that will generate compile time errors if duplicate id's are reused
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Code modified from Boost.Units base_dimension.hpp | |
// https://www.boost.org/doc/libs/1_81_0/boost/units/base_dimension.hpp | |
// | |
// Copyright (C) 2003-2008 Matthias Christian Schabel | |
// Copyright (C) 2007-2008 Steven Watanabe | |
// | |
// Distributed under the Boost Software License, Version 1.0. (See | |
// accompanying file LICENSE_1_0.txt or copy at | |
// http://www.boost.org/LICENSE_1_0.txt) | |
#ifndef UNIQUE_INDEX_HPP | |
#define UNIQUE_INDEX_HPP | |
#include <boost/mpl/bool.hpp> | |
#include <boost/mpl/less.hpp> | |
#include <boost/mpl/long.hpp> | |
namespace unique { | |
namespace detail { | |
struct ordinal_tag {}; | |
struct no { | |
constexpr no() : dummy() {} | |
char dummy; | |
}; | |
struct yes { | |
no dummy[2]; | |
}; | |
template <bool> | |
struct ordinal_has_already_been_defined; | |
template <> | |
struct ordinal_has_already_been_defined<true> {}; | |
template <> | |
struct ordinal_has_already_been_defined<false> { | |
typedef void type; | |
}; | |
} // namespace detail | |
template <int N> | |
struct ordinal { | |
typedef detail::ordinal_tag tag; | |
static constexpr long value = N; | |
}; | |
template <int N> | |
constexpr long ordinal<N>::value; | |
/// This must be in namespace boost::units so that ADL | |
/// will work with friend functions defined inline. | |
/// INTERNAL ONLY | |
template <long N> | |
struct unique_ordinal {}; | |
/// INTERNAL ONLY | |
template <class T, long N> | |
struct check_unique_index { | |
enum { value = sizeof((unique_ordinal<N>())) == sizeof(detail::yes) }; | |
}; | |
template <class Derived, long N, | |
class = typename detail::ordinal_has_already_been_defined< | |
check_unique_index<Derived, N>::value>::type> | |
class unique_index : public ordinal<N> { | |
public: | |
/// INTERNAL ONLY | |
typedef unique_index this_type; | |
/// Provided for mpl compatability. | |
typedef Derived type; | |
private: | |
/// Check for C++0x. In C++0x, we have to have identical | |
/// arguments but a different return type to trigger an | |
/// error. Note that this is only needed for clang as | |
/// check_unique_index will trigger an error earlier | |
/// for compilers with less strict name lookup. | |
/// INTERNAL ONLY | |
friend constexpr Derived* check_double_register(const unique_ordinal<N>&) { | |
return (0); | |
} | |
}; | |
} // namespace unique | |
namespace boost { | |
namespace mpl { | |
template <> | |
struct less_impl<unique::detail::ordinal_tag, unique::detail::ordinal_tag> { | |
template <class T1, class T2> | |
struct apply : bool_<(T1::value) < (T2::value)> {}; | |
}; | |
} // namespace mpl | |
} // namespace boost | |
#endif // UNIQUE_INDEX_HPP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment