<commit_before>/* value.tcc                                 -*- C++ -*-
   <NAME> (<EMAIL>), 25 Mar 2014
   FreeBSD-style copyright and disclaimer apply

   Template implementation for Value.
*/

#include "reflect.h"
#pragma once

namespace reflect {


/******************************************************************************/
/* VALUE                                                                      */
/******************************************************************************/

template<typename T>
Value::
Value(T&& value) :
    arg(Argument::make(std::forward<T>(value))),
    value_((void*)&value) // cast-away any const
{
    if (refType() != RefType::RValue) return;

    typedef typename std::decay<T>::type CleanT;
    storage.reset(value_ = new CleanT(std::move(value)));

    // We now own the value so we're now l-ref-ing our internal storage.
    arg = Argument(arg.type(), RefType::LValue, false);
}


template<typename T>
const T&
Value::
get() const
{
    if (!type()->isConvertibleTo<T>()) {
        reflectError("<%s> is not convertible to <%s>",
                type()->id(), reflect::type<T>()->id());
    }

    return *static_cast<T*>(value_);
}


template<typename T>
bool
Value::
castable() const
{
    typedef typename CleanRef<T>::type Target;<commit_msg>Value now statically asserts if T isn't copiable or movable.<commit_after>/* value.tcc                                 -*- C++ -*-
   <NAME> (<EMAIL>), 25 Mar 2014
   FreeBSD-style copyright and disclaimer apply

   Template implementation for Value.
*/

#include "reflect.h"
#pragma once

namespace reflect {


/******************************************************************************/
/* VALUE                                                                      */
/******************************************************************************/

template<typename T>
Value::
Value(T&& value) :
    arg(Argument::make(std::forward<T>(value))),
    value_((void*)&value) // cast-away any const
{
    if (refType() != RefType::RValue) return;

    typedef typename std::decay<T>::type CleanT;
    reflectStaticAssert(
            std::is_copy_constructible<CleanT>::value ||
            std::is_move_constructible<CleanT>::value);

    storage.reset(value_ = new CleanT(std::forward<T>(value)));

    // We now own the value so we're now l-ref-ing our internal storage.
    arg = Argument(arg.type(), RefType::LValue, false);
}


template<typename T>
const T&
Value::
get() const
{
    if (!type()->isConvertibleTo<T>()) {
        reflectError("<%s> is not convertible to <%s>",
                type()->id(), reflect::type<T>()->id());
    }

    return *static_cast<T*>(value_);
}


template<typename T>
bool
Value::
castable() const
{
    typedef typename CleanRef<T>::type Target;
{'fraction_non_alphanumeric': 0.2528694404591105, 'fraction_numerical': 0.00430416068866571, 'mean_word_length': 2.961647727272727, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6762598', 'n_tokens_mistral': 795, 'n_tokens_neox': 741, 'n_words': 191}