diff --git a/CMakeLists.txt b/CMakeLists.txt index 4274820..0dec32a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,3 @@ -# Copyright (c) 2008-2013 Andrew Sutton -# # This file is distributed under the MIT License. See the accompanying file # LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms # and conditions. @@ -8,7 +6,7 @@ cmake_minimum_required(VERSION 2.8) # Set the project, required language, and default flags. project(origin CXX) -set(CMAKE_CXX_FLAGS -std=c++1y) +set(CMAKE_CXX_FLAGS -std=c++1z) enable_testing() diff --git a/origin/CMakeLists.txt b/origin/CMakeLists.txt index ade1b2c..7b6efe4 100644 --- a/origin/CMakeLists.txt +++ b/origin/CMakeLists.txt @@ -1,8 +1,9 @@ -# Copyright (c) 2008-2013 Andrew Sutton -# # This file is distributed under the MIT License. See the accompanying file # LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms # and conditions. add_subdirectory(core) +add_subdirectory(memory) +add_subdirectory(numeric) add_subdirectory(sequence) +add_subdirectory(data) diff --git a/origin/core/CMakeLists.txt b/origin/core/CMakeLists.txt index 9de7902..e545a0f 100644 --- a/origin/core/CMakeLists.txt +++ b/origin/core/CMakeLists.txt @@ -1,8 +1,17 @@ -# Copyright (c) 2008-2014 Andrew Sutton -# # This file is distributed under the MIT License. See the accompanying file # LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms # and conditions. +add_library(origin-core + traits.cpp + concepts.cpp + function.cpp + type.cpp +) + +# FIXME: The tests in this library need to link against +# the origin-core library. + add_subdirectory(concepts.test) add_subdirectory(function.test) + diff --git a/origin/core/concepts.cpp b/origin/core/concepts.cpp new file mode 100644 index 0000000..c5312d1 --- /dev/null +++ b/origin/core/concepts.cpp @@ -0,0 +1,5 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#include "concepts.hpp" diff --git a/origin/core/concepts.hpp b/origin/core/concepts.hpp index 6ab28d1..95ad405 100644 --- a/origin/core/concepts.hpp +++ b/origin/core/concepts.hpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. @@ -15,22 +13,26 @@ namespace origin { -// Is true if and only if T and U are the same type. +// A type `T` is the same as a type `U` if template concept bool Same() { return __is_same_as(T, U); } + // Is true if and only if T is derived from U or is the same as U. template concept bool Derived() { return __is_base_of(U, T); } -// Is true if and only if T can be implicitly converted to U through -// a user-defined conversion sequence. + +// A type `T` is convertible to another type `U` if an object +// `t` of type `T` can be returned from a function whose return +// type is `U`. template concept bool Convertible() { return __is_convertible_to(T, U); } + // Represents the common type of a sequence of type arguments. More // precisely, if there exists some type C such that each type T in Ts // can be converted to C, then C is the common type of all T in Ts. @@ -61,60 +63,38 @@ template }; } + // True if and only if an expression of type T can be contextually // converted to bool. template concept bool Conditional() { return requires (T p) { p ? true : false; }; } -namespace core_impl { -template - concept bool - User_defined_logical() - { - return Class_type() - && requires (T a, T b) { - {a && b} -> T; - {a || b} -> T; - {!a} -> T; - }; - } -} // namespace core_impl - -// Declarations -// Is true if and only if T is a Conditional type but not a user-defined -// logical type. That is T must not overload the &&, ||, and ! operators. +// -------------------------------------------------------------------------- // +// Relational concepts [concepts.comp] // -// TODO: Is there a way to determine the user has overloaded an operator? -template - concept bool - Boolean() { - return Conditional() && not core_impl::User_defined_logical(); - } +// The relational concepts define requirements on types that can be +// compared using the C++ relational operators. -// Relational Concepts -// Is true if and only if arguments of type T can be compared using the -// `==` and `!=` operators. +// A type T is equality comparable if its values can be compared using +// oerators `==` and `!=`. // // Types modeling this concept must ensure that the `==` operator -// returns true only when the arguments have the same value. +// returns true only when the arguments have the same value and that +// `!=` is the logical inverse of `==`. template concept bool Equality_comparable() { return requires (T a, T b) { - a == b; requires Boolean(); - a != b; requires Boolean(); + { a == b } -> bool; + { a != b } -> bool; }; } -// Is true if and only if arguments of types T and U share a common type -// and can be compared using the == and != operators. -// -// Pairs of types modeling this concept must ensure the `==` operator -// returns true only when the arguments, when converted to their common -// type, and those converted values are the same. +// A pair of types T and U are (cross-type) equality comparable +// only when ... template concept bool Equality_comparable() { @@ -122,31 +102,34 @@ template && Equality_comparable() && Common() && requires (T t, T u) { - t == u; requires Boolean(); - u == t; requires Boolean(); - t != u; requires Boolean(); - u != t; requires Boolean(); + { t == u } -> bool; + { u == t } -> bool; + { t != u } -> bool; + { u != t } -> bool; }; } -// Is true if and only if arguments of type T can be compared using the -// inequality operators `<`, `>`, `<=`, and `>=`. +// A type T is weakly ordered when it can be compared using the +// operators `<`, `>`, `<=`, and `>=`. +// +// TODO: Document semantics. // -// Types modeling this concept must ensure that the `<` operator defines -// a strict weak order. +// Note that in a weakly ordered type, for all objects `a` and `b` +// of type `T`, when `a <= b` and `b <= a`, `a` and `b` are +// equivalent, but they are not known to be equal. template concept bool Weakly_ordered() { return requires (T a, T b) { - a < b; requires Boolean(); - a > b; requires Boolean b)>(); - a <= b; requires Boolean(); - a >= b; requires Boolean= b)>(); + { a < b } -> bool; + { a > b } -> bool; + { a <= b } -> bool; + { a >= b } -> bool; }; } -// Weakly ordered +// TODO: Document me. template concept bool Weakly_ordered() { @@ -154,25 +137,29 @@ template && Weakly_ordered() && Common() && requires (T t, T u) { - t < u; requires Boolean(); - u < t; requires Boolean(); - t > u; requires Boolean u)>(); - u > t; requires Boolean t)>(); - t <= u; requires Boolean(); - u <= t; requires Boolean(); - t >= u; requires Boolean= u)>(); - u <= t; requires Boolean= t)>(); + { t < u } -> bool; + { u < t } -> bool; + { t > u } -> bool; + { u > t } -> bool; + { t <= u } -> bool; + { u <= t } -> bool; + { t >= u } -> bool; + { u <= t } -> bool; }; } -// Totally ordered +// A type `T` is totally ordered when it is both equality comparable +// and weakly ordered. +// +// Types modeling this concept must guarantee that, for all `a` and +// `b` of type `T`, when `a <= b` and `b <= a`, `a == b`. template concept bool Totally_ordered() { return Equality_comparable() && Weakly_ordered(); } -// Totally ordered +// TODO: Document me. template concept bool Totally_ordered() { @@ -183,7 +170,11 @@ template } -// Regular types +// -------------------------------------------------------------------------- // +// Regular types [concepts.type] +// +// There are a number of concepts that contributed (piecewise) to the +// definition of regular types. // Is true if a variable of type T can be destroyed. template @@ -193,8 +184,8 @@ template // Is true if and only if an object of type T can be constructed with // the types of arguments in Args. template - concept bool Constructible() - { + concept bool + Constructible() { return Destructible() && std::is_constructible::value; } @@ -207,11 +198,13 @@ template concept bool Default_constructible() { return Constructible(); } + // Is true if and only if an object of type T can be move constructed. template concept bool Move_constructible() { return Constructible(); } + // Is true if and only if an object of type T can be copy constructed. template concept bool @@ -227,11 +220,13 @@ template concept bool Assignable() { return std::is_assignable::value; } + // Is true if and only if an object of type T can be move assigned. template concept bool Move_assignable() { return Assignable(); } + // Is true if and only if an object of type T can be copy assigned. template concept bool @@ -256,23 +251,32 @@ template return Copy_constructible() && Copy_assignable(); } -// Is true if and only if T is a semiregular type. A semiregular type -// is both default constructible and copyable. + +// A type is a semiregular type if it is default constructible and +// copyable. Alternatively, a semiregular type is a regular type that +// is not equality comparable. +// +// The semiregular type represents types like C structures, which can +// be default constructed and copied, but have no default definition +// of equality. template concept bool Semiregular() { return Default_constructible() && Copyable(); } -// Is true if T is a regular type. A regular type is a semiregular type -// that is also equality comparable. + +// A type `T` is regular when it is semiregular and equality comparable. +// Regular types can be used like most scalar types, although they +// are not guaranteed to be ordered (comparble with `<`). template concept bool Regular() { return Semiregular() && Equality_comparable(); } -// Is true if T is an ordered type. An ordered type is a + +// A type is ordered if it is a regular type that is also totally ordered. template concept bool Ordered() { @@ -280,7 +284,14 @@ template } -// Functional types +// -------------------------------------------------------------------------- // +// Function concepts [concepts.fn] +// +// The function concepts describe requirements on types that can be +// called as functions using the syntax 'f(args...)', where 'f' is +// the function-like type and 'args' is a (possibly empty) sequence +// of arguments. + // Function template @@ -349,6 +360,13 @@ template } +// -------------------------------------------------------------------------- // +// Streaming concepts [concepts.stream] // +// +// The I/O streaming concepts relate types the std::istream and +// std::ostream streaming facilities. + + // A type is input streamable if it can be extracted from a formatted // input stream derived from std::istream. template @@ -359,6 +377,8 @@ template }; } +// A type is output streamable if it can be extracted from a formatted +// output stream dervied from std::ostream. template concept bool Output_streamable() { @@ -367,6 +387,7 @@ template }; } +// A type is streamable if it is both input and output streamable. template concept bool Streamable() { @@ -377,6 +398,7 @@ template // Miscellaneous associated types namespace core_impl { + template struct get_value_type; @@ -403,6 +425,7 @@ template template using value_type = typename get_value_type>::type; + } // namespace core_impl // Value type @@ -411,6 +434,7 @@ template namespace core_impl { + template struct get_difference_type; @@ -429,6 +453,7 @@ template template using difference_type = typename get_difference_type>::type; + } // namespace core_impl // Difference_type @@ -454,6 +479,7 @@ template template using size_type = typename get_size_type>::type; + } // namespace core_impl // Size_type diff --git a/origin/core/concepts.test/CMakeLists.txt b/origin/core/concepts.test/CMakeLists.txt index 00b70d9..d6aeffb 100644 --- a/origin/core/concepts.test/CMakeLists.txt +++ b/origin/core/concepts.test/CMakeLists.txt @@ -1,5 +1,3 @@ -# Copyright (c) 2008-2013 Andrew Sutton -# # This file is distributed under the MIT License. See the accompanying file # LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms # and conditions. @@ -29,8 +27,6 @@ add_run_test(core_semiregular semiregular.cpp) add_run_test(core_regular regular.cpp) add_run_test(core_ordered ordered.cpp) -add_run_test(core_boolean boolean.cpp) - add_run_test(core_function function.cpp) add_run_test(core_predicate predicate.cpp) add_run_test(core_relation relation.cpp) diff --git a/origin/core/concepts.test/assignable.cpp b/origin/core/concepts.test/assignable.cpp index 6a9f969..629a6a0 100644 --- a/origin/core/concepts.test/assignable.cpp +++ b/origin/core/concepts.test/assignable.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/binary_operation.cpp b/origin/core/concepts.test/binary_operation.cpp index fd5d3cb..ec0512a 100644 --- a/origin/core/concepts.test/binary_operation.cpp +++ b/origin/core/concepts.test/binary_operation.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/boolean.cpp b/origin/core/concepts.test/boolean.cpp deleted file mode 100644 index 473fdc3..0000000 --- a/origin/core/concepts.test/boolean.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// -// This file is distributed under the MIT License. See the accompanying file -// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms -// and conditions. - -#include - -#include - -// Integral types are conditional types -static_assert(origin::Boolean(), ""); -static_assert(origin::Boolean(), ""); -static_assert(origin::Boolean(), ""); -static_assert(origin::Boolean(), ""); -static_assert(origin::Boolean(), ""); -static_assert(origin::Boolean(), ""); - -// Pointers are conditional (except weak_ptr) -static_assert(origin::Boolean(), ""); -static_assert(origin::Boolean>(), ""); -static_assert(origin::Boolean>(), ""); -static_assert(not origin::Boolean>(), ""); - -struct S0 -{ - explicit operator bool() { return true; } -}; - -S0 operator&&(S0, S0) { return S0 {}; } -S0 operator||(S0, S0) { return S0 {}; } -S0 operator!(S0) { return S0 {}; } - -static_assert(not origin::Boolean(), ""); - -int main() { return 0; } diff --git a/origin/core/concepts.test/common.cpp b/origin/core/concepts.test/common.cpp index 6981e0c..fba157f 100644 --- a/origin/core/concepts.test/common.cpp +++ b/origin/core/concepts.test/common.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/common_type.cpp b/origin/core/concepts.test/common_type.cpp index 5d9bfb5..6cc42d7 100644 --- a/origin/core/concepts.test/common_type.cpp +++ b/origin/core/concepts.test/common_type.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/conditional.cpp b/origin/core/concepts.test/conditional.cpp index 5b4e622..49e52be 100644 --- a/origin/core/concepts.test/conditional.cpp +++ b/origin/core/concepts.test/conditional.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/constructible.cpp b/origin/core/concepts.test/constructible.cpp index aea7569..b75aac5 100644 --- a/origin/core/concepts.test/constructible.cpp +++ b/origin/core/concepts.test/constructible.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/convertible.cpp b/origin/core/concepts.test/convertible.cpp index 1b31470..b11c42c 100644 --- a/origin/core/concepts.test/convertible.cpp +++ b/origin/core/concepts.test/convertible.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. @@ -29,6 +27,8 @@ static_assert(origin::Convertible(), ""); static_assert(origin::Convertible(), ""); static_assert(origin::Convertible(), ""); +static_assert(origin::Convertible(), ""); + // TODO: Write more tests. Obviously... int main() { return 0; } diff --git a/origin/core/concepts.test/copy_assignable.cpp b/origin/core/concepts.test/copy_assignable.cpp index f28318d..01baf2f 100644 --- a/origin/core/concepts.test/copy_assignable.cpp +++ b/origin/core/concepts.test/copy_assignable.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/copy_constructible.cpp b/origin/core/concepts.test/copy_constructible.cpp index f28318d..01baf2f 100644 --- a/origin/core/concepts.test/copy_constructible.cpp +++ b/origin/core/concepts.test/copy_constructible.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/copyable.cpp b/origin/core/concepts.test/copyable.cpp index 4b08cc2..eb8c6f2 100644 --- a/origin/core/concepts.test/copyable.cpp +++ b/origin/core/concepts.test/copyable.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/default_constructible.cpp b/origin/core/concepts.test/default_constructible.cpp index 72f928e..ca34950 100644 --- a/origin/core/concepts.test/default_constructible.cpp +++ b/origin/core/concepts.test/default_constructible.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/derived.cpp b/origin/core/concepts.test/derived.cpp index a0060d9..872def2 100644 --- a/origin/core/concepts.test/derived.cpp +++ b/origin/core/concepts.test/derived.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/destructible.cpp b/origin/core/concepts.test/destructible.cpp index d383110..d6d085d 100644 --- a/origin/core/concepts.test/destructible.cpp +++ b/origin/core/concepts.test/destructible.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/difference_type.cpp b/origin/core/concepts.test/difference_type.cpp index 58c18d1..76deda2 100644 --- a/origin/core/concepts.test/difference_type.cpp +++ b/origin/core/concepts.test/difference_type.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/equality_comparable.cpp b/origin/core/concepts.test/equality_comparable.cpp index 0fa9de8..72cc942 100644 --- a/origin/core/concepts.test/equality_comparable.cpp +++ b/origin/core/concepts.test/equality_comparable.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/function.cpp b/origin/core/concepts.test/function.cpp index 17b4ad0..d285798 100644 --- a/origin/core/concepts.test/function.cpp +++ b/origin/core/concepts.test/function.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/movable.cpp b/origin/core/concepts.test/movable.cpp index e2e0e62..06be078 100644 --- a/origin/core/concepts.test/movable.cpp +++ b/origin/core/concepts.test/movable.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/move_assignable.cpp b/origin/core/concepts.test/move_assignable.cpp index f4ca2d7..392b42a 100644 --- a/origin/core/concepts.test/move_assignable.cpp +++ b/origin/core/concepts.test/move_assignable.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/move_constructible.cpp b/origin/core/concepts.test/move_constructible.cpp index eae96d4..9b063a5 100644 --- a/origin/core/concepts.test/move_constructible.cpp +++ b/origin/core/concepts.test/move_constructible.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/ordered.cpp b/origin/core/concepts.test/ordered.cpp index aa0221a..7ab3276 100644 --- a/origin/core/concepts.test/ordered.cpp +++ b/origin/core/concepts.test/ordered.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/predicate.cpp b/origin/core/concepts.test/predicate.cpp index fd5d3cb..ec0512a 100644 --- a/origin/core/concepts.test/predicate.cpp +++ b/origin/core/concepts.test/predicate.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/regular.cpp b/origin/core/concepts.test/regular.cpp index 086c529..3dc2891 100644 --- a/origin/core/concepts.test/regular.cpp +++ b/origin/core/concepts.test/regular.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/relation.cpp b/origin/core/concepts.test/relation.cpp index fd5d3cb..ec0512a 100644 --- a/origin/core/concepts.test/relation.cpp +++ b/origin/core/concepts.test/relation.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/same.cpp b/origin/core/concepts.test/same.cpp index 30ae3d5..a10ee30 100644 --- a/origin/core/concepts.test/same.cpp +++ b/origin/core/concepts.test/same.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/semiregular.cpp b/origin/core/concepts.test/semiregular.cpp index e6267be..b424a45 100644 --- a/origin/core/concepts.test/semiregular.cpp +++ b/origin/core/concepts.test/semiregular.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/totally_ordered.cpp b/origin/core/concepts.test/totally_ordered.cpp index 668b62a..c53d73d 100644 --- a/origin/core/concepts.test/totally_ordered.cpp +++ b/origin/core/concepts.test/totally_ordered.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/unary_operation.cpp b/origin/core/concepts.test/unary_operation.cpp index fd5d3cb..ec0512a 100644 --- a/origin/core/concepts.test/unary_operation.cpp +++ b/origin/core/concepts.test/unary_operation.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/value_type.cpp b/origin/core/concepts.test/value_type.cpp index 5b0c995..1c2b921 100644 --- a/origin/core/concepts.test/value_type.cpp +++ b/origin/core/concepts.test/value_type.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/concepts.test/weakly_ordered.cpp b/origin/core/concepts.test/weakly_ordered.cpp index 75ac099..ee991a8 100644 --- a/origin/core/concepts.test/weakly_ordered.cpp +++ b/origin/core/concepts.test/weakly_ordered.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/function.cpp b/origin/core/function.cpp new file mode 100644 index 0000000..b400798 --- /dev/null +++ b/origin/core/function.cpp @@ -0,0 +1,5 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#include "function.hpp" diff --git a/origin/core/function.hpp b/origin/core/function.hpp index cbf43df..cf10f57 100644 --- a/origin/core/function.hpp +++ b/origin/core/function.hpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2014 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/function.test/CMakeLists.txt b/origin/core/function.test/CMakeLists.txt index 7c5c5aa..5c73d0c 100644 --- a/origin/core/function.test/CMakeLists.txt +++ b/origin/core/function.test/CMakeLists.txt @@ -1,5 +1,3 @@ -# Copyright (c) 2008-2014 Andrew Sutton -# # This file is distributed under the MIT License. See the accompanying file # LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms # and conditions. diff --git a/origin/core/function.test/invoke.cpp b/origin/core/function.test/invoke.cpp index a5c8809..28430de 100644 --- a/origin/core/function.test/invoke.cpp +++ b/origin/core/function.test/invoke.cpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2014 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/core/traits.cpp b/origin/core/traits.cpp new file mode 100644 index 0000000..1fce0f9 --- /dev/null +++ b/origin/core/traits.cpp @@ -0,0 +1,5 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#include "traits.hpp" diff --git a/origin/core/traits.hpp b/origin/core/traits.hpp index cc1fb3d..1e1ee2a 100644 --- a/origin/core/traits.hpp +++ b/origin/core/traits.hpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2013 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. @@ -13,26 +11,30 @@ namespace origin { // Primary type categories -// Is true if an only if T is possibly cv-qualified `void.` +// Returns true if an only if `T` is possibly cv-qualified `void.` template concept bool Void_type() { return std::is_void::value; } -// Is true if an only if T is a possibly cv-qualified integral +// Returns true if an only if `T` is a possibly cv-qualified integral // type. The integral types are: // // * `bool` -// * `char`, `signed char`, `unsigned char`, `wchar_t`, `char16_t`, `char32_t` +// * `char`, `signed char`, `unsigned char` +// * `wchar_t`, `char16_t`, `char32_t` // * `short`, `unsigned short` // * `int`, `unsigned int` // * `long`, `unsigned long` // * `long long`, `unsigned long long` -// * `extended integral types` +// * any extended integral types +// +// Note that the set of extended integral types is implementation +// defined. template concept bool Integral_type() { return std::is_integral::value; } -// Is true if and only if T is a (possibly cv-qualified) floating +// Returns true if and only if T is a (possibly cv-qualified) floating // point type. The floating point types are: // // * `float` @@ -128,18 +130,16 @@ template // both integral and floating point types. template concept bool - Arithmetic_type() - { + Arithmetic_type() { return Integral_type() || Floating_point_type(); } // Is true if and only if T is a fundamental type. The fundamental types are // the built-in types of the programming language and include: -// -// * void -// * nullptr_t -// * arithmetic types -// * cv-qualified variants of those types. +// * void +// * nullptr_t +// * arithmetic types +// * cv-qualified variants of those types. template concept bool Fundamental_type() { return std::is_fundamental::value; } diff --git a/origin/core/type.cpp b/origin/core/type.cpp new file mode 100644 index 0000000..44fb336 --- /dev/null +++ b/origin/core/type.cpp @@ -0,0 +1,5 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#include "type.hpp" diff --git a/origin/core/type.hpp b/origin/core/type.hpp index 184eed9..fb6189d 100644 --- a/origin/core/type.hpp +++ b/origin/core/type.hpp @@ -1,5 +1,3 @@ -// Copyright (c) 2008-2014 Andrew Sutton -// // This file is distributed under the MIT License. See the accompanying file // LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms // and conditions. diff --git a/origin/data/CMakeLists.txt b/origin/data/CMakeLists.txt new file mode 100644 index 0000000..77be963 --- /dev/null +++ b/origin/data/CMakeLists.txt @@ -0,0 +1,9 @@ +# This file is distributed under the MIT License. See the accompanying file +# LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +# and conditions. + +add_library(origin-data + vector.cpp +) + +# FIXME: Add tests. \ No newline at end of file diff --git a/origin/data/vector.cpp b/origin/data/vector.cpp new file mode 100644 index 0000000..9f56996 --- /dev/null +++ b/origin/data/vector.cpp @@ -0,0 +1,5 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#include "vector.hpp" diff --git a/origin/data/vector.hpp b/origin/data/vector.hpp new file mode 100644 index 0000000..c868ef6 --- /dev/null +++ b/origin/data/vector.hpp @@ -0,0 +1,68 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#ifndef ORIGIN_CORE_DATA_HPP +#define ORIGIN_CORE_DATA_HPP + +#include +#include +#include + +namespace origin { + +namespace vector_impl { + +template + struct vector_base { + vector_base(); + vector_base(vector_base&&); + vector_base(const vector_base&) = delete; + vector_base(allocator*); + vector_base(std::size_t); + vector_base(std::size_t, allocator*); + ~vector_base(); + + T* allocate(std::size_t); + void deallocate(T*); + + allocator* alloc; + T* first; + T* last; + T* limit; + }; + +} // namespace vector_impl + + +// A vector is a container that stores a linear arrangement of +// elements. +// +// TODO: Write better documentation. +// +// TODO: Wrap iterators. +template + class vector : vector_impl::vector_base { + vector(); + vector(vector&&); + vector(const vector&) requires Copy_constructible(); + ~vector(); + + vector(allocator*); + + // Observers + std::size_t size() const; + bool is_empty() const; + + // Iterators + T* begin(); + T* end(); + const T* begin() const; + const T* end() const; + }; + +} // namespace origin + +#include + +#endif diff --git a/origin/data/vector.ipp b/origin/data/vector.ipp new file mode 100644 index 0000000..98f522a --- /dev/null +++ b/origin/data/vector.ipp @@ -0,0 +1,98 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +namespace origin { + +namespace vector_impl { + +template + inline + vector_base::vector_base(allocator* a) + : alloc(a), first(), last(), limit() + { } + +template + inline + vector_base::vector_base() + : vector_base(&default_allocator()) + { } + +// TODO: Replace the calls to std::exchange with origin::exchange. +template + inline + vector_base::vector_base(vector_base&& x) + : alloc(default_allocator) + , first(std::exchange(x.first, nullptr)) + , last(std::exchange(x.last, nullptr)) + , limit(std::exchange(x.limit, nullptr)) + { } + +template + inline + vector_base::vector_base(std::size_t n, allocator* a) + : alloc(a), first(allocate(n)), last(first + n), limit(last) + { } + +template + inline + vector_base::vector_base(std::size_t n) + : vector_base(n, &default_allocator()) + { } + +template + inline + vector_base::~vector_base() { + deallocate(first); + } + +template + inline T* + vector_base::allocate(std::size_t n) { return alloc->allocate(n); } + +template + inline void + vector_base::deallocate(T* p) { alloc->deallocate(p); } + +} // namespace vector_impl + + +template + inline + vector::vector() + : vector_impl::vector_base() + { } + +template + inline + vector::vector(const vector& v) requires Copy_constructible() + : vector_impl::vector_base(v.size()) + { uninitialized_copy(v, *this); } + +// Note that T is not required to be Move_constructible. The +// move constructor only exchanges pointers; it does not exchange +// the values of elements. +template + inline + vector::vector(vector&& v) + : vector_impl::vector_base(std::move(v)) + { } + +template + inline T* + vector::begin() { return this->first; } + +template + inline T* + vector::end() { return this->last; } + +template + inline const T* + vector::begin() const { return this->first; } + +template + inline const T* + vector::end() const { return this->last; } + + +} // namespace origin diff --git a/origin/memory/CMakeLists.txt b/origin/memory/CMakeLists.txt new file mode 100644 index 0000000..a392d91 --- /dev/null +++ b/origin/memory/CMakeLists.txt @@ -0,0 +1,5 @@ +# This file is distributed under the MIT License. See the accompanying file +# LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +# and conditions. + +add_library(origin-memory memory.cpp allocator.cpp) diff --git a/origin/memory/allocator.cpp b/origin/memory/allocator.cpp new file mode 100644 index 0000000..07597b1 --- /dev/null +++ b/origin/memory/allocator.cpp @@ -0,0 +1,20 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#include "allocator.hpp" + +namespace origin { + +namespace { + +// The global default allocator. +allocator alloc_; + +} // namespace + +// Returns the default allocator. +allocator& +default_allocator() { return alloc_; } + +} // namespace origin diff --git a/origin/memory/allocator.hpp b/origin/memory/allocator.hpp new file mode 100644 index 0000000..00ef141 --- /dev/null +++ b/origin/memory/allocator.hpp @@ -0,0 +1,36 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#ifndef ORIGIN_MEMORY_ALLOCATOR_HPP +#define ORIGIN_MEMORY_ALLOCATOR_HPP + +#include + +#include + +namespace origin { + +// ---------------------------------------------------------------------------// +// Allocator + +// An allocator is a resource type that is responsible for the acquisition +// and release of memory. It is an abstract base class. +// +// TODO: Write better docs. +// +// TODO: Look at recent allocator specifications to determine what +// sets of operations are actually being required. +struct allocator { + virtual ~allocator(); + virtual void* allocate(int); + virtual void deallocate(void*); +}; + +allocator& default_allocator(); + +} // namespace + +#include + +#endif diff --git a/origin/memory/allocator.ipp b/origin/memory/allocator.ipp new file mode 100644 index 0000000..c20b5f0 --- /dev/null +++ b/origin/memory/allocator.ipp @@ -0,0 +1,19 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +namespace origin { + +// ---------------------------------------------------------------------------// +// Abstract allocator + +inline +allocator::~allocator() { } + +inline void* +allocator::allocate(int n) { return ::operator new(n); } + +inline void +allocator::deallocate(void* p) { ::operator delete(p); } + +} // namespace diff --git a/origin/memory/memory.cpp b/origin/memory/memory.cpp new file mode 100644 index 0000000..8e592a5 --- /dev/null +++ b/origin/memory/memory.cpp @@ -0,0 +1,5 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#include "memory.hpp" diff --git a/origin/memory/memory.hpp b/origin/memory/memory.hpp new file mode 100644 index 0000000..9cdda98 --- /dev/null +++ b/origin/memory/memory.hpp @@ -0,0 +1,34 @@ +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#ifndef ORIGIN_MEMORY_MEMORY_HPP +#define ORIGIN_MEMORY_MEMORY_HPP + +#include + +namespace origin { + +// Construct an object of type `T` at address `p` with the given +// arguments. Note that this does not allocate the memory where the +// object is constructed. +// +// Behavior is undefined if insufficient memory has not been allocated +// for the given object. +template + inline void + construct(T* p, Args&&... args) { + return new(p) T(std::forward(args)...); + } + +// Destroy an object of type `T` at the address `p`. Note that this +// does not release the memory of stored object. +template + inline void + destroy(T* p) { + p->~T(); + } + +} // namespace origin + +#endif diff --git a/origin/numeric/CMakeLists.txt b/origin/numeric/CMakeLists.txt new file mode 100644 index 0000000..b488b07 --- /dev/null +++ b/origin/numeric/CMakeLists.txt @@ -0,0 +1,7 @@ +# This file is distributed under the MIT License. See the accompanying file +# LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +# and conditions. + +add_library(origin-numeric numeric.cpp algebra.cpp) + +add_subdirectory(algebra.test) \ No newline at end of file diff --git a/origin/numeric/algebra.cpp b/origin/numeric/algebra.cpp new file mode 100644 index 0000000..6196753 --- /dev/null +++ b/origin/numeric/algebra.cpp @@ -0,0 +1,2 @@ + +#include "algebra.hpp" \ No newline at end of file diff --git a/origin/numeric/algebra.hpp b/origin/numeric/algebra.hpp new file mode 100644 index 0000000..6b7cfb0 --- /dev/null +++ b/origin/numeric/algebra.hpp @@ -0,0 +1,218 @@ + +#ifndef ORIGIN_NUMERIC_ALGEBRA_HPP +#define ORIGIN_NUMERIC_ALGEBRA_HPP + +#include +#include + +namespace origin { + +// A monoid is a set of values equipped with an associative binary +// operation and some identity element. +template + concept bool Monoid() { + return Binary_operation(); + } + + +// The left fold operation. +template + requires Monoid, Op>() + Value_type + foldl(I first, I last, Op op, const Value_type& e) { + Value_type x = e; + while (first != last) { + x = op(x, *first); + ++first; + } + return x; + } + + +// The right fold operation. +template + requires Monoid, Op>() + Value_type + foldr(I first, I last, Op op) { + using R = std::reverse_iterator; + return foldl(R{last}, R{first}, op); + } + + +// -------------------------------------------------------------------------- // +// Monoid structure [monoid.struct] // + +// The monoid algebraic structure is used to encapsulate operators +// end their identity functions. A number of constructors are provided +// for common abstractions. +template + requires Monoid() + struct monoid { + T id; + Op op; + }; + + +// Left-fold with a monoid structure. +template + inline Value_type + foldl(I first, I last, monoid, Op> const& m) { + return foldl(first, last, m.op, m.id); + } + +// Right-fold with a monoid structure. +template + inline Value_type + foldr(I first, I last, monoid, Op> const& m) { + return foldr(first, last, m.op, m.id); + } + + +// -------------------------------------------------------------------------- // +// Monoid constructors [monoid.ctor] // +// +// The following functions are used to construct instances of +// monoids for different types. +// +// Each of the following constructs a monoid for its corresponding +// operations. +// +// +// Sum() addition +// Product() multiplication +// All() intersection +// Any() union +// +// Note that +// +// Each constructor above also accepts the identity element, when +// there is no direct association of the identity with the +// type (e.g., matrices of dynamic bound). +// +// Sum(e) +// Product(e) +// All(e) +// Any(e) +// +// These functions are capitalized to emphasize the idea that they +// construct unspecified models of a concept. +// +// NOTE: In the following declarations, the defaulted operators +// are not part of the public interface. + +namespace monoid_impl { + +template + struct all_any_traits { + using all_op = std::bit_and; + using any_op = std::bit_or; + static constexpr T all_id = -1; + static constexpr T any_id = 0; + }; + +template<> + struct all_any_traits { + using all_op = std::logical_and; + using any_op = std::logical_or; + static constexpr bool all_id = true; + static constexpr bool any_id = false; + }; + +template + using all_op = typename all_any_traits::all_op; + +template + using any_op = typename all_any_traits::any_op; + +template + static constexpr T all_id() { return all_any_traits::all_id; } + +template + static constexpr T any_id() { return all_any_traits::any_id; } + +} // namespace monoid_impl + +// -------------------------------------------------------------------------- // +// Sum [monoid.sum] // +// +// The Sum constructor defines a monoid (T, +) where T is an +// arithmetic type. + +template> + inline monoid + Sum() { return monoid{T{0}, Op{}}; } + +template> + requires Monoid() + inline monoid + Sum(T const& e) { return monoid{e, Op{}}; } + + +// -------------------------------------------------------------------------- // +// Product [monoid.product] // + +template> + inline monoid + Product() { return monoid{T{1}, Op{}}; } + +template> + requires Monoid() + inline monoid + Product(T const& e) { return monoid{e, Op{}}; } + + +// -------------------------------------------------------------------------- // +// All [monoid.all] // +// +// The All constructor defines the algebraic structure (T, op) where +// op is defined as follows: +// +// - if T has type bool, op is the logical and operator and the +// identity element is true; +// - otherwise, if T is some other integral type, it is the bitwise +// and operator and the identity element is -1. +// +// In general, the semantics of the operator in this monoid can be +// thought of as computing the intersection of sets. When used in +// a fold, the result is a set containing the common elements of +// the operand. +// +// TODO: Can we extend this for set-like data structures? + +template> + inline monoid + All() { return monoid{monoid_impl::all_id(), Op{}}; } + +template + requires Monoid() + inline monoid + All(T const& e) { return monoid{e, Op{}}; } + + +// -------------------------------------------------------------------------- // +// Any [monoid.any] // +// +// The Any constructor defines the algebraic structure (T, op) where +// op is defined as follows: +// +// - if T has type bool, op is the logical or operator and the +// identity element is false; +// - otherwise, if T is some other integral type, it is the bitwise +// or operator and the identity element is 0. +// +// In general, the semantics of the operator in this monoid can be +// thought of as computing the union of sets. + +template> + inline monoid + Any() { return monoid{monoid_impl::any_id(), Op{}}; } + +template + requires Monoid() + inline monoid + Any(T const& e) { return monoid{e, Op{}}; } + + +} // namespace origin + +#endif diff --git a/origin/numeric/algebra.test/CMakeLists.txt b/origin/numeric/algebra.test/CMakeLists.txt new file mode 100644 index 0000000..16291a2 --- /dev/null +++ b/origin/numeric/algebra.test/CMakeLists.txt @@ -0,0 +1,5 @@ +# This file is distributed under the MIT License. See the accompanying file +# LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +# and conditions. + +add_run_test(algebra_foldl foldl.cpp) diff --git a/origin/numeric/algebra.test/foldl.cpp b/origin/numeric/algebra.test/foldl.cpp new file mode 100644 index 0000000..e0b090d --- /dev/null +++ b/origin/numeric/algebra.test/foldl.cpp @@ -0,0 +1,21 @@ + +#include + +#include +#include + +using namespace origin; + +int +main() { + int a[] {1, 2, 3}; + assert(foldl(a, a + 3, std::plus{}, 0) == 6); + assert(foldl(a, a + 3, Sum()) == 6); + assert(foldl(a, a + 3, Product()) == 6); + + + bool b1[] {true, true, true}; + bool b2[] {false, false, true}; + assert(foldl(b1, b1 + 3, All<>()) == true); + assert(foldl(b1, b1 + 3, Any<>()) == true); +} diff --git a/origin/numeric/numeric.cpp b/origin/numeric/numeric.cpp new file mode 100644 index 0000000..95e4e42 --- /dev/null +++ b/origin/numeric/numeric.cpp @@ -0,0 +1,3 @@ + +#include "numeric.hpp" + diff --git a/origin/numeric/numeric.hpp b/origin/numeric/numeric.hpp new file mode 100644 index 0000000..f9c9d64 --- /dev/null +++ b/origin/numeric/numeric.hpp @@ -0,0 +1,35 @@ + +#ifndef ORIGIN_NUMERIC_HPP +#define ORIGIN_NUMERIC_HPP + +// This module defines the entirety of the Origin Numeric library, which +// includes numeric and algebraic concepts and their models. +// +// TODO: There are a lot of interesting things that this library could +// use: an arbitrary precision integer library, a library of statically +// bound fixed-precision integer types (e.g., Boost.Multiprecision), +// dynamically bound fixed-precision integer types, fractions and rational +// numbers, etc. + +#include +#include + +namespace origin { + +// -------------------------------------------------------------------------- // +// Numbers [num] // +// +// A number is a mathematical object that represents some quantity. + + +// The Number concept defines the abstract notion of a number. +// +// FIXME: This does not allow +template + concept bool Number() { return std::is_arithmetic::value; } + + +} // namespace origin + +#endif + diff --git a/origin/sequence/CMakeLists.txt b/origin/sequence/CMakeLists.txt index 338a8e4..5152e16 100644 --- a/origin/sequence/CMakeLists.txt +++ b/origin/sequence/CMakeLists.txt @@ -4,8 +4,15 @@ # LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms # and conditions. +# FIXME: This is simply not a complete algorithm. +add_library(origin-sequence + uninitialized.cpp +) + add_subdirectory(concepts.test) add_subdirectory(range.test) add_subdirectory(algorithm.test) +# TODO: Add tests for uninitialized copy. + # add_subdirectory(stream.test) diff --git a/origin/sequence/algorithm.hpp b/origin/sequence/algorithm.hpp index 43a9f1a..a2bf12b 100644 --- a/origin/sequence/algorithm.hpp +++ b/origin/sequence/algorithm.hpp @@ -651,6 +651,30 @@ template begin(range2), end(range2), comp); } + +// -------------------------------------------------------------------------- // +// Modifying algorithms + +// FIXME: Indirectly copyable is specified in the wrong order. + +template> O> + O copy(I first, I last, O out) { + while (first != last) { + *out = *first; + ++first; + ++out; + } + return out; + } + +template> R2> + Iterator_type + copy(R1&& in, R2&& out) { + using std::begin; + using std::end; + return copy(begin(in), end(in), begin(out)); + } + } // namesapce origin #endif diff --git a/origin/sequence/algorithm.test/CMakeLists.txt b/origin/sequence/algorithm.test/CMakeLists.txt index c241e8e..c027c5c 100644 --- a/origin/sequence/algorithm.test/CMakeLists.txt +++ b/origin/sequence/algorithm.test/CMakeLists.txt @@ -21,3 +21,5 @@ add_run_test(range_algo_count_if count_if.cpp) # add_run_test(range_algo_equal equal.cpp) # add_run_test(range_algo_find_first_of find_first_of.cpp) # add_run_test(range_algo_find_end find_end.cpp) + +add_run_test(seq_algo_copy copy.cpp) diff --git a/origin/sequence/algorithm.test/copy.cpp b/origin/sequence/algorithm.test/copy.cpp new file mode 100644 index 0000000..bd4992f --- /dev/null +++ b/origin/sequence/algorithm.test/copy.cpp @@ -0,0 +1,24 @@ +// Copyright (c) 2008-2013 Andrew Sutton +// +// This file is distributed under the MIT License. See the accompanying file +// LICENSE.txt or http://www.opensource.org/licenses/mit-license.php for terms +// and conditions. + +#include + +#include +#include +#include + +int main() +{ + int a1[3] { 1, 1, 2 }; + + std::vector v1(3); + origin::copy(a1, a1 + 3, v1.begin()); + assert(std::equal(a1, a1 + 3, v1.begin())); + + std::vector v2(3); + origin::copy(a1, v2); + assert(std::equal(a1, a1 + 3, v2.begin())); +} diff --git a/origin/sequence/uninitialized.cpp b/origin/sequence/uninitialized.cpp new file mode 100644 index 0000000..ac16db0 --- /dev/null +++ b/origin/sequence/uninitialized.cpp @@ -0,0 +1,7 @@ +// Copyright (c) 2008-2014 Andrew Sutton +// +// This file is distributed under the MIT License. See +// http://www.opensource.org/licenses/mit-license.php +// for terms and conditions. + +#include "uninitialized.hpp" diff --git a/origin/sequence/uninitialized.hpp b/origin/sequence/uninitialized.hpp new file mode 100644 index 0000000..7d12634 --- /dev/null +++ b/origin/sequence/uninitialized.hpp @@ -0,0 +1,78 @@ +// Copyright (c) 2008-2014 Andrew Sutton +// +// This file is distributed under the MIT License. See +// http://www.opensource.org/licenses/mit-license.php +// for terms and conditions. + +#ifndef ORIGIN_SEQUENCE_UNINITIALIZED_HPP +#define ORIGIN_SEQUENCE_UNINITIALIZED_HPP + +#include +#include + +namespace origin { + +// FIXME: For all of these algorithms the constraints are +// essentially input iterators that point to legitimate objects, +// that is, non-proxy iterators. + + +// Explicitly destroy the objects in the range [first, last). +// +// FIXME: Write constraints. +template + void + destroy(I first, I last) { + destroy(&*first); + } + +// Copy initialize each element in the bounded range [first2, last2) +// from the elements in the range [first1, last1) where last2 is +// first2 + distance(first1, last1). +// +// Before this call, the memory in [first2, last) is uninitialized. +// +// FIXME: Write constraints. +template + I2 + uninitialized_copy(I1 first1, I1 last1, I2 first2) { + I2 iter = first2; + while (first1 != last1) { + try { + construct(&*iter, *first1); + } catch (...) { + destroy(first1, iter); + throw; + } + ++first1; + ++iter; + } + } + + +// Move initialize each element in the range [first2, last2) from the +// elements in the range [first1, last1) where last2 is +// first2 + distance(first1, last1). +// +// Before this call, the memory in [first2, last) is uninitialized. +// +// FIXME: Write constraints. +template + I2 + uninitialized_move(I1 first1, I1 last1, I2 first2) { + I2 iter = first2; + while (first1 != last1) { + try { + construct(&*iter, std::move(*first1)); + } catch (...) { + destroy(first1, iter); + throw; + } + ++first1; + ++iter; + } + } + +} // namespace origin + +#endif