Skip to content

Commit

Permalink
fixed unit test error because of usage of std::memcmp
Browse files Browse the repository at this point in the history
std::memcmp cannot be used to compare custom structs!
Therefore for every custom type you need to register now the equal
and less than operator, 2 new functions were introduced:

type::register_equal_comparator<MyType>();
type::register_less_than_comparator<MyType>();
  • Loading branch information
acki-m committed Oct 14, 2016
1 parent 661570a commit c90b497
Show file tree
Hide file tree
Showing 19 changed files with 536 additions and 148 deletions.
58 changes: 58 additions & 0 deletions src/rttr/detail/misc/compare_array_equal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/************************************************************************************
* *
* Copyright (c) 2014, 2015 - 2016 Axel Menzel <info@rttr.org> *
* *
* This file is part of RTTR (Run Time Type Reflection) *
* License: MIT License *
* *
* Permission is hereby granted, free of charge, to any person obtaining *
* a copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
* *
*************************************************************************************/

#ifndef RTTR_COMPARE_ARRAY_EQUAL_H_
#define RTTR_COMPARE_ARRAY_EQUAL_H_

#include "rttr/detail/base/core_prerequisites.h"
#include "rttr/detail/misc/misc_type_traits.h"
#include "rttr/string_view.h"

#include <type_traits>
#include <cstring>

namespace rttr
{
namespace detail
{

/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// compare whether two arrays are the same or not
// the comparison will go down till element wise comparison

template<typename ElementType, std::size_t Count>
RTTR_INLINE bool compare_array_equal(const ElementType(&lhs)[Count], const ElementType(&rhs)[Count]);

/////////////////////////////////////////////////////////////////////////////////////////

} // end namespace detail
} // end namespace rttr

#include "rttr/detail/misc/compare_array_equal_impl.h"

#endif // RTTR_COMPARE_ARRAY_EQUAL_H_
86 changes: 86 additions & 0 deletions src/rttr/detail/misc/compare_array_equal_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/************************************************************************************
* *
* Copyright (c) 2014, 2015 - 2016 Axel Menzel <info@rttr.org> *
* *
* This file is part of RTTR (Run Time Type Reflection) *
* License: MIT License *
* *
* Permission is hereby granted, free of charge, to any person obtaining *
* a copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
* *
*************************************************************************************/

#ifndef RTTR_COMPARE_ARRAY_EQUAL_IMPL_H_
#define RTTR_COMPARE_ARRAY_EQUAL_IMPL_H_

#include "rttr/detail/base/core_prerequisites.h"
#include "rttr/detail/misc/misc_type_traits.h"
#include "rttr/detail/misc/compare_equal.h"

#include <type_traits>
#include <cstring>

namespace rttr
{
namespace detail
{

/////////////////////////////////////////////////////////////////////////////////////////
// default impl, compares per type

template<typename ElementType>
struct compare_array_equal_impl
{
bool operator()(const ElementType &lhs, const ElementType &rhs)
{
return compare_equal(lhs, rhs);
}
};

/////////////////////////////////////////////////////////////////////////////////////////

template<typename ElementType, std::size_t Count>
struct compare_array_equal_impl<ElementType[Count]>
{
bool operator()(const ElementType (&lhs)[Count], const ElementType (&rhs)[Count])
{
for(std::size_t i = 0; i < Count; ++i)
{
if (!compare_array_equal_impl<ElementType>()(lhs[i], rhs[i]))
return false;
}

return true;
}
};


/////////////////////////////////////////////////////////////////////////////////////////

template<typename ElementType, std::size_t Count>
RTTR_INLINE bool compare_array_equal(const ElementType (&lhs)[Count], const ElementType (&rhs)[Count])
{
return compare_array_equal_impl<ElementType[Count]>()(lhs, rhs);
}

/////////////////////////////////////////////////////////////////////////////////////////

} // end namespace detail
} // end namespace rttr

#endif // RTTR_COMPARE_ARRAY_EQUAL_IMPL_H_
58 changes: 58 additions & 0 deletions src/rttr/detail/misc/compare_array_less.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/************************************************************************************
* *
* Copyright (c) 2014, 2015 - 2016 Axel Menzel <info@rttr.org> *
* *
* This file is part of RTTR (Run Time Type Reflection) *
* License: MIT License *
* *
* Permission is hereby granted, free of charge, to any person obtaining *
* a copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
* *
*************************************************************************************/

#ifndef RTTR_COMPARE_ARRAY_LESS_H_
#define RTTR_COMPARE_ARRAY_LESS_H_

#include "rttr/detail/base/core_prerequisites.h"
#include "rttr/detail/misc/misc_type_traits.h"
#include "rttr/string_view.h"

#include <type_traits>
#include <cstring>

namespace rttr
{
namespace detail
{

/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// compare whether array lhs is less than rhs
// the comparison will go down till element wise comparison

template<typename ElementType, std::size_t Count>
RTTR_INLINE bool compare_array_less(const ElementType(&lhs)[Count], const ElementType(&rhs)[Count]);

/////////////////////////////////////////////////////////////////////////////////////////

} // end namespace detail
} // end namespace rttr

#include "rttr/detail/misc/compare_array_less_impl.h"

