Skip to content

Commit

Permalink
Fix ODR violations with nested static constexpr function objects
Browse files Browse the repository at this point in the history
Fixes #75
Fixes #76
  • Loading branch information
ldionne committed May 21, 2015
1 parent 6b9eb57 commit 7083d8e
Show file tree
Hide file tree
Showing 74 changed files with 1,226 additions and 442 deletions.
4 changes: 2 additions & 2 deletions include/boost/hana/comparable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ namespace boost { namespace hana {

//! @cond
template <typename X>
constexpr decltype(auto) _equal::_to::operator()(X&& x) const
constexpr decltype(auto) _equal_to::operator()(X&& x) const
{ return hana::partial(equal, static_cast<X&&>(x)); }
//! @endcond

Expand Down Expand Up @@ -127,7 +127,7 @@ namespace boost { namespace hana {

//! @cond
template <typename X>
constexpr decltype(auto) _not_equal::_to::operator()(X&& x) const
constexpr decltype(auto) _not_equal_to::operator()(X&& x) const
{ return hana::partial(not_equal, static_cast<X&&>(x)); }
//! @endcond

Expand Down
5 changes: 4 additions & 1 deletion include/boost/hana/detail/insert_fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_HANA_DETAIL_INSERT_FWD_HPP
#define BOOST_HANA_DETAIL_INSERT_FWD_HPP

#include <boost/hana/detail/static_constexpr.hpp>
#include <boost/hana/fwd/core/datatype.hpp>
#include <boost/hana/fwd/core/when.hpp>

Expand All @@ -31,7 +32,9 @@ namespace boost { namespace hana {
}
};

constexpr _insert insert{};
namespace {
constexpr auto const& insert = detail::static_constexpr<_insert>;
}
}} // end namespace boost::hana

#endif // !BOOST_HANA_DETAIL_INSERT_FWD_HPP
5 changes: 4 additions & 1 deletion include/boost/hana/detail/keys_fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_HANA_DETAIL_KEYS_FWD_HPP
#define BOOST_HANA_DETAIL_KEYS_FWD_HPP

#include <boost/hana/detail/static_constexpr.hpp>
#include <boost/hana/fwd/core/datatype.hpp>
#include <boost/hana/fwd/core/when.hpp>

Expand All @@ -30,7 +31,9 @@ namespace boost { namespace hana {
}
};

constexpr _keys keys{};
namespace {
constexpr auto const& keys = detail::static_constexpr<_keys>;
}
}} // end namespace boost::hana

#endif // !BOOST_HANA_DETAIL_KEYS_FWD_HPP
34 changes: 34 additions & 0 deletions include/boost/hana/detail/static_constexpr.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*!
@file
Defines `boost::hana::detail::static_constexpr`.
@copyright Louis Dionne 2015
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/

#ifndef BOOST_HANA_DETAIL_STATIC_CONSTEXPR_HPP
#define BOOST_HANA_DETAIL_STATIC_CONSTEXPR_HPP

namespace boost { namespace hana { namespace detail {
template <typename T>
struct _static_constexpr {
static constexpr T value{};
};

template <typename T>
constexpr T _static_constexpr<T>::value;

//! @ingroup group-details
//! Workaround to avoid ODR violations when declaring `static constexpr`
//! objects.
//!
//! See [this paper][1] for a detailed explanation of how to use this
//! utility.
//!
//! [1]: http://ericniebler.github.io/std/wg21/D4381.html
template <typename T>
constexpr auto const& static_constexpr = _static_constexpr<T>::value;
}}} // end namespace boost::hana::detail

#endif // !BOOST_HANA_DETAIL_STATIC_CONSTEXPR_HPP
2 changes: 1 addition & 1 deletion include/boost/hana/ext/boost/fusion/detail/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ namespace boost { namespace hana {
//////////////////////////////////////////////////////////////////////////
template <typename S>
struct models_impl<Sequence, S, when<detail::is_fusion_sequence<S>{}()>>
: decltype(true_)
: _integral_constant<bool, true>
{ };
}} // end namespace boost::hana

Expand Down
2 changes: 1 addition & 1 deletion include/boost/hana/ext/boost/tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ namespace boost { namespace hana {
//////////////////////////////////////////////////////////////////////////
template <>
struct models_impl<Sequence, ext::boost::Tuple>
: decltype(true_)
: _integral_constant<bool, true>
{ };
}} // end namespace boost::hana

Expand Down
2 changes: 1 addition & 1 deletion include/boost/hana/ext/std/tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ namespace boost { namespace hana {
//////////////////////////////////////////////////////////////////////////
template <>
struct models_impl<Sequence, ext::std::Tuple>
: decltype(true_)
: _integral_constant<bool, true>
{ };
}} // end namespace boost::hana

Expand Down
27 changes: 27 additions & 0 deletions include/boost/hana/foldable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,24 @@ namespace boost { namespace hana {
}
};

