Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
davidstone committed Dec 6, 2019
0 parents commit 9597bef
Show file tree
Hide file tree
Showing 22 changed files with 2,202 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build*/
.vscode/
170 changes: 170 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# Copyright David Stone 2019.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)

cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

project(operators LANGUAGES CXX)

enable_testing()

add_library(operators INTERFACE)

target_sources(operators INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include/operators/binary_minus.hpp
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include/operators/bracket.hpp
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include/operators/compound_assignment.hpp
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include/operators/forward.hpp
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include/operators/increment_decrement.hpp
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include/operators/operators.hpp
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include/operators/unary_minus.hpp
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include/operators/unary_plus.hpp
)

target_include_directories(operators INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

add_executable(operators_test
source/operators/binary_minus.cpp
source/operators/bracket.cpp
source/operators/compound_assignment.cpp
source/operators/forward.cpp
source/operators/increment_decrement.cpp
source/operators/operators.cpp
source/operators/returns.cpp
source/operators/unary_minus.cpp
source/operators/unary_plus.cpp
)

target_link_libraries(operators_test PUBLIC operators)

set(COMMON_CLANG_COMPILE_OPTIONS
"-Xclang"
"-fconcepts-ts"
"-Weverything"
"-Werror"
"-Wno-c++98-compat"
"-Wno-c++98-compat-pedantic"
"-Wno-newline-eof"
"-Wno-unused-function"
"-Wno-unused-member-function"
"-Wno-unused-template"
)

if(MSVC)
target_compile_options(operators INTERFACE
"/std:c++latest"
"/MP"
)
target_link_options(operators INTERFACE
"/WX"
)

if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
target_compile_options(operators INTERFACE
${COMMON_CLANG_COMPILE_OPTIONS}
)
else()
target_compile_options(operators INTERFACE
"/FI ciso646"
)
endif()

elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
target_compile_options(operators INTERFACE
"-std=c++2a"
)
target_compile_options(operators INTERFACE
${COMMON_CLANG_COMPILE_OPTIONS}
"-g"
"-stdlib=libc++"
"-march=native"
$<$<CONFIG:Release>:-flto=thin>
)
target_link_options(operators INTERFACE
"-Wl,--fatal-warnings"
"-stdlib=libc++"
"-fuse-ld=lld"
# TODO: Figure out how to make this work on Visual Studio
"-Wl,--thinlto-cache-dir=${CMAKE_BINARY_DIR}/lto-cache"
)

elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
target_compile_options(operators INTERFACE
"-std=c++2a"
)
target_compile_options(operators INTERFACE
"-g"
"-march=native"
"-fconcepts"
$<$<CONFIG:Release>:-flto=4 -flto-odr-type-merging -fuse-linker-plugin>
"-Wall"
"-Wextra"
"-Wpedantic"
# Do not care about ABI differences
# "-Wabi"
"-Wcast-align"
"-Wcast-qual"
# It seems impossible to initialize bit fields with this warning on
#"-Wconversion"
"-Wctor-dtor-privacy"
"-Wdisabled-optimization"
"-Wdouble-promotion"
# -Weffc++ includes a warning if all data members are not explicitly
# initialized in the initializer list. I intentionally do not do this in
# many cases. This would be more useful as a collection of warnings
# like -Wall instead of a single warning on its own.
# "-Weffc++"
"-Wfloat-equal"
"-Wformat=2"
"-Winit-self"
"-Winvalid-pch"
# -Wlogical-op warns for expressions that happen to be equal in a
# template instantiation
# "-Wlogical-op"
"-Wmissing-declarations"
# -Wmissing-format-attribute is not used because I do not use GNU
# extensions. Same for -Wsuggest-attribute and several others.
"-Wmissing-include-dirs"
#"-Wnoexcept"
"-Wno-non-template-friend"
"-Wold-style-cast"
"-Woverloaded-virtual"
"-Wredundant-decls"
"-Wshadow"
"-Wsign-conversion"
"-Wsign-promo"
"-Wsuggest-final-methods"
"-Wsuggest-final-types"
"-Wstrict-null-sentinel"
# -Wstrict-overflow=2 warns about comparing two pointers
"-Wstrict-overflow=1"
"-Wswitch-default"
"-Wswitch-enum"
"-Wtrampolines"
"-Wundef"
# -Wunsafe-loop-optimizations causes too many spurious warnings. It may
# be useful to apply this one periodically and manually verify the
# results. It generated this warning in my code when I looped over all
# elements in a vector to apply a set of functions to them (using the
# range-based for loop). It is also warning for the constructor of a
# const array of const std::string where there is no loop in user code.
# "-Wunsafe-loop-optimizations"
# -Wunused-but-set-parameter does not properly account for
# `if constexpr` branches.
"-Wno-unused-but-set-parameter"
# -Wunused-but-set-variable does not properly account for
# `if constexpr` branches.
"-Wno-unused-but-set-variable"
"-Wuseless-cast"
"-Wvector-operation-performance"
"-Werror"
)
endif()

set(all_targets operators_test)

add_test(operators_test operators_test)
27 changes: 27 additions & 0 deletions LICENSE_1_0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--- LICENSE_1_0.txt
+++ LICENSE_1_0.txt
@@ -0,0 +1,24 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
26 changes: 26 additions & 0 deletions include/operators/binary_minus.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright David Stone 2019.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#pragma once

#include <operators/forward.hpp>
#include <operators/returns.hpp>

// Not proposed for standardization
namespace operators::binary {
// cannot use inline namespace because that causes unintended ADL
namespace binary_minus {

constexpr auto operator-(auto && lhs, auto && rhs) OPERATORS_RETURNS(
OPERATORS_FORWARD(lhs) + -OPERATORS_FORWARD(rhs)
)

struct minus {};

} // namespace binary_minus

using namespace binary_minus;

} // namespace operators::binary
98 changes: 98 additions & 0 deletions include/operators/bracket.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright David Stone 2019.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#pragma once

#include <operators/forward.hpp>
#include <operators/returns.hpp>

#include <type_traits>

// Not proposed for standardization
namespace operators {
namespace bracket {
namespace bracket_detail {

// We currently cannot have a free-function `operator[]`, so the approaches used
// in the rest of this library cannot apply here.

constexpr auto iterator_operator_bracket(auto && lhs, auto && rhs) OPERATORS_RETURNS(
*(OPERATORS_FORWARD(lhs) + OPERATORS_FORWARD(rhs))
)

constexpr auto sequence_range_operator_bracket(auto && lhs, auto && rhs) OPERATORS_RETURNS(
*(begin(OPERATORS_FORWARD(lhs)) + OPERATORS_FORWARD(rhs))
)

// This must use the full template syntax to avoid a clang crash
#define OPERATORS_DETAIL_BRACKET_DEFINITIONS(self, function) \
template<typename Index> \
constexpr auto operator[](Index && index) const & -> \
decltype(function(self, index)) { \
return function(self, OPERATORS_FORWARD(index)); \
} \
template<typename Index> \
constexpr auto operator[](Index && index) & -> \
decltype(function(self, index)) { \
return function(self, OPERATORS_FORWARD(index)); \
} \
template<typename Index> \
constexpr auto operator[](Index && index) && -> \
decltype(function(std::move(self), index)) { \
return function(std::move(self), OPERATORS_FORWARD(index)); \
}

#define OPERATORS_DETAIL_BRACKET_ITERATOR_DEFINITIONS_IMPL(self) \
OPERATORS_DETAIL_BRACKET_DEFINITIONS(self, ::operators::bracket::bracket_detail::iterator_operator_bracket)

#define OPERATORS_DETAIL_BRACKET_SEQUENCE_RANGE_DEFINITIONS_IMPL(self) \
OPERATORS_DETAIL_BRACKET_DEFINITIONS(self, ::operators::bracket::bracket_detail::sequence_range_operator_bracket)


} // namespace bracket_detail


#define OPERATORS_BRACKET_ITERATOR_DEFINITIONS \
OPERATORS_DETAIL_BRACKET_ITERATOR_DEFINITIONS_IMPL(*this)

#define OPERATORS_BRACKET_SEQUENCE_RANGE_DEFINITIONS \
OPERATORS_DETAIL_BRACKET_SEQUENCE_RANGE_DEFINITIONS_IMPL(*this)


template<typename Derived>
struct iterator {
private:
constexpr auto self() const & -> Derived const & {
return static_cast<Derived const &>(*this);
}
constexpr auto self() & -> Derived & {
return static_cast<Derived &>(*this);
}
constexpr auto self() && -> Derived && {
return static_cast<Derived &&>(*this);
}
public:
OPERATORS_DETAIL_BRACKET_ITERATOR_DEFINITIONS_IMPL(self())
};


template<typename Derived>
struct sequence_range {
private:
constexpr auto self() const & -> Derived const & {
return static_cast<Derived const &>(*this);
}
constexpr auto self() & -> Derived & {
return static_cast<Derived &>(*this);
}
constexpr auto self() && -> Derived && {
return static_cast<Derived &&>(*this);
}
public:
OPERATORS_DETAIL_BRACKET_SEQUENCE_RANGE_DEFINITIONS_IMPL(self())
};

} // namespace bracket
} // namespace operators
Loading

0 comments on commit 9597bef

Please sign in to comment.