#endif // RTTR_COMPARE_ARRAY_LESS_H_
88 changes: 88 additions & 0 deletions src/rttr/detail/misc/compare_array_less_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/************************************************************************************
* *
* Copyright (c) 2014, 2015 - 2016 Axel Menzel <info@rttr.org> *
* *
* This file is part of RTTR (Run Time Type Reflection) *
* License: MIT License *
* *
* Permission is hereby granted, free of charge, to any person obtaining *
* a copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
* *
*************************************************************************************/

#ifndef RTTR_COMPARE_ARRAY_LESS_IMPL_H_
#define RTTR_COMPARE_ARRAY_LESS_IMPL_H_

#include "rttr/detail/base/core_prerequisites.h"
#include "rttr/detail/misc/misc_type_traits.h"
#include "rttr/detail/misc/compare_equal.h"

#include <type_traits>
#include <cstring>

namespace rttr
{
namespace detail
{

/////////////////////////////////////////////////////////////////////////////////////////

template<typename ElementType>
struct compare_array_less_impl
{
int operator()(const ElementType &lhs, const ElementType &rhs)
{
return (lhs < rhs ? - 1 : ((rhs < lhs) ? 1 : 0));
}
};

/////////////////////////////////////////////////////////////////////////////////////////

template<typename ElementType, std::size_t Count>
struct compare_array_less_impl<ElementType[Count]>
{
int operator()(const ElementType (&lhs)[Count], const ElementType (&rhs)[Count])
{
int flag = 0;
for(std::size_t i = 0; i < Count; ++i)
{
if ((flag = compare_array_less_impl<ElementType>()(lhs[i], rhs[i])) != 0)
return flag;
}

return 0;
}
};

/////////////////////////////////////////////////////////////////////////////////////////

template<typename ElementType, std::size_t Count>
RTTR_INLINE bool compare_array_less(const ElementType (&lhs)[Count], const ElementType (&rhs)[Count])
{
if (compare_array_less_impl<ElementType[Count]>()(lhs, rhs) == -1)
return true;

return false;
}

/////////////////////////////////////////////////////////////////////////////////////////

} // end namespace detail
} // end namespace rttr

#endif // RTTR_COMPARE_ARRAY_LESS_IMPL_H_
6 changes: 3 additions & 3 deletions src/rttr/detail/misc/compare_equal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ namespace detail

bool compare_types_equal(const void* lhs, const void* rhs, const type& t)
{
if (auto cmp_f = type_register_private::get_comparator(t))
return cmp_f->equal(lhs, rhs);
if (auto cmp_f = type_register_private::get_equal_comparator(t))
return cmp_f->cmp(lhs, rhs);

return (std::memcmp(lhs, rhs, t.get_sizeof()) == 0);
return false;
}

} // end namespace detail
Expand Down
26 changes: 11 additions & 15 deletions src/rttr/detail/misc/compare_equal.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "rttr/detail/base/core_prerequisites.h"
#include "rttr/detail/misc/misc_type_traits.h"
#include "rttr/string_view.h"

#include <type_traits>
#include <cstring>
Expand All @@ -39,38 +40,33 @@ namespace rttr
namespace detail
{

template<typename T>
using is_comparable_type = std::integral_constant<bool, std::is_same<T, std::string>::value ||
std::is_same<T, string_view>::value ||
std::is_arithmetic<T>::value ||
std::is_same<T, std::nullptr_t>::value
>;

/////////////////////////////////////////////////////////////////////////////////////////

/*!
* \brief This function return the result of the expression `lhs == rhs` when the type \p T has the equal operator defined,
* otherwise this function will return false.
*/
template<typename T>
RTTR_INLINE typename std::enable_if<has_equal_operator<T>::value && !std::is_array<T>::value && !is_custom_type<T>::value, bool>::type
compare_equal(const T& lhs, const T& rhs);

/////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
RTTR_INLINE typename std::enable_if<has_equal_operator<T>::value && !std::is_array<T>::value && is_custom_type<T>::value, bool>::type
compare_equal(const T& lhs, const T& rhs);

/////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
RTTR_INLINE typename std::enable_if<!has_equal_operator<T>::value && !std::is_array<T>::value, bool>::type
RTTR_INLINE typename std::enable_if<std::is_enum<T>::value || is_comparable_type<T>::value, bool>::type
compare_equal(const T& lhs, const T& rhs);

/////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
RTTR_INLINE typename std::enable_if<std::is_array<T>::value && has_equal_operator<typename array_mapper<T>::raw_type>::value, bool>::type
RTTR_INLINE typename std::enable_if<!std::is_enum<T>::value && !is_comparable_type<T>::value && !std::is_array<T>::value, bool>::type
compare_equal(const T& lhs, const T& rhs);

/////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
RTTR_INLINE typename std::enable_if<std::is_array<T>::value && !has_equal_operator<typename array_mapper<T>::raw_type>::value, bool>::type
RTTR_INLINE typename std::enable_if<!std::is_enum<T>::value && !is_comparable_type<T>::value && std::is_array<T>::value, bool>::type
compare_equal(const T& lhs, const T& rhs);

/////////////////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit c90b497

Please sign in to comment.