//////////////////////////////////////////////////////////////////////////
// reverse_fold
//////////////////////////////////////////////////////////////////////////
//! @cond
template <typename Xs, typename S, typename F>
constexpr decltype(auto) _reverse_fold::operator()(Xs&& xs, S&& s, F&& f) const {
return hana::fold.right(static_cast<Xs&&>(xs),
static_cast<S&&>(s),
hana::flip(static_cast<F&&>(f)));
}

template <typename Xs, typename F>
constexpr decltype(auto) _reverse_fold::operator()(Xs&& xs, F&& f) const {
return hana::fold.right(static_cast<Xs&&>(xs),
hana::flip(static_cast<F&&>(f)));
}
//! @endcond

//////////////////////////////////////////////////////////////////////////
// for_each
//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -683,6 +701,15 @@ namespace boost { namespace hana {
}
};

//////////////////////////////////////////////////////////////////////////
// fuse
//////////////////////////////////////////////////////////////////////////
//! @cond
template <typename F>
constexpr decltype(auto) _fuse::operator()(F&& f) const
{ return hana::partial(hana::flip(hana::unpack), static_cast<F&&>(f)); }
//! @endcond

//////////////////////////////////////////////////////////////////////////
// models
//////////////////////////////////////////////////////////////////////////
Expand Down
5 changes: 4 additions & 1 deletion include/boost/hana/functional/always.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Distributed under the Boost Software License, Version 1.0.

#include <boost/hana/config.hpp>
#include <boost/hana/detail/create.hpp>
#include <boost/hana/detail/static_constexpr.hpp>
#include <boost/hana/detail/std/move.hpp>


Expand Down Expand Up @@ -58,7 +59,9 @@ namespace boost { namespace hana {
{ return detail::std::move(val_); }
};

constexpr detail::create<_always> always{};
namespace {
constexpr auto const& always = detail::static_constexpr<detail::create<_always>>;
}
#endif
}} // end namespace boost::hana

Expand Down
7 changes: 6 additions & 1 deletion include/boost/hana/functional/apply.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_HANA_FUNCTIONAL_APPLY_HPP
#define BOOST_HANA_FUNCTIONAL_APPLY_HPP

#include <boost/hana/detail/static_constexpr.hpp>


namespace boost { namespace hana {
//! @ingroup group-functional
//! Invoke `f` with `x...` as arguments.
Expand Down Expand Up @@ -40,7 +43,9 @@ namespace boost { namespace hana {
}
};

constexpr _apply apply{};
namespace {
constexpr auto const& apply = detail::static_constexpr<_apply>;
}
#endif
}} // end namespace boost::hana

Expand Down
7 changes: 5 additions & 2 deletions include/boost/hana/functional/arg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_HANA_FUNCTIONAL_ARG_HPP

#include <boost/hana/config.hpp>
#include <boost/hana/detail/static_constexpr.hpp>
#include <boost/hana/detail/std/enable_if.hpp>
#include <boost/hana/detail/std/size_t.hpp>

Expand Down Expand Up @@ -132,8 +133,10 @@ namespace boost { namespace hana {
{ return _arg<n - 25>{}(static_cast<Xn&&>(xn)...); }
};

template <detail::std::size_t n>
constexpr _arg<n> arg{};
namespace {
template <detail::std::size_t n>
constexpr auto const& arg = detail::static_constexpr<_arg<n>>;
}
#endif
}} // end namespace boost::hana

Expand Down
5 changes: 4 additions & 1 deletion include/boost/hana/functional/capture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Distributed under the Boost Software License, Version 1.0.

#include <boost/hana/detail/closure.hpp>
#include <boost/hana/detail/create.hpp>
#include <boost/hana/detail/static_constexpr.hpp>
#include <boost/hana/functional/partial.hpp>


Expand Down Expand Up @@ -74,7 +75,9 @@ namespace boost { namespace hana {
}
};

constexpr _make_capture capture{};
namespace {
constexpr auto const& capture = detail::static_constexpr<_make_capture>;
}
#endif
}} // end namespace boost::hana

Expand Down
5 changes: 4 additions & 1 deletion include/boost/hana/functional/compose.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Distributed under the Boost Software License, Version 1.0.

#include <boost/hana/config.hpp>
#include <boost/hana/detail/create.hpp>
#include <boost/hana/detail/static_constexpr.hpp>
#include <boost/hana/detail/std/move.hpp>
#include <boost/hana/detail/variadic/foldl1.hpp>

Expand Down Expand Up @@ -102,7 +103,9 @@ namespace boost { namespace hana {
}
};

constexpr _make_compose compose{};
namespace {
constexpr auto const& compose = detail::static_constexpr<_make_compose>;
}
#endif
}} // end namespace boost::hana

