set.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #ifndef BOOST_MP11_SET_HPP_INCLUDED
  2. #define BOOST_MP11_SET_HPP_INCLUDED
  3. // Copyright 2015 Peter Dimov.
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. //
  7. // See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt
  9. #include <boost/mp11/utility.hpp>
  10. #include <boost/mp11/detail/mp_list.hpp>
  11. #include <type_traits>
  12. namespace boost
  13. {
  14. namespace mp11
  15. {
  16. // mp_set_contains<S, V>
  17. namespace detail
  18. {
  19. template<class S, class V> struct mp_set_contains_impl;
  20. template<template<class...> class L, class... T, class V> struct mp_set_contains_impl<L<T...>, V>
  21. {
  22. using type = mp_to_bool<std::is_base_of<mp_identity<V>, mp_inherit<mp_identity<T>...> > >;
  23. };
  24. } // namespace detail
  25. template<class S, class V> using mp_set_contains = typename detail::mp_set_contains_impl<S, V>::type;
  26. // mp_set_push_back<S, T...>
  27. namespace detail
  28. {
  29. template<class S, class... T> struct mp_set_push_back_impl;
  30. template<template<class...> class L, class... U> struct mp_set_push_back_impl<L<U...>>
  31. {
  32. using type = L<U...>;
  33. };
  34. template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_back_impl<L<U...>, T1, T...>
  35. {
  36. using S = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<U..., T1>>;
  37. using type = typename mp_set_push_back_impl<S, T...>::type;
  38. };
  39. } // namespace detail
  40. template<class S, class... T> using mp_set_push_back = typename detail::mp_set_push_back_impl<S, T...>::type;
  41. // mp_set_push_front<S, T...>
  42. namespace detail
  43. {
  44. template<class S, class... T> struct mp_set_push_front_impl;
  45. template<template<class...> class L, class... U> struct mp_set_push_front_impl<L<U...>>
  46. {
  47. using type = L<U...>;
  48. };
  49. template<template<class...> class L, class... U, class T1> struct mp_set_push_front_impl<L<U...>, T1>
  50. {
  51. using type = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<T1, U...>>;
  52. };
  53. template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_front_impl<L<U...>, T1, T...>
  54. {
  55. using S = typename mp_set_push_front_impl<L<U...>, T...>::type;
  56. using type = typename mp_set_push_front_impl<S, T1>::type;
  57. };
  58. } // namespace detail
  59. template<class S, class... T> using mp_set_push_front = typename detail::mp_set_push_front_impl<S, T...>::type;
  60. // mp_is_set<S>
  61. namespace detail
  62. {
  63. template<class S> struct mp_is_set_impl
  64. {
  65. using type = mp_false;
  66. };
  67. template<template<class...> class L, class... T> struct mp_is_set_impl<L<T...>>
  68. {
  69. using type = mp_to_bool<std::is_same<mp_list<T...>, mp_set_push_back<mp_list<>, T...> > >;
  70. };
  71. } // namespace detail
  72. template<class S> using mp_is_set = typename detail::mp_is_set_impl<S>::type;
  73. } // namespace mp11
  74. } // namespace boost
  75. #endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED