Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contracts header with assertion macros specific to Sparrow #77

Merged
merged 3 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ set(SPARROW_HEADERS
${SPARROW_INCLUDE_DIR}/sparrow/array_data.hpp
${SPARROW_INCLUDE_DIR}/sparrow/buffer.hpp
${SPARROW_INCLUDE_DIR}/sparrow/buffer_view.hpp
${SPARROW_INCLUDE_DIR}/sparrow/contracts.hpp
${SPARROW_INCLUDE_DIR}/sparrow/data_type.hpp
${SPARROW_INCLUDE_DIR}/sparrow/data_traits.hpp
${SPARROW_INCLUDE_DIR}/sparrow/dynamic_bitset.hpp
Expand Down
8 changes: 4 additions & 4 deletions include/sparrow/array_data.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024 Man Group Operations Limited

Check notice on line 1 in include/sparrow/array_data.hpp

View workflow job for this annotation

GitHub Actions / build

Run clang-format on include/sparrow/array_data.hpp

File include/sparrow/array_data.hpp does not conform to Custom style guidelines. (lines 17)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -14,11 +14,11 @@

#pragma once

#include <cassert>
#include <compare>
#include <optional>
#include <vector>

#include "sparrow/contracts.hpp"
#include "sparrow/buffer.hpp"
#include "sparrow/data_type.hpp"
#include "sparrow/dynamic_bitset.hpp"
Expand Down Expand Up @@ -327,7 +327,7 @@
template <class L>
auto const_reference_proxy<L>::value() const -> const_reference
{
assert(has_value());
SPARROW_ASSERT_TRUE(has_value());
return m_val_ref;
}

Expand Down Expand Up @@ -357,14 +357,14 @@
template <class L>
auto reference_proxy<L>::value() -> value_type&
{
assert(has_value());
SPARROW_ASSERT_TRUE(has_value());
return m_val_ref;
}

template <class L>
auto reference_proxy<L>::value() const -> const value_type&
{
assert(has_value());
SPARROW_ASSERT_TRUE(has_value());
return m_val_ref;
}

Expand Down
10 changes: 8 additions & 2 deletions include/sparrow/buffer.hpp
jjerphan marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024 Man Group Operations Limited

Check notice on line 1 in include/sparrow/buffer.hpp

View workflow job for this annotation

GitHub Actions / build

Run clang-format on include/sparrow/buffer.hpp

File include/sparrow/buffer.hpp does not conform to Custom style guidelines. (lines 17)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -15,12 +15,12 @@
#pragma once

#include <algorithm>
#include <cassert>
#include <concepts>
#include <cstdint>
#include <iterator>
#include <stdexcept>

#include "sparrow/contracts.hpp"
#include "sparrow/allocator.hpp"
#include "sparrow/iterator.hpp"
#include "sparrow/mp_utils.hpp"
Expand Down Expand Up @@ -370,7 +370,7 @@
template <class T>
constexpr void buffer_base<T>::assign_storage(pointer p, size_type n, size_type cap)
{
assert(n <= cap);
SPARROW_ASSERT_TRUE(n <= cap);
m_data.p_begin = p;
m_data.p_end = p + n;
m_data.p_storage_end = p + cap;
Expand Down Expand Up @@ -501,36 +501,42 @@
template <class T>
constexpr auto buffer<T>::operator[](size_type i) -> reference
{
SPARROW_ASSERT_TRUE(i < size());
return get_data().p_begin[i];
}

template <class T>
constexpr auto buffer<T>::operator[](size_type i) const -> const_reference
{
SPARROW_ASSERT_TRUE(i < size());
return get_data().p_begin[i];
}

template <class T>
constexpr auto buffer<T>::front() -> reference
{
SPARROW_ASSERT_FALSE(empty());
return *(get_data().p_begin);
}

template <class T>
constexpr auto buffer<T>::front() const -> const_reference
{
SPARROW_ASSERT_FALSE(empty());
return *(get_data().p_begin);
}

template <class T>
constexpr auto buffer<T>::back() -> reference
{
SPARROW_ASSERT_FALSE(empty());
return *(get_data().p_end - 1);
}

template <class T>
constexpr auto buffer<T>::back() const -> const_reference
{
SPARROW_ASSERT_FALSE(empty());
return *(get_data().p_end - 1);
}

Expand Down
144 changes: 144 additions & 0 deletions include/sparrow/contracts.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Copyright 2024 Man Group Operations Limited

Check notice on line 1 in include/sparrow/contracts.hpp

View workflow job for this annotation

GitHub Actions / build

Run clang-format on include/sparrow/contracts.hpp

File include/sparrow/contracts.hpp does not conform to Custom style guidelines. (lines 15, 16, 19, 28, 29, 30, 31, 32, 33, 36, 37, 38, 43, 44, 45, 46, 47, 48, 50, 51, 52, 57, 58, 59, 60, 61, 62, 66, 67, 69, 70, 71, 72, 74, 75, 76, 77, 79, 80, 81, 85, 91, 92, 96, 97, 98, 99, 100, 109, 110, 111, 119, 122, 124, 125, 126, 127, 129, 130, 131, 132, 133, 135, 136, 138, 139, 140, 141, 142, 143)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// NOTE: This is based upon v0.3.0 of NoContracts library https://github.com/Klaim/nocontracts/tree/0ffc183f7527213e3f0a57b8dae9befa7c0ca02c
// Modifications: renamed macros

#pragma once
#include <cstdio>
#include <csignal>


///////////////////////////////////////////////////////////////////
// Possible bits used to compose the behavior:

// if not specified by the user but available, use std::print
#if not defined(SPARROW_CONTRACTS_USE_STD_PRINT) and not defined(SPARROW_CONTRACTS_USE_STD_FORMAT)
# if __cplusplus >= 202002L
# include <version>
# ifdef __cpp_lib_print
# define SPARROW_CONTRACTS_USE_STD_PRINT 1
# endif
# endif
#else
// The option is defined, but is it supported? If not we fail.
# if defined(SPARROW_CONTRACTS_USE_STD_PRINT) and not defined(__cpp_lib_print)
# error "std::print usage is requested but not available"
# endif
#endif

// if not specified by the user but available and std::print is not already forced, use std::format
#if not defined(SPARROW_CONTRACTS_USE_STD_FORMAT) and not defined(SPARROW_CONTRACTS_USE_STD_PRINT)
# if __cplusplus >= 202002L
# include <version>
# ifdef __cpp_lib_format
# define SPARROW_CONTRACTS_USE_STD_FORMAT 1
# endif
# endif
// The option is defined, but is it supported? If not we fail.
# if defined(SPARROW_CONTRACTS_USE_STD_FORMAT) and not defined(__cpp_lib_format)
# error "std::format usage is requested but not available"
# endif
#endif

// user specified to use neither std::format nor std::print, but C's formatting
#if defined(SPARROW_CONTRACTS_USE_CFORMAT) && SPARROW_CONTRACTS_USE_CFORMAT == 1
# ifdef SPARROW_CONTRACTS_USE_STD_FORMAT
# undef SPARROW_CONTRACTS_USE_STD_FORMAT
# endif
# ifdef SPARROW_CONTRACTS_USE_STD_PRINT
# undef SPARROW_CONTRACTS_USE_STD_PRINT
# endif
#endif

#ifndef SPARROW_CONTRACTS_LOG_FAILURE
# if defined(SPARROW_CONTRACTS_USE_STD_PRINT) && SPARROW_CONTRACTS_USE_STD_PRINT == 1
# include <print>
# include <cstdio>
# define SPARROW_CONTRACTS_LOG_FAILURE( expr__, message__ ) \
::std::print(stderr, "Assertion Failed ({}:{}): {} - ({} is wrong)\n", __FILE__, __LINE__, message__, #expr__ )
# elif defined(SPARROW_CONTRACTS_USE_STD_FORMAT) && SPARROW_CONTRACTS_USE_STD_FORMAT == 1
# include <format>
# include <cstdio>
# define SPARROW_CONTRACTS_LOG_FAILURE( expr__, message__ ) \
::fprintf(stderr, ::std::format("Assertion Failed ({}:{}): {} - ({} is wrong)\n", __FILE__, __LINE__, message__, #expr__ ).c_str())
# else
# include <cstdlib>
# include <cstdio>
# define SPARROW_CONTRACTS_LOG_FAILURE( expr__, message__ ) \
::fprintf(stderr, "Assertion Failed (%s:%i): %s - (%s is wrong)\n", __FILE__, __LINE__, message__, #expr__ )
# endif
#endif

#ifndef SPARROW_CONTRACTS_ABORT
# define SPARROW_CONTRACTS_ABORT() \
std::abort()
#endif

// User specifies to just continue instead of abort on failure.
#if defined(SPARROW_CONTRACTS_CONTINUE_ON_FAILURE) and SPARROW_CONTRACTS_CONTINUE_ON_FAILURE == 1
# undef SPARROW_CONTRACTS_ABORT
# define SPARROW_CONTRACTS_ABORT
#endif

#ifndef SPARROW_CONTRACTS_DEBUGBREAK
# ifdef _WIN32
# define SPARROW_CONTRACTS_DEBUGBREAK() __debugbreak();
# else
# define SPARROW_CONTRACTS_DEBUGBREAK() std::raise(SIGTRAP);
# endif
#endif

///////////////////////////////////////////////////////////////////
// Default behavior:

#define SPARROW_CONTRACTS_DEFAULT_CHECKS_ENABLED 1
#define SPARROW_CONTRACTS_DEFAULT_ABORT_ON_FAILURE 1

#define SPARROW_CONTRACTS_DEFAULT_ON_FAILURE( expr__, message__ ) \
SPARROW_CONTRACTS_LOG_FAILURE( expr__, message__ ); \
SPARROW_CONTRACTS_DEBUGBREAK(); \
SPARROW_CONTRACTS_ABORT();

///////////////////////////////////////////////////////////////////
// Apply Configuration:

// If not override, use the default behavior.
#ifndef SPARROW_CONTRACTS_CHECKS_ENABLED
# define SPARROW_CONTRACTS_CHECKS_ENABLED SPARROW_CONTRACTS_DEFAULT_CHECKS_ENABLED
#endif

#if SPARROW_CONTRACTS_CHECKS_ENABLED == 1 // Behavior when contracts are enabled.

# ifndef SPARROW_CONTRACTS_ON_FAILURE
# define SPARROW_CONTRACTS_ON_FAILURE( expr__, message__ ) \
SPARROW_CONTRACTS_DEFAULT_ON_FAILURE( expr__, message__ )
# endif

# ifndef SPARROW_ASSERT
# define SPARROW_ASSERT( expr__, message__ ) \
if(!( expr__ )) \
{ SPARROW_CONTRACTS_ON_FAILURE( expr__, message__ ); }
# endif

# define SPARROW_ASSERT_TRUE( expr__ ) SPARROW_ASSERT( expr__, #expr__ )
# define SPARROW_ASSERT_FALSE( expr__ ) SPARROW_ASSERT( !(expr__), "!("#expr__")" )

# else // Do nothing otherwise.
# define SPARROW_CONTRACTS_ON_FAILURE( expr__ )
# define SPARROW_ASSERT( expr__, message__ )
# define SPARROW_ASSERT_TRUE( expr__ )
# define SPARROW_ASSERT_FALSE( expr__ )
#endif

7 changes: 4 additions & 3 deletions include/sparrow/dictionary_encoded_layout.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024 Man Group Operations Limited

Check notice on line 1 in include/sparrow/dictionary_encoded_layout.hpp

View workflow job for this annotation

GitHub Actions / build

Run clang-format on include/sparrow/dictionary_encoded_layout.hpp

File include/sparrow/dictionary_encoded_layout.hpp does not conform to Custom style guidelines. (lines 17)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -14,6 +14,7 @@

#pragma once

#include "sparrow/contracts.hpp"
#include "sparrow/array_data.hpp"
#include "sparrow/fixed_size_layout.hpp"
#include "sparrow/iterator.hpp"
Expand Down Expand Up @@ -203,7 +204,7 @@
template <class IL, class SL, bool is_const>
auto dictionary_value_iterator<IL, SL, is_const>::dereference() const -> reference
{
assert(m_sub_layout_reference.has_value());
SPARROW_ASSERT_TRUE(m_sub_layout_reference.has_value());
return (*m_sub_layout_reference).get()[*m_index_it];
}

Expand Down Expand Up @@ -250,7 +251,7 @@
template <std::integral T, class SL, layout_offset OT>
dictionary_encoded_layout<T, SL, OT>::dictionary_encoded_layout(array_data& data)
{
assert(data.dictionary);
SPARROW_ASSERT_TRUE(data.dictionary);
m_sub_layout = std::make_unique<SL>(*data.dictionary);
m_indexes_layout = std::make_unique<indexes_layout>(data);
}
Expand All @@ -264,7 +265,7 @@
template <std::integral T, class SL, layout_offset OT>
auto dictionary_encoded_layout<T, SL, OT>::operator[](size_type i) const -> const_reference
{
assert(i < size());
SPARROW_ASSERT_TRUE(i < size());
const auto index = (*m_indexes_layout)[i];
if (index.has_value())
{
Expand Down
20 changes: 10 additions & 10 deletions include/sparrow/dynamic_bitset.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024 Man Group Operations Limited

Check notice on line 1 in include/sparrow/dynamic_bitset.hpp

View workflow job for this annotation

GitHub Actions / build

Run clang-format on include/sparrow/dynamic_bitset.hpp

File include/sparrow/dynamic_bitset.hpp does not conform to Custom style guidelines. (lines 17)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -14,11 +14,11 @@

#pragma once

#include <cassert>
#include <climits>
#include <concepts>
#include <ranges>

#include "sparrow/contracts.hpp"
#include "sparrow/buffer.hpp"
#include "sparrow/buffer_view.hpp"
#include "sparrow/mp_utils.hpp"
Expand Down Expand Up @@ -314,28 +314,28 @@
template <random_access_range B>
auto dynamic_bitset_base<B>::operator[](size_type pos) -> reference
{
assert(pos < size());
SPARROW_ASSERT_TRUE(pos < size());
return reference(*this, m_buffer.data()[block_index(pos)], bit_mask(pos));
}

template <random_access_range B>
bool dynamic_bitset_base<B>::operator[](size_type pos) const
{
assert(pos < size());
SPARROW_ASSERT_TRUE(pos < size());
return !m_null_count || m_buffer.data()[block_index(pos)] & bit_mask(pos);
}

template <random_access_range B>
bool dynamic_bitset_base<B>::test(size_type pos) const
{
assert(pos < size());
SPARROW_ASSERT_TRUE(pos < size());
return !m_null_count || m_buffer.data()[block_index(pos)] & bit_mask(pos);
}

template <random_access_range B>
void dynamic_bitset_base<B>::set(size_type pos, value_type value)
{
assert(pos < size());
SPARROW_ASSERT_TRUE(pos < size());
block_type& block = m_buffer.data()[block_index(pos)];
const bool old_value = block & bit_mask(pos);
if (value)
Expand Down Expand Up @@ -430,7 +430,7 @@
, m_null_count(null_count)
{
zero_unused_bits();
assert(m_null_count == m_size - count_non_null());
SPARROW_ASSERT_TRUE(m_null_count == m_size - count_non_null());
}

template <random_access_range B>
Expand Down Expand Up @@ -698,7 +698,7 @@
, p_block(block)
, m_index(index)
{
assert(m_index < bitset_type::s_bits_per_block);
SPARROW_ASSERT_TRUE(m_index < bitset_type::s_bits_per_block);
}

template <class B, bool is_const>
Expand All @@ -724,7 +724,7 @@
++p_block;
m_index = 0u;
}
assert(m_index < bitset_type::s_bits_per_block);
SPARROW_ASSERT_TRUE(m_index < bitset_type::s_bits_per_block);
}

template <class B, bool is_const>
Expand All @@ -740,7 +740,7 @@
{
--m_index;
}
assert(m_index < bitset_type::s_bits_per_block);
SPARROW_ASSERT_TRUE(m_index < bitset_type::s_bits_per_block);
}

template <class B, bool is_const>
Expand Down Expand Up @@ -786,7 +786,7 @@
}
}
}
assert(m_index < bitset_type::s_bits_per_block);
SPARROW_ASSERT_TRUE(m_index < bitset_type::s_bits_per_block);
}

template <class B, bool is_const>
Expand Down
Loading
Loading