Expand Down
12 changes: 7 additions & 5 deletions include/boost/hana/functional/curry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,10 @@ namespace boost { namespace hana {
operator()(F&& f) const { return {static_cast<F&&>(f)}; }
};

template <detail::std::size_t n>
constexpr _make_curry<n> curry{};
namespace {
template <detail::std::size_t n>
constexpr auto const& curry = detail::static_constexpr<_make_curry<n>>;
}

namespace curry_detail {
template <detail::std::size_t n>
Expand All @@ -127,7 +129,7 @@ namespace boost { namespace hana {
static_assert(sizeof...(x) <= n,
"too many arguments provided to boost::hana::curry");
return curry_detail::curry_or_call<n - sizeof...(x)>(
partial(f, static_cast<X&&>(x)...)
hana::partial(f, static_cast<X&&>(x)...)
);
}

Expand All @@ -137,7 +139,7 @@ namespace boost { namespace hana {
static_assert(sizeof...(x) <= n,
"too many arguments provided to boost::hana::curry");
return curry_detail::curry_or_call<n - sizeof...(x)>(
partial(f, static_cast<X&&>(x)...)
hana::partial(f, static_cast<X&&>(x)...)
);
}
#endif
Expand All @@ -147,7 +149,7 @@ namespace boost { namespace hana {
static_assert(sizeof...(x) <= n,
"too many arguments provided to boost::hana::curry");
return curry_detail::curry_or_call<n - sizeof...(x)>(
partial(detail::std::move(f), static_cast<X&&>(x)...)
hana::partial(detail::std::move(f), static_cast<X&&>(x)...)
);
}
};
Expand Down
5 changes: 4 additions & 1 deletion include/boost/hana/functional/demux.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/detail/closure.hpp>
#include <boost/hana/detail/create.hpp>
#include <boost/hana/detail/static_constexpr.hpp>
#include <boost/hana/detail/std/move.hpp>


Expand Down Expand Up @@ -210,7 +211,9 @@ namespace boost { namespace hana {
}
};

constexpr detail::create<_pre_demux> demux{};
namespace {
constexpr auto const& demux = detail::static_constexpr<detail::create<_pre_demux>>;
}
#endif
}} // end namespace boost::hana

Expand Down
5 changes: 4 additions & 1 deletion include/boost/hana/functional/fix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Distributed under the Boost Software License, Version 1.0.

#include <boost/hana/config.hpp>
#include <boost/hana/detail/create.hpp>
#include <boost/hana/detail/static_constexpr.hpp>
#include <boost/hana/detail/std/move.hpp>


Expand Down Expand Up @@ -58,7 +59,9 @@ namespace boost { namespace hana {
template <typename F>
struct _fix;

constexpr detail::create<_fix> fix{};
namespace {
constexpr auto const& fix = detail::static_constexpr<detail::create<_fix>>;
}

template <typename F>
struct _fix {
Expand Down
5 changes: 4 additions & 1 deletion include/boost/hana/functional/flip.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Distributed under the Boost Software License, Version 1.0.

#include <boost/hana/config.hpp>
#include <boost/hana/detail/create.hpp>
#include <boost/hana/detail/static_constexpr.hpp>
#include <boost/hana/detail/std/move.hpp>


Expand Down Expand Up @@ -67,7 +68,9 @@ namespace boost { namespace hana {
}
};

constexpr detail::create<_flip> flip{};
namespace {
constexpr auto const& flip = detail::static_constexpr<detail::create<_flip>>;
}
#endif
}} // end namespace boost::hana

Expand Down
7 changes: 6 additions & 1 deletion include/boost/hana/functional/id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_HANA_FUNCTIONAL_ID_HPP
#define BOOST_HANA_FUNCTIONAL_ID_HPP

#include <boost/hana/detail/static_constexpr.hpp>


namespace boost { namespace hana {
//! @ingroup group-functional
//! The identity function -- returns its argument unchanged.
Expand All @@ -28,7 +31,9 @@ namespace boost { namespace hana {
}
};

constexpr _id id{};
namespace {
constexpr auto const& id = detail::static_constexpr<_id>;
}
#endif
}} // end namespace boost::hana

Expand Down
6 changes: 5 additions & 1 deletion include/boost/hana/functional/infix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_HANA_FUNCTIONAL_INFIX_HPP

#include <boost/hana/config.hpp>
#include <boost/hana/detail/static_constexpr.hpp>
#include <boost/hana/detail/std/decay.hpp>
#include <boost/hana/detail/std/move.hpp>
#include <boost/hana/detail/std/remove_cv.hpp>
Expand Down Expand Up @@ -180,7 +181,10 @@ namespace boost { namespace hana {
}
} // end namespace infix_detail

constexpr infix_detail::make_infix<false, false> infix{};
namespace {
constexpr auto const& infix =
detail::static_constexpr<infix_detail::make_infix<false, false>>;
}
#endif
}} // end namespace boost::hana

Expand Down
Loading

0 comments on commit 7083d8e

Please sign in to comment.