changeset 195:bfac4cfaf5f5 release

Merge with candidate 0.5.0.
author John Schneiderman <JohnMS@member.fsf.org>
date Mon, 01 Mar 2021 16:17:10 +0100
parents a826881ee3b6 (current diff) e25fc2ac9f8c (diff)
children c601191ec1bf
files LICENSE conan/conanfile.py conan/test_package/CMakeLists.txt conan/test_package/conanfile.py conan/test_package/example.cpp src/pecunia/Algorithm.hpp src/pecunia/Codes.cpp src/pecunia/Codes.h src/pecunia/CodesEnum.hpp src/pecunia/Conversion.cpp src/pecunia/Conversion.h src/pecunia/Information.cpp src/pecunia/Information.h src/pecunia/Math.cpp src/pecunia/Math.h src/pecunia/Money.cpp src/pecunia/Money.h src/pecunia/MoneyManip.cpp src/pecunia/MoneyManip.h src/pecunia/MoneyTypes.cpp src/pecunia/MoneyTypes.h src/pecunia/Rounders.cpp src/pecunia/Rounders.h src/pecunia/SetUp.cpp src/pecunia/SetUp.h src/pecunia/internal/Adjustments.cpp src/pecunia/internal/Adjustments.h src/pecunia/internal/Verification.cpp src/pecunia/internal/Verification.h
diffstat 98 files changed, 10005 insertions(+), 5046 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sat Dec 12 15:09:09 2020 +0100
+++ b/.hgignore	Mon Mar 01 16:17:10 2021 +0100
@@ -7,3 +7,4 @@
 .anjuta_sym_db.db
 CMakeLists.txt.user
 *.orig
+src/scripts/__pycache__/*
--- a/.hgtags	Sat Dec 12 15:09:09 2020 +0100
+++ b/.hgtags	Mon Mar 01 16:17:10 2021 +0100
@@ -10,3 +10,19 @@
 1b36dbaadebc12a62bac1df5efd3e085446ad616 0.4.0
 a2c9d9f7a9b86ffde921648eadb67f92e609296f 0.4.1
 278107cbfa859a1168b9ae248e3f39cd08df38a6 0.4.2
+2923b29c497e8102cf73a8b949216d597a54d4f0 0.5.0
+2923b29c497e8102cf73a8b949216d597a54d4f0 0.5.0
+767e4e0db05a7c2513711e7c1b6e0ddaab43e7df 0.5.0
+767e4e0db05a7c2513711e7c1b6e0ddaab43e7df 0.5.0
+741cf3b51fc16d3de8afd85b729cad945ee622e9 0.5.0
+741cf3b51fc16d3de8afd85b729cad945ee622e9 0.5.0
+dbb873bf098640b973fdd9c7bce018d271f29059 0.5.0
+dbb873bf098640b973fdd9c7bce018d271f29059 0.5.0
+d915a24754e606b38e6290995d6c17116c645b55 0.5.0
+ca41dcf0ac295f1c4f843a8c8842271584d7ee91 0.5.5
+ca41dcf0ac295f1c4f843a8c8842271584d7ee91 0.5.5
+0000000000000000000000000000000000000000 0.5.5
+d915a24754e606b38e6290995d6c17116c645b55 0.5.0
+e209330fc79ce3c289f69998a476782092f2038f 0.5.0
+e209330fc79ce3c289f69998a476782092f2038f 0.5.0
+46b88327bdb855800f924bd063d7b86cea1f023f 0.5.0
--- a/CMakeLists.txt	Sat Dec 12 15:09:09 2020 +0100
+++ b/CMakeLists.txt	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 #*******************************************************************************
 #**  This file is part of Pecunia.                                           ***
 #**                                                                          ***
-#**  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 #**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 #**                                                                          ***
 #**  This program is free software: you can redistribute it and/or modify it ***
@@ -17,9 +17,10 @@
 #**  You should have received a copy of the GNU Lesser General Public License***
 #**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
 #*******************************************************************************
-cmake_minimum_required (VERSION 3.0 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
 project(Pecunia
-	VERSION 0.4.2
+	VERSION 0.5.0
+	DESCRIPTION "Library for working with currencies using ISO-4217 standard and a fixed unit size."
 	LANGUAGES CXX
 )
 
@@ -33,7 +34,16 @@
 	conan_basic_setup()
 endif (EXISTS "${CMAKE_BINARY_DIR}/conanbuildinfo.cmake")
 
-option(${PROJECT_NAME}_ENABLE_TESTS "Enables compiling and executing tests." OFF)
+option(${PROJECT_NAME}_BUILD_SHARED_LIBRARY "Enables building as a shared library, else static." ON)
+
+
+if (${PROJECT_NAME}_BUILD_SHARED_LIBRARY)
+	set(${PROJECT_NAME}_LIBRARY_TYPE "SHARED")
+else ()
+	set(${PROJECT_NAME}_LIBRARY_TYPE "STATIC")
+endif (${PROJECT_NAME}_BUILD_SHARED_LIBRARY)
+
+option(${PROJECT_NAME}_ENABLE_TESTS "Enables building and executing tests." OFF)
 
 if (${PROJECT_NAME}_ENABLE_TESTS)
 	include(CTest)
@@ -75,20 +85,33 @@
 	STRING
 	"Sets the extra number of digit precision during floating point operations."
 )
-set(${PROJECT_NAME}_COPYRIGHT_YEARS "\"2016 - 2019\"")
+set(
+	${PROJECT_NAME}_LOCALE
+	"C.UTF-8"
+	CACHE
+	STRING
+	"Sets the default locale used when setting up the library."
+)
+set(${PROJECT_NAME}_COPYRIGHT_YEARS "\"2016 - 2021\"")
 set(
 	${PROJECT_NAME}_DESCRIPTION
 	"A C++ library for working with currencies using the ISO-4217 standard and a fixed unit size."
 )
 set(${PROJECT_NAME}_HOMEPAGE_URL "http://source.schneiderman.me/pecunia/")
 
-set (LIBRARY_INSTALL_DIR lib)
-if (EXISTS "${CMAKE_INSTALL_PREFIX}/lib32/" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
-	set (LIBRARY_INSTALL_DIR lib32)
-elseif (EXISTS "${CMAKE_INSTALL_PREFIX}/lib64/" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
-	set (LIBRARY_INSTALL_DIR lib64)
-endif (EXISTS "${CMAKE_INSTALL_PREFIX}/lib32/" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
-set(LIBRARY_INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/${LIBRARY_INSTALL_DIR}")
+# Allow for packagers to supply the name of the library directory.
+if (DEFINED LIB_INSTALL_DIR)
+	message(STATUS "Using supplied library directory installation path.")
+	set (${PROJECT_NAME}_LIBRARY_INSTALL_DIR ${LIB_INSTALL_DIR})
+else ()
+	if (EXISTS "${CMAKE_INSTALL_PREFIX}/lib32/" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+		set (${PROJECT_NAME}_LIBRARY_INSTALL_DIR lib32)
+	elseif (EXISTS "${CMAKE_INSTALL_PREFIX}/lib64/" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+		set (${PROJECT_NAME}_LIBRARY_INSTALL_DIR lib64)
+	else ()
+		set (${PROJECT_NAME}_LIBRARY_INSTALL_DIR lib)
+	endif (EXISTS "${CMAKE_INSTALL_PREFIX}/lib32/" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+endif (DEFINED LIB_INSTALL_DIR)
 
 if (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)
 	add_compile_options("-Wall")
@@ -103,6 +126,7 @@
 	message(WARNING "Compilations options not set.")
 elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
 	add_compile_options("/fp:strict")
+	add_compile_options("/fp:except")
 	add_compile_options("/W4")
 	add_compile_options("/utf-8")
 	add_compile_options("/WX")
@@ -113,3 +137,7 @@
 endif()
 
 add_subdirectory(src)
+
+set(CPACK_PACKAGE_HOMEPAGE_URL ${${PROJECT_NAME}_HOMEPAGE_URL})
+set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/COPYING)
+include(CPack)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/COPYING	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,165 @@
+                   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CREDITS	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,36 @@
+********************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+********************************************************************************
+This is a listing of the people that have contributed to the project. It is
+sorted by name, and formatted in a format that allows for easy grepping and
+beautification by scripts. The fields are:
+	name (N)
+	E-mail (E)
+	web-site (W)
+	PGP key ID / fingerprint (P)
+	role (R)
+If one of the contributors did not wish to make a field public the text
+NOT_MADE_PUBLIC is used instead.
+This format was modified from: http://www.kernel.org/pub/linux/kernel/CREDITS
+--------------------------------------------------------------------------------
+N: Schneiderman, John
+E: JohnMS_AT_member_DOT_fsf_DOT_org
+W: http://www.schneiderman.me
+P: FDF5 85DC 4AE7 029A / 7055 CDF3 A4F6 88BC C2FC B1BF FDF5 85DC 4AE7 029A
+R: Lead Software Engineer
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ChangeLog	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,89 @@
+#*******************************************************************************
+#**  This file is part of Pecunia.                                           ***
+#**                                                                          ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+#**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+#**                                                                          ***
+#**  This program is free software: you can redistribute it and/or modify it ***
+#**  under the terms of the GNU Lesser General Public License as published   ***
+#**  by the Free Software Foundation, either version 3 of the License, or    ***
+#**  (at your option) any later version.                                     ***
+#**                                                                          ***
+#**  This program is distributed in the hope that it will be useful, but     ***
+#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+#**  See the GNU Lesser General Public License for more details.             ***
+#**                                                                          ***
+#**  You should have received a copy of the GNU Lesser General Public License***
+#**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+#*******************************************************************************
+2021-02-27 John Schneiderman <JohnMS_AT_member_DOT_fsf_DOT_org> 0.5.0
+	* Feature: All currency codes supplied by the ISO.
+	* Feature: The money object swaperator is now noexcept.
+	* Feature: Look-up the country/entity that uses a currency is available.
+	* Feature: Look-up the name of a currency via its code.
+	* Feature: Refactored the API to be clearer about intention.
+	* Bug Fix: Triggering potential undefined behaviour when sorting.
+	* Development: Uses the built-in CMake internal/external source code functionality.
+	* Development: Ability to select building a static or shared library.
+	* Development: Set of scripts to automate the generation of the currency codes.
+	* Development: Individual unit-tests now be debugged via Visual Studio by default.
+	* Development: Made the default locale configurable from within CMake.
+	* Development: Scripts for automating package creation.
+	* Development: Updated all libraries to match the lowest supported target, Debian stable.
+2020-12-07 John Schneiderman <JohnMS_AT_member_DOT_fsf_DOT_org> 0.4.2
+	* Bug Fix: incorrect linkage declaration on Windows.
+2020-12-07 John Schneiderman <JohnMS_AT_member_DOT_fsf_DOT_org> 0.4.1
+	* Bug Fix: Adds taking in the swaperator to make the sort function able to be used by custom
+			types.
+	* Development: The release branch is created.
+2020-12-07 John Schneiderman <JohnMS_AT_member_DOT_fsf_DOT_org> 0.4.0
+	* Feature: packaging for Conan.io support.
+	* Feature: a sorting algorithm to ensure that currencies are not converted while sorting.
+	* Feature: a swap function support for the Money type.
+	* Feature: move support for the Money type.
+	* Bug Fix: normaliseAmount performed more than just the normalisation of the amount and now only
+			returns the normalised amount value.
+2020-06-06 John Schneiderman <JohnMS_AT_member_DOT_fsf_DOT_org> 0.3.0
+	* Feature: Functions taking the money raw types const&.
+	* Bug Fix: implicit conversion from a code to a money type.
+	* Bug Fix: not selecting correct abs function.
+	* Development: Fixed ctest not working on the command line and only in KDevelop.
+	* Development: Made the testing enabling project labeled for better grouping.
+2019-06-27 John Schneiderman <JohnMS_AT_member_DOT_fsf_DOT_org> 0.2.0
+	* Feature: The underlying types are configurable during compilation.
+	* Feature: Adds overload for multiplication and division of integral types.
+	* Feature: The floating point equality function is be based upon the smallest possible
+			comparable valid currency minor unit.
+	* Feature: Renamed "number" member function to "toFloatingPoint" to be clear it's a conversion.
+	* Feature: All floating-point operations use and extra number of guard digits to protect the
+			money object's precision.
+	* Feature: Generate the sum from a container of money objects.
+	* Bug Fix: Multiplication used floating-point values during some operations.
+	* Bug Fix: Division used floating-point values during some operations.
+	* Bug Fix: Rounding could lose precision
+	* Bug Fix: Normalisation could lose precision
+2018-10-20 John Schneiderman <JohnMS_AT_member_DOT_fsf_DOT_org> 0.1.0
+	* Feature: Support for rounding a money's amount value.
+	* Feature: Support for getting the absolute value of a money's amount value.
+	* Feature: Support for to_string functionality.
+	* Feature: Support converting back into a floating-point value.
+	* Feature: Ability to change a money object's currency code, without changing its amount value.
+	* Feature: Division support between two money objects.
+	* Feature: Container of all supported currency codes.
+	* Feature: Ability to get the maximum and minimum values a monetary type can support.
+	* Feature: An initialisation function to give the library in a known state.
+	* Feature: Functions for getting the library configuration information.
+	* Bug fix: Issue with multiple references of convert function.
+	* Bug fix: Issue with the relational operators silently failing when the currency codes did not
+			match.
+	* Development: Fixed packaging issues.
+	* Development: Specify requiring C++14.
+	* Development: Default compile with warnings as errors for the project.
+	* Development: Uses the built-in CMake package config generators.
+	* Development: Uses the built-in CMake export mechanism.
+	* Development: Selected the final name for the library.
+	* Development: Removed the template based money object type.
+2017-01-09 John Schneiderman <JohnMS_AT_member_DOT_fsf_DOT_org> 0.0.0
+	* Feature: Basic money type (templated & non-templated) with arithmetic operations & verification.
+	* Development: Ability to link against using CMake.
--- a/INSTALL	Sat Dec 12 15:09:09 2020 +0100
+++ b/INSTALL	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 ********************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -21,21 +21,24 @@
 Needed for compiling
 ====================
 0) C++ Compiler
-   - Version: Any supporting ISO C++14
-   - Source: Any, http://gcc.gnu.org/
+	- Version: Any supporting ISO C++14
+	- Source: Any, http://gcc.gnu.org/
 
 1) CMake
-   - Version: 3.0+
-   - Source: http://www.cmake.org
+	- Version: 3.13+
+	- Source: http://www.cmake.org
 
-2) QT
-   - Only needed when developing unit tests for the library, the option is disable by default.
-   - Version: 5.4+
-   - Source: http://www.qt.io/
+2) Qt (Optional)
+	- Only needed when developing unit tests for the library.
+	- Version: 5.11+
+	- Source: http://www.qt.io/
+
+3) Conan (Optional)
+	- Mercurial on the path.
 
 Build Options
 =============
-0) To enable the unit tests, set the CMake option Pecunia_ENABLE_UNIT_TESTS to ON.
+0) Optionally to enable the unit tests, set the CMake option Pecunia_ENABLE_TESTS to ON.
 
 How-To compile the program
 ==========================
@@ -45,4 +48,5 @@
 
 Known Issues
 ============
-0) None.
+0) Stream insertion operator does not clean up afterwards.
+1) Stream extraction operator does not clean up afterwards.
--- a/LICENSE	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-                   GNU LESSER GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
-  This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
-  0. Additional Definitions.
-
-  As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
-  "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
-  An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
-  A "Combined Work" is a work produced by combining or linking an
-Application with the Library.  The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
-  The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
-  The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
-  1. Exception to Section 3 of the GNU GPL.
-
-  You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
-  2. Conveying Modified Versions.
-
-  If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
-   a) under this License, provided that you make a good faith effort to
-   ensure that, in the event an Application does not supply the
-   function or data, the facility still operates, and performs
-   whatever part of its purpose remains meaningful, or
-
-   b) under the GNU GPL, with none of the additional permissions of
-   this License applicable to that copy.
-
-  3. Object Code Incorporating Material from Library Header Files.
-
-  The object code form of an Application may incorporate material from
-a header file that is part of the Library.  You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
-   a) Give prominent notice with each copy of the object code that the
-   Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the object code with a copy of the GNU GPL and this license
-   document.
-
-  4. Combined Works.
-
-  You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
-   a) Give prominent notice with each copy of the Combined Work that
-   the Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the Combined Work with a copy of the GNU GPL and this license
-   document.
-
-   c) For a Combined Work that displays copyright notices during
-   execution, include the copyright notice for the Library among
-   these notices, as well as a reference directing the user to the
-   copies of the GNU GPL and this license document.
-
-   d) Do one of the following:
-
-       0) Convey the Minimal Corresponding Source under the terms of this
-       License, and the Corresponding Application Code in a form
-       suitable for, and under terms that permit, the user to
-       recombine or relink the Application with a modified version of
-       the Linked Version to produce a modified Combined Work, in the
-       manner specified by section 6 of the GNU GPL for conveying
-       Corresponding Source.
-
-       1) Use a suitable shared library mechanism for linking with the
-       Library.  A suitable mechanism is one that (a) uses at run time
-       a copy of the Library already present on the user's computer
-       system, and (b) will operate properly with a modified version
-       of the Library that is interface-compatible with the Linked
-       Version.
-
-   e) Provide Installation Information, but only if you would otherwise
-   be required to provide such information under section 6 of the
-   GNU GPL, and only to the extent that such information is
-   necessary to install and execute a modified version of the
-   Combined Work produced by recombining or relinking the
-   Application with a modified version of the Linked Version. (If
-   you use option 4d0, the Installation Information must accompany
-   the Minimal Corresponding Source and Corresponding Application
-   Code. If you use option 4d1, you must provide the Installation
-   Information in the manner specified by section 6 of the GNU GPL
-   for conveying Corresponding Source.)
-
-  5. Combined Libraries.
-
-  You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
-   a) Accompany the combined library with a copy of the same work based
-   on the Library, uncombined with any other library facilities,
-   conveyed under the terms of this License.
-
-   b) Give prominent notice with the combined library that part of it
-   is a work based on the Library, and explaining where to find the
-   accompanying uncombined form of the same work.
-
-  6. Revised Versions of the GNU Lesser General Public License.
-
-  The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
-  Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
-  If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
--- a/conan/conanfile.py	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-#*******************************************************************************
-#**  This file is part of Pecunia.                                           ***
-#**                                                                          ***
-#**  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-#**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-#**                                                                          ***
-#**  This program is free software: you can redistribute it and/or modify it ***
-#**  under the terms of the GNU Lesser General Public License as published   ***
-#**  by the Free Software Foundation, either version 3 of the License, or    ***
-#**  (at your option) any later version.                                     ***
-#**                                                                          ***
-#**  This program is distributed in the hope that it will be useful, but     ***
-#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-#**  See the GNU Lesser General Public License for more details.             ***
-#**                                                                          ***
-#**  You should have received a copy of the GNU Lesser General Public License***
-#**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-#*******************************************************************************
-from conans import ConanFile, CMake, tools
-
-
-class PecuniaConan(ConanFile):
-	name = "pecunia"
-	version = "0.4.0.0"
-	license = "LGPLv3"
-	author = "John Schneiderman <Licencing _AT_ Schneiderman _DOT_ me>"
-	url = "https://source.schneiderman.me/pecunia/"
-	description = "A C++ library for working with currencies using the ISO-4217 standard and a fixed unit size."
-#    topics = ("<Put some tag here>", "<here>", "<and here>")
-	settings = "os", "compiler", "build_type", "arch"
-#    options = {"shared": [True, False]}
-#    default_options = {"shared": False}
-	generators = "cmake"
-
-	def source(self):
-		self.run("hg clone {}".format(PecuniaConan.url))
-
-
-	def build(self):
-		cmake = CMake(self)
-		cmake.configure(source_folder="pecunia")
-		cmake.build()
-
-	def package(self):
-		cmake = CMake(self)
-		cmake.install()
-
-	def package_info(self):
-		self.cpp_info.includedirs = ["include/pecunia"]
-		self.cpp_info.libs = ["pecunia"]
--- a/conan/test_package/CMakeLists.txt	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#*******************************************************************************
-#**  This file is part of Pecunia.                                           ***
-#**                                                                          ***
-#**  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-#**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-#**                                                                          ***
-#**  This program is free software: you can redistribute it and/or modify it ***
-#**  under the terms of the GNU Lesser General Public License as published   ***
-#**  by the Free Software Foundation, either version 3 of the License, or    ***
-#**  (at your option) any later version.                                     ***
-#**                                                                          ***
-#**  This program is distributed in the hope that it will be useful, but     ***
-#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-#**  See the GNU Lesser General Public License for more details.             ***
-#**                                                                          ***
-#**  You should have received a copy of the GNU Lesser General Public License***
-#**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-#*******************************************************************************
-cmake_minimum_required(VERSION 3.0)
-project(PackageTest CXX)
-
-include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
-conan_basic_setup()
-
-find_package(pecunia REQUIRED)
-
-add_executable(example example.cpp)
-target_link_libraries(example pecunia)
--- a/conan/test_package/conanfile.py	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#*******************************************************************************
-#**  This file is part of Pecunia.                                           ***
-#**                                                                          ***
-#**  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-#**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-#**                                                                          ***
-#**  This program is free software: you can redistribute it and/or modify it ***
-#**  under the terms of the GNU Lesser General Public License as published   ***
-#**  by the Free Software Foundation, either version 3 of the License, or    ***
-#**  (at your option) any later version.                                     ***
-#**                                                                          ***
-#**  This program is distributed in the hope that it will be useful, but     ***
-#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-#**  See the GNU Lesser General Public License for more details.             ***
-#**                                                                          ***
-#**  You should have received a copy of the GNU Lesser General Public License***
-#**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-#*******************************************************************************
-import os
-
-from conans import ConanFile, CMake, tools
-
-
-class PecuniaTestConan(ConanFile):
-    settings = "os", "compiler", "build_type", "arch"
-    generators = "cmake"
-
-    def build(self):
-        cmake = CMake(self)
-        # Current dir is "test_package/build/<build_id>" and CMakeLists.txt is
-        # in "test_package"
-        cmake.configure()
-        cmake.build()
-
-    def imports(self):
-        self.copy("*.dll", dst="bin", src="bin")
-        self.copy("*.dylib*", dst="bin", src="lib")
-        self.copy('*.so*', dst='bin', src='lib')
-
-    def test(self):
-        if not tools.cross_building(self):
-            os.chdir("bin")
-            self.run(".%sexample" % os.sep)
--- a/conan/test_package/example.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include <iostream>
-using std::cout;
-using std::endl;
-
-#include <pecunia/Information.h>
-using pecunia::version;
-
-int main()
-{
-	cout << "Successfully packaged the version: " << version() << endl;
-	return 0;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/buildDeb.sh	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,136 @@
+#*******************************************************************************
+#**  This file is part of Pecunia.                                           ***
+#**                                                                          ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+#**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+#**                                                                          ***
+#**  This program is free software: you can redistribute it and/or modify it ***
+#**  under the terms of the GNU Lesser General Public License as published   ***
+#**  by the Free Software Foundation, either version 3 of the License, or    ***
+#**  (at your option) any later version.                                     ***
+#**                                                                          ***
+#**  This program is distributed in the hope that it will be useful, but     ***
+#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+#**  See the GNU Lesser General Public License for more details.             ***
+#**                                                                          ***
+#**  You should have received a copy of the GNU Lesser General Public License***
+#**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+#*******************************************************************************
+
+#!/usr/bin/env bash
+shopt -s -o nounset  # Don't allow the use of variables that haven't been declared
+shopt -s -o pipefail  # This option sets the exit code of a pipeline to that of the rightmost
+					  # command to exit with a non-zero status, or zero if all commands of the
+					  # pipeline exit successfully.
+shopt -s -o errexit  # Exit when a command fails
+shopt -s extglob  # Allow the use of the extra pattern
+
+# Program Variables
+#___________________________________________________________________________________________________
+declare -r scriptName=${0##*/}
+declare -r path="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
+declare -r options="hk:v:"
+declare optionResult=""
+declare -r projectName="pecunia"
+declare version=""
+declare keyId=""
+declare -r debBuildDirectoryPath="$HOME/debbuild"
+declare tarballFileName=""
+declare tarballOrigFileName=""
+# licence in copyright file (apache|artistic|bsd|gpl|gpl2|gpl3|isc|lgpl|lgpl2|lgpl3|mit|custom)
+declare -r licence="lgpl3"
+# single, indep (arch-independent), library, python
+declare -r packageclass="library"
+
+# Program Argument Validation
+#___________________________________________________________________________________________________
+while getopts "${options}" optionResult
+do
+    case ${optionResult} in
+    h)  # Show help
+        printf "usage: ${scriptName} [options]\n"
+        printf "Options:\n"
+        printf "  -k <id>         Sets the ID of the sign key.\n"
+        printf "  -v <version>    Sets the version to package.\n"
+        exit 0
+        ;;
+    k)  # Set Key Sign ID
+		keyId="$OPTARG"
+        ;;
+    v)  # Set Package Version
+		version="$OPTARG"
+        ;;
+    \?)
+        exit 2
+        ;;
+    *)
+        exit 2
+        ;;
+    esac
+done
+
+if [[ -z "${keyId}" ]]
+then
+	echo "The ID for the signing key must be specified."
+	exit 1
+fi
+
+if [[ -z "${version}" ]]
+then
+	echo "The version of ${projectName} must be specified."
+	exit 1
+fi
+
+
+# Program Execution
+#___________________________________________________________________________________________________
+tarballFileName="${projectName}-${version}.tar"
+tarballOrigFileName="${projectName}_${version}.orig.tar.xz"
+cd "$path/.."
+
+echo "Generating project tarball..."
+hg archive "${tarballFileName}" -r "${version}" || exit $?
+
+if [[ ! -e "${debBuildDirectoryPath}/" ]]
+then
+	mkdir "${debBuildDirectoryPath}/" || exit $?
+fi
+mv "${tarballFileName}" "${debBuildDirectoryPath}/" || exit $?
+
+echo "Generating Debian file structure..."
+cd "${debBuildDirectoryPath}" || exit $?
+tar -xf "${tarballFileName}" || exit $?
+cd "${projectName}-${version}/" || exit $?
+
+if [[ -e "${debBuildDirectoryPath}/${projectName}-${version}/pkg/debian" ]]
+then
+	mv "${debBuildDirectoryPath}/${projectName}-${version}/pkg/debian" . || exit $?
+	xz "../${tarballFileName}" || exit $?
+	mv "../${tarballFileName}.xz" "../${tarballOrigFileName}" || exit $?
+else
+	dh_make \
+		--yes  \
+		--copyright ${licence}  \
+		--${packageclass}  \
+		--createorig  \
+		|| exit $?
+fi
+
+echo "Building DEB package..."
+dpkg-buildpackage -us -uc || exit $?
+
+echo "Signing DEB package..."
+debsign -k${keyId} || exit $?
+
+echo "Cleaning up temporary build files..."
+cd .. || exit $?
+rm --recursive --dir "${projectName}-${version}/" || exit $?
+
+if [[ -e "${tarballFileName}" ]]
+then
+	rm "${tarballFileName}" || exit $?
+fi
+
+echo "Successfully created DEB package."
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/buildRpm.sh	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,94 @@
+#*******************************************************************************
+#**  This file is part of Pecunia.                                           ***
+#**                                                                          ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+#**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+#**                                                                          ***
+#**  This program is free software: you can redistribute it and/or modify it ***
+#**  under the terms of the GNU Lesser General Public License as published   ***
+#**  by the Free Software Foundation, either version 3 of the License, or    ***
+#**  (at your option) any later version.                                     ***
+#**                                                                          ***
+#**  This program is distributed in the hope that it will be useful, but     ***
+#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+#**  See the GNU Lesser General Public License for more details.             ***
+#**                                                                          ***
+#**  You should have received a copy of the GNU Lesser General Public License***
+#**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+#*******************************************************************************
+
+#!/usr/bin/env bash
+shopt -s -o nounset  # Don't allow the use of variables that haven't been declared
+shopt -s -o pipefail  # This option sets the exit code of a pipeline to that of the rightmost
+					  # command to exit with a non-zero status, or zero if all commands of the
+					  # pipeline exit successfully.
+shopt -s -o errexit  # Exit when a command fails
+shopt -s extglob  # Allow the use of the extra pattern
+
+# Program Variables
+#___________________________________________________________________________________________________
+declare -r scriptName=${0##*/}
+declare -r path=$(dirname $0)
+declare -r options="hv:"
+declare optionResult=""
+declare -r projectName="pecunia"
+declare version=""
+declare -r rpmBuildDirectoryPath="$HOME/rpmbuild"
+declare -r rpmSpecDirectoryPath="${rpmBuildDirectoryPath}/SPECS"
+declare tarballFileName=""
+declare -r specFileName="${projectName}.spec"
+
+# Program Argument Validation
+#___________________________________________________________________________________________________
+while getopts "${options}" optionResult
+do
+    case ${optionResult} in
+    h)  # Show help
+        printf "usage: ${scriptName} [options]\n"
+        printf "Options:\n"
+        printf "  -v <version>    Sets the version to package.\n"
+        exit 0
+        ;;
+    v)  # Set Package Version
+		version="$OPTARG"
+        ;;
+    \?)
+        exit 2
+        ;;
+    *)
+        exit 2
+        ;;
+    esac
+done
+
+if [[ -z "${version}" ]]
+then
+	echo "The version of ${projectName} must be specified."
+	exit 1
+fi
+
+# Program Execution
+#___________________________________________________________________________________________________
+tarballFileName="${projectName}-${version}.tar.gz"
+pushd "$path/.."
+
+echo "Generating project tarball..."
+hg archive "${tarballFileName}" -r "${version}" || exit $?
+mv "${tarballFileName}" "${rpmBuildDirectoryPath}/SOURCES" || exit $?
+
+echo "Copying SPEC file..."
+cp "pkg/${specFileName}" "${rpmSpecDirectoryPath}" || exit $?
+
+echo "Building RPM package..."
+rpmbuild -ba --clean --rmsource --rmspec "${rpmSpecDirectoryPath}/${specFileName}" || exit $?
+
+echo "Signing RPM package..."
+rpm --addsign  \
+	"${rpmBuildDirectoryPath}/RPMS/noarch/"${projectName}*-${version}-*.rpm  \
+	"${rpmBuildDirectoryPath}/RPMS/x86_64/"${projectName}*-${version}-*.rpm  \
+	"${rpmBuildDirectoryPath}/SRPMS/"${projectName}*-${version}-*.rpm  \
+	|| exit $?
+
+echo "Successfully created RPM package."
+popd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/conan/conanfile.py	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,51 @@
+#*******************************************************************************
+#**  This file is part of Pecunia.                                           ***
+#**                                                                          ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+#**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+#**                                                                          ***
+#**  This program is free software: you can redistribute it and/or modify it ***
+#**  under the terms of the GNU Lesser General Public License as published   ***
+#**  by the Free Software Foundation, either version 3 of the License, or    ***
+#**  (at your option) any later version.                                     ***
+#**                                                                          ***
+#**  This program is distributed in the hope that it will be useful, but     ***
+#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+#**  See the GNU Lesser General Public License for more details.             ***
+#**                                                                          ***
+#**  You should have received a copy of the GNU Lesser General Public License***
+#**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+#*******************************************************************************
+from conans import ConanFile, CMake, tools
+
+
+class PecuniaConan(ConanFile):
+	name = "pecunia"
+	version = "0.5.0"
+	license = "LGPLv3"
+	author = "John Schneiderman <Licencing _AT_ Schneiderman _DOT_ me>"
+	url = "https://source.schneiderman.me/pecunia/"
+	description = "A C++ library for working with currencies using the ISO-4217 standard and a fixed unit size."
+	#topics = ("<Put some tag here>", "<here>", "<and here>")
+	settings = "os", "compiler", "build_type", "arch"
+	#options = {"shared": [True, False]}
+	#default_options = {"shared": True}
+	generators = "cmake"
+
+
+	def source(self):
+		self.run("hg clone {url} -r {version_tag}".format(url=PecuniaConan.url, version_tag=PecuniaConan.version))
+
+	def build(self):
+		cmake = CMake(self)
+		cmake.configure(source_folder="pecunia")
+		cmake.build()
+
+	def package(self):
+		cmake = CMake(self)
+		cmake.install()
+
+	def package_info(self):
+		self.cpp_info.includedirs = ["include/pecunia"]
+		self.cpp_info.libs = ["pecunia"]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/conan/test_package/CMakeLists.txt	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,29 @@
+#*******************************************************************************
+#**  This file is part of Pecunia.                                           ***
+#**                                                                          ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+#**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+#**                                                                          ***
+#**  This program is free software: you can redistribute it and/or modify it ***
+#**  under the terms of the GNU Lesser General Public License as published   ***
+#**  by the Free Software Foundation, either version 3 of the License, or    ***
+#**  (at your option) any later version.                                     ***
+#**                                                                          ***
+#**  This program is distributed in the hope that it will be useful, but     ***
+#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+#**  See the GNU Lesser General Public License for more details.             ***
+#**                                                                          ***
+#**  You should have received a copy of the GNU Lesser General Public License***
+#**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+#*******************************************************************************
+cmake_minimum_required(VERSION 3.0)
+project(PackageTest CXX)
+
+include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+conan_basic_setup()
+
+find_package(pecunia REQUIRED)
+
+add_executable(example example.cpp)
+target_link_libraries(example pecunia)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/conan/test_package/conanfile.py	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,44 @@
+#*******************************************************************************
+#**  This file is part of Pecunia.                                           ***
+#**                                                                          ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+#**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+#**                                                                          ***
+#**  This program is free software: you can redistribute it and/or modify it ***
+#**  under the terms of the GNU Lesser General Public License as published   ***
+#**  by the Free Software Foundation, either version 3 of the License, or    ***
+#**  (at your option) any later version.                                     ***
+#**                                                                          ***
+#**  This program is distributed in the hope that it will be useful, but     ***
+#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+#**  See the GNU Lesser General Public License for more details.             ***
+#**                                                                          ***
+#**  You should have received a copy of the GNU Lesser General Public License***
+#**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+#*******************************************************************************
+import os
+
+from conans import ConanFile, CMake, tools
+
+
+class PecuniaTestConan(ConanFile):
+    settings = "os", "compiler", "build_type", "arch"
+    generators = "cmake"
+
+    def build(self):
+        cmake = CMake(self)
+        # Current dir is "test_package/build/<build_id>" and CMakeLists.txt is
+        # in "test_package"
+        cmake.configure()
+        cmake.build()
+
+    def imports(self):
+        self.copy("*.dll", dst="bin", src="bin")
+        self.copy("*.dylib*", dst="bin", src="lib")
+        self.copy('*.so*', dst='bin', src='lib')
+
+    def test(self):
+        if not tools.cross_building(self):
+            os.chdir("bin")
+            self.run(".%sexample" % os.sep)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/conan/test_package/example.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,32 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include <iostream>
+using std::cout;
+using std::endl;
+
+#include <pecunia/Information.h>
+using pecunia::version;
+
+
+int main()
+{
+	cout << "Successfully packaged the version: " << version() << endl;
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/changelog	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,5 @@
+pecunia (0.5.0-1) unstable; urgency=medium
+
+  * Initial release
+
+ -- John Schneiderman <JohnMS@member.fsf.org>  Sat, 27 FEb 2021 12:06:00 +0100
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/compat	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,1 @@
+11
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/control	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,26 @@
+Source: pecunia
+Priority: optional
+Maintainer: John Schneiderman <JohnMS@member.fsf.org>
+Build-Depends: debhelper (>= 11)
+Standards-Version: 4.1.3
+Section: libs
+Homepage: http://www.schneiderman.me/projects/pecunia
+Vcs-Browser: https://source.schneiderman.me/pecunia
+#Vcs-Git: https://salsa.debian.org/debian/pecunia.git
+
+Package: pecunia-dev
+Section: libdevel
+Architecture: any
+Multi-Arch: same
+Depends: pecunia (= ${binary:Version}), ${misc:Depends}
+Description: Provides the headers needed for development.
+
+Package: pecunia
+Architecture: any
+Multi-Arch: same
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: A C++ library for working with currencies using
+ the ISO-4217 standard. The monetary representation is in a
+ fixed size and the operations between difference currencies
+ is seamlessly supported.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/copyright	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,34 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: pecunia
+Source: https://source.schneiderman.me/pecunia
+
+Files: *
+Copyright: 2021 John Schneiderman <JohnMS@member.fsf.org>
+
+License: LGPL-3.0+
+
+Files: debian/*
+Copyright: 2021 John Schneiderman <JohnMS@member.fsf.org>
+License: LGPL-3.0+
+
+License: LGPL-3.0+
+ This package is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+ .
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ .
+ On Debian systems, the complete text of the GNU Lesser General
+ Public License can be found in "/usr/share/common-licenses/LGPL-3".
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
+# Please avoid picking licenses with terms that are more restrictive than the
+# packaged work, as it may make Debian's contributions unacceptable upstream.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/pecunia-dev.dirs	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,2 @@
+usr/lib
+usr/include
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/pecunia-dev.install	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,2 @@
+usr/include/*
+usr/lib/cmake/*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/pecunia.dirs	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,1 @@
+usr/lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/pecunia.install	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,1 @@
+usr/lib/lib*.so.*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/rules	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,25 @@
+#!/usr/bin/make -f
+# See debhelper(7) (uncomment to enable)
+# output every command that modifies files on the build system.
+#export DH_VERBOSE = 1
+
+
+# see FEATURE AREAS in dpkg-buildflags(1)
+#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+# see ENVIRONMENT in dpkg-buildflags(1)
+# package maintainers to append CFLAGS
+#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
+# package maintainers to append LDFLAGS
+#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
+
+
+%:
+	dh $@
+
+
+# dh_make generated override targets
+# This is example for Cmake (See https://bugs.debian.org/641051 )
+#override_dh_auto_configure:
+#	dh_auto_configure -- #	-DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/shlibs.local	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,1 @@
+libpecunia 0.5.0 pecunia (>> 0.5.0-0), pecunia (<< 0.5.0-99)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/debian/source/format	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,1 @@
+3.0 (quilt)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/pecunia.spec	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,100 @@
+#*******************************************************************************
+#**  This file is part of Pecunia.                                           ***
+#**                                                                          ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+#**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+#**                                                                          ***
+#**  This program is free software: you can redistribute it and/or modify it ***
+#**  under the terms of the GNU Lesser General Public License as published   ***
+#**  by the Free Software Foundation, either version 3 of the License, or    ***
+#**  (at your option) any later version.                                     ***
+#**                                                                          ***
+#**  This program is distributed in the hope that it will be useful, but     ***
+#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+#**  See the GNU Lesser General Public License for more details.             ***
+#**                                                                          ***
+#**  You should have received a copy of the GNU Lesser General Public License***
+#**  along with this program. If not, see <http:/www.gnu.org/licenses/>.    ***
+#*******************************************************************************
+
+%define so_number	0
+
+Name:			pecunia
+Version:		0.5.0
+Release:		1%distsuffix%dist
+Summary:		C++ ISO-4217 Currency Library
+Source0:		https:/packaging.schneiderman.me/binaries/%{name}-%{version}.tar.gz
+URL:			http:/www.schneiderman.me/projects/%{name}
+
+Group:			Development/C++
+License:		LGPLv3+
+
+
+%description
+A C++ library for working with currencies using the ISO-4217 standard.
+The monetary representation is in a fixed size and the operations
+between difference currencies is seamlessly supported.
+
+
+%package devel
+Summary: Development headers
+Requires: %{name}
+BuildArch: noarch
+%description devel
+Provides the headers needed for development.
+
+%prep
+%setup -q -a 0
+
+%build
+%cmake \
+	-DLIB_INSTALL_DIR=%{_libdir}
+if [ -d %_build ]
+then
+	cd %_build
+fi
+%make_build
+
+%install
+if [ -d build ]
+then
+	cd build
+elif [ -d %_build ]
+then
+	cd %_build
+fi
+%make_install
+
+%files
+%doc ChangeLog CREDITS
+%{_libdir}/libpecunia.so
+%{_libdir}/libpecunia.so.%{version}
+%{_libdir}/libpecunia.so.%{so_number}
+
+###
+### Devel
+###
+%files devel
+%{_includedir}/pecunia/Algorithm.hpp
+%{_includedir}/pecunia/Codes.h
+%{_includedir}/pecunia/Conversion.h
+%{_includedir}/pecunia/Information.h
+%{_includedir}/pecunia/Math.h
+%{_includedir}/pecunia/Money.h
+%{_includedir}/pecunia/MoneyManip.h
+%{_includedir}/pecunia/MoneySize.hpp
+%{_includedir}/pecunia/MoneyTypes.h
+%{_includedir}/pecunia/Rounders.h
+%{_includedir}/pecunia/SetUp.h
+%{_includedir}/pecunia/pecunia_export.h
+%{_libdir}/cmake/pecunia/pecuniaConfig.cmake
+%{_libdir}/cmake/pecunia/pecuniaTargets-*.cmake
+%{_libdir}/cmake/pecunia/pecuniaTargets.cmake
+%{_libdir}/cmake/pecunia/pecuniaVersion.cmake
+
+
+%changelog
+* Sat Feb 27 2021 John Schneiderman <JohnMS@member.fsf.org> 0.5.0-1jms
+- Initial packaging.
+
--- a/src/CMakeLists.txt	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/CMakeLists.txt	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 #*******************************************************************************
 #**  This file is part of Pecunia.                                           ***
 #**                                                                          ***
-#**  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 #**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 #**                                                                          ***
 #**  This program is free software: you can redistribute it and/or modify it ***
@@ -17,66 +17,77 @@
 #**  You should have received a copy of the GNU Lesser General Public License***
 #**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
 #*******************************************************************************
-cmake_minimum_required (VERSION 3.0 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
 project(
 	pecunia
+	DESCRIPTION ${Pecunia_DESCRIPTION}
 	VERSION ${Pecunia_VERSION}
+	LANGUAGES CXX
 )
 
 configure_file(
 	"${CMAKE_CURRENT_SOURCE_DIR}/config.hpp.in"
-	"${PROJECT_BINARY_DIR}/${PROJECT_NAME}/internal/config.hpp"
+	"${PROJECT_BINARY_DIR}/internal/config.hpp"
 )
 configure_file(
 	"${CMAKE_CURRENT_SOURCE_DIR}/MoneySize.hpp.in"
-	"${PROJECT_BINARY_DIR}/${PROJECT_NAME}/MoneySize.hpp"
+	"${PROJECT_BINARY_DIR}/external/${PROJECT_NAME}/MoneySize.hpp"
 )
-include_directories(${PROJECT_BINARY_DIR})
 
 set(${PROJECT_NAME}_PUBLIC_DECLARATIONS
-	${PROJECT_NAME}/Algorithm.hpp
-	${PROJECT_NAME}/Codes.h
-	${PROJECT_NAME}/CodesEnum.hpp
-	${PROJECT_NAME}/Conversion.h
-	${PROJECT_NAME}/Math.h
-	${PROJECT_NAME}/Money.h
-	${PROJECT_NAME}/MoneyManip.h
-	${PROJECT_NAME}/MoneyTypes.h
-	${PROJECT_NAME}/Rounders.h
-	${PROJECT_NAME}/Information.h
-	${PROJECT_NAME}/SetUp.h
-)
-set(${PROJECT_NAME}_PRIVATE_DECLARATIONS
-	${PROJECT_NAME}/internal/Adjustments.h
-	${PROJECT_NAME}/internal/Verification.h
+	external/${PROJECT_NAME}/Algorithm.hpp
+	external/${PROJECT_NAME}/Codes.h
+	external/${PROJECT_NAME}/Conversion.h
+	"${PROJECT_BINARY_DIR}/${PROJECT_NAME}_export.h"
+	external/${PROJECT_NAME}/Math.h
+	external/${PROJECT_NAME}/Money.h
+	external/${PROJECT_NAME}/MoneyManip.h
+	"${PROJECT_BINARY_DIR}/external/${PROJECT_NAME}/MoneySize.hpp"
+	external/${PROJECT_NAME}/MoneyTypes.h
+	external/${PROJECT_NAME}/Rounders.h
+	external/${PROJECT_NAME}/Information.h
+	external/${PROJECT_NAME}/SetUp.h
 )
 set(${PROJECT_NAME}_PUBLIC_DEFINITIONS
-	${PROJECT_NAME}/Algorithm.hpp
-	${PROJECT_NAME}/Codes.cpp
-	${PROJECT_NAME}/CodesEnum.hpp
-	${PROJECT_NAME}/Conversion.cpp
-	${PROJECT_NAME}/Information.cpp
-	${PROJECT_NAME}/Math.cpp
-	${PROJECT_NAME}/Money.cpp
-	${PROJECT_NAME}/MoneyManip.cpp
-	${PROJECT_NAME}/MoneyTypes.cpp
-	${PROJECT_NAME}/Rounders.cpp
-	${PROJECT_NAME}/SetUp.cpp
+	external/${PROJECT_NAME}/Algorithm.hpp
+	external/${PROJECT_NAME}/Codes.cpp
+	external/${PROJECT_NAME}/Conversion.cpp
+	"${PROJECT_BINARY_DIR}/${PROJECT_NAME}_export.h"
+	external/${PROJECT_NAME}/Information.cpp
+	external/${PROJECT_NAME}/Math.cpp
+	external/${PROJECT_NAME}/Money.cpp
+	external/${PROJECT_NAME}/MoneyManip.cpp
+	"${PROJECT_BINARY_DIR}/external/${PROJECT_NAME}/MoneySize.hpp"
+	external/${PROJECT_NAME}/MoneyTypes.cpp
+	external/${PROJECT_NAME}/Rounders.cpp
+	external/${PROJECT_NAME}/SetUp.cpp
+)
+set(${PROJECT_NAME}_PRIVATE_DECLARATIONS
+	internal/Adjustments.h
+	internal/config.hpp
+	internal/Verification.h
 )
 set(${PROJECT_NAME}_PRIVATE_DEFINITIONS
-	${PROJECT_NAME}/internal/Adjustments.cpp
-	${PROJECT_NAME}/internal/Verification.cpp
+	internal/Adjustments.cpp
+	internal/config.hpp
+	internal/Verification.cpp
 )
 
-include(GenerateExportHeader)
-
 add_library(${PROJECT_NAME}
-	SHARED
+	${Pecunia_LIBRARY_TYPE}
 	${${PROJECT_NAME}_PUBLIC_DEFINITIONS}
 	${${PROJECT_NAME}_PRIVATE_DEFINITIONS}
+	${${PROJECT_NAME}_PUBLIC_DECLARATIONS}
+	${${PROJECT_NAME}_PRIVATE_DECLARATIONS}
 )
-
-generate_export_header(${PROJECT_NAME})
+target_include_directories(${PROJECT_NAME}
+	PUBLIC
+		$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external>
+	PRIVATE
+		$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+		$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
+		$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/external/${PROJECT_NAME}>
+)
 
 set_target_properties(${PROJECT_NAME} PROPERTIES
 	VERSION ${PROJECT_VERSION}
@@ -86,6 +97,9 @@
 )
 set_property(TARGET ${PROJECT_NAME} PROPERTY INTERFACE_${PROJECT_NAME}_MAJOR_VERSION ${PROJECT_VERSION_MAJOR})
 
+include(GenerateExportHeader)
+generate_export_header(${PROJECT_NAME})
+
 if (Pecunia_ENABLE_TESTS)
 	add_subdirectory(unit-tests)
 endif (Pecunia_ENABLE_TESTS)
@@ -93,52 +107,46 @@
 install(
 	TARGETS ${PROJECT_NAME}
 	EXPORT ${PROJECT_NAME}Targets
-	RUNTIME DESTINATION bin COMPONENT bin
-	LIBRARY DESTINATION ${LIBRARY_INSTALL_DIR} COMPONENT shlib
-	ARCHIVE DESTINATION ${LIBRARY_INSTALL_DIR} COMPONENT lib
-	PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}" COMPONENT Devel
-	PRIVATE_HEADER DESTINATION "${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}/internal" COMPONENT Devel
+	RUNTIME DESTINATION bin
+	LIBRARY DESTINATION ${Pecunia_LIBRARY_INSTALL_DIR}
+	ARCHIVE DESTINATION ${Pecunia_LIBRARY_INSTALL_DIR}
+	INCLUDES DESTINATION include
 )
 install(
-	FILES
-		${${PROJECT_NAME}_PUBLIC_DECLARATIONS}
-		"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_export.h"
-		"${PROJECT_BINARY_DIR}/${PROJECT_NAME}/MoneySize.hpp"
-	DESTINATION "${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}"
-	COMPONENT Devel
+	FILES ${${PROJECT_NAME}_PUBLIC_DECLARATIONS}
+	DESTINATION include/${PROJECT_NAME}
 )
 if (WIN32)
 	install(
 		FILES $<TARGET_PDB_FILE:${PROJECT_NAME}>
 		DESTINATION bin
-		OPTIONAL
 	)
 endif(WIN32)
 
 include(CMakePackageConfigHelpers)
 write_basic_package_version_file(
-  "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}ConfigVersion.cmake"
-  VERSION ${PROJECT_VERSION}
-  COMPATIBILITY AnyNewerVersion
+	${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Version.cmake
+	VERSION ${PROJECT_VERSION}
+	COMPATIBILITY SameMajorVersion
 )
 export(EXPORT ${PROJECT_NAME}Targets
-  FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Targets.cmake"
+	FILE ${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Targets.cmake
 )
 configure_file(
-	"${PROJECT_NAME}Config.cmake.in"
-	"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Config.cmake" @ONLY
+	${PROJECT_NAME}Config.cmake.in
+	"${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake"
+	@ONLY
 )
 install(
 	EXPORT ${PROJECT_NAME}Targets
 	FILE ${PROJECT_NAME}Targets.cmake
-	DESTINATION ${LIBRARY_INSTALL_DIR}/cmake/${PROJECT_NAME}
+	DESTINATION ${Pecunia_LIBRARY_INSTALL_DIR}/cmake/${PROJECT_NAME}
 )
 install(
 	FILES
-		"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Config.cmake"
-		"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}ConfigVersion.cmake"
-	DESTINATION ${LIBRARY_INSTALL_DIR}/cmake/${PROJECT_NAME}
-	COMPONENT Devel
+		${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake
+		${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Version.cmake
+	DESTINATION ${Pecunia_LIBRARY_INSTALL_DIR}/cmake/${PROJECT_NAME}
 )
 
 if(NOT TARGET uninstall)
@@ -153,3 +161,9 @@
 		COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
 	)
 endif()
+
+set(CPACK_PACKAGE_VENDOR "John M. Schneiderman")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${Pecunia_DESCRIPTION})
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "Pecunia")
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
+include(CPack)
--- a/src/MoneySize.hpp.in	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/MoneySize.hpp.in	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 /*******************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -28,13 +28,11 @@
 namespace internal
 {
 
-/// @brief The number of extra digits to use when performing floating point operations.
+/// The number of extra digits to use when performing floating point operations.
 constexpr uint8_t extraFloatingPointPrecision{@Pecunia_FLOATING_POINT_PRECISION@};
 
 }
 
-/// @brief The number of extra digits to use when performing mathematical operations.
-constexpr std::uint8_t precision{@Pecunia_PRECISION@};
 /// @brief The type used when working with the currency minor unit.
 using MinorUnit = @Pecunia_MINOR_UNIT_TYPE@;
 /// @brief The type used when working with the currency major unit and the minor and major unit
@@ -42,6 +40,10 @@
 using UnitStorage = @Pecunia_UNIT_STORAGE_TYPE@;
 /// @brief The type used for all floating point operations.
 using FloatingPoint = @Pecunia_FLOATING_POINT_TYPE@;
+/// The number of extra digits to use when performing mathematical operations.
+constexpr std::uint8_t precision{@Pecunia_PRECISION@};
+/// The default locale used within the library.
+constexpr const char* defaultLocale{"@Pecunia_LOCALE@"};
 
 }
 
--- a/src/cmake_uninstall.cmake.in	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/cmake_uninstall.cmake.in	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 #*******************************************************************************
 #**  This file is part of Pecunia.                                           ***
 #**                                                                          ***
-#**  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 #**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 #**                                                                          ***
 #**  This program is free software: you can redistribute it and/or modify it ***
--- a/src/config.hpp.in	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/config.hpp.in	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 /*******************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -17,8 +17,8 @@
 ***  You should have received a copy of the GNU Lesser General Public License***
 ***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
 *******************************************************************************/
-#ifndef PECUNIA_CURRENCY_INTERNAL_CONFIG_HPP_
-#define PECUNIA_CURRENCY_INTERNAL_CONFIG_HPP_
+#ifndef PECUNIA_INTERNAL_CONFIG_HPP_
+#define PECUNIA_INTERNAL_CONFIG_HPP_
 
 #define @PROJECT_NAME@_VERSION_MAJOR @Pecunia_VERSION_MAJOR@
 #define @PROJECT_NAME@_VERSION_MINOR @Pecunia_VERSION_MINOR@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Algorithm.hpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,145 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_ALGORITHM_HPP_
+#define PECUNIA_ALGORITHM_HPP_
+
+#include <functional>
+#include <type_traits>
+
+#include "Money.h"
+
+
+namespace pecunia
+{
+
+/**
+ * @brief Sorts the container using a less-than comparison operator. The sort is not stable.
+ *
+ * @tparam ContainerType The type of container holding the monetary values to sort. The container
+ * must have random access iterator support. The contained type must support the operators
+ * less-than, greater-than, and have a swap function.
+ *
+ * @param container The container holding the monetary values to sort.
+ * @param swaperator A function that will swap the contained values using no monetary conversion in
+ * the process.
+ */
+template<typename ContainerType>
+void sort(
+	ContainerType& container,
+	const std::function<
+		void(typename ContainerType::value_type&, typename ContainerType::value_type&)
+	>& swaperator = pecunia::currency::swap
+);
+
+namespace internal
+{
+
+template<typename RandomIteratorType, typename ContainerValueType>
+void quicksort(
+	RandomIteratorType low,
+	RandomIteratorType high,
+	const std::function<void(ContainerValueType&, ContainerValueType&)>& swaperator,
+	const bool isLowBegin
+);
+template<typename RandomIteratorType, typename ContainerValueType>
+RandomIteratorType partition(
+	RandomIteratorType low,
+	RandomIteratorType high,
+	const std::function<void(ContainerValueType&, ContainerValueType&)>& swaperator,
+	const bool isLowBegin
+);
+
+}}
+
+template<typename ContainerType>
+void pecunia::sort(
+	ContainerType& container,
+	const std::function<
+		void(typename ContainerType::value_type&, typename ContainerType::value_type&)
+	>& swaperator
+)
+{
+	const auto size{container.size()};
+
+	if (size > 2)
+		internal::quicksort(container.begin(), std::prev(container.end()), swaperator, true);
+	else if (size == 2)
+	{
+		auto lhs{container.begin()};
+		auto rhs(std::next(lhs));
+
+		if (*rhs < *lhs)
+			swaperator(*lhs, *rhs);
+	}
+
+}
+
+template<typename RandomIteratorType, typename ContainerValueType>
+void pecunia::internal::quicksort(
+	RandomIteratorType low,
+	RandomIteratorType high,
+	const std::function<void(ContainerValueType&, ContainerValueType&)>& swaperator,
+	const bool isLowBegin
+)
+{
+	if (low < high)
+	{
+		const auto pivot{partition(low, high, swaperator, isLowBegin)};
+		quicksort(low, pivot, swaperator, isLowBegin);
+		quicksort(std::next(pivot), high, swaperator, false);
+	}
+}
+
+template<typename RandomIteratorType, typename ContainerValueType>
+RandomIteratorType pecunia::internal::partition(
+	RandomIteratorType low,
+	RandomIteratorType high,
+	const std::function<void(ContainerValueType&, ContainerValueType&)>& swaperator,
+	const bool isLowBegin
+)
+{
+	const auto pivotValue{*std::next(low, std::distance(low, high) / 2)};
+	// N.B. Cannot use the previous iterator if it's the begining of the container.
+	auto lowIndex{isLowBegin ? low : std::prev(low)};
+	auto highIndex{std::next(high)};
+	bool handledLowBegin{ ! isLowBegin};
+
+	do
+	{
+		do
+			// Only advance when the we are not at the begining since it's not been evaluated yet.
+			if (handledLowBegin)
+				std::advance(lowIndex, 1);
+			else
+				handledLowBegin = true;
+		while (*lowIndex < pivotValue);
+
+		do
+			std::advance(highIndex, -1);
+		while (*highIndex > pivotValue);
+
+		if (lowIndex >= highIndex)
+			return highIndex;
+		swaperator(*lowIndex, *highIndex);
+	}
+	while (true);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Codes.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,3190 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+
+//  ██████╗  ██████╗     ███╗   ██╗ ██████╗ ████████╗    ███████╗██████╗ ██╗████████╗██╗
+//  ██╔══██╗██╔═══██╗    ████╗  ██║██╔═══██╗╚══██╔══╝    ██╔════╝██╔══██╗██║╚══██╔══╝██║
+//  ██║  ██║██║   ██║    ██╔██╗ ██║██║   ██║   ██║       █████╗  ██║  ██║██║   ██║   ██║
+//  ██║  ██║██║   ██║    ██║╚██╗██║██║   ██║   ██║       ██╔══╝  ██║  ██║██║   ██║   ╚═╝
+//  ██████╔╝╚██████╔╝    ██║ ╚████║╚██████╔╝   ██║       ███████╗██████╔╝██║   ██║   ██╗
+//  ╚═════╝  ╚═════╝     ╚═╝  ╚═══╝ ╚═════╝    ╚═╝       ╚══════╝╚═════╝ ╚═╝   ╚═╝   ╚═╝
+//
+//  ███████╗██╗██╗     ███████╗     ██████╗ ██████╗ ███╗   ██╗████████╗███████╗███╗   ██╗████████╗
+//  ██╔════╝██║██║     ██╔════╝    ██╔════╝██╔═══██╗████╗  ██║╚══██╔══╝██╔════╝████╗  ██║╚══██╔══╝
+//  █████╗  ██║██║     █████╗      ██║     ██║   ██║██╔██╗ ██║   ██║   █████╗  ██╔██╗ ██║   ██║
+//  ██╔══╝  ██║██║     ██╔══╝      ██║     ██║   ██║██║╚██╗██║   ██║   ██╔══╝  ██║╚██╗██║   ██║
+//  ██║     ██║███████╗███████╗    ╚██████╗╚██████╔╝██║ ╚████║   ██║   ███████╗██║ ╚████║   ██║
+//  ╚═╝     ╚═╝╚══════╝╚══════╝     ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝   ╚═╝   ╚══════╝╚═╝  ╚═══╝   ╚═╝
+//
+//   ██████╗██████╗ ███████╗ █████╗ ████████╗██╗ ██████╗ ███╗   ██╗    ██╗███████╗
+//  ██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗  ██║    ██║██╔════╝
+//  ██║     ██████╔╝█████╗  ███████║   ██║   ██║██║   ██║██╔██╗ ██║    ██║███████╗
+//  ██║     ██╔══██╗██╔══╝  ██╔══██║   ██║   ██║██║   ██║██║╚██╗██║    ██║╚════██║
+//  ╚██████╗██║  ██║███████╗██║  ██║   ██║   ██║╚██████╔╝██║ ╚████║    ██║███████║
+//   ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝    ╚═╝╚══════╝
+//
+//   █████╗ ██╗   ██╗████████╗ ██████╗ ███╗   ███╗ █████╗ ████████╗███████╗██████╗
+//  ██╔══██╗██║   ██║╚══██╔══╝██╔═══██╗████╗ ████║██╔══██╗╚══██╔══╝██╔════╝██╔══██╗
+//  ███████║██║   ██║   ██║   ██║   ██║██╔████╔██║███████║   ██║   █████╗  ██║  ██║
+//  ██╔══██║██║   ██║   ██║   ██║   ██║██║╚██╔╝██║██╔══██║   ██║   ██╔══╝  ██║  ██║
+//  ██║  ██║╚██████╔╝   ██║   ╚██████╔╝██║ ╚═╝ ██║██║  ██║   ██║   ███████╗██████╔╝██╗
+//  ╚═╝  ╚═╝ ╚═════╝    ╚═╝    ╚═════╝ ╚═╝     ╚═╝╚═╝  ╚═╝   ╚═╝   ╚══════╝╚═════╝ ╚═╝
+// Generated At: 2021-01-19T16:37:57.856699
+
+#include "Codes.h"
+using namespace std::string_literals;
+using std::array;
+using std::ostream;
+using std::string;
+using std::to_string;
+using std::vector;
+using pecunia::currency::Iso4217Codes;
+using pecunia::currency::numberOfIso4217Codes;
+
+#include <cassert>
+// Used for assert.
+#include <cmath>
+using std::pow;
+#include <map>
+using std::map;
+#include <stdexcept>
+using std::runtime_error;
+
+#include "MoneyTypes.h"
+using pecunia::precision;
+
+
+string pecunia::currency::toStdString(const Iso4217Codes& code)
+{
+	switch (code)
+	{
+	case Iso4217Codes::AED:
+		return "AED";
+	case Iso4217Codes::AFN:
+		return "AFN";
+	case Iso4217Codes::ALL:
+		return "ALL";
+	case Iso4217Codes::AMD:
+		return "AMD";
+	case Iso4217Codes::ANG:
+		return "ANG";
+	case Iso4217Codes::AOA:
+		return "AOA";
+	case Iso4217Codes::ARS:
+		return "ARS";
+	case Iso4217Codes::AUD:
+		return "AUD";
+	case Iso4217Codes::AWG:
+		return "AWG";
+	case Iso4217Codes::AZN:
+		return "AZN";
+	case Iso4217Codes::BAM:
+		return "BAM";
+	case Iso4217Codes::BBD:
+		return "BBD";
+	case Iso4217Codes::BDT:
+		return "BDT";
+	case Iso4217Codes::BGN:
+		return "BGN";
+	case Iso4217Codes::BHD:
+		return "BHD";
+	case Iso4217Codes::BIF:
+		return "BIF";
+	case Iso4217Codes::BMD:
+		return "BMD";
+	case Iso4217Codes::BND:
+		return "BND";
+	case Iso4217Codes::BOB:
+		return "BOB";
+	case Iso4217Codes::BOV:
+		return "BOV";
+	case Iso4217Codes::BRL:
+		return "BRL";
+	case Iso4217Codes::BSD:
+		return "BSD";
+	case Iso4217Codes::BTN:
+		return "BTN";
+	case Iso4217Codes::BWP:
+		return "BWP";
+	case Iso4217Codes::BYN:
+		return "BYN";
+	case Iso4217Codes::BZD:
+		return "BZD";
+	case Iso4217Codes::CAD:
+		return "CAD";
+	case Iso4217Codes::CDF:
+		return "CDF";
+	case Iso4217Codes::CHE:
+		return "CHE";
+	case Iso4217Codes::CHF:
+		return "CHF";
+	case Iso4217Codes::CHW:
+		return "CHW";
+	case Iso4217Codes::CLF:
+		return "CLF";
+	case Iso4217Codes::CLP:
+		return "CLP";
+	case Iso4217Codes::CNY:
+		return "CNY";
+	case Iso4217Codes::COP:
+		return "COP";
+	case Iso4217Codes::COU:
+		return "COU";
+	case Iso4217Codes::CRC:
+		return "CRC";
+	case Iso4217Codes::CUC:
+		return "CUC";
+	case Iso4217Codes::CUP:
+		return "CUP";
+	case Iso4217Codes::CVE:
+		return "CVE";
+	case Iso4217Codes::CZK:
+		return "CZK";
+	case Iso4217Codes::DJF:
+		return "DJF";
+	case Iso4217Codes::DKK:
+		return "DKK";
+	case Iso4217Codes::DOP:
+		return "DOP";
+	case Iso4217Codes::DZD:
+		return "DZD";
+	case Iso4217Codes::EGP:
+		return "EGP";
+	case Iso4217Codes::ERN:
+		return "ERN";
+	case Iso4217Codes::ETB:
+		return "ETB";
+	case Iso4217Codes::EUR:
+		return "EUR";
+	case Iso4217Codes::FJD:
+		return "FJD";
+	case Iso4217Codes::FKP:
+		return "FKP";
+	case Iso4217Codes::GBP:
+		return "GBP";
+	case Iso4217Codes::GEL:
+		return "GEL";
+	case Iso4217Codes::GHS:
+		return "GHS";
+	case Iso4217Codes::GIP:
+		return "GIP";
+	case Iso4217Codes::GMD:
+		return "GMD";
+	case Iso4217Codes::GNF:
+		return "GNF";
+	case Iso4217Codes::GTQ:
+		return "GTQ";
+	case Iso4217Codes::GYD:
+		return "GYD";
+	case Iso4217Codes::HKD:
+		return "HKD";
+	case Iso4217Codes::HNL:
+		return "HNL";
+	case Iso4217Codes::HRK:
+		return "HRK";
+	case Iso4217Codes::HTG:
+		return "HTG";
+	case Iso4217Codes::HUF:
+		return "HUF";
+	case Iso4217Codes::IDR:
+		return "IDR";
+	case Iso4217Codes::ILS:
+		return "ILS";
+	case Iso4217Codes::INR:
+		return "INR";
+	case Iso4217Codes::IQD:
+		return "IQD";
+	case Iso4217Codes::IRR:
+		return "IRR";
+	case Iso4217Codes::ISK:
+		return "ISK";
+	case Iso4217Codes::JMD:
+		return "JMD";
+	case Iso4217Codes::JOD:
+		return "JOD";
+	case Iso4217Codes::JPY:
+		return "JPY";
+	case Iso4217Codes::KES:
+		return "KES";
+	case Iso4217Codes::KGS:
+		return "KGS";
+	case Iso4217Codes::KHR:
+		return "KHR";
+	case Iso4217Codes::KMF:
+		return "KMF";
+	case Iso4217Codes::KPW:
+		return "KPW";
+	case Iso4217Codes::KRW:
+		return "KRW";
+	case Iso4217Codes::KWD:
+		return "KWD";
+	case Iso4217Codes::KYD:
+		return "KYD";
+	case Iso4217Codes::KZT:
+		return "KZT";
+	case Iso4217Codes::LAK:
+		return "LAK";
+	case Iso4217Codes::LBP:
+		return "LBP";
+	case Iso4217Codes::LKR:
+		return "LKR";
+	case Iso4217Codes::LRD:
+		return "LRD";
+	case Iso4217Codes::LSL:
+		return "LSL";
+	case Iso4217Codes::LYD:
+		return "LYD";
+	case Iso4217Codes::MAD:
+		return "MAD";
+	case Iso4217Codes::MDL:
+		return "MDL";
+	case Iso4217Codes::MGA:
+		return "MGA";
+	case Iso4217Codes::MKD:
+		return "MKD";
+	case Iso4217Codes::MMK:
+		return "MMK";
+	case Iso4217Codes::MNT:
+		return "MNT";
+	case Iso4217Codes::MOP:
+		return "MOP";
+	case Iso4217Codes::MRU:
+		return "MRU";
+	case Iso4217Codes::MUR:
+		return "MUR";
+	case Iso4217Codes::MVR:
+		return "MVR";
+	case Iso4217Codes::MWK:
+		return "MWK";
+	case Iso4217Codes::MXN:
+		return "MXN";
+	case Iso4217Codes::MXV:
+		return "MXV";
+	case Iso4217Codes::MYR:
+		return "MYR";
+	case Iso4217Codes::MZN:
+		return "MZN";
+	case Iso4217Codes::NAD:
+		return "NAD";
+	case Iso4217Codes::NGN:
+		return "NGN";
+	case Iso4217Codes::NIO:
+		return "NIO";
+	case Iso4217Codes::NOK:
+		return "NOK";
+	case Iso4217Codes::NPR:
+		return "NPR";
+	case Iso4217Codes::NZD:
+		return "NZD";
+	case Iso4217Codes::OMR:
+		return "OMR";
+	case Iso4217Codes::PAB:
+		return "PAB";
+	case Iso4217Codes::PEN:
+		return "PEN";
+	case Iso4217Codes::PGK:
+		return "PGK";
+	case Iso4217Codes::PHP:
+		return "PHP";
+	case Iso4217Codes::PKR:
+		return "PKR";
+	case Iso4217Codes::PLN:
+		return "PLN";
+	case Iso4217Codes::PYG:
+		return "PYG";
+	case Iso4217Codes::QAR:
+		return "QAR";
+	case Iso4217Codes::RON:
+		return "RON";
+	case Iso4217Codes::RSD:
+		return "RSD";
+	case Iso4217Codes::RUB:
+		return "RUB";
+	case Iso4217Codes::RWF:
+		return "RWF";
+	case Iso4217Codes::SAR:
+		return "SAR";
+	case Iso4217Codes::SBD:
+		return "SBD";
+	case Iso4217Codes::SCR:
+		return "SCR";
+	case Iso4217Codes::SDG:
+		return "SDG";
+	case Iso4217Codes::SEK:
+		return "SEK";
+	case Iso4217Codes::SGD:
+		return "SGD";
+	case Iso4217Codes::SHP:
+		return "SHP";
+	case Iso4217Codes::SLL:
+		return "SLL";
+	case Iso4217Codes::SOS:
+		return "SOS";
+	case Iso4217Codes::SRD:
+		return "SRD";
+	case Iso4217Codes::SSP:
+		return "SSP";
+	case Iso4217Codes::STN:
+		return "STN";
+	case Iso4217Codes::SVC:
+		return "SVC";
+	case Iso4217Codes::SYP:
+		return "SYP";
+	case Iso4217Codes::SZL:
+		return "SZL";
+	case Iso4217Codes::THB:
+		return "THB";
+	case Iso4217Codes::TJS:
+		return "TJS";
+	case Iso4217Codes::TMT:
+		return "TMT";
+	case Iso4217Codes::TND:
+		return "TND";
+	case Iso4217Codes::TOP:
+		return "TOP";
+	case Iso4217Codes::TRY:
+		return "TRY";
+	case Iso4217Codes::TTD:
+		return "TTD";
+	case Iso4217Codes::TWD:
+		return "TWD";
+	case Iso4217Codes::TZS:
+		return "TZS";
+	case Iso4217Codes::UAH:
+		return "UAH";
+	case Iso4217Codes::UGX:
+		return "UGX";
+	case Iso4217Codes::USD:
+		return "USD";
+	case Iso4217Codes::USN:
+		return "USN";
+	case Iso4217Codes::UYI:
+		return "UYI";
+	case Iso4217Codes::UYU:
+		return "UYU";
+	case Iso4217Codes::UYW:
+		return "UYW";
+	case Iso4217Codes::UZS:
+		return "UZS";
+	case Iso4217Codes::VES:
+		return "VES";
+	case Iso4217Codes::VND:
+		return "VND";
+	case Iso4217Codes::VUV:
+		return "VUV";
+	case Iso4217Codes::WST:
+		return "WST";
+	case Iso4217Codes::XAF:
+		return "XAF";
+	case Iso4217Codes::XAG:
+		return "XAG";
+	case Iso4217Codes::XAU:
+		return "XAU";
+	case Iso4217Codes::XBA:
+		return "XBA";
+	case Iso4217Codes::XBB:
+		return "XBB";
+	case Iso4217Codes::XBC:
+		return "XBC";
+	case Iso4217Codes::XBD:
+		return "XBD";
+	case Iso4217Codes::XCD:
+		return "XCD";
+	case Iso4217Codes::XDR:
+		return "XDR";
+	case Iso4217Codes::XOF:
+		return "XOF";
+	case Iso4217Codes::XPD:
+		return "XPD";
+	case Iso4217Codes::XPF:
+		return "XPF";
+	case Iso4217Codes::XPT:
+		return "XPT";
+	case Iso4217Codes::XSU:
+		return "XSU";
+	case Iso4217Codes::XTS:
+		return "XTS";
+	case Iso4217Codes::XUA:
+		return "XUA";
+	case Iso4217Codes::XXX:
+		return "XXX";
+	case Iso4217Codes::YER:
+		return "YER";
+	case Iso4217Codes::ZAR:
+		return "ZAR";
+	case Iso4217Codes::ZMW:
+		return "ZMW";
+	case Iso4217Codes::ZWL:
+		return "ZWL";
+	default:
+		assert(false && "Unhandled currency code for conversion to an ISO-4217 string.");
+		return "";
+	};
+}
+
+Iso4217Codes pecunia::currency::toIso4217Code(const string& code)
+{
+	if ("AED" == code)
+		return Iso4217Codes::AED;
+
+	if ("AFN" == code)
+		return Iso4217Codes::AFN;
+
+	if ("ALL" == code)
+		return Iso4217Codes::ALL;
+
+	if ("AMD" == code)
+		return Iso4217Codes::AMD;
+
+	if ("ANG" == code)
+		return Iso4217Codes::ANG;
+
+	if ("AOA" == code)
+		return Iso4217Codes::AOA;
+
+	if ("ARS" == code)
+		return Iso4217Codes::ARS;
+
+	if ("AUD" == code)
+		return Iso4217Codes::AUD;
+
+	if ("AWG" == code)
+		return Iso4217Codes::AWG;
+
+	if ("AZN" == code)
+		return Iso4217Codes::AZN;
+
+	if ("BAM" == code)
+		return Iso4217Codes::BAM;
+
+	if ("BBD" == code)
+		return Iso4217Codes::BBD;
+
+	if ("BDT" == code)
+		return Iso4217Codes::BDT;
+
+	if ("BGN" == code)
+		return Iso4217Codes::BGN;
+
+	if ("BHD" == code)
+		return Iso4217Codes::BHD;
+
+	if ("BIF" == code)
+		return Iso4217Codes::BIF;
+
+	if ("BMD" == code)
+		return Iso4217Codes::BMD;
+
+	if ("BND" == code)
+		return Iso4217Codes::BND;
+
+	if ("BOB" == code)
+		return Iso4217Codes::BOB;
+
+	if ("BOV" == code)
+		return Iso4217Codes::BOV;
+
+	if ("BRL" == code)
+		return Iso4217Codes::BRL;
+
+	if ("BSD" == code)
+		return Iso4217Codes::BSD;
+
+	if ("BTN" == code)
+		return Iso4217Codes::BTN;
+
+	if ("BWP" == code)
+		return Iso4217Codes::BWP;
+
+	if ("BYN" == code)
+		return Iso4217Codes::BYN;
+
+	if ("BZD" == code)
+		return Iso4217Codes::BZD;
+
+	if ("CAD" == code)
+		return Iso4217Codes::CAD;
+
+	if ("CDF" == code)
+		return Iso4217Codes::CDF;
+
+	if ("CHE" == code)
+		return Iso4217Codes::CHE;
+
+	if ("CHF" == code)
+		return Iso4217Codes::CHF;
+
+	if ("CHW" == code)
+		return Iso4217Codes::CHW;
+
+	if ("CLF" == code)
+		return Iso4217Codes::CLF;
+
+	if ("CLP" == code)
+		return Iso4217Codes::CLP;
+
+	if ("CNY" == code)
+		return Iso4217Codes::CNY;
+
+	if ("COP" == code)
+		return Iso4217Codes::COP;
+
+	if ("COU" == code)
+		return Iso4217Codes::COU;
+
+	if ("CRC" == code)
+		return Iso4217Codes::CRC;
+
+	if ("CUC" == code)
+		return Iso4217Codes::CUC;
+
+	if ("CUP" == code)
+		return Iso4217Codes::CUP;
+
+	if ("CVE" == code)
+		return Iso4217Codes::CVE;
+
+	if ("CZK" == code)
+		return Iso4217Codes::CZK;
+
+	if ("DJF" == code)
+		return Iso4217Codes::DJF;
+
+	if ("DKK" == code)
+		return Iso4217Codes::DKK;
+
+	if ("DOP" == code)
+		return Iso4217Codes::DOP;
+
+	if ("DZD" == code)
+		return Iso4217Codes::DZD;
+
+	if ("EGP" == code)
+		return Iso4217Codes::EGP;
+
+	if ("ERN" == code)
+		return Iso4217Codes::ERN;
+
+	if ("ETB" == code)
+		return Iso4217Codes::ETB;
+
+	if ("EUR" == code)
+		return Iso4217Codes::EUR;
+
+	if ("FJD" == code)
+		return Iso4217Codes::FJD;
+
+	if ("FKP" == code)
+		return Iso4217Codes::FKP;
+
+	if ("GBP" == code)
+		return Iso4217Codes::GBP;
+
+	if ("GEL" == code)
+		return Iso4217Codes::GEL;
+
+	if ("GHS" == code)
+		return Iso4217Codes::GHS;
+
+	if ("GIP" == code)
+		return Iso4217Codes::GIP;
+
+	if ("GMD" == code)
+		return Iso4217Codes::GMD;
+
+	if ("GNF" == code)
+		return Iso4217Codes::GNF;
+
+	if ("GTQ" == code)
+		return Iso4217Codes::GTQ;
+
+	if ("GYD" == code)
+		return Iso4217Codes::GYD;
+
+	if ("HKD" == code)
+		return Iso4217Codes::HKD;
+
+	if ("HNL" == code)
+		return Iso4217Codes::HNL;
+
+	if ("HRK" == code)
+		return Iso4217Codes::HRK;
+
+	if ("HTG" == code)
+		return Iso4217Codes::HTG;
+
+	if ("HUF" == code)
+		return Iso4217Codes::HUF;
+
+	if ("IDR" == code)
+		return Iso4217Codes::IDR;
+
+	if ("ILS" == code)
+		return Iso4217Codes::ILS;
+
+	if ("INR" == code)
+		return Iso4217Codes::INR;
+
+	if ("IQD" == code)
+		return Iso4217Codes::IQD;
+
+	if ("IRR" == code)
+		return Iso4217Codes::IRR;
+
+	if ("ISK" == code)
+		return Iso4217Codes::ISK;
+
+	if ("JMD" == code)
+		return Iso4217Codes::JMD;
+
+	if ("JOD" == code)
+		return Iso4217Codes::JOD;
+
+	if ("JPY" == code)
+		return Iso4217Codes::JPY;
+
+	if ("KES" == code)
+		return Iso4217Codes::KES;
+
+	if ("KGS" == code)
+		return Iso4217Codes::KGS;
+
+	if ("KHR" == code)
+		return Iso4217Codes::KHR;
+
+	if ("KMF" == code)
+		return Iso4217Codes::KMF;
+
+	if ("KPW" == code)
+		return Iso4217Codes::KPW;
+
+	if ("KRW" == code)
+		return Iso4217Codes::KRW;
+
+	if ("KWD" == code)
+		return Iso4217Codes::KWD;
+
+	if ("KYD" == code)
+		return Iso4217Codes::KYD;
+
+	if ("KZT" == code)
+		return Iso4217Codes::KZT;
+
+	if ("LAK" == code)
+		return Iso4217Codes::LAK;
+
+	if ("LBP" == code)
+		return Iso4217Codes::LBP;
+
+	if ("LKR" == code)
+		return Iso4217Codes::LKR;
+
+	if ("LRD" == code)
+		return Iso4217Codes::LRD;
+
+	if ("LSL" == code)
+		return Iso4217Codes::LSL;
+
+	if ("LYD" == code)
+		return Iso4217Codes::LYD;
+
+	if ("MAD" == code)
+		return Iso4217Codes::MAD;
+
+	if ("MDL" == code)
+		return Iso4217Codes::MDL;
+
+	if ("MGA" == code)
+		return Iso4217Codes::MGA;
+
+	if ("MKD" == code)
+		return Iso4217Codes::MKD;
+
+	if ("MMK" == code)
+		return Iso4217Codes::MMK;
+
+	if ("MNT" == code)
+		return Iso4217Codes::MNT;
+
+	if ("MOP" == code)
+		return Iso4217Codes::MOP;
+
+	if ("MRU" == code)
+		return Iso4217Codes::MRU;
+
+	if ("MUR" == code)
+		return Iso4217Codes::MUR;
+
+	if ("MVR" == code)
+		return Iso4217Codes::MVR;
+
+	if ("MWK" == code)
+		return Iso4217Codes::MWK;
+
+	if ("MXN" == code)
+		return Iso4217Codes::MXN;
+
+	if ("MXV" == code)
+		return Iso4217Codes::MXV;
+
+	if ("MYR" == code)
+		return Iso4217Codes::MYR;
+
+	if ("MZN" == code)
+		return Iso4217Codes::MZN;
+
+	if ("NAD" == code)
+		return Iso4217Codes::NAD;
+
+	if ("NGN" == code)
+		return Iso4217Codes::NGN;
+
+	if ("NIO" == code)
+		return Iso4217Codes::NIO;
+
+	if ("NOK" == code)
+		return Iso4217Codes::NOK;
+
+	if ("NPR" == code)
+		return Iso4217Codes::NPR;
+
+	if ("NZD" == code)
+		return Iso4217Codes::NZD;
+
+	if ("OMR" == code)
+		return Iso4217Codes::OMR;
+
+	if ("PAB" == code)
+		return Iso4217Codes::PAB;
+
+	if ("PEN" == code)
+		return Iso4217Codes::PEN;
+
+	if ("PGK" == code)
+		return Iso4217Codes::PGK;
+
+	if ("PHP" == code)
+		return Iso4217Codes::PHP;
+
+	if ("PKR" == code)
+		return Iso4217Codes::PKR;
+
+	if ("PLN" == code)
+		return Iso4217Codes::PLN;
+
+	if ("PYG" == code)
+		return Iso4217Codes::PYG;
+
+	if ("QAR" == code)
+		return Iso4217Codes::QAR;
+
+	if ("RON" == code)
+		return Iso4217Codes::RON;
+
+	if ("RSD" == code)
+		return Iso4217Codes::RSD;
+
+	if ("RUB" == code)
+		return Iso4217Codes::RUB;
+
+	if ("RWF" == code)
+		return Iso4217Codes::RWF;
+
+	if ("SAR" == code)
+		return Iso4217Codes::SAR;
+
+	if ("SBD" == code)
+		return Iso4217Codes::SBD;
+
+	if ("SCR" == code)
+		return Iso4217Codes::SCR;
+
+	if ("SDG" == code)
+		return Iso4217Codes::SDG;
+
+	if ("SEK" == code)
+		return Iso4217Codes::SEK;
+
+	if ("SGD" == code)
+		return Iso4217Codes::SGD;
+
+	if ("SHP" == code)
+		return Iso4217Codes::SHP;
+
+	if ("SLL" == code)
+		return Iso4217Codes::SLL;
+
+	if ("SOS" == code)
+		return Iso4217Codes::SOS;
+
+	if ("SRD" == code)
+		return Iso4217Codes::SRD;
+
+	if ("SSP" == code)
+		return Iso4217Codes::SSP;
+
+	if ("STN" == code)
+		return Iso4217Codes::STN;
+
+	if ("SVC" == code)
+		return Iso4217Codes::SVC;
+
+	if ("SYP" == code)
+		return Iso4217Codes::SYP;
+
+	if ("SZL" == code)
+		return Iso4217Codes::SZL;
+
+	if ("THB" == code)
+		return Iso4217Codes::THB;
+
+	if ("TJS" == code)
+		return Iso4217Codes::TJS;
+
+	if ("TMT" == code)
+		return Iso4217Codes::TMT;
+
+	if ("TND" == code)
+		return Iso4217Codes::TND;
+
+	if ("TOP" == code)
+		return Iso4217Codes::TOP;
+
+	if ("TRY" == code)
+		return Iso4217Codes::TRY;
+
+	if ("TTD" == code)
+		return Iso4217Codes::TTD;
+
+	if ("TWD" == code)
+		return Iso4217Codes::TWD;
+
+	if ("TZS" == code)
+		return Iso4217Codes::TZS;
+
+	if ("UAH" == code)
+		return Iso4217Codes::UAH;
+
+	if ("UGX" == code)
+		return Iso4217Codes::UGX;
+
+	if ("USD" == code)
+		return Iso4217Codes::USD;
+
+	if ("USN" == code)
+		return Iso4217Codes::USN;
+
+	if ("UYI" == code)
+		return Iso4217Codes::UYI;
+
+	if ("UYU" == code)
+		return Iso4217Codes::UYU;
+
+	if ("UYW" == code)
+		return Iso4217Codes::UYW;
+
+	if ("UZS" == code)
+		return Iso4217Codes::UZS;
+
+	if ("VES" == code)
+		return Iso4217Codes::VES;
+
+	if ("VND" == code)
+		return Iso4217Codes::VND;
+
+	if ("VUV" == code)
+		return Iso4217Codes::VUV;
+
+	if ("WST" == code)
+		return Iso4217Codes::WST;
+
+	if ("XAF" == code)
+		return Iso4217Codes::XAF;
+
+	if ("XAG" == code)
+		return Iso4217Codes::XAG;
+
+	if ("XAU" == code)
+		return Iso4217Codes::XAU;
+
+	if ("XBA" == code)
+		return Iso4217Codes::XBA;
+
+	if ("XBB" == code)
+		return Iso4217Codes::XBB;
+
+	if ("XBC" == code)
+		return Iso4217Codes::XBC;
+
+	if ("XBD" == code)
+		return Iso4217Codes::XBD;
+
+	if ("XCD" == code)
+		return Iso4217Codes::XCD;
+
+	if ("XDR" == code)
+		return Iso4217Codes::XDR;
+
+	if ("XOF" == code)
+		return Iso4217Codes::XOF;
+
+	if ("XPD" == code)
+		return Iso4217Codes::XPD;
+
+	if ("XPF" == code)
+		return Iso4217Codes::XPF;
+
+	if ("XPT" == code)
+		return Iso4217Codes::XPT;
+
+	if ("XSU" == code)
+		return Iso4217Codes::XSU;
+
+	if ("XTS" == code)
+		return Iso4217Codes::XTS;
+
+	if ("XUA" == code)
+		return Iso4217Codes::XUA;
+
+	if ("XXX" == code)
+		return Iso4217Codes::XXX;
+
+	if ("YER" == code)
+		return Iso4217Codes::YER;
+
+	if ("ZAR" == code)
+		return Iso4217Codes::ZAR;
+
+	if ("ZMW" == code)
+		return Iso4217Codes::ZMW;
+
+	if ("ZWL" == code)
+		return Iso4217Codes::ZWL;
+	throw runtime_error{
+		"Unhandled currency code '" + code + "' for conversion to its strong type."
+	};
+}
+
+string pecunia::currency::currencySymbol(const Iso4217Codes& code)
+{
+	switch (code)
+	{
+	case Iso4217Codes::EUR:
+		return "€";
+	case Iso4217Codes::PLN:
+		return "zł";
+	case Iso4217Codes::USD:
+		return "$";
+	default:
+		assert(false && "Unhandled currency code for conversion to a symbol.");
+		return "";
+	};
+}
+
+uint8_t pecunia::currency::minorUnitDigits(const Iso4217Codes& code)
+{
+	switch (code)
+	{
+	case Iso4217Codes::BIF:
+	case Iso4217Codes::CLP:
+	case Iso4217Codes::DJF:
+	case Iso4217Codes::GNF:
+	case Iso4217Codes::ISK:
+	case Iso4217Codes::JPY:
+	case Iso4217Codes::KMF:
+	case Iso4217Codes::KRW:
+	case Iso4217Codes::PYG:
+	case Iso4217Codes::RWF:
+	case Iso4217Codes::UGX:
+	case Iso4217Codes::UYI:
+	case Iso4217Codes::VND:
+	case Iso4217Codes::VUV:
+	case Iso4217Codes::XAF:
+	case Iso4217Codes::XAG:
+	case Iso4217Codes::XAU:
+	case Iso4217Codes::XBA:
+	case Iso4217Codes::XBB:
+	case Iso4217Codes::XBC:
+	case Iso4217Codes::XBD:
+	case Iso4217Codes::XDR:
+	case Iso4217Codes::XOF:
+	case Iso4217Codes::XPD:
+	case Iso4217Codes::XPF:
+	case Iso4217Codes::XPT:
+	case Iso4217Codes::XSU:
+	case Iso4217Codes::XTS:
+	case Iso4217Codes::XUA:
+	case Iso4217Codes::XXX:
+		return 0u;
+	case Iso4217Codes::AED:
+	case Iso4217Codes::AFN:
+	case Iso4217Codes::ALL:
+	case Iso4217Codes::AMD:
+	case Iso4217Codes::ANG:
+	case Iso4217Codes::AOA:
+	case Iso4217Codes::ARS:
+	case Iso4217Codes::AUD:
+	case Iso4217Codes::AWG:
+	case Iso4217Codes::AZN:
+	case Iso4217Codes::BAM:
+	case Iso4217Codes::BBD:
+	case Iso4217Codes::BDT:
+	case Iso4217Codes::BGN:
+	case Iso4217Codes::BMD:
+	case Iso4217Codes::BND:
+	case Iso4217Codes::BOB:
+	case Iso4217Codes::BOV:
+	case Iso4217Codes::BRL:
+	case Iso4217Codes::BSD:
+	case Iso4217Codes::BTN:
+	case Iso4217Codes::BWP:
+	case Iso4217Codes::BYN:
+	case Iso4217Codes::BZD:
+	case Iso4217Codes::CAD:
+	case Iso4217Codes::CDF:
+	case Iso4217Codes::CHE:
+	case Iso4217Codes::CHF:
+	case Iso4217Codes::CHW:
+	case Iso4217Codes::CNY:
+	case Iso4217Codes::COP:
+	case Iso4217Codes::COU:
+	case Iso4217Codes::CRC:
+	case Iso4217Codes::CUC:
+	case Iso4217Codes::CUP:
+	case Iso4217Codes::CVE:
+	case Iso4217Codes::CZK:
+	case Iso4217Codes::DKK:
+	case Iso4217Codes::DOP:
+	case Iso4217Codes::DZD:
+	case Iso4217Codes::EGP:
+	case Iso4217Codes::ERN:
+	case Iso4217Codes::ETB:
+	case Iso4217Codes::EUR:
+	case Iso4217Codes::FJD:
+	case Iso4217Codes::FKP:
+	case Iso4217Codes::GBP:
+	case Iso4217Codes::GEL:
+	case Iso4217Codes::GHS:
+	case Iso4217Codes::GIP:
+	case Iso4217Codes::GMD:
+	case Iso4217Codes::GTQ:
+	case Iso4217Codes::GYD:
+	case Iso4217Codes::HKD:
+	case Iso4217Codes::HNL:
+	case Iso4217Codes::HRK:
+	case Iso4217Codes::HTG:
+	case Iso4217Codes::HUF:
+	case Iso4217Codes::IDR:
+	case Iso4217Codes::ILS:
+	case Iso4217Codes::INR:
+	case Iso4217Codes::IRR:
+	case Iso4217Codes::JMD:
+	case Iso4217Codes::KES:
+	case Iso4217Codes::KGS:
+	case Iso4217Codes::KHR:
+	case Iso4217Codes::KPW:
+	case Iso4217Codes::KYD:
+	case Iso4217Codes::KZT:
+	case Iso4217Codes::LAK:
+	case Iso4217Codes::LBP:
+	case Iso4217Codes::LKR:
+	case Iso4217Codes::LRD:
+	case Iso4217Codes::LSL:
+	case Iso4217Codes::MAD:
+	case Iso4217Codes::MDL:
+	case Iso4217Codes::MGA:
+	case Iso4217Codes::MKD:
+	case Iso4217Codes::MMK:
+	case Iso4217Codes::MNT:
+	case Iso4217Codes::MOP:
+	case Iso4217Codes::MRU:
+	case Iso4217Codes::MUR:
+	case Iso4217Codes::MVR:
+	case Iso4217Codes::MWK:
+	case Iso4217Codes::MXN:
+	case Iso4217Codes::MXV:
+	case Iso4217Codes::MYR:
+	case Iso4217Codes::MZN:
+	case Iso4217Codes::NAD:
+	case Iso4217Codes::NGN:
+	case Iso4217Codes::NIO:
+	case Iso4217Codes::NOK:
+	case Iso4217Codes::NPR:
+	case Iso4217Codes::NZD:
+	case Iso4217Codes::PAB:
+	case Iso4217Codes::PEN:
+	case Iso4217Codes::PGK:
+	case Iso4217Codes::PHP:
+	case Iso4217Codes::PKR:
+	case Iso4217Codes::PLN:
+	case Iso4217Codes::QAR:
+	case Iso4217Codes::RON:
+	case Iso4217Codes::RSD:
+	case Iso4217Codes::RUB:
+	case Iso4217Codes::SAR:
+	case Iso4217Codes::SBD:
+	case Iso4217Codes::SCR:
+	case Iso4217Codes::SDG:
+	case Iso4217Codes::SEK:
+	case Iso4217Codes::SGD:
+	case Iso4217Codes::SHP:
+	case Iso4217Codes::SLL:
+	case Iso4217Codes::SOS:
+	case Iso4217Codes::SRD:
+	case Iso4217Codes::SSP:
+	case Iso4217Codes::STN:
+	case Iso4217Codes::SVC:
+	case Iso4217Codes::SYP:
+	case Iso4217Codes::SZL:
+	case Iso4217Codes::THB:
+	case Iso4217Codes::TJS:
+	case Iso4217Codes::TMT:
+	case Iso4217Codes::TOP:
+	case Iso4217Codes::TRY:
+	case Iso4217Codes::TTD:
+	case Iso4217Codes::TWD:
+	case Iso4217Codes::TZS:
+	case Iso4217Codes::UAH:
+	case Iso4217Codes::USD:
+	case Iso4217Codes::USN:
+	case Iso4217Codes::UYU:
+	case Iso4217Codes::UZS:
+	case Iso4217Codes::VES:
+	case Iso4217Codes::WST:
+	case Iso4217Codes::XCD:
+	case Iso4217Codes::YER:
+	case Iso4217Codes::ZAR:
+	case Iso4217Codes::ZMW:
+	case Iso4217Codes::ZWL:
+		return 2u;
+	case Iso4217Codes::BHD:
+	case Iso4217Codes::IQD:
+	case Iso4217Codes::JOD:
+	case Iso4217Codes::KWD:
+	case Iso4217Codes::LYD:
+	case Iso4217Codes::OMR:
+	case Iso4217Codes::TND:
+		return 3u;
+	case Iso4217Codes::CLF:
+	case Iso4217Codes::UYW:
+		return 4u;
+	default:
+		assert(false && "Unhandled currency code for minor unit digits.");
+		return 0u;
+	};
+}
+
+int32_t pecunia::currency::minorUnitPrecisionFactor(const Iso4217Codes& code)
+{
+	return static_cast<int32_t>(pow(10, minorUnitDigits(code) + precision));
+}
+
+ostream& pecunia::currency::operator<<(ostream& stream, const Iso4217Codes& code)
+{
+	return stream << toStdString(code);
+}
+
+vector<string> pecunia::currency::countriesUsing(const Iso4217Codes& code)
+{
+	static const map<Iso4217Codes, vector<string>> codeCountries{
+		{
+			Iso4217Codes::AED,
+			{
+				{"UNITED ARAB EMIRATES (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::AFN,
+			{
+				{"AFGHANISTAN"s}
+			}
+		},
+		{
+			Iso4217Codes::ALL,
+			{
+				{"ALBANIA"s}
+			}
+		},
+		{
+			Iso4217Codes::AMD,
+			{
+				{"ARMENIA"s}
+			}
+		},
+		{
+			Iso4217Codes::ANG,
+			{
+				{"CURAÇAO"s, "SINT MAARTEN (DUTCH PART)"s}
+			}
+		},
+		{
+			Iso4217Codes::AOA,
+			{
+				{"ANGOLA"s}
+			}
+		},
+		{
+			Iso4217Codes::ARS,
+			{
+				{"ARGENTINA"s}
+			}
+		},
+		{
+			Iso4217Codes::AUD,
+			{
+				{"AUSTRALIA"s, "CHRISTMAS ISLAND"s, "COCOS (KEELING) ISLANDS (THE)"s, "HEARD ISLAND AND McDONALD ISLANDS"s, "KIRIBATI"s, "NAURU"s, "NORFOLK ISLAND"s, "TUVALU"s}
+			}
+		},
+		{
+			Iso4217Codes::AWG,
+			{
+				{"ARUBA"s}
+			}
+		},
+		{
+			Iso4217Codes::AZN,
+			{
+				{"AZERBAIJAN"s}
+			}
+		},
+		{
+			Iso4217Codes::BAM,
+			{
+				{"BOSNIA AND HERZEGOVINA"s}
+			}
+		},
+		{
+			Iso4217Codes::BBD,
+			{
+				{"BARBADOS"s}
+			}
+		},
+		{
+			Iso4217Codes::BDT,
+			{
+				{"BANGLADESH"s}
+			}
+		},
+		{
+			Iso4217Codes::BGN,
+			{
+				{"BULGARIA"s}
+			}
+		},
+		{
+			Iso4217Codes::BHD,
+			{
+				{"BAHRAIN"s}
+			}
+		},
+		{
+			Iso4217Codes::BIF,
+			{
+				{"BURUNDI"s}
+			}
+		},
+		{
+			Iso4217Codes::BMD,
+			{
+				{"BERMUDA"s}
+			}
+		},
+		{
+			Iso4217Codes::BND,
+			{
+				{"BRUNEI DARUSSALAM"s}
+			}
+		},
+		{
+			Iso4217Codes::BOB,
+			{
+				{"BOLIVIA (PLURINATIONAL STATE OF)"s}
+			}
+		},
+		{
+			Iso4217Codes::BOV,
+			{
+				{"BOLIVIA (PLURINATIONAL STATE OF)"s}
+			}
+		},
+		{
+			Iso4217Codes::BRL,
+			{
+				{"BRAZIL"s}
+			}
+		},
+		{
+			Iso4217Codes::BSD,
+			{
+				{"BAHAMAS (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::BTN,
+			{
+				{"BHUTAN"s}
+			}
+		},
+		{
+			Iso4217Codes::BWP,
+			{
+				{"BOTSWANA"s}
+			}
+		},
+		{
+			Iso4217Codes::BYN,
+			{
+				{"BELARUS"s}
+			}
+		},
+		{
+			Iso4217Codes::BZD,
+			{
+				{"BELIZE"s}
+			}
+		},
+		{
+			Iso4217Codes::CAD,
+			{
+				{"CANADA"s}
+			}
+		},
+		{
+			Iso4217Codes::CDF,
+			{
+				{"CONGO (THE DEMOCRATIC REPUBLIC OF THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::CHE,
+			{
+				{"SWITZERLAND"s}
+			}
+		},
+		{
+			Iso4217Codes::CHF,
+			{
+				{"LIECHTENSTEIN"s, "SWITZERLAND"s}
+			}
+		},
+		{
+			Iso4217Codes::CHW,
+			{
+				{"SWITZERLAND"s}
+			}
+		},
+		{
+			Iso4217Codes::CLF,
+			{
+				{"CHILE"s}
+			}
+		},
+		{
+			Iso4217Codes::CLP,
+			{
+				{"CHILE"s}
+			}
+		},
+		{
+			Iso4217Codes::CNY,
+			{
+				{"CHINA"s}
+			}
+		},
+		{
+			Iso4217Codes::COP,
+			{
+				{"COLOMBIA"s}
+			}
+		},
+		{
+			Iso4217Codes::COU,
+			{
+				{"COLOMBIA"s}
+			}
+		},
+		{
+			Iso4217Codes::CRC,
+			{
+				{"COSTA RICA"s}
+			}
+		},
+		{
+			Iso4217Codes::CUC,
+			{
+				{"CUBA"s}
+			}
+		},
+		{
+			Iso4217Codes::CUP,
+			{
+				{"CUBA"s}
+			}
+		},
+		{
+			Iso4217Codes::CVE,
+			{
+				{"CABO VERDE"s}
+			}
+		},
+		{
+			Iso4217Codes::CZK,
+			{
+				{"CZECHIA"s}
+			}
+		},
+		{
+			Iso4217Codes::DJF,
+			{
+				{"DJIBOUTI"s}
+			}
+		},
+		{
+			Iso4217Codes::DKK,
+			{
+				{"DENMARK"s, "FAROE ISLANDS (THE)"s, "GREENLAND"s}
+			}
+		},
+		{
+			Iso4217Codes::DOP,
+			{
+				{"DOMINICAN REPUBLIC (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::DZD,
+			{
+				{"ALGERIA"s}
+			}
+		},
+		{
+			Iso4217Codes::EGP,
+			{
+				{"EGYPT"s}
+			}
+		},
+		{
+			Iso4217Codes::ERN,
+			{
+				{"ERITREA"s}
+			}
+		},
+		{
+			Iso4217Codes::ETB,
+			{
+				{"ETHIOPIA"s}
+			}
+		},
+		{
+			Iso4217Codes::EUR,
+			{
+				{"ANDORRA"s, "AUSTRIA"s, "BELGIUM"s, "CYPRUS"s, "ESTONIA"s, "EUROPEAN UNION"s, "FINLAND"s, "FRANCE"s, "FRENCH GUIANA"s, "FRENCH SOUTHERN TERRITORIES (THE)"s, "GERMANY"s, "GREECE"s, "GUADELOUPE"s, "HOLY SEE (THE)"s, "IRELAND"s, "ITALY"s, "LATVIA"s, "LITHUANIA"s, "LUXEMBOURG"s, "MALTA"s, "MARTINIQUE"s, "MAYOTTE"s, "MONACO"s, "MONTENEGRO"s, "NETHERLANDS (THE)"s, "PORTUGAL"s, "RÉUNION"s, "SAINT BARTHÉLEMY"s, "SAINT MARTIN (FRENCH PART)"s, "SAINT PIERRE AND MIQUELON"s, "SAN MARINO"s, "SLOVAKIA"s, "SLOVENIA"s, "SPAIN"s, "ÅLAND ISLANDS"s}
+			}
+		},
+		{
+			Iso4217Codes::FJD,
+			{
+				{"FIJI"s}
+			}
+		},
+		{
+			Iso4217Codes::FKP,
+			{
+				{"FALKLAND ISLANDS (THE) [MALVINAS]"s}
+			}
+		},
+		{
+			Iso4217Codes::GBP,
+			{
+				{"GUERNSEY"s, "ISLE OF MAN"s, "JERSEY"s, "UNITED KINGDOM OF GREAT BRITAIN AND NORTHERN IRELAND (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::GEL,
+			{
+				{"GEORGIA"s}
+			}
+		},
+		{
+			Iso4217Codes::GHS,
+			{
+				{"GHANA"s}
+			}
+		},
+		{
+			Iso4217Codes::GIP,
+			{
+				{"GIBRALTAR"s}
+			}
+		},
+		{
+			Iso4217Codes::GMD,
+			{
+				{"GAMBIA (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::GNF,
+			{
+				{"GUINEA"s}
+			}
+		},
+		{
+			Iso4217Codes::GTQ,
+			{
+				{"GUATEMALA"s}
+			}
+		},
+		{
+			Iso4217Codes::GYD,
+			{
+				{"GUYANA"s}
+			}
+		},
+		{
+			Iso4217Codes::HKD,
+			{
+				{"HONG KONG"s}
+			}
+		},
+		{
+			Iso4217Codes::HNL,
+			{
+				{"HONDURAS"s}
+			}
+		},
+		{
+			Iso4217Codes::HRK,
+			{
+				{"CROATIA"s}
+			}
+		},
+		{
+			Iso4217Codes::HTG,
+			{
+				{"HAITI"s}
+			}
+		},
+		{
+			Iso4217Codes::HUF,
+			{
+				{"HUNGARY"s}
+			}
+		},
+		{
+			Iso4217Codes::IDR,
+			{
+				{"INDONESIA"s}
+			}
+		},
+		{
+			Iso4217Codes::ILS,
+			{
+				{"ISRAEL"s}
+			}
+		},
+		{
+			Iso4217Codes::INR,
+			{
+				{"BHUTAN"s, "INDIA"s}
+			}
+		},
+		{
+			Iso4217Codes::IQD,
+			{
+				{"IRAQ"s}
+			}
+		},
+		{
+			Iso4217Codes::IRR,
+			{
+				{"IRAN (ISLAMIC REPUBLIC OF)"s}
+			}
+		},
+		{
+			Iso4217Codes::ISK,
+			{
+				{"ICELAND"s}
+			}
+		},
+		{
+			Iso4217Codes::JMD,
+			{
+				{"JAMAICA"s}
+			}
+		},
+		{
+			Iso4217Codes::JOD,
+			{
+				{"JORDAN"s}
+			}
+		},
+		{
+			Iso4217Codes::JPY,
+			{
+				{"JAPAN"s}
+			}
+		},
+		{
+			Iso4217Codes::KES,
+			{
+				{"KENYA"s}
+			}
+		},
+		{
+			Iso4217Codes::KGS,
+			{
+				{"KYRGYZSTAN"s}
+			}
+		},
+		{
+			Iso4217Codes::KHR,
+			{
+				{"CAMBODIA"s}
+			}
+		},
+		{
+			Iso4217Codes::KMF,
+			{
+				{"COMOROS (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::KPW,
+			{
+				{"KOREA (THE DEMOCRATIC PEOPLE’S REPUBLIC OF)"s}
+			}
+		},
+		{
+			Iso4217Codes::KRW,
+			{
+				{"KOREA (THE REPUBLIC OF)"s}
+			}
+		},
+		{
+			Iso4217Codes::KWD,
+			{
+				{"KUWAIT"s}
+			}
+		},
+		{
+			Iso4217Codes::KYD,
+			{
+				{"CAYMAN ISLANDS (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::KZT,
+			{
+				{"KAZAKHSTAN"s}
+			}
+		},
+		{
+			Iso4217Codes::LAK,
+			{
+				{"LAO PEOPLE’S DEMOCRATIC REPUBLIC (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::LBP,
+			{
+				{"LEBANON"s}
+			}
+		},
+		{
+			Iso4217Codes::LKR,
+			{
+				{"SRI LANKA"s}
+			}
+		},
+		{
+			Iso4217Codes::LRD,
+			{
+				{"LIBERIA"s}
+			}
+		},
+		{
+			Iso4217Codes::LSL,
+			{
+				{"LESOTHO"s}
+			}
+		},
+		{
+			Iso4217Codes::LYD,
+			{
+				{"LIBYA"s}
+			}
+		},
+		{
+			Iso4217Codes::MAD,
+			{
+				{"MOROCCO"s, "WESTERN SAHARA"s}
+			}
+		},
+		{
+			Iso4217Codes::MDL,
+			{
+				{"MOLDOVA (THE REPUBLIC OF)"s}
+			}
+		},
+		{
+			Iso4217Codes::MGA,
+			{
+				{"MADAGASCAR"s}
+			}
+		},
+		{
+			Iso4217Codes::MKD,
+			{
+				{"NORTH MACEDONIA"s}
+			}
+		},
+		{
+			Iso4217Codes::MMK,
+			{
+				{"MYANMAR"s}
+			}
+		},
+		{
+			Iso4217Codes::MNT,
+			{
+				{"MONGOLIA"s}
+			}
+		},
+		{
+			Iso4217Codes::MOP,
+			{
+				{"MACAO"s}
+			}
+		},
+		{
+			Iso4217Codes::MRU,
+			{
+				{"MAURITANIA"s}
+			}
+		},
+		{
+			Iso4217Codes::MUR,
+			{
+				{"MAURITIUS"s}
+			}
+		},
+		{
+			Iso4217Codes::MVR,
+			{
+				{"MALDIVES"s}
+			}
+		},
+		{
+			Iso4217Codes::MWK,
+			{
+				{"MALAWI"s}
+			}
+		},
+		{
+			Iso4217Codes::MXN,
+			{
+				{"MEXICO"s}
+			}
+		},
+		{
+			Iso4217Codes::MXV,
+			{
+				{"MEXICO"s}
+			}
+		},
+		{
+			Iso4217Codes::MYR,
+			{
+				{"MALAYSIA"s}
+			}
+		},
+		{
+			Iso4217Codes::MZN,
+			{
+				{"MOZAMBIQUE"s}
+			}
+		},
+		{
+			Iso4217Codes::NAD,
+			{
+				{"NAMIBIA"s}
+			}
+		},
+		{
+			Iso4217Codes::NGN,
+			{
+				{"NIGERIA"s}
+			}
+		},
+		{
+			Iso4217Codes::NIO,
+			{
+				{"NICARAGUA"s}
+			}
+		},
+		{
+			Iso4217Codes::NOK,
+			{
+				{"BOUVET ISLAND"s, "NORWAY"s, "SVALBARD AND JAN MAYEN"s}
+			}
+		},
+		{
+			Iso4217Codes::NPR,
+			{
+				{"NEPAL"s}
+			}
+		},
+		{
+			Iso4217Codes::NZD,
+			{
+				{"COOK ISLANDS (THE)"s, "NEW ZEALAND"s, "NIUE"s, "PITCAIRN"s, "TOKELAU"s}
+			}
+		},
+		{
+			Iso4217Codes::OMR,
+			{
+				{"OMAN"s}
+			}
+		},
+		{
+			Iso4217Codes::PAB,
+			{
+				{"PANAMA"s}
+			}
+		},
+		{
+			Iso4217Codes::PEN,
+			{
+				{"PERU"s}
+			}
+		},
+		{
+			Iso4217Codes::PGK,
+			{
+				{"PAPUA NEW GUINEA"s}
+			}
+		},
+		{
+			Iso4217Codes::PHP,
+			{
+				{"PHILIPPINES (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::PKR,
+			{
+				{"PAKISTAN"s}
+			}
+		},
+		{
+			Iso4217Codes::PLN,
+			{
+				{"POLAND"s}
+			}
+		},
+		{
+			Iso4217Codes::PYG,
+			{
+				{"PARAGUAY"s}
+			}
+		},
+		{
+			Iso4217Codes::QAR,
+			{
+				{"QATAR"s}
+			}
+		},
+		{
+			Iso4217Codes::RON,
+			{
+				{"ROMANIA"s}
+			}
+		},
+		{
+			Iso4217Codes::RSD,
+			{
+				{"SERBIA"s}
+			}
+		},
+		{
+			Iso4217Codes::RUB,
+			{
+				{"RUSSIAN FEDERATION (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::RWF,
+			{
+				{"RWANDA"s}
+			}
+		},
+		{
+			Iso4217Codes::SAR,
+			{
+				{"SAUDI ARABIA"s}
+			}
+		},
+		{
+			Iso4217Codes::SBD,
+			{
+				{"SOLOMON ISLANDS"s}
+			}
+		},
+		{
+			Iso4217Codes::SCR,
+			{
+				{"SEYCHELLES"s}
+			}
+		},
+		{
+			Iso4217Codes::SDG,
+			{
+				{"SUDAN (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::SEK,
+			{
+				{"SWEDEN"s}
+			}
+		},
+		{
+			Iso4217Codes::SGD,
+			{
+				{"SINGAPORE"s}
+			}
+		},
+		{
+			Iso4217Codes::SHP,
+			{
+				{"SAINT HELENA, ASCENSION AND TRISTAN DA CUNHA"s}
+			}
+		},
+		{
+			Iso4217Codes::SLL,
+			{
+				{"SIERRA LEONE"s}
+			}
+		},
+		{
+			Iso4217Codes::SOS,
+			{
+				{"SOMALIA"s}
+			}
+		},
+		{
+			Iso4217Codes::SRD,
+			{
+				{"SURINAME"s}
+			}
+		},
+		{
+			Iso4217Codes::SSP,
+			{
+				{"SOUTH SUDAN"s}
+			}
+		},
+		{
+			Iso4217Codes::STN,
+			{
+				{"SAO TOME AND PRINCIPE"s}
+			}
+		},
+		{
+			Iso4217Codes::SVC,
+			{
+				{"EL SALVADOR"s}
+			}
+		},
+		{
+			Iso4217Codes::SYP,
+			{
+				{"SYRIAN ARAB REPUBLIC"s}
+			}
+		},
+		{
+			Iso4217Codes::SZL,
+			{
+				{"ESWATINI"s}
+			}
+		},
+		{
+			Iso4217Codes::THB,
+			{
+				{"THAILAND"s}
+			}
+		},
+		{
+			Iso4217Codes::TJS,
+			{
+				{"TAJIKISTAN"s}
+			}
+		},
+		{
+			Iso4217Codes::TMT,
+			{
+				{"TURKMENISTAN"s}
+			}
+		},
+		{
+			Iso4217Codes::TND,
+			{
+				{"TUNISIA"s}
+			}
+		},
+		{
+			Iso4217Codes::TOP,
+			{
+				{"TONGA"s}
+			}
+		},
+		{
+			Iso4217Codes::TRY,
+			{
+				{"TURKEY"s}
+			}
+		},
+		{
+			Iso4217Codes::TTD,
+			{
+				{"TRINIDAD AND TOBAGO"s}
+			}
+		},
+		{
+			Iso4217Codes::TWD,
+			{
+				{"TAIWAN (PROVINCE OF CHINA)"s}
+			}
+		},
+		{
+			Iso4217Codes::TZS,
+			{
+				{"TANZANIA, UNITED REPUBLIC OF"s}
+			}
+		},
+		{
+			Iso4217Codes::UAH,
+			{
+				{"UKRAINE"s}
+			}
+		},
+		{
+			Iso4217Codes::UGX,
+			{
+				{"UGANDA"s}
+			}
+		},
+		{
+			Iso4217Codes::USD,
+			{
+				{"AMERICAN SAMOA"s, "BONAIRE, SINT EUSTATIUS AND SABA"s, "BRITISH INDIAN OCEAN TERRITORY (THE)"s, "ECUADOR"s, "EL SALVADOR"s, "GUAM"s, "HAITI"s, "MARSHALL ISLANDS (THE)"s, "MICRONESIA (FEDERATED STATES OF)"s, "NORTHERN MARIANA ISLANDS (THE)"s, "PALAU"s, "PANAMA"s, "PUERTO RICO"s, "TIMOR-LESTE"s, "TURKS AND CAICOS ISLANDS (THE)"s, "UNITED STATES MINOR OUTLYING ISLANDS (THE)"s, "UNITED STATES OF AMERICA (THE)"s, "VIRGIN ISLANDS (BRITISH)"s, "VIRGIN ISLANDS (U.S.)"s}
+			}
+		},
+		{
+			Iso4217Codes::USN,
+			{
+				{"UNITED STATES OF AMERICA (THE)"s}
+			}
+		},
+		{
+			Iso4217Codes::UYI,
+			{
+				{"URUGUAY"s}
+			}
+		},
+		{
+			Iso4217Codes::UYU,
+			{
+				{"URUGUAY"s}
+			}
+		},
+		{
+			Iso4217Codes::UYW,
+			{
+				{"URUGUAY"s}
+			}
+		},
+		{
+			Iso4217Codes::UZS,
+			{
+				{"UZBEKISTAN"s}
+			}
+		},
+		{
+			Iso4217Codes::VES,
+			{
+				{"VENEZUELA (BOLIVARIAN REPUBLIC OF)"s}
+			}
+		},
+		{
+			Iso4217Codes::VND,
+			{
+				{"VIET NAM"s}
+			}
+		},
+		{
+			Iso4217Codes::VUV,
+			{
+				{"VANUATU"s}
+			}
+		},
+		{
+			Iso4217Codes::WST,
+			{
+				{"SAMOA"s}
+			}
+		},
+		{
+			Iso4217Codes::XAF,
+			{
+				{"CAMEROON"s, "CENTRAL AFRICAN REPUBLIC (THE)"s, "CHAD"s, "CONGO (THE)"s, "EQUATORIAL GUINEA"s, "GABON"s}
+			}
+		},
+		{
+			Iso4217Codes::XAG,
+			{
+				{"ZZ11_Silver"s}
+			}
+		},
+		{
+			Iso4217Codes::XAU,
+			{
+				{"ZZ08_Gold"s}
+			}
+		},
+		{
+			Iso4217Codes::XBA,
+			{
+				{"ZZ01_Bond Markets Unit European_EURCO"s}
+			}
+		},
+		{
+			Iso4217Codes::XBB,
+			{
+				{"ZZ02_Bond Markets Unit European_EMU-6"s}
+			}
+		},
+		{
+			Iso4217Codes::XBC,
+			{
+				{"ZZ03_Bond Markets Unit European_EUA-9"s}
+			}
+		},
+		{
+			Iso4217Codes::XBD,
+			{
+				{"ZZ04_Bond Markets Unit European_EUA-17"s}
+			}
+		},
+		{
+			Iso4217Codes::XCD,
+			{
+				{"ANGUILLA"s, "ANTIGUA AND BARBUDA"s, "DOMINICA"s, "GRENADA"s, "MONTSERRAT"s, "SAINT KITTS AND NEVIS"s, "SAINT LUCIA"s, "SAINT VINCENT AND THE GRENADINES"s}
+			}
+		},
+		{
+			Iso4217Codes::XDR,
+			{
+				{"INTERNATIONAL MONETARY FUND (IMF) "s}
+			}
+		},
+		{
+			Iso4217Codes::XOF,
+			{
+				{"BENIN"s, "BURKINA FASO"s, "CÔTE D'IVOIRE"s, "GUINEA-BISSAU"s, "MALI"s, "NIGER (THE)"s, "SENEGAL"s, "TOGO"s}
+			}
+		},
+		{
+			Iso4217Codes::XPD,
+			{
+				{"ZZ09_Palladium"s}
+			}
+		},
+		{
+			Iso4217Codes::XPF,
+			{
+				{"FRENCH POLYNESIA"s, "NEW CALEDONIA"s, "WALLIS AND FUTUNA"s}
+			}
+		},
+		{
+			Iso4217Codes::XPT,
+			{
+				{"ZZ10_Platinum"s}
+			}
+		},
+		{
+			Iso4217Codes::XSU,
+			{
+				{"SISTEMA UNITARIO DE COMPENSACION REGIONAL DE PAGOS \"SUCRE\""s}
+			}
+		},
+		{
+			Iso4217Codes::XTS,
+			{
+				{"ZZ06_Testing_Code"s}
+			}
+		},
+		{
+			Iso4217Codes::XUA,
+			{
+				{"MEMBER COUNTRIES OF THE AFRICAN DEVELOPMENT BANK GROUP"s}
+			}
+		},
+		{
+			Iso4217Codes::XXX,
+			{
+				{"ZZ07_No_Currency"s}
+			}
+		},
+		{
+			Iso4217Codes::YER,
+			{
+				{"YEMEN"s}
+			}
+		},
+		{
+			Iso4217Codes::ZAR,
+			{
+				{"LESOTHO"s, "NAMIBIA"s, "SOUTH AFRICA"s}
+			}
+		},
+		{
+			Iso4217Codes::ZMW,
+			{
+				{"ZAMBIA"s}
+			}
+		},
+		{
+			Iso4217Codes::ZWL,
+			{
+				{"ZIMBABWE"s}
+			}
+		}
+	};
+	return codeCountries.at(code);
+}
+
+string pecunia::currency::currencyName(const Iso4217Codes& code)
+{
+	static const map<Iso4217Codes, string> codeNames{
+		{
+			Iso4217Codes::AED,
+			"UAE Dirham"s
+		},
+		{
+			Iso4217Codes::AFN,
+			"Afghani"s
+		},
+		{
+			Iso4217Codes::ALL,
+			"Lek"s
+		},
+		{
+			Iso4217Codes::AMD,
+			"Armenian Dram"s
+		},
+		{
+			Iso4217Codes::ANG,
+			"Netherlands Antillean Guilder"s
+		},
+		{
+			Iso4217Codes::AOA,
+			"Kwanza"s
+		},
+		{
+			Iso4217Codes::ARS,
+			"Argentine Peso"s
+		},
+		{
+			Iso4217Codes::AUD,
+			"Australian Dollar"s
+		},
+		{
+			Iso4217Codes::AWG,
+			"Aruban Florin"s
+		},
+		{
+			Iso4217Codes::AZN,
+			"Azerbaijan Manat"s
+		},
+		{
+			Iso4217Codes::BAM,
+			"Convertible Mark"s
+		},
+		{
+			Iso4217Codes::BBD,
+			"Barbados Dollar"s
+		},
+		{
+			Iso4217Codes::BDT,
+			"Taka"s
+		},
+		{
+			Iso4217Codes::BGN,
+			"Bulgarian Lev"s
+		},
+		{
+			Iso4217Codes::BHD,
+			"Bahraini Dinar"s
+		},
+		{
+			Iso4217Codes::BIF,
+			"Burundi Franc"s
+		},
+		{
+			Iso4217Codes::BMD,
+			"Bermudian Dollar"s
+		},
+		{
+			Iso4217Codes::BND,
+			"Brunei Dollar"s
+		},
+		{
+			Iso4217Codes::BOB,
+			"Boliviano"s
+		},
+		{
+			Iso4217Codes::BOV,
+			"Mvdol"s
+		},
+		{
+			Iso4217Codes::BRL,
+			"Brazilian Real"s
+		},
+		{
+			Iso4217Codes::BSD,
+			"Bahamian Dollar"s
+		},
+		{
+			Iso4217Codes::BTN,
+			"Ngultrum"s
+		},
+		{
+			Iso4217Codes::BWP,
+			"Pula"s
+		},
+		{
+			Iso4217Codes::BYN,
+			"Belarusian Ruble"s
+		},
+		{
+			Iso4217Codes::BZD,
+			"Belize Dollar"s
+		},
+		{
+			Iso4217Codes::CAD,
+			"Canadian Dollar"s
+		},
+		{
+			Iso4217Codes::CDF,
+			"Congolese Franc"s
+		},
+		{
+			Iso4217Codes::CHE,
+			"WIR Euro"s
+		},
+		{
+			Iso4217Codes::CHF,
+			"Swiss Franc"s
+		},
+		{
+			Iso4217Codes::CHW,
+			"WIR Franc"s
+		},
+		{
+			Iso4217Codes::CLF,
+			"Unidad de Fomento"s
+		},
+		{
+			Iso4217Codes::CLP,
+			"Chilean Peso"s
+		},
+		{
+			Iso4217Codes::CNY,
+			"Yuan Renminbi"s
+		},
+		{
+			Iso4217Codes::COP,
+			"Colombian Peso"s
+		},
+		{
+			Iso4217Codes::COU,
+			"Unidad de Valor Real"s
+		},
+		{
+			Iso4217Codes::CRC,
+			"Costa Rican Colon"s
+		},
+		{
+			Iso4217Codes::CUC,
+			"Peso Convertible"s
+		},
+		{
+			Iso4217Codes::CUP,
+			"Cuban Peso"s
+		},
+		{
+			Iso4217Codes::CVE,
+			"Cabo Verde Escudo"s
+		},
+		{
+			Iso4217Codes::CZK,
+			"Czech Koruna"s
+		},
+		{
+			Iso4217Codes::DJF,
+			"Djibouti Franc"s
+		},
+		{
+			Iso4217Codes::DKK,
+			"Danish Krone"s
+		},
+		{
+			Iso4217Codes::DOP,
+			"Dominican Peso"s
+		},
+		{
+			Iso4217Codes::DZD,
+			"Algerian Dinar"s
+		},
+		{
+			Iso4217Codes::EGP,
+			"Egyptian Pound"s
+		},
+		{
+			Iso4217Codes::ERN,
+			"Nakfa"s
+		},
+		{
+			Iso4217Codes::ETB,
+			"Ethiopian Birr"s
+		},
+		{
+			Iso4217Codes::EUR,
+			"Euro"s
+		},
+		{
+			Iso4217Codes::FJD,
+			"Fiji Dollar"s
+		},
+		{
+			Iso4217Codes::FKP,
+			"Falkland Islands Pound"s
+		},
+		{
+			Iso4217Codes::GBP,
+			"Pound Sterling"s
+		},
+		{
+			Iso4217Codes::GEL,
+			"Lari"s
+		},
+		{
+			Iso4217Codes::GHS,
+			"Ghana Cedi"s
+		},
+		{
+			Iso4217Codes::GIP,
+			"Gibraltar Pound"s
+		},
+		{
+			Iso4217Codes::GMD,
+			"Dalasi"s
+		},
+		{
+			Iso4217Codes::GNF,
+			"Guinean Franc"s
+		},
+		{
+			Iso4217Codes::GTQ,
+			"Quetzal"s
+		},
+		{
+			Iso4217Codes::GYD,
+			"Guyana Dollar"s
+		},
+		{
+			Iso4217Codes::HKD,
+			"Hong Kong Dollar"s
+		},
+		{
+			Iso4217Codes::HNL,
+			"Lempira"s
+		},
+		{
+			Iso4217Codes::HRK,
+			"Kuna"s
+		},
+		{
+			Iso4217Codes::HTG,
+			"Gourde"s
+		},
+		{
+			Iso4217Codes::HUF,
+			"Forint"s
+		},
+		{
+			Iso4217Codes::IDR,
+			"Rupiah"s
+		},
+		{
+			Iso4217Codes::ILS,
+			"New Israeli Sheqel"s
+		},
+		{
+			Iso4217Codes::INR,
+			"Indian Rupee"s
+		},
+		{
+			Iso4217Codes::IQD,
+			"Iraqi Dinar"s
+		},
+		{
+			Iso4217Codes::IRR,
+			"Iranian Rial"s
+		},
+		{
+			Iso4217Codes::ISK,
+			"Iceland Krona"s
+		},
+		{
+			Iso4217Codes::JMD,
+			"Jamaican Dollar"s
+		},
+		{
+			Iso4217Codes::JOD,
+			"Jordanian Dinar"s
+		},
+		{
+			Iso4217Codes::JPY,
+			"Yen"s
+		},
+		{
+			Iso4217Codes::KES,
+			"Kenyan Shilling"s
+		},
+		{
+			Iso4217Codes::KGS,
+			"Som"s
+		},
+		{
+			Iso4217Codes::KHR,
+			"Riel"s
+		},
+		{
+			Iso4217Codes::KMF,
+			"Comorian Franc "s
+		},
+		{
+			Iso4217Codes::KPW,
+			"North Korean Won"s
+		},
+		{
+			Iso4217Codes::KRW,
+			"Won"s
+		},
+		{
+			Iso4217Codes::KWD,
+			"Kuwaiti Dinar"s
+		},
+		{
+			Iso4217Codes::KYD,
+			"Cayman Islands Dollar"s
+		},
+		{
+			Iso4217Codes::KZT,
+			"Tenge"s
+		},
+		{
+			Iso4217Codes::LAK,
+			"Lao Kip"s
+		},
+		{
+			Iso4217Codes::LBP,
+			"Lebanese Pound"s
+		},
+		{
+			Iso4217Codes::LKR,
+			"Sri Lanka Rupee"s
+		},
+		{
+			Iso4217Codes::LRD,
+			"Liberian Dollar"s
+		},
+		{
+			Iso4217Codes::LSL,
+			"Loti"s
+		},
+		{
+			Iso4217Codes::LYD,
+			"Libyan Dinar"s
+		},
+		{
+			Iso4217Codes::MAD,
+			"Moroccan Dirham"s
+		},
+		{
+			Iso4217Codes::MDL,
+			"Moldovan Leu"s
+		},
+		{
+			Iso4217Codes::MGA,
+			"Malagasy Ariary"s
+		},
+		{
+			Iso4217Codes::MKD,
+			"Denar"s
+		},
+		{
+			Iso4217Codes::MMK,
+			"Kyat"s
+		},
+		{
+			Iso4217Codes::MNT,
+			"Tugrik"s
+		},
+		{
+			Iso4217Codes::MOP,
+			"Pataca"s
+		},
+		{
+			Iso4217Codes::MRU,
+			"Ouguiya"s
+		},
+		{
+			Iso4217Codes::MUR,
+			"Mauritius Rupee"s
+		},
+		{
+			Iso4217Codes::MVR,
+			"Rufiyaa"s
+		},
+		{
+			Iso4217Codes::MWK,
+			"Malawi Kwacha"s
+		},
+		{
+			Iso4217Codes::MXN,
+			"Mexican Peso"s
+		},
+		{
+			Iso4217Codes::MXV,
+			"Mexican Unidad de Inversion (UDI)"s
+		},
+		{
+			Iso4217Codes::MYR,
+			"Malaysian Ringgit"s
+		},
+		{
+			Iso4217Codes::MZN,
+			"Mozambique Metical"s
+		},
+		{
+			Iso4217Codes::NAD,
+			"Namibia Dollar"s
+		},
+		{
+			Iso4217Codes::NGN,
+			"Naira"s
+		},
+		{
+			Iso4217Codes::NIO,
+			"Cordoba Oro"s
+		},
+		{
+			Iso4217Codes::NOK,
+			"Norwegian Krone"s
+		},
+		{
+			Iso4217Codes::NPR,
+			"Nepalese Rupee"s
+		},
+		{
+			Iso4217Codes::NZD,
+			"New Zealand Dollar"s
+		},
+		{
+			Iso4217Codes::OMR,
+			"Rial Omani"s
+		},
+		{
+			Iso4217Codes::PAB,
+			"Balboa"s
+		},
+		{
+			Iso4217Codes::PEN,
+			"Sol"s
+		},
+		{
+			Iso4217Codes::PGK,
+			"Kina"s
+		},
+		{
+			Iso4217Codes::PHP,
+			"Philippine Peso"s
+		},
+		{
+			Iso4217Codes::PKR,
+			"Pakistan Rupee"s
+		},
+		{
+			Iso4217Codes::PLN,
+			"Zloty"s
+		},
+		{
+			Iso4217Codes::PYG,
+			"Guarani"s
+		},
+		{
+			Iso4217Codes::QAR,
+			"Qatari Rial"s
+		},
+		{
+			Iso4217Codes::RON,
+			"Romanian Leu"s
+		},
+		{
+			Iso4217Codes::RSD,
+			"Serbian Dinar"s
+		},
+		{
+			Iso4217Codes::RUB,
+			"Russian Ruble"s
+		},
+		{
+			Iso4217Codes::RWF,
+			"Rwanda Franc"s
+		},
+		{
+			Iso4217Codes::SAR,
+			"Saudi Riyal"s
+		},
+		{
+			Iso4217Codes::SBD,
+			"Solomon Islands Dollar"s
+		},
+		{
+			Iso4217Codes::SCR,
+			"Seychelles Rupee"s
+		},
+		{
+			Iso4217Codes::SDG,
+			"Sudanese Pound"s
+		},
+		{
+			Iso4217Codes::SEK,
+			"Swedish Krona"s
+		},
+		{
+			Iso4217Codes::SGD,
+			"Singapore Dollar"s
+		},
+		{
+			Iso4217Codes::SHP,
+			"Saint Helena Pound"s
+		},
+		{
+			Iso4217Codes::SLL,
+			"Leone"s
+		},
+		{
+			Iso4217Codes::SOS,
+			"Somali Shilling"s
+		},
+		{
+			Iso4217Codes::SRD,
+			"Surinam Dollar"s
+		},
+		{
+			Iso4217Codes::SSP,
+			"South Sudanese Pound"s
+		},
+		{
+			Iso4217Codes::STN,
+			"Dobra"s
+		},
+		{
+			Iso4217Codes::SVC,
+			"El Salvador Colon"s
+		},
+		{
+			Iso4217Codes::SYP,
+			"Syrian Pound"s
+		},
+		{
+			Iso4217Codes::SZL,
+			"Lilangeni"s
+		},
+		{
+			Iso4217Codes::THB,
+			"Baht"s
+		},
+		{
+			Iso4217Codes::TJS,
+			"Somoni"s
+		},
+		{
+			Iso4217Codes::TMT,
+			"Turkmenistan New Manat"s
+		},
+		{
+			Iso4217Codes::TND,
+			"Tunisian Dinar"s
+		},
+		{
+			Iso4217Codes::TOP,
+			"Pa’anga"s
+		},
+		{
+			Iso4217Codes::TRY,
+			"Turkish Lira"s
+		},
+		{
+			Iso4217Codes::TTD,
+			"Trinidad and Tobago Dollar"s
+		},
+		{
+			Iso4217Codes::TWD,
+			"New Taiwan Dollar"s
+		},
+		{
+			Iso4217Codes::TZS,
+			"Tanzanian Shilling"s
+		},
+		{
+			Iso4217Codes::UAH,
+			"Hryvnia"s
+		},
+		{
+			Iso4217Codes::UGX,
+			"Uganda Shilling"s
+		},
+		{
+			Iso4217Codes::USD,
+			"US Dollar"s
+		},
+		{
+			Iso4217Codes::USN,
+			"US Dollar (Next day)"s
+		},
+		{
+			Iso4217Codes::UYI,
+			"Uruguay Peso en Unidades Indexadas (UI)"s
+		},
+		{
+			Iso4217Codes::UYU,
+			"Peso Uruguayo"s
+		},
+		{
+			Iso4217Codes::UYW,
+			"Unidad Previsional"s
+		},
+		{
+			Iso4217Codes::UZS,
+			"Uzbekistan Sum"s
+		},
+		{
+			Iso4217Codes::VES,
+			"Bolívar Soberano"s
+		},
+		{
+			Iso4217Codes::VND,
+			"Dong"s
+		},
+		{
+			Iso4217Codes::VUV,
+			"Vatu"s
+		},
+		{
+			Iso4217Codes::WST,
+			"Tala"s
+		},
+		{
+			Iso4217Codes::XAF,
+			"CFA Franc BEAC"s
+		},
+		{
+			Iso4217Codes::XAG,
+			"Silver"s
+		},
+		{
+			Iso4217Codes::XAU,
+			"Gold"s
+		},
+		{
+			Iso4217Codes::XBA,
+			"Bond Markets Unit European Composite Unit (EURCO)"s
+		},
+		{
+			Iso4217Codes::XBB,
+			"Bond Markets Unit European Monetary Unit (E.M.U.-6)"s
+		},
+		{
+			Iso4217Codes::XBC,
+			"Bond Markets Unit European Unit of Account 9 (E.U.A.-9)"s
+		},
+		{
+			Iso4217Codes::XBD,
+			"Bond Markets Unit European Unit of Account 17 (E.U.A.-17)"s
+		},
+		{
+			Iso4217Codes::XCD,
+			"East Caribbean Dollar"s
+		},
+		{
+			Iso4217Codes::XDR,
+			"SDR (Special Drawing Right)"s
+		},
+		{
+			Iso4217Codes::XOF,
+			"CFA Franc BCEAO"s
+		},
+		{
+			Iso4217Codes::XPD,
+			"Palladium"s
+		},
+		{
+			Iso4217Codes::XPF,
+			"CFP Franc"s
+		},
+		{
+			Iso4217Codes::XPT,
+			"Platinum"s
+		},
+		{
+			Iso4217Codes::XSU,
+			"Sucre"s
+		},
+		{
+			Iso4217Codes::XTS,
+			"Codes specifically reserved for testing purposes"s
+		},
+		{
+			Iso4217Codes::XUA,
+			"ADB Unit of Account"s
+		},
+		{
+			Iso4217Codes::XXX,
+			"The codes assigned for transactions where no currency is involved"s
+		},
+		{
+			Iso4217Codes::YER,
+			"Yemeni Rial"s
+		},
+		{
+			Iso4217Codes::ZAR,
+			"Rand"s
+		},
+		{
+			Iso4217Codes::ZMW,
+			"Zambian Kwacha"s
+		},
+		{
+			Iso4217Codes::ZWL,
+			"Zimbabwe Dollar"s
+		}
+	};
+	return codeNames.at(code);
+}
+
+const array<Iso4217Codes, numberOfIso4217Codes> pecunia::currency::allIso4217Codes
+{
+	{
+		Iso4217Codes::AED,
+		Iso4217Codes::AFN,
+		Iso4217Codes::ALL,
+		Iso4217Codes::AMD,
+		Iso4217Codes::ANG,
+		Iso4217Codes::AOA,
+		Iso4217Codes::ARS,
+		Iso4217Codes::AUD,
+		Iso4217Codes::AWG,
+		Iso4217Codes::AZN,
+		Iso4217Codes::BAM,
+		Iso4217Codes::BBD,
+		Iso4217Codes::BDT,
+		Iso4217Codes::BGN,
+		Iso4217Codes::BHD,
+		Iso4217Codes::BIF,
+		Iso4217Codes::BMD,
+		Iso4217Codes::BND,
+		Iso4217Codes::BOB,
+		Iso4217Codes::BOV,
+		Iso4217Codes::BRL,
+		Iso4217Codes::BSD,
+		Iso4217Codes::BTN,
+		Iso4217Codes::BWP,
+		Iso4217Codes::BYN,
+		Iso4217Codes::BZD,
+		Iso4217Codes::CAD,
+		Iso4217Codes::CDF,
+		Iso4217Codes::CHE,
+		Iso4217Codes::CHF,
+		Iso4217Codes::CHW,
+		Iso4217Codes::CLF,
+		Iso4217Codes::CLP,
+		Iso4217Codes::CNY,
+		Iso4217Codes::COP,
+		Iso4217Codes::COU,
+		Iso4217Codes::CRC,
+		Iso4217Codes::CUC,
+		Iso4217Codes::CUP,
+		Iso4217Codes::CVE,
+		Iso4217Codes::CZK,
+		Iso4217Codes::DJF,
+		Iso4217Codes::DKK,
+		Iso4217Codes::DOP,
+		Iso4217Codes::DZD,
+		Iso4217Codes::EGP,
+		Iso4217Codes::ERN,
+		Iso4217Codes::ETB,
+		Iso4217Codes::EUR,
+		Iso4217Codes::FJD,
+		Iso4217Codes::FKP,
+		Iso4217Codes::GBP,
+		Iso4217Codes::GEL,
+		Iso4217Codes::GHS,
+		Iso4217Codes::GIP,
+		Iso4217Codes::GMD,
+		Iso4217Codes::GNF,
+		Iso4217Codes::GTQ,
+		Iso4217Codes::GYD,
+		Iso4217Codes::HKD,
+		Iso4217Codes::HNL,
+		Iso4217Codes::HRK,
+		Iso4217Codes::HTG,
+		Iso4217Codes::HUF,
+		Iso4217Codes::IDR,
+		Iso4217Codes::ILS,
+		Iso4217Codes::INR,
+		Iso4217Codes::IQD,
+		Iso4217Codes::IRR,
+		Iso4217Codes::ISK,
+		Iso4217Codes::JMD,
+		Iso4217Codes::JOD,
+		Iso4217Codes::JPY,
+		Iso4217Codes::KES,
+		Iso4217Codes::KGS,
+		Iso4217Codes::KHR,
+		Iso4217Codes::KMF,
+		Iso4217Codes::KPW,
+		Iso4217Codes::KRW,
+		Iso4217Codes::KWD,
+		Iso4217Codes::KYD,
+		Iso4217Codes::KZT,
+		Iso4217Codes::LAK,
+		Iso4217Codes::LBP,
+		Iso4217Codes::LKR,
+		Iso4217Codes::LRD,
+		Iso4217Codes::LSL,
+		Iso4217Codes::LYD,
+		Iso4217Codes::MAD,
+		Iso4217Codes::MDL,
+		Iso4217Codes::MGA,
+		Iso4217Codes::MKD,
+		Iso4217Codes::MMK,
+		Iso4217Codes::MNT,
+		Iso4217Codes::MOP,
+		Iso4217Codes::MRU,
+		Iso4217Codes::MUR,
+		Iso4217Codes::MVR,
+		Iso4217Codes::MWK,
+		Iso4217Codes::MXN,
+		Iso4217Codes::MXV,
+		Iso4217Codes::MYR,
+		Iso4217Codes::MZN,
+		Iso4217Codes::NAD,
+		Iso4217Codes::NGN,
+		Iso4217Codes::NIO,
+		Iso4217Codes::NOK,
+		Iso4217Codes::NPR,
+		Iso4217Codes::NZD,
+		Iso4217Codes::OMR,
+		Iso4217Codes::PAB,
+		Iso4217Codes::PEN,
+		Iso4217Codes::PGK,
+		Iso4217Codes::PHP,
+		Iso4217Codes::PKR,
+		Iso4217Codes::PLN,
+		Iso4217Codes::PYG,
+		Iso4217Codes::QAR,
+		Iso4217Codes::RON,
+		Iso4217Codes::RSD,
+		Iso4217Codes::RUB,
+		Iso4217Codes::RWF,
+		Iso4217Codes::SAR,
+		Iso4217Codes::SBD,
+		Iso4217Codes::SCR,
+		Iso4217Codes::SDG,
+		Iso4217Codes::SEK,
+		Iso4217Codes::SGD,
+		Iso4217Codes::SHP,
+		Iso4217Codes::SLL,
+		Iso4217Codes::SOS,
+		Iso4217Codes::SRD,
+		Iso4217Codes::SSP,
+		Iso4217Codes::STN,
+		Iso4217Codes::SVC,
+		Iso4217Codes::SYP,
+		Iso4217Codes::SZL,
+		Iso4217Codes::THB,
+		Iso4217Codes::TJS,
+		Iso4217Codes::TMT,
+		Iso4217Codes::TND,
+		Iso4217Codes::TOP,
+		Iso4217Codes::TRY,
+		Iso4217Codes::TTD,
+		Iso4217Codes::TWD,
+		Iso4217Codes::TZS,
+		Iso4217Codes::UAH,
+		Iso4217Codes::UGX,
+		Iso4217Codes::USD,
+		Iso4217Codes::USN,
+		Iso4217Codes::UYI,
+		Iso4217Codes::UYU,
+		Iso4217Codes::UYW,
+		Iso4217Codes::UZS,
+		Iso4217Codes::VES,
+		Iso4217Codes::VND,
+		Iso4217Codes::VUV,
+		Iso4217Codes::WST,
+		Iso4217Codes::XAF,
+		Iso4217Codes::XAG,
+		Iso4217Codes::XAU,
+		Iso4217Codes::XBA,
+		Iso4217Codes::XBB,
+		Iso4217Codes::XBC,
+		Iso4217Codes::XBD,
+		Iso4217Codes::XCD,
+		Iso4217Codes::XDR,
+		Iso4217Codes::XOF,
+		Iso4217Codes::XPD,
+		Iso4217Codes::XPF,
+		Iso4217Codes::XPT,
+		Iso4217Codes::XSU,
+		Iso4217Codes::XTS,
+		Iso4217Codes::XUA,
+		Iso4217Codes::XXX,
+		Iso4217Codes::YER,
+		Iso4217Codes::ZAR,
+		Iso4217Codes::ZMW,
+		Iso4217Codes::ZWL
+	}
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Codes.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,517 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_CURRENCY_CODES_H_
+#define PECUNIA_CURRENCY_CODES_H_
+
+//  ██████╗  ██████╗     ███╗   ██╗ ██████╗ ████████╗    ███████╗██████╗ ██╗████████╗██╗
+//  ██╔══██╗██╔═══██╗    ████╗  ██║██╔═══██╗╚══██╔══╝    ██╔════╝██╔══██╗██║╚══██╔══╝██║
+//  ██║  ██║██║   ██║    ██╔██╗ ██║██║   ██║   ██║       █████╗  ██║  ██║██║   ██║   ██║
+//  ██║  ██║██║   ██║    ██║╚██╗██║██║   ██║   ██║       ██╔══╝  ██║  ██║██║   ██║   ╚═╝
+//  ██████╔╝╚██████╔╝    ██║ ╚████║╚██████╔╝   ██║       ███████╗██████╔╝██║   ██║   ██╗
+//  ╚═════╝  ╚═════╝     ╚═╝  ╚═══╝ ╚═════╝    ╚═╝       ╚══════╝╚═════╝ ╚═╝   ╚═╝   ╚═╝
+//
+//  ███████╗██╗██╗     ███████╗     ██████╗ ██████╗ ███╗   ██╗████████╗███████╗███╗   ██╗████████╗
+//  ██╔════╝██║██║     ██╔════╝    ██╔════╝██╔═══██╗████╗  ██║╚══██╔══╝██╔════╝████╗  ██║╚══██╔══╝
+//  █████╗  ██║██║     █████╗      ██║     ██║   ██║██╔██╗ ██║   ██║   █████╗  ██╔██╗ ██║   ██║
+//  ██╔══╝  ██║██║     ██╔══╝      ██║     ██║   ██║██║╚██╗██║   ██║   ██╔══╝  ██║╚██╗██║   ██║
+//  ██║     ██║███████╗███████╗    ╚██████╗╚██████╔╝██║ ╚████║   ██║   ███████╗██║ ╚████║   ██║
+//  ╚═╝     ╚═╝╚══════╝╚══════╝     ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝   ╚═╝   ╚══════╝╚═╝  ╚═══╝   ╚═╝
+//
+//   ██████╗██████╗ ███████╗ █████╗ ████████╗██╗ ██████╗ ███╗   ██╗    ██╗███████╗
+//  ██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗  ██║    ██║██╔════╝
+//  ██║     ██████╔╝█████╗  ███████║   ██║   ██║██║   ██║██╔██╗ ██║    ██║███████╗
+//  ██║     ██╔══██╗██╔══╝  ██╔══██║   ██║   ██║██║   ██║██║╚██╗██║    ██║╚════██║
+//  ╚██████╗██║  ██║███████╗██║  ██║   ██║   ██║╚██████╔╝██║ ╚████║    ██║███████║
+//   ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝    ╚═╝╚══════╝
+//
+//   █████╗ ██╗   ██╗████████╗ ██████╗ ███╗   ███╗ █████╗ ████████╗███████╗██████╗
+//  ██╔══██╗██║   ██║╚══██╔══╝██╔═══██╗████╗ ████║██╔══██╗╚══██╔══╝██╔════╝██╔══██╗
+//  ███████║██║   ██║   ██║   ██║   ██║██╔████╔██║███████║   ██║   █████╗  ██║  ██║
+//  ██╔══██║██║   ██║   ██║   ██║   ██║██║╚██╔╝██║██╔══██║   ██║   ██╔══╝  ██║  ██║
+//  ██║  ██║╚██████╔╝   ██║   ╚██████╔╝██║ ╚═╝ ██║██║  ██║   ██║   ███████╗██████╔╝██╗
+//  ╚═╝  ╚═╝ ╚═════╝    ╚═╝    ╚═════╝ ╚═╝     ╚═╝╚═╝  ╚═╝   ╚═╝   ╚══════╝╚═════╝ ╚═╝
+// Generated At: 2021-01-19T16:37:57.856699
+
+#include <array>
+#include <cstdint>
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "pecunia_export.h"
+
+
+namespace pecunia
+{
+namespace currency
+{
+
+/**
+ * @brief The unique identifier for a country's currency, monetary market, etc..
+ *
+ * @see ISO 4217 https://en.wikipedia.org/wiki/ISO_4217
+ */
+enum class PECUNIA_EXPORT Iso4217Codes : std::uint16_t
+{
+	/// The currency code for the "UAE Dirham" used in: UNITED ARAB EMIRATES (THE).
+	AED = 784,
+	/// The currency code for the "Afghani" used in: AFGHANISTAN.
+	AFN = 971,
+	/// The currency code for the "Lek" used in: ALBANIA.
+	ALL = 8,
+	/// The currency code for the "Armenian Dram" used in: ARMENIA.
+	AMD = 51,
+	/// The currency code for the "Netherlands Antillean Guilder" used in: CURAÇAO; SINT MAARTEN (DUTCH PART).
+	ANG = 532,
+	/// The currency code for the "Kwanza" used in: ANGOLA.
+	AOA = 973,
+	/// The currency code for the "Argentine Peso" used in: ARGENTINA.
+	ARS = 32,
+	/// The currency code for the "Australian Dollar" used in: AUSTRALIA; CHRISTMAS ISLAND; COCOS (KEELING) ISLANDS (THE); HEARD ISLAND AND McDONALD ISLANDS; KIRIBATI; NAURU; NORFOLK ISLAND; TUVALU.
+	AUD = 36,
+	/// The currency code for the "Aruban Florin" used in: ARUBA.
+	AWG = 533,
+	/// The currency code for the "Azerbaijan Manat" used in: AZERBAIJAN.
+	AZN = 944,
+	/// The currency code for the "Convertible Mark" used in: BOSNIA AND HERZEGOVINA.
+	BAM = 977,
+	/// The currency code for the "Barbados Dollar" used in: BARBADOS.
+	BBD = 52,
+	/// The currency code for the "Taka" used in: BANGLADESH.
+	BDT = 50,
+	/// The currency code for the "Bulgarian Lev" used in: BULGARIA.
+	BGN = 975,
+	/// The currency code for the "Bahraini Dinar" used in: BAHRAIN.
+	BHD = 48,
+	/// The currency code for the "Burundi Franc" used in: BURUNDI.
+	BIF = 108,
+	/// The currency code for the "Bermudian Dollar" used in: BERMUDA.
+	BMD = 60,
+	/// The currency code for the "Brunei Dollar" used in: BRUNEI DARUSSALAM.
+	BND = 96,
+	/// The currency code for the "Boliviano" used in: BOLIVIA (PLURINATIONAL STATE OF).
+	BOB = 68,
+	/// The currency code for the "Mvdol" used in: BOLIVIA (PLURINATIONAL STATE OF).
+	BOV = 984,
+	/// The currency code for the "Brazilian Real" used in: BRAZIL.
+	BRL = 986,
+	/// The currency code for the "Bahamian Dollar" used in: BAHAMAS (THE).
+	BSD = 44,
+	/// The currency code for the "Ngultrum" used in: BHUTAN.
+	BTN = 64,
+	/// The currency code for the "Pula" used in: BOTSWANA.
+	BWP = 72,
+	/// The currency code for the "Belarusian Ruble" used in: BELARUS.
+	BYN = 933,
+	/// The currency code for the "Belize Dollar" used in: BELIZE.
+	BZD = 84,
+	/// The currency code for the "Canadian Dollar" used in: CANADA.
+	CAD = 124,
+	/// The currency code for the "Congolese Franc" used in: CONGO (THE DEMOCRATIC REPUBLIC OF THE).
+	CDF = 976,
+	/// The currency code for the "WIR Euro" used in: SWITZERLAND.
+	CHE = 947,
+	/// The currency code for the "Swiss Franc" used in: LIECHTENSTEIN; SWITZERLAND.
+	CHF = 756,
+	/// The currency code for the "WIR Franc" used in: SWITZERLAND.
+	CHW = 948,
+	/// The currency code for the "Unidad de Fomento" used in: CHILE.
+	CLF = 990,
+	/// The currency code for the "Chilean Peso" used in: CHILE.
+	CLP = 152,
+	/// The currency code for the "Yuan Renminbi" used in: CHINA.
+	CNY = 156,
+	/// The currency code for the "Colombian Peso" used in: COLOMBIA.
+	COP = 170,
+	/// The currency code for the "Unidad de Valor Real" used in: COLOMBIA.
+	COU = 970,
+	/// The currency code for the "Costa Rican Colon" used in: COSTA RICA.
+	CRC = 188,
+	/// The currency code for the "Peso Convertible" used in: CUBA.
+	CUC = 931,
+	/// The currency code for the "Cuban Peso" used in: CUBA.
+	CUP = 192,
+	/// The currency code for the "Cabo Verde Escudo" used in: CABO VERDE.
+	CVE = 132,
+	/// The currency code for the "Czech Koruna" used in: CZECHIA.
+	CZK = 203,
+	/// The currency code for the "Djibouti Franc" used in: DJIBOUTI.
+	DJF = 262,
+	/// The currency code for the "Danish Krone" used in: DENMARK; FAROE ISLANDS (THE); GREENLAND.
+	DKK = 208,
+	/// The currency code for the "Dominican Peso" used in: DOMINICAN REPUBLIC (THE).
+	DOP = 214,
+	/// The currency code for the "Algerian Dinar" used in: ALGERIA.
+	DZD = 12,
+	/// The currency code for the "Egyptian Pound" used in: EGYPT.
+	EGP = 818,
+	/// The currency code for the "Nakfa" used in: ERITREA.
+	ERN = 232,
+	/// The currency code for the "Ethiopian Birr" used in: ETHIOPIA.
+	ETB = 230,
+	/// The currency code for the "Euro" used in: ANDORRA; AUSTRIA; BELGIUM; CYPRUS; ESTONIA; EUROPEAN UNION; FINLAND; FRANCE; FRENCH GUIANA; FRENCH SOUTHERN TERRITORIES (THE); GERMANY; GREECE; GUADELOUPE; HOLY SEE (THE); IRELAND; ITALY; LATVIA; LITHUANIA; LUXEMBOURG; MALTA; MARTINIQUE; MAYOTTE; MONACO; MONTENEGRO; NETHERLANDS (THE); PORTUGAL; RÉUNION; SAINT BARTHÉLEMY; SAINT MARTIN (FRENCH PART); SAINT PIERRE AND MIQUELON; SAN MARINO; SLOVAKIA; SLOVENIA; SPAIN; ÅLAND ISLANDS.
+	EUR = 978,
+	/// The currency code for the "Fiji Dollar" used in: FIJI.
+	FJD = 242,
+	/// The currency code for the "Falkland Islands Pound" used in: FALKLAND ISLANDS (THE) [MALVINAS].
+	FKP = 238,
+	/// The currency code for the "Pound Sterling" used in: GUERNSEY; ISLE OF MAN; JERSEY; UNITED KINGDOM OF GREAT BRITAIN AND NORTHERN IRELAND (THE).
+	GBP = 826,
+	/// The currency code for the "Lari" used in: GEORGIA.
+	GEL = 981,
+	/// The currency code for the "Ghana Cedi" used in: GHANA.
+	GHS = 936,
+	/// The currency code for the "Gibraltar Pound" used in: GIBRALTAR.
+	GIP = 292,
+	/// The currency code for the "Dalasi" used in: GAMBIA (THE).
+	GMD = 270,
+	/// The currency code for the "Guinean Franc" used in: GUINEA.
+	GNF = 324,
+	/// The currency code for the "Quetzal" used in: GUATEMALA.
+	GTQ = 320,
+	/// The currency code for the "Guyana Dollar" used in: GUYANA.
+	GYD = 328,
+	/// The currency code for the "Hong Kong Dollar" used in: HONG KONG.
+	HKD = 344,
+	/// The currency code for the "Lempira" used in: HONDURAS.
+	HNL = 340,
+	/// The currency code for the "Kuna" used in: CROATIA.
+	HRK = 191,
+	/// The currency code for the "Gourde" used in: HAITI.
+	HTG = 332,
+	/// The currency code for the "Forint" used in: HUNGARY.
+	HUF = 348,
+	/// The currency code for the "Rupiah" used in: INDONESIA.
+	IDR = 360,
+	/// The currency code for the "New Israeli Sheqel" used in: ISRAEL.
+	ILS = 376,
+	/// The currency code for the "Indian Rupee" used in: BHUTAN; INDIA.
+	INR = 356,
+	/// The currency code for the "Iraqi Dinar" used in: IRAQ.
+	IQD = 368,
+	/// The currency code for the "Iranian Rial" used in: IRAN (ISLAMIC REPUBLIC OF).
+	IRR = 364,
+	/// The currency code for the "Iceland Krona" used in: ICELAND.
+	ISK = 352,
+	/// The currency code for the "Jamaican Dollar" used in: JAMAICA.
+	JMD = 388,
+	/// The currency code for the "Jordanian Dinar" used in: JORDAN.
+	JOD = 400,
+	/// The currency code for the "Yen" used in: JAPAN.
+	JPY = 392,
+	/// The currency code for the "Kenyan Shilling" used in: KENYA.
+	KES = 404,
+	/// The currency code for the "Som" used in: KYRGYZSTAN.
+	KGS = 417,
+	/// The currency code for the "Riel" used in: CAMBODIA.
+	KHR = 116,
+	/// The currency code for the "Comorian Franc " used in: COMOROS (THE).
+	KMF = 174,
+	/// The currency code for the "North Korean Won" used in: KOREA (THE DEMOCRATIC PEOPLE’S REPUBLIC OF).
+	KPW = 408,
+	/// The currency code for the "Won" used in: KOREA (THE REPUBLIC OF).
+	KRW = 410,
+	/// The currency code for the "Kuwaiti Dinar" used in: KUWAIT.
+	KWD = 414,
+	/// The currency code for the "Cayman Islands Dollar" used in: CAYMAN ISLANDS (THE).
+	KYD = 136,
+	/// The currency code for the "Tenge" used in: KAZAKHSTAN.
+	KZT = 398,
+	/// The currency code for the "Lao Kip" used in: LAO PEOPLE’S DEMOCRATIC REPUBLIC (THE).
+	LAK = 418,
+	/// The currency code for the "Lebanese Pound" used in: LEBANON.
+	LBP = 422,
+	/// The currency code for the "Sri Lanka Rupee" used in: SRI LANKA.
+	LKR = 144,
+	/// The currency code for the "Liberian Dollar" used in: LIBERIA.
+	LRD = 430,
+	/// The currency code for the "Loti" used in: LESOTHO.
+	LSL = 426,
+	/// The currency code for the "Libyan Dinar" used in: LIBYA.
+	LYD = 434,
+	/// The currency code for the "Moroccan Dirham" used in: MOROCCO; WESTERN SAHARA.
+	MAD = 504,
+	/// The currency code for the "Moldovan Leu" used in: MOLDOVA (THE REPUBLIC OF).
+	MDL = 498,
+	/// The currency code for the "Malagasy Ariary" used in: MADAGASCAR.
+	MGA = 969,
+	/// The currency code for the "Denar" used in: NORTH MACEDONIA.
+	MKD = 807,
+	/// The currency code for the "Kyat" used in: MYANMAR.
+	MMK = 104,
+	/// The currency code for the "Tugrik" used in: MONGOLIA.
+	MNT = 496,
+	/// The currency code for the "Pataca" used in: MACAO.
+	MOP = 446,
+	/// The currency code for the "Ouguiya" used in: MAURITANIA.
+	MRU = 929,
+	/// The currency code for the "Mauritius Rupee" used in: MAURITIUS.
+	MUR = 480,
+	/// The currency code for the "Rufiyaa" used in: MALDIVES.
+	MVR = 462,
+	/// The currency code for the "Malawi Kwacha" used in: MALAWI.
+	MWK = 454,
+	/// The currency code for the "Mexican Peso" used in: MEXICO.
+	MXN = 484,
+	/// The currency code for the "Mexican Unidad de Inversion (UDI)" used in: MEXICO.
+	MXV = 979,
+	/// The currency code for the "Malaysian Ringgit" used in: MALAYSIA.
+	MYR = 458,
+	/// The currency code for the "Mozambique Metical" used in: MOZAMBIQUE.
+	MZN = 943,
+	/// The currency code for the "Namibia Dollar" used in: NAMIBIA.
+	NAD = 516,
+	/// The currency code for the "Naira" used in: NIGERIA.
+	NGN = 566,
+	/// The currency code for the "Cordoba Oro" used in: NICARAGUA.
+	NIO = 558,
+	/// The currency code for the "Norwegian Krone" used in: BOUVET ISLAND; NORWAY; SVALBARD AND JAN MAYEN.
+	NOK = 578,
+	/// The currency code for the "Nepalese Rupee" used in: NEPAL.
+	NPR = 524,
+	/// The currency code for the "New Zealand Dollar" used in: COOK ISLANDS (THE); NEW ZEALAND; NIUE; PITCAIRN; TOKELAU.
+	NZD = 554,
+	/// The currency code for the "Rial Omani" used in: OMAN.
+	OMR = 512,
+	/// The currency code for the "Balboa" used in: PANAMA.
+	PAB = 590,
+	/// The currency code for the "Sol" used in: PERU.
+	PEN = 604,
+	/// The currency code for the "Kina" used in: PAPUA NEW GUINEA.
+	PGK = 598,
+	/// The currency code for the "Philippine Peso" used in: PHILIPPINES (THE).
+	PHP = 608,
+	/// The currency code for the "Pakistan Rupee" used in: PAKISTAN.
+	PKR = 586,
+	/// The currency code for the "Zloty" used in: POLAND.
+	PLN = 985,
+	/// The currency code for the "Guarani" used in: PARAGUAY.
+	PYG = 600,
+	/// The currency code for the "Qatari Rial" used in: QATAR.
+	QAR = 634,
+	/// The currency code for the "Romanian Leu" used in: ROMANIA.
+	RON = 946,
+	/// The currency code for the "Serbian Dinar" used in: SERBIA.
+	RSD = 941,
+	/// The currency code for the "Russian Ruble" used in: RUSSIAN FEDERATION (THE).
+	RUB = 643,
+	/// The currency code for the "Rwanda Franc" used in: RWANDA.
+	RWF = 646,
+	/// The currency code for the "Saudi Riyal" used in: SAUDI ARABIA.
+	SAR = 682,
+	/// The currency code for the "Solomon Islands Dollar" used in: SOLOMON ISLANDS.
+	SBD = 90,
+	/// The currency code for the "Seychelles Rupee" used in: SEYCHELLES.
+	SCR = 690,
+	/// The currency code for the "Sudanese Pound" used in: SUDAN (THE).
+	SDG = 938,
+	/// The currency code for the "Swedish Krona" used in: SWEDEN.
+	SEK = 752,
+	/// The currency code for the "Singapore Dollar" used in: SINGAPORE.
+	SGD = 702,
+	/// The currency code for the "Saint Helena Pound" used in: SAINT HELENA, ASCENSION AND TRISTAN DA CUNHA.
+	SHP = 654,
+	/// The currency code for the "Leone" used in: SIERRA LEONE.
+	SLL = 694,
+	/// The currency code for the "Somali Shilling" used in: SOMALIA.
+	SOS = 706,
+	/// The currency code for the "Surinam Dollar" used in: SURINAME.
+	SRD = 968,
+	/// The currency code for the "South Sudanese Pound" used in: SOUTH SUDAN.
+	SSP = 728,
+	/// The currency code for the "Dobra" used in: SAO TOME AND PRINCIPE.
+	STN = 930,
+	/// The currency code for the "El Salvador Colon" used in: EL SALVADOR.
+	SVC = 222,
+	/// The currency code for the "Syrian Pound" used in: SYRIAN ARAB REPUBLIC.
+	SYP = 760,
+	/// The currency code for the "Lilangeni" used in: ESWATINI.
+	SZL = 748,
+	/// The currency code for the "Baht" used in: THAILAND.
+	THB = 764,
+	/// The currency code for the "Somoni" used in: TAJIKISTAN.
+	TJS = 972,
+	/// The currency code for the "Turkmenistan New Manat" used in: TURKMENISTAN.
+	TMT = 934,
+	/// The currency code for the "Tunisian Dinar" used in: TUNISIA.
+	TND = 788,
+	/// The currency code for the "Pa’anga" used in: TONGA.
+	TOP = 776,
+	/// The currency code for the "Turkish Lira" used in: TURKEY.
+	TRY = 949,
+	/// The currency code for the "Trinidad and Tobago Dollar" used in: TRINIDAD AND TOBAGO.
+	TTD = 780,
+	/// The currency code for the "New Taiwan Dollar" used in: TAIWAN (PROVINCE OF CHINA).
+	TWD = 901,
+	/// The currency code for the "Tanzanian Shilling" used in: TANZANIA, UNITED REPUBLIC OF.
+	TZS = 834,
+	/// The currency code for the "Hryvnia" used in: UKRAINE.
+	UAH = 980,
+	/// The currency code for the "Uganda Shilling" used in: UGANDA.
+	UGX = 800,
+	/// The currency code for the "US Dollar" used in: AMERICAN SAMOA; BONAIRE, SINT EUSTATIUS AND SABA; BRITISH INDIAN OCEAN TERRITORY (THE); ECUADOR; EL SALVADOR; GUAM; HAITI; MARSHALL ISLANDS (THE); MICRONESIA (FEDERATED STATES OF); NORTHERN MARIANA ISLANDS (THE); PALAU; PANAMA; PUERTO RICO; TIMOR-LESTE; TURKS AND CAICOS ISLANDS (THE); UNITED STATES MINOR OUTLYING ISLANDS (THE); UNITED STATES OF AMERICA (THE); VIRGIN ISLANDS (BRITISH); VIRGIN ISLANDS (U.S.).
+	USD = 840,
+	/// The currency code for the "US Dollar (Next day)" used in: UNITED STATES OF AMERICA (THE).
+	USN = 997,
+	/// The currency code for the "Uruguay Peso en Unidades Indexadas (UI)" used in: URUGUAY.
+	UYI = 940,
+	/// The currency code for the "Peso Uruguayo" used in: URUGUAY.
+	UYU = 858,
+	/// The currency code for the "Unidad Previsional" used in: URUGUAY.
+	UYW = 927,
+	/// The currency code for the "Uzbekistan Sum" used in: UZBEKISTAN.
+	UZS = 860,
+	/// The currency code for the "Bolívar Soberano" used in: VENEZUELA (BOLIVARIAN REPUBLIC OF).
+	VES = 928,
+	/// The currency code for the "Dong" used in: VIET NAM.
+	VND = 704,
+	/// The currency code for the "Vatu" used in: VANUATU.
+	VUV = 548,
+	/// The currency code for the "Tala" used in: SAMOA.
+	WST = 882,
+	/// The currency code for the "CFA Franc BEAC" used in: CAMEROON; CENTRAL AFRICAN REPUBLIC (THE); CHAD; CONGO (THE); EQUATORIAL GUINEA; GABON.
+	XAF = 950,
+	/// The currency code for the "Silver" used in: ZZ11_Silver.
+	XAG = 961,
+	/// The currency code for the "Gold" used in: ZZ08_Gold.
+	XAU = 959,
+	/// The currency code for the "Bond Markets Unit European Composite Unit (EURCO)" used in: ZZ01_Bond Markets Unit European_EURCO.
+	XBA = 955,
+	/// The currency code for the "Bond Markets Unit European Monetary Unit (E.M.U.-6)" used in: ZZ02_Bond Markets Unit European_EMU-6.
+	XBB = 956,
+	/// The currency code for the "Bond Markets Unit European Unit of Account 9 (E.U.A.-9)" used in: ZZ03_Bond Markets Unit European_EUA-9.
+	XBC = 957,
+	/// The currency code for the "Bond Markets Unit European Unit of Account 17 (E.U.A.-17)" used in: ZZ04_Bond Markets Unit European_EUA-17.
+	XBD = 958,
+	/// The currency code for the "East Caribbean Dollar" used in: ANGUILLA; ANTIGUA AND BARBUDA; DOMINICA; GRENADA; MONTSERRAT; SAINT KITTS AND NEVIS; SAINT LUCIA; SAINT VINCENT AND THE GRENADINES.
+	XCD = 951,
+	/// The currency code for the "SDR (Special Drawing Right)" used in: INTERNATIONAL MONETARY FUND (IMF) .
+	XDR = 960,
+	/// The currency code for the "CFA Franc BCEAO" used in: BENIN; BURKINA FASO; CÔTE D'IVOIRE; GUINEA-BISSAU; MALI; NIGER (THE); SENEGAL; TOGO.
+	XOF = 952,
+	/// The currency code for the "Palladium" used in: ZZ09_Palladium.
+	XPD = 964,
+	/// The currency code for the "CFP Franc" used in: FRENCH POLYNESIA; NEW CALEDONIA; WALLIS AND FUTUNA.
+	XPF = 953,
+	/// The currency code for the "Platinum" used in: ZZ10_Platinum.
+	XPT = 962,
+	/// The currency code for the "Sucre" used in: SISTEMA UNITARIO DE COMPENSACION REGIONAL DE PAGOS "SUCRE".
+	XSU = 994,
+	/// The currency code for the "Codes specifically reserved for testing purposes" used in: ZZ06_Testing_Code.
+	XTS = 963,
+	/// The currency code for the "ADB Unit of Account" used in: MEMBER COUNTRIES OF THE AFRICAN DEVELOPMENT BANK GROUP.
+	XUA = 965,
+	/// The currency code for the "The codes assigned for transactions where no currency is involved" used in: ZZ07_No_Currency.
+	XXX = 999,
+	/// The currency code for the "Yemeni Rial" used in: YEMEN.
+	YER = 886,
+	/// The currency code for the "Rand" used in: LESOTHO; NAMIBIA; SOUTH AFRICA.
+	ZAR = 710,
+	/// The currency code for the "Zambian Kwacha" used in: ZAMBIA.
+	ZMW = 967,
+	/// The currency code for the "Zimbabwe Dollar" used in: ZIMBABWE.
+	ZWL = 932,
+};
+
+/**
+ * @brief Converts from a strongly-typed ISO code to a weak string form.
+ *
+ * @param[in] code The country's monetary unit whose ISO code is to be converted.
+ *
+ * @return The weak type form of the ISO code.
+ */
+PECUNIA_EXPORT std::string toStdString(const Iso4217Codes& code);
+/**
+ * @brief Converts from a weakly-typed ISO code to the strongly-typed form. The code must be all
+ * upper-cased for the match to be performed.
+ *
+ * @exception std::runtime_error When the supplied weak code does not match any known strong code.
+ *
+ * @param[in] code The country's monetary unit whose ISO code is to be converted.
+ *
+ * @return The strong type form of the ISO code.
+ */
+PECUNIA_EXPORT Iso4217Codes toIso4217Code(const std::string& code);
+/**
+ * @brief Provides the native currency symbol used by a currency code. N.B. currency symbols are
+ * shared by others and are therefore cannot be unique.
+ *
+ * @note Currently not all codes are supported.
+ *
+ * @param[in] code The country's monetary unit whose currency symbol is desired.
+ *
+ * @return The string representation of the currency symbol.
+ */
+PECUNIA_EXPORT std::string currencySymbol(const Iso4217Codes& code);
+/**
+ * @brief Provides the number of digits used by the minor currency unit using the currency's
+ * ISO exponent.
+ *
+ * @param[in] code The country's monetary unit whose number of digits is desired.
+ *
+ * @return The number of digits used by the minor currency unit.
+ */
+PECUNIA_EXPORT std::uint8_t minorUnitDigits(const Iso4217Codes& code);
+/**
+ * @brief Calculates the currency factor between the major unit and the minor unit accounting for
+ * the system precision of the minor monetary unit. The precision is in terms of how many extra
+ * digits to add for the minor unit, e.g. USD starts with 2 and a precision of 2 would provide
+ * for a total precision of 4 digits.
+ *
+ * @param[in] code The country's monetary unit to calculate the ratio for.
+ *
+ * @return The multiplicative factor between the major and minor unit with a supplied precision.
+ */
+PECUNIA_EXPORT std::int32_t minorUnitPrecisionFactor(const Iso4217Codes& code);
+/**
+* @brief Performs the stream insertion for displaying the currency code in the ISO-4217 form.
+*
+* @param stream The stream into which the code should be inserted.
+* @param code The code that will be inserted.
+*
+* @return The same stream that was supplied, but now containing the code.
+*/
+PECUNIA_EXPORT std::ostream& operator<<(std::ostream& stream, const Iso4217Codes& code);
+/**
+ * @brief Looks-up the countries which are using a given currency.
+ *
+ * @param code The code of the currency to look-up for all the countries.
+ *
+ * @return All the countries found.
+ */
+PECUNIA_EXPORT std::vector<std::string> countriesUsing(const Iso4217Codes& code);
+/**
+ * @brief Looks-up the name of a currency using a given currency code.
+ *
+ * @param code The code of the currency to look-up for its name.
+ *
+ * @return The name of the currency in English.
+ */
+PECUNIA_EXPORT std::string currencyName(const Iso4217Codes& code);
+
+/// The total number of currency codes supported.
+constexpr std::uint8_t numberOfIso4217Codes{179};
+/// A container of every currency code supported. The codes are all other codes in alphabetical
+/// order.
+extern PECUNIA_EXPORT const std::array<Iso4217Codes, numberOfIso4217Codes> allIso4217Codes;
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Conversion.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,49 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include "Conversion.h"
+using pecunia::MinorUnit;
+
+#include <cmath>
+using std::pow;
+#include <string>
+using std::string;
+using std::to_string;
+#include <stdexcept>
+using std::overflow_error;
+
+#include "Codes.h"
+using pecunia::currency::Iso4217Codes;
+using pecunia::currency::minorUnitDigits;
+using pecunia::currency::toStdString;
+
+
+MinorUnit pecunia::toMinorUnit(const MinorUnit& minor, const Iso4217Codes& code)
+{
+	const auto digits{minorUnitDigits(code)};
+	const auto conversionFactor{pow(10, digits)};
+
+	if (minor >= conversionFactor)
+		throw overflow_error{
+			string{"The minor unit value "} + to_string(minor) + " is too large for the currency '"
+				+ toStdString(code) + "'."
+		};
+	return static_cast<MinorUnit>(minor * conversionFactor);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Conversion.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,55 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_CONVERSION_H_
+#define PECUNIA_CONVERSION_H_
+
+#include "MoneyTypes.h"
+#include "pecunia_export.h"
+
+
+namespace pecunia
+{
+namespace currency
+{
+
+enum class Iso4217Codes : std::uint16_t;
+
+}}
+
+namespace pecunia
+{
+
+/**
+ * @brief Converts a non-precious minor value into an expected minor value, i.e. given a value of
+ * USD 25 cents it'll convert it into "2500".
+ *
+ * @exception std::overflow_error When the supplied minor value is greater than possibly can be
+ * stored in a currency's minor value.
+ *
+ * @param minor The minor value without the extra precision amount.
+ * @param code The currency the minor unit is in.
+ * @return The minor amount adjusted for the amount of precious and minor digits found in the
+ * currency where all the precision is padded with zeros.
+ */
+PECUNIA_EXPORT MinorUnit toMinorUnit(const MinorUnit& minor, const currency::Iso4217Codes& code);
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Information.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,63 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include "Information.h"
+
+#include "internal/config.hpp"
+// using COPYRIGHT_YEARS
+// using DESCRIPTION
+// using FULL_VERSION
+// using HOMEPAGE_URL
+
+
+const char* pecunia::version()
+{
+	return pecunia_FULL_VERSION;
+}
+
+const char* pecunia::copyright()
+{
+	return "(C) " pecunia_COPYRIGHT_YEARS " John M. Schneiderman";
+}
+
+const char* pecunia::licence()
+{
+	return R"~(This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.)~";
+}
+
+const char* pecunia::url()
+{
+	return pecunia_HOMEPAGE_URL;
+}
+
+const char* pecunia::description()
+{
+	return pecunia_DESCRIPTION;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Information.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,52 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_INFORMATION_H_
+#define PECUNIA_INFORMATION_H_
+
+#include "pecunia_export.h"
+
+
+namespace pecunia
+{
+
+/**
+ * @brief Provides the version of the library.
+ */
+PECUNIA_EXPORT const char* version();
+/**
+ * @brief Provides the copyright of the library.
+ */
+PECUNIA_EXPORT const char* copyright();
+/**
+ * @brief Provides the license of the library.
+ */
+PECUNIA_EXPORT const char* licence();
+/**
+ * @brief Provides the URL of the library.
+ */
+PECUNIA_EXPORT const char* url();
+/**
+ * @brief Provides the description of the library.
+ */
+PECUNIA_EXPORT const char* description();
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Math.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,67 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include "Math.h"
+using std::function;
+using std::map;
+using pecunia::currency::Iso4217Codes;
+using pecunia::currency::Money;
+
+#include <cmath>
+using std::abs;
+#include <numeric>
+using std::accumulate;
+
+
+Money pecunia::math::absoluteValue(const Money& money)
+{
+	auto copy{money};
+	copy.amount_ = abs(copy.amount_);
+	return copy;
+}
+
+void pecunia::math::internal::addToRunningTotals(
+	map<Iso4217Codes, Money>& runningTotals,
+	const Money& amount,
+	const function<Money(const Money &)>& adjustor
+)
+{
+	if (runningTotals.count(amount.code()) == 0)
+		runningTotals[amount.code()].setCode(amount.code());
+	runningTotals[amount.code()] += adjustor == nullptr ? amount : adjustor(amount);
+}
+
+Money pecunia::math::internal::accumulateRunningTotals(
+	const Iso4217Codes& accumulateCurrency,
+	const map<Iso4217Codes, Money>& totals
+)
+{
+	const auto total{
+		accumulate(
+			totals.cbegin(),
+			totals.cend(),
+			Money{accumulateCurrency},
+			[] (const auto& accumulator, const auto& currencyRunningTotals)
+			{
+				return accumulator + currencyRunningTotals.second;
+			}
+		)
+	};
+	return total;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Math.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,162 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_MATH_H_
+#define PECUNIA_MATH_H_
+
+#include <functional>
+#include <map>
+#include <type_traits>
+#include <vector>
+
+#include "Codes.h"
+#include "Money.h"
+#include "pecunia_export.h"
+
+
+namespace pecunia
+{
+namespace math
+{
+/**
+ * @breif Calculates the absolute value of a supplied amount of money.
+ *
+ * @param money The money whose monetary amount should be an absolute value.
+ *
+ * @return The absolute value of the monetary amount.
+ */
+PECUNIA_EXPORT currency::Money absoluteValue(const currency::Money& money);
+/**
+ * @brief Accumulates the total of all the supplied monies with the fewest possible number of
+ * conversions.
+ *
+ * @tparam Container The type of container holding the monies.
+ * @tparam ValueType This must be the Money type.
+ * @tparam Allocator The allocator used by the container.
+ *
+ * @param accumulateCurrency The currency to accumulate the total in.
+ * @param monies The container of the monies to total.
+ * @param adjustor When supplied, a functor to apply to each element in the container of monies
+ * prior to final summation.
+ *
+ * @return The sum of all the monies in the requested currency.
+ */
+template<template<typename, typename> class Container, typename ValueType, typename Allocator>
+currency::Money sum(
+	const currency::Iso4217Codes& accumulateCurrency,
+	const Container<ValueType, Allocator>& monies,
+	const std::function<
+		currency::Money(const currency::Money& money)
+	>& adjustor = nullptr
+);
+/**
+ * @brief Accumulates the total of all the supplied monies with the fewest possible number of
+ * conversions.
+ *
+ * @tparam AssociativeContainer The type of associative container holding the monies.
+ * @tparam KeyType The type the monies are keyed against, not used.
+ * @tparam ValueType This must be the Money type.
+ * @tparam Allocator The allocator used by the container.
+ *
+ * @param accumulateCurrency The currency to accumulate the total in.
+ * @param monies The container of the monies to total.
+ * @param adjustor When supplied, a functor to apply to each element in the container of monies
+ * prior to final summation.
+ *
+ * @return The sum of all the monies in the requested currency.
+ */
+template<
+	template<typename, typename, typename, typename> class AssociativeContainer,
+	class KeyType,
+	class ValueType,
+	class Compare = std::less<KeyType>,
+	class Allocator = std::allocator<std::pair<const KeyType, ValueType>>
+>
+currency::Money sum(
+	const currency::Iso4217Codes& accumulateCurrency,
+	const AssociativeContainer<KeyType, ValueType, Compare, Allocator>& monies,
+	const std::function<
+		currency::Money(const currency::Money& money)
+	>& adjustor = nullptr
+);
+
+namespace internal
+{
+
+PECUNIA_EXPORT void addToRunningTotals(
+	std::map<currency::Iso4217Codes, currency::Money>& runningTotals,
+	const currency::Money& amount,
+	const std::function<
+		currency::Money(const currency::Money& money)
+	>& adjustor
+);
+PECUNIA_EXPORT currency::Money accumulateRunningTotals(
+	const currency::Iso4217Codes& accumulateCurrency,
+	const std::map<currency::Iso4217Codes, currency::Money>& totals
+);
+
+}}}
+
+template<template<typename, typename> class Container, typename ValueType, typename Allocator>
+pecunia::currency::Money pecunia::math::sum(
+	const pecunia::currency::Iso4217Codes& accumulateCurrency,
+	const Container<ValueType, Allocator>& monies,
+	const std::function<
+		pecunia::currency::Money(const pecunia::currency::Money& money)
+	>& adjustor
+)
+{
+	static_assert(
+		std::is_same<ValueType, pecunia::currency::Money>::value,
+		"The contained type must be Money."
+	);
+	std::map<pecunia::currency::Iso4217Codes, pecunia::currency::Money> runningTotals{};
+
+	for (const auto& money : monies)
+		internal::addToRunningTotals(runningTotals, money, adjustor);
+	return internal::accumulateRunningTotals(accumulateCurrency, runningTotals);
+}
+
+template<
+	template<typename, typename, typename, typename> class AssociativeContainer,
+	class KeyType,
+	class ValueType,
+	class Compare,
+	class Allocator
+>
+pecunia::currency::Money pecunia::math::sum(
+	const pecunia::currency::Iso4217Codes& accumulateCurrency,
+	const AssociativeContainer<KeyType, ValueType, Compare, Allocator>& monies,
+	const std::function<
+		pecunia::currency::Money(const pecunia::currency::Money& money)
+	>& adjustor
+)
+{
+	static_assert(
+		std::is_same<ValueType, pecunia::currency::Money>::value,
+		"The contained type must be Money."
+	);
+	std::map<pecunia::currency::Iso4217Codes, pecunia::currency::Money> runningTotals{};
+
+	for (const auto& keyMoney : monies)
+		internal::addToRunningTotals(runningTotals, keyMoney.second, adjustor);
+	return internal::accumulateRunningTotals(accumulateCurrency, runningTotals);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Money.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,1037 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include "Money.h"
+using std::int8_t;
+using std::int16_t;
+using std::int32_t;
+using std::int64_t;
+using std::pair;
+using std::uint8_t;
+using pecunia::currency::Iso4217Codes;
+using pecunia::currency::Money;
+using pecunia::currency::toStdString;
+using pecunia::currency::toIso4217Code;
+using pecunia::precision;
+using pecunia::MinorUnit;
+using pecunia::MinorSign;
+using pecunia::FloatingPoint;
+using pecunia::FloatingPointRounderFunction;
+using pecunia::RounderFunction;
+using pecunia::UnitStorage;
+
+#include <cassert>
+// Used for assert.
+#include <cstdlib>
+// Used for lldiv.
+#include <cmath>
+using std::abs;
+using std::pow;
+
+#include <iomanip>
+using std::fixed;
+using std::setprecision;
+#include <istream>
+using std::istream;
+#include <limits>
+using std::logic_error;
+using std::numeric_limits;
+#include <locale>
+#include <ostream>
+using std::ostream;
+#include <stdexcept>
+using std::domain_error;
+using std::exception;
+using std::overflow_error;
+using std::runtime_error;
+using std::underflow_error;
+#include <string>
+using std::string;
+using std::to_string;
+#include <sstream>
+using std::stringstream;
+
+#include "internal/Adjustments.h"
+using pecunia::currency::internal::fromFloatingPointMajor;
+using pecunia::currency::internal::fromFloatingPointMinor;
+using pecunia::currency::internal::normaliseAmount;
+#include "internal/Verification.h"
+using pecunia::internal::isEqual;
+using pecunia::internal::verifiedFloatingPoint;
+using pecunia::internal::VerifiedValue;
+using pecunia::internal::verifyAdditionFits;
+using pecunia::internal::verifyDivisionFits;
+using pecunia::internal::verifyMultiplicationFits;
+using pecunia::internal::verifySubtractionFits;
+#include "MoneyManip.h"
+using pecunia::currency::countryLeadingIndex;
+#include "MoneySize.hpp"
+using pecunia::internal::extraFloatingPointPrecision;
+
+
+UnitStorage Money::maximumMajorValue() const
+{
+	UnitStorage rawMaxMajor{
+		static_cast<UnitStorage>(
+			numeric_limits<UnitStorage>::max() - this->maximumMinorValue()
+		)
+	};
+	const int32_t ratio{minorUnitPrecisionFactor(this->iso4217Code_)};
+	UnitStorage maxMajor{static_cast<UnitStorage>(rawMaxMajor / ratio)};
+	return maxMajor;
+}
+
+UnitStorage Money::minimumMajorValue() const
+{
+	const auto maxMinorValue{this->maximumMinorValue()};
+	UnitStorage rawMinMajor{
+		static_cast<UnitStorage>(numeric_limits<UnitStorage>::lowest() + maxMinorValue)
+	};
+	const auto minorPrecisionRatio{minorUnitPrecisionFactor(this->iso4217Code_)};
+	UnitStorage minMajor{static_cast<UnitStorage>(rawMinMajor / minorPrecisionRatio)};
+	return minMajor;
+}
+
+MinorUnit Money::maximumMinorValue() const
+{
+	const int32_t digits{minorUnitDigits(this->iso4217Code_)};
+	const MinorUnit max{static_cast<MinorUnit>(pow(10, digits + precision) - 1.0)};
+	return max;
+}
+
+UnitStorage Money::maximumAmountValue() const
+{
+	const int32_t unitRatio{minorUnitPrecisionFactor(this->iso4217Code_)};
+	const UnitStorage max{
+		static_cast<UnitStorage>(
+			(this->maximumMajorValue() * unitRatio) + this->maximumMinorValue()
+		)
+	};
+	return max;
+}
+
+UnitStorage Money::minimumAmountValue() const
+{
+	const int32_t unitRatio{minorUnitPrecisionFactor(this->iso4217Code_)};
+	const auto minimumMajorValue{this->minimumMajorValue()};
+	const auto maximumMinorValue{this->maximumMinorValue()};
+	const UnitStorage min{
+		static_cast<UnitStorage>((minimumMajorValue * unitRatio) - maximumMinorValue)
+	};
+	return min;
+}
+
+Money::Money() :
+	Money{Iso4217Codes::XXX}
+{}
+
+Money::Money(const Iso4217Codes& code) :
+	Money{0, 0, code}
+{}
+
+Money::Money(const MinorSign& sign, const MinorUnit& minor, const Iso4217Codes& code) :
+	Money{0, minor, code}
+{
+	assert(
+		(minor > 0 || (minor == 0 && sign == MinorSign::Neither))
+		&& "The value of zero has no sign."
+	);
+
+	if (sign == MinorSign::Negative)
+		this->amount_ *= -1;
+}
+
+Money::Money(const UnitStorage& major, const MinorUnit& minor, const Iso4217Codes& code) :
+	amount_{0},
+	iso4217Code_{code}
+{
+	assert(
+		pow(10, minorUnitDigits(code) + precision) - 1.0 <= numeric_limits<MinorUnit>::max()
+		&& "The number of digits with precision is too large and cannot fit inside the minor type."
+	);
+	const int32_t unitRatio{minorUnitPrecisionFactor(code)};
+
+	if (major > this->maximumMajorValue())
+		throw overflow_error{
+			"The major money value, " + std::to_string(major)
+				+ ", is too large to store within the currency."
+		};
+
+	if (major < this->minimumMajorValue())
+		throw overflow_error{
+			"The major money value, " + std::to_string(major)
+				+ ", is too small to store within the currency."
+		};
+
+	if (minor > this->maximumMinorValue())
+		throw overflow_error{
+			"The minor money value, " + std::to_string(minor)
+				+ ", is too large to store within the currency."
+		};
+
+	if (major >= 0)
+		this->amount_ = (major * unitRatio) + minor;
+	else
+		this->amount_ = (major * unitRatio) - minor;
+}
+
+Money::Money(
+	const FloatingPoint& value,
+	const Iso4217Codes& code,
+	const FloatingPointRounderFunction& rounder
+) :
+	Money{
+		fromFloatingPointMajor(value, code, precision, rounder),
+		fromFloatingPointMinor(value, code, precision, rounder),
+		code
+	}
+{
+	if (
+		this->amount_ == 0
+		&& ! isEqual(value, 0.0, static_cast<uint8_t>(minorUnitDigits(code) + precision))
+	)
+		throw underflow_error{
+			"The value " + std::to_string(value)
+				+ " is too small to store within the supplied precision."
+		};
+}
+
+Money::operator FloatingPoint() const
+{
+	return this->toFloatingPoint();
+}
+
+Money Money::operator-() const
+{
+	Money m{*this};
+	m.amount_ *= -1;
+	return m;
+}
+
+Money Money::operator+(const Money& other) const
+{
+	Money m{*this};
+	m += other;
+	return m;
+}
+
+Money Money::operator-(const Money& other) const
+{
+	Money m{*this};
+	m -= other;
+	return m;
+}
+
+Money Money::operator*(const int8_t value) const
+{
+	Money m{*this};
+	m *= static_cast<int64_t>(value);
+	return m;
+}
+
+Money Money::operator*(const int16_t value) const
+{
+	Money m{*this};
+	m *= static_cast<int64_t>(value);
+	return m;
+}
+
+Money Money::operator*(const int32_t value) const
+{
+	Money m{*this};
+	m *= static_cast<int64_t>(value);
+	return m;
+}
+
+Money Money::operator*(const int64_t value) const
+{
+	Money m{*this};
+	m *= value;
+	return m;
+}
+
+Money Money::operator*(const FloatingPoint& value) const
+{
+	Money m{*this};
+	m *= value;
+	return m;
+}
+
+FloatingPoint Money::operator/(const Money& other) const
+{
+	if (other.amount_ == 0)
+		throw domain_error{
+			"The division operation of " + std::to_string(this->amount_) + " and "
+				+ std::to_string(other.amount_) + " result is undefined."
+		};
+	const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
+	return static_cast<FloatingPoint>(this->amount_) / static_cast<FloatingPoint>(normalisedAmount);
+}
+
+Money Money::operator/(const int8_t value) const
+{
+	Money m{*this};
+	m /= static_cast<int64_t>(value);
+	return m;
+}
+
+Money Money::operator/(const int16_t value) const
+{
+	Money m{*this};
+	m /= static_cast<int64_t>(value);
+	return m;
+}
+
+Money Money::operator/(const int32_t value) const
+{
+	Money m{*this};
+	m /= static_cast<int64_t>(value);
+	return m;
+}
+
+Money Money::operator/(const int64_t value) const
+{
+	Money m{*this};
+	m /= value;
+	return m;
+}
+
+Money Money::operator/(const FloatingPoint& value) const
+{
+	Money m{*this};
+	m /= value;
+	return m;
+}
+
+UnitStorage Money::operator%(const UnitStorage& value) const
+{
+	if (value == 0)
+		throw domain_error{
+			"The modulus operation of " + std::to_string(this->amount_) + " and "
+			+ std::to_string(value) + " result is undefined."
+		};
+	return this->major() % value;
+}
+
+Money& Money::operator=(const Money& other)
+{
+	if (this != &other)
+	{
+		const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
+		const auto maximumAmountValue{this->maximumAmountValue()};
+		const auto minimumAmountValue{this->minimumAmountValue()};
+
+		if (normalisedAmount <= maximumAmountValue && normalisedAmount >= minimumAmountValue)
+			this->amount_ = normalisedAmount;
+		else
+			throw overflow_error{
+				"The assignment operation of " + std::to_string(other.amount_) + " to "
+					+ std::to_string(this->amount_) + " is too large to fit within the precision."
+			};
+	}
+	return *this;
+}
+
+Money& Money::operator=(Money&& other)
+{
+	if (this != &other)
+	{
+		const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
+		const auto maximumAmountValue{this->maximumAmountValue()};
+		const auto minimumAmountValue{this->minimumAmountValue()};
+
+		if (normalisedAmount <= maximumAmountValue && normalisedAmount >= minimumAmountValue)
+			this->amount_ = normalisedAmount;
+		else
+			throw overflow_error{
+				"The assignment operation of " + std::to_string(other.amount_) + " to "
+					+ std::to_string(this->amount_) + " is too large to fit within the precision."
+			};
+	}
+	return *this;
+}
+
+bool Money::operator<(const Money& other) const
+{
+	try
+	{
+		const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
+		return this->amount_ < normalisedAmount;
+	}
+	catch (const logic_error&)
+	{
+		throw;
+	}
+	catch (const exception&)
+	{
+		if (other.amount_ > 0) // other.amount_ is too large positive.
+			return true;
+
+		if (other.amount_ < 0) // other.amount_ is too large negative.
+			return false;
+		throw; // Something strange has occurred.
+	}
+}
+
+bool Money::operator<(const int8_t value) const
+{
+	return this->amount_ < static_cast<int64_t>(value);
+}
+
+bool Money::operator<(const int16_t value) const
+{
+	return this->amount_ < static_cast<int64_t>(value);
+}
+
+bool Money::operator<(const int32_t value) const
+{
+	return this->amount_ < static_cast<int64_t>(value);
+}
+
+bool Money::operator<(const int64_t value) const
+{
+	return this->amount_ < value;
+}
+
+bool Money::operator<=(const Money& other) const
+{
+	return (*this < other) || (*this == other);
+}
+
+bool Money::operator<=(const int8_t value) const
+{
+	return this->amount_ <= static_cast<int64_t>(value);
+}
+
+bool Money::operator<=(const int16_t value) const
+{
+	return this->amount_ <= static_cast<int64_t>(value);
+}
+
+bool Money::operator<=(const int32_t value) const
+{
+	return this->amount_ <= static_cast<int64_t>(value);
+}
+
+bool Money::operator<=(const int64_t value) const
+{
+	return this->amount_ <= value;
+}
+
+bool Money::operator>(const Money& other) const
+{
+	try
+	{
+		const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
+		return this->amount_ > normalisedAmount;
+	}
+	catch (const logic_error&)
+	{
+		throw;
+	}
+	catch (const exception&)
+	{
+		if (other.amount_ > 0) // other.amount_ is too large positive.
+			return false;
+
+		if (other.amount_ < 0) // other.amount_ is too large negative.
+			return true;
+		throw; // Something strange has occurred.
+	}
+}
+
+bool Money::operator>(const int8_t value) const
+{
+	return this->amount_ > static_cast<int8_t>(value);
+}
+
+bool Money::operator>(const int16_t value) const
+{
+	return this->amount_ > static_cast<int64_t>(value);
+}
+
+bool Money::operator>(const int32_t value) const
+{
+	return this->amount_ > static_cast<int64_t>(value);
+}
+
+bool Money::operator>(const int64_t value) const
+{
+	return this->amount_ > value;
+}
+
+bool Money::operator>=(const Money& other) const
+{
+	return (*this > other) || (*this == other);
+}
+
+bool Money::operator>=(const int8_t value) const
+{
+	return this->amount_ >= static_cast<int64_t>(value);
+}
+
+bool Money::operator>=(const int16_t value) const
+{
+	return this->amount_ >= static_cast<int64_t>(value);
+}
+
+bool Money::operator>=(const int32_t value) const
+{
+	return this->amount_ >= static_cast<int64_t>(value);
+}
+
+bool Money::operator>=(const int64_t value) const
+{
+	return this->amount_ >= value;
+}
+
+bool Money::operator==(const Money& other) const
+{
+	try
+	{
+		const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
+		return this->amount_ == normalisedAmount;
+	}
+	catch (const exception&)
+	{
+		// Doesn't matter why we threw, e.g. overflow, underflow, different codes, the error itself
+		// is enough to know that the two values are not equal.
+		return false;
+	}
+}
+
+bool Money::operator==(const int8_t value) const
+{
+	return this->amount_ == static_cast<int8_t>(value);
+}
+
+bool Money::operator==(const int16_t value) const
+{
+	return this->amount_ == static_cast<int16_t>(value);
+}
+
+bool Money::operator==(const int32_t value) const
+{
+	return this->amount_ == static_cast<int64_t>(value);
+}
+
+bool Money::operator==(const int64_t value) const
+{
+	return this->amount_ == value;
+}
+
+bool Money::operator!=(const Money& other) const
+{
+	return ! (*this == other);
+}
+
+bool Money::operator!=(const int8_t other) const
+{
+	return ! (*this == static_cast<int64_t>(other));
+}
+
+bool Money::operator!=(const int16_t other) const
+{
+	return ! (*this == static_cast<int64_t>(other));
+}
+
+bool Money::operator!=(const int32_t other) const
+{
+	return ! (*this == static_cast<int64_t>(other));
+}
+
+bool Money::operator!=(const int64_t other) const
+{
+	return ! (*this == other);
+}
+
+Money& Money::operator+=(const Money& other)
+{
+	const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
+	const VerifiedValue verified{
+		verifyAdditionFits(
+			this->amount_,
+			normalisedAmount,
+			this->maximumAmountValue(),
+			this->minimumAmountValue()
+		)
+	};
+	switch (verified)
+	{
+	case VerifiedValue::Fits:
+		this->amount_ += normalisedAmount;
+		return *this;
+	case VerifiedValue::Overflows:
+		throw overflow_error{
+			"The addition operation of " + std::to_string(this->amount_) + ' '
+				+ toStdString(this->iso4217Code_) + " and " + std::to_string(other.amount_) + ' '
+				+ toStdString(other.iso4217Code_) + " cannot be safely stored."
+		};
+	case VerifiedValue::Underflows:
+		throw underflow_error{
+			"The addition operation of " + std::to_string(this->amount_) + ' '
+				+ toStdString(this->iso4217Code_) + " and " + std::to_string(other.amount_) + ' '
+				+ toStdString(other.iso4217Code_) + " cannot be safely stored."
+		};
+	case VerifiedValue::Undefined:
+	default:
+		throw logic_error{"Incorrect addition verification result."};
+	};
+}
+
+Money& Money::operator-=(const Money& other)
+{
+	const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
+	const VerifiedValue verified{
+		verifySubtractionFits(
+			this->amount_,
+			normalisedAmount,
+			this->maximumAmountValue(),
+			this->minimumAmountValue()
+		)
+	};
+	switch (verified)
+	{
+	case VerifiedValue::Fits:
+		this->amount_ -= normalisedAmount;
+		return *this;
+	case VerifiedValue::Overflows:
+		throw overflow_error{
+			"The subtraction operation of " + std::to_string(this->amount_) + ' '
+				+ toStdString(this->iso4217Code_) + " and " + std::to_string(other.amount_) + ' '
+				+ toStdString(other.iso4217Code_) + " cannot be safely stored."
+		};
+	case VerifiedValue::Underflows:
+		throw underflow_error{
+			"The subtraction operation of " + std::to_string(this->amount_) + ' '
+				+ toStdString(this->iso4217Code_) + " and " + std::to_string(other.amount_) + ' '
+				+ toStdString(other.iso4217Code_) + " cannot be safely stored."
+		};
+	case VerifiedValue::Undefined:
+	default:
+		throw logic_error{"Incorrect subtraction verification result."};
+	};
+}
+
+Money& Money::operator*=(const int8_t value)
+{
+	return *this *= static_cast<int64_t>(value);
+}
+
+Money& Money::operator*=(const int16_t value)
+{
+	return *this *= static_cast<int64_t>(value);
+}
+
+Money& Money::operator*=(const int32_t value)
+{
+	return *this *= static_cast<int64_t>(value);
+}
+
+Money& Money::operator*=(const int64_t value)
+{
+	const VerifiedValue verified{
+		verifyMultiplicationFits(
+			this->amount_,
+			value,
+			this->maximumAmountValue(),
+			this->minimumAmountValue()
+		)
+	};
+
+	switch (verified)
+	{
+	case VerifiedValue::Fits:
+		this->amount_ = this->amount_ * value;
+		return *this;
+	case VerifiedValue::Overflows:
+		throw overflow_error{
+			"The multiplication operation of " + std::to_string(this->amount_) + " and "
+			+ std::to_string(value) + " cannot be safely stored."
+		};
+	case VerifiedValue::Underflows:
+		throw underflow_error{
+			"The multiplication operation of " + std::to_string(this->amount_) + " and "
+			+ std::to_string(value) + " cannot be safely stored."
+		};
+	case VerifiedValue::Undefined:
+	default:
+		throw logic_error{"Incorrect multiplication verification result."};
+	};
+}
+
+Money& Money::operator*=(const FloatingPoint& value)
+{
+	// Need to verify before adjustment and during the multiplication.
+	const VerifiedValue verified{
+		verifyMultiplicationFits(
+			this->amount_,
+			value,
+			this->maximumAmountValue(),
+			this->minimumAmountValue(),
+			this->maximumMinorValue(),
+			static_cast<uint8_t>(
+				minorUnitDigits(this->iso4217Code_) + precision + extraFloatingPointPrecision
+			)
+		)
+	};
+
+	switch (verified)
+	{
+	case VerifiedValue::Fits:
+		break;
+	case VerifiedValue::Overflows:
+		throw overflow_error{
+			"The multiplication operation of " + std::to_string(this->amount_) + " and "
+			+ std::to_string(value) + " cannot be safely stored."
+		};
+	case VerifiedValue::Underflows:
+		throw underflow_error{
+			"The multiplication operation of " + std::to_string(this->amount_) + " and "
+			+ std::to_string(value) + " cannot be safely stored."
+		};
+	case VerifiedValue::Undefined:
+	default:
+		throw logic_error{"Incorrect multiplication verification result."};
+	};
+	const int32_t unitRatio{
+		minorUnitPrecisionFactor(this->iso4217Code_)
+			* static_cast<int32_t>(pow(10, extraFloatingPointPrecision))
+	};
+	const auto adjustedValue{verifiedFloatingPoint(value * unitRatio)};
+	*this *= static_cast<int64_t>(adjustedValue);
+	this->amount_ /= unitRatio;
+	return *this;
+}
+
+Money& Money::operator/=(const int8_t value)
+{
+	return *this /= static_cast<int64_t>(value);
+}
+
+Money& Money::operator/=(const int16_t value)
+{
+	return *this /= static_cast<int64_t>(value);
+}
+
+Money& Money::operator/=(const int32_t value)
+{
+	return *this /= static_cast<int64_t>(value);
+}
+
+Money& Money::operator/=(const int64_t value)
+{
+	const VerifiedValue verified{
+		verifyDivisionFits(
+			this->amount_,
+			value,
+			static_cast<uint8_t>(minorUnitDigits(this->iso4217Code_) + precision)
+		)
+	};
+
+	switch (verified)
+	{
+	case VerifiedValue::Fits:
+		this->amount_ = this->amount_ / value;
+		return *this;
+	case VerifiedValue::Overflows:
+		throw overflow_error{
+			"The division operation of " + std::to_string(this->amount_) + " and "
+				+ std::to_string(value) + " cannot be safely stored."
+		};
+	case VerifiedValue::Undefined:
+		throw domain_error{
+			"The division operation of " + std::to_string(this->amount_) + " and "
+				+ std::to_string(value) + " result is undefined."
+		};
+	case VerifiedValue::Underflows:
+		throw underflow_error{
+			"The division operation of " + std::to_string(this->amount_) + " and "
+				+ std::to_string(value) + " cannot be safely stored."
+		};
+	default:
+		throw logic_error{"Incorrect division verification result."};
+	};
+}
+
+Money& Money::operator/=(const FloatingPoint& value)
+{
+	// Need to verify before adjustment, during the multiplication, and division.
+	const VerifiedValue preVerified{
+		verifyDivisionFits(
+			this->amount_,
+			value,
+			this->maximumAmountValue(),
+			this->minimumAmountValue(),
+			this->maximumMinorValue(),
+			static_cast<uint8_t>(
+				minorUnitDigits(this->iso4217Code_) + precision + extraFloatingPointPrecision
+			)
+		)
+	};
+
+	switch (preVerified)
+	{
+	case VerifiedValue::Fits:
+		break;
+	case VerifiedValue::Overflows:
+		throw overflow_error{
+			"The division operation of " + std::to_string(this->amount_) + " and "
+				+ std::to_string(value) + " cannot be safely stored."
+		};
+	case VerifiedValue::Undefined:
+		throw domain_error{
+			"The division operation of " + std::to_string(this->amount_) + " and "
+				+ std::to_string(value) + " result is undefined."
+		};
+	case VerifiedValue::Underflows:
+		throw underflow_error{
+			"The division operation of " + std::to_string(this->amount_) + " and "
+				+ std::to_string(value) + " cannot be safely stored."
+		};
+	default:
+		throw logic_error{"Incorrect division verification result."};
+	};
+	const int64_t unitRatio{
+		minorUnitPrecisionFactor(this->iso4217Code_)
+			* static_cast<int64_t>(pow(10, extraFloatingPointPrecision))
+	};
+	const VerifiedValue verifiedMultiplication{
+		verifyMultiplicationFits(
+			this->amount_,
+			unitRatio,
+			this->maximumAmountValue(),
+			this->minimumAmountValue()
+		)
+	};
+
+	switch (verifiedMultiplication)
+	{
+	case VerifiedValue::Fits:
+		break;
+	case VerifiedValue::Overflows:
+		throw overflow_error{
+			"The multiplication operation of " + std::to_string(this->amount_) + " and "
+				+ std::to_string(value) + " cannot be safely stored during division."
+		};
+	case VerifiedValue::Underflows:
+		throw underflow_error{
+			"The multiplication operation of " + std::to_string(this->amount_) + " and "
+				+ std::to_string(value) + " cannot be safely stored during division."
+		};
+	case VerifiedValue::Undefined:
+	default:
+		throw logic_error{"Incorrect multiplication verification result during division."};
+	};
+	const auto adjustedValue{
+		static_cast<UnitStorage>(
+			verifiedFloatingPoint(value * static_cast<FloatingPoint>(unitRatio))
+		)
+	};
+	const auto adjustedAmount{this->amount_ * unitRatio};
+	const auto preAmount{this->amount_};
+
+	try
+	{
+		this->amount_ = adjustedAmount;
+		*this /= adjustedValue;
+		return *this;
+	}
+	catch (const exception&)
+	{
+		this->amount_ = preAmount;
+		throw;
+	}
+}
+
+const UnitStorage& Money::amount() const noexcept
+{
+	return this->amount_;
+}
+
+UnitStorage Money::major() const
+{
+	return this->amount_ / minorUnitPrecisionFactor(this->iso4217Code_);
+}
+
+MinorUnit Money::minor() const
+{
+	return static_cast<MinorUnit>(
+		abs(this->amount_ % minorUnitPrecisionFactor(this->iso4217Code_))
+	);
+}
+
+const Iso4217Codes& Money::code() const
+{
+	return this->iso4217Code_;
+}
+
+bool Money::isPositive() const
+{
+	return this->amount_ > 0;
+}
+
+FloatingPoint Money::toFloatingPoint(const RounderFunction& rounder, const uint8_t digits) const
+{
+	assert(rounder != nullptr && "The money rounder must be a function.");
+	const auto minorDigits{
+		static_cast<uint8_t>(minorUnitDigits(this->iso4217Code_) + precision)
+	};
+	const auto rounded{rounder(this->amount_, minorDigits, digits)};
+	const int32_t ratio{minorUnitPrecisionFactor(this->iso4217Code_)};
+	const FloatingPoint converted{
+		static_cast<FloatingPoint>(rounded) / static_cast<FloatingPoint>(ratio)
+	};
+	return converted;
+}
+
+Money& Money::round(const RounderFunction& rounder, const uint8_t digits)
+{
+	assert(rounder != nullptr && "The money rounder must be a function.");
+	const auto minorDigits{
+		static_cast<uint8_t>(minorUnitDigits(this->iso4217Code_) + precision)
+	};
+	const auto roundedAmount{rounder(this->amount_, minorDigits, digits)};
+	const auto maximumAmountValue{this->maximumAmountValue()};
+	const auto minimumAmountValue{this->minimumAmountValue()};
+
+	if (roundedAmount <= maximumAmountValue && roundedAmount >= minimumAmountValue)
+		this->amount_ = roundedAmount;
+	else
+		throw overflow_error{
+			"The result of the rounding operation " + std::to_string(roundedAmount) + " from "
+				+ std::to_string(this->amount_) + " is too large to fit within the precision."
+		};
+	return *this;
+}
+
+bool Money::hasAmount() const
+{
+	return this->amount_ != 0 && this->iso4217Code_ != Iso4217Codes::XXX;
+}
+
+void Money::setCode(const pecunia::currency::Iso4217Codes& code)
+{
+	this->iso4217Code_ = code;
+}
+
+pair<UnitStorage, MinorUnit> Money::maximum(const Iso4217Codes& code)
+{
+	const auto ratio{minorUnitPrecisionFactor(code)};
+	const Money test{code};
+	const auto value{test.maximumAmountValue()};
+	const UnitStorage max{value / ratio};
+	const auto minor{static_cast<MinorUnit>(value % ratio)};
+	return {max, minor};
+}
+
+pair<UnitStorage, MinorUnit> Money::minimum(const Iso4217Codes& code)
+{
+	const auto ratio{minorUnitPrecisionFactor(code)};
+	const Money test{code};
+	const auto value{test.minimumAmountValue()};
+	const UnitStorage min{value / ratio};
+	const auto minor{static_cast<MinorUnit>(-value % ratio)};
+	return {min, minor};
+}
+
+Money pecunia::currency::operator*(const int8_t lhs, const Money& rhs)
+{
+	return rhs * lhs;
+}
+
+Money pecunia::currency::operator*(const int16_t lhs, const Money& rhs)
+{
+	return rhs * lhs;
+}
+
+Money pecunia::currency::operator*(const int32_t lhs, const Money& rhs)
+{
+	return rhs * lhs;
+}
+
+Money pecunia::currency::operator*(const int64_t lhs, const Money& rhs)
+{
+	return rhs * lhs;
+}
+
+Money pecunia::currency::operator*(const FloatingPoint& lhs, const Money& rhs)
+{
+	return rhs * lhs;
+}
+
+ostream& pecunia::currency::operator<<(ostream& stream, const Money& m)
+{
+	const bool isSymbolUsed{stream.iword(pecunia::currency::useSymbolIndex()) == 1};
+	const string currencyMarker{
+		isSymbolUsed ? currencySymbol(m.iso4217Code_) : toStdString(m.iso4217Code_)
+	};
+	const bool isCountryLeading{stream.iword(countryLeadingIndex()) == 1};
+	const bool isSpaced{stream.iword(pecunia::currency::spacedIndex()) == 1};
+	const FloatingPoint value{m};
+	stream << setprecision(minorUnitDigits(m.iso4217Code_) + precision) << fixed
+			<< (isCountryLeading ? currencyMarker : "")
+			<< (isSpaced && isCountryLeading ? " " : "")
+			<< value
+			<< (isSpaced && ! isCountryLeading ? " " : "")
+			<< ( ! isCountryLeading ? currencyMarker : "");
+	return stream;
+}
+
+istream& pecunia::currency::operator>>(istream& stream, Money& m)
+{
+	const bool isCountryLeading{stream.iword(countryLeadingIndex()) == 1};
+	long double rawAmount;
+	string rawCode;
+
+	if (isCountryLeading)
+		stream >> rawCode >> std::get_money(rawAmount);
+	else
+		stream >> std::get_money(rawAmount) >> rawCode;
+
+	if ( ! stream)
+		throw runtime_error{
+			"Failed to read valid input for the monetary amount and/or code."
+		};
+
+	m.iso4217Code_ = toIso4217Code(rawCode);
+	const auto amount{
+		static_cast<FloatingPoint>(
+			rawAmount / pow(10, pecunia::currency::minorUnitDigits(m.iso4217Code_))
+		)
+	};
+	m = Money{amount, m.iso4217Code_};
+	return stream;
+}
+
+string pecunia::currency::to_string(const Money& m)
+{
+	stringstream ss;
+	ss << pecunia::currency::spaced << pecunia::currency::trail << m;
+	return ss.str();
+}
+
+void pecunia::currency::swap(Money& lhs, Money& rhs) noexcept
+{
+	const Money temp{lhs};
+	lhs.amount_ = rhs.amount_;
+	lhs.iso4217Code_ = rhs.iso4217Code_;
+	rhs.amount_ = temp.amount_;
+	rhs.iso4217Code_ = temp.iso4217Code_;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Money.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,1095 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_CURRENCY_MONEY_H_
+#define PECUNIA_CURRENCY_MONEY_H_
+
+#include <cstdint>
+#include <functional>
+#include <iomanip>
+#include <istream>
+#include <locale>
+#include <ostream>
+#include <string>
+#include <utility>
+
+#include "Codes.h"
+#include "MoneyTypes.h"
+
+
+namespace pecunia
+{
+namespace currency
+{
+
+class Money;
+
+}
+namespace math
+{
+
+PECUNIA_EXPORT currency::Money absoluteValue(const currency::Money& money);
+
+}
+namespace currency
+{
+
+/**
+ * @breif A representation of a country's currency supporting basic arithmetic usage and
+ * guaranteeing all operations succeed without a loss of precision, overflow, or underflow.
+ */
+class PECUNIA_EXPORT Money
+{
+	friend PECUNIA_EXPORT Money math::absoluteValue(const Money&);
+	friend PECUNIA_EXPORT Money operator*(const std::int8_t lhs, const Money& rhs);
+	friend PECUNIA_EXPORT Money operator*(const std::int16_t lhs, const Money& rhs);
+	friend PECUNIA_EXPORT Money operator*(const std::int32_t lhs, const Money& rhs);
+	friend PECUNIA_EXPORT Money operator*(const std::int64_t lhs, const Money& rhs);
+	friend PECUNIA_EXPORT Money operator*(const FloatingPoint& lhs, const Money& rhs);
+	friend PECUNIA_EXPORT std::ostream& operator<<(std::ostream& stream, const Money& m);
+	friend PECUNIA_EXPORT std::istream& operator>>(std::istream& stream, Money& m);
+	friend PECUNIA_EXPORT void swap(Money& lhs, Money& rhs) noexcept;
+
+	/**
+	 * @breif Calculates the largest storable monetary major value.
+	 */
+	UnitStorage maximumMajorValue() const;
+	/**
+	 * @breif Calculates the smallest storable monetary major value.
+	 */
+	UnitStorage minimumMajorValue() const;
+	/**
+	 * @breif Calculates the largest storable monetary minor value.
+	 */
+	MinorUnit maximumMinorValue() const;
+	/**
+	 * @breif Calculates the largest storable monetary amount value.
+	 */
+	UnitStorage maximumAmountValue() const;
+	/**
+	 * @breif Calculates the smallest storable monetary amount value.
+	 */
+	UnitStorage minimumAmountValue() const;
+
+	/// The entire representation of the monetary amount using the currency's minor unit, e.g. cents
+	/// for USD, plus any extra digits of precision.
+	UnitStorage amount_;
+	/// The ISO 4217 currency code the monetary amount represents.
+	Iso4217Codes iso4217Code_;
+
+public:
+	/**
+	 * @breif Constructor for a fully formed object that initialises the stored amount to zero
+	 * unknown currency.
+	 */
+	Money();
+	/**
+	 * @breif  Constructor for a fully formed object that initialises the stored amount to zero.
+	 *
+	 * @param[in] code The ISO 4217 currency code the amount represents.
+	 */
+	explicit Money(const Iso4217Codes& code);
+	/**
+	 * @breif Constructor for setting an exact minor monetary value whose major value is zero. The
+	 * minor value is expected to be adjusted for the level of precision the object is expecting,
+	 * e.g. U.S.A. dollars with a precision of two would enter twelve cents as 1200.
+	 *
+	 * @pre When the minor value is zero, the sign must be Sign::Neither.
+	 *
+	 * @exception overflow_error When the minor unit is too large to be stored.
+	 *
+	 * @param[in] minor The amount of minor currency to store, e.g. U.S.A. cents.
+	 * @param[in] sign The associated signedness of the minor value, e.g. negative.
+	 * @param[in] code The ISO 4217 currency code the amount represents.
+	 */
+	Money(
+		const MinorSign& sign,
+		const MinorUnit& minor,
+		const Iso4217Codes& code = Iso4217Codes::XXX
+	);
+	/**
+	 * @breif Constructor for setting an exact monetary value of a fully formed object. The minor
+	 * value is expected to be adjusted for the level of precision the object is expecting,
+	 * e.g. U.S.A. dollars with a precision of two would enter twelve cents as 1200.
+	 *
+	 * @pre The maximum minor value must fit within the MinorUnit.
+	 *
+	 * @exception overflow_error When the major unit is too large to be stored in a positive
+	 * direction.
+	 * @exception overflow_error When the major unit is too small to be stored in a negative
+	 * direction.
+	 * @exception overflow_error When the minor unit is too large to be stored.
+	 *
+	 * @param[in] major The amount of major currency to store, e.g. U.S.A. dollars.
+	 * @param[in] minor The amount of minor currency to store, e.g. U.S.A. cents.
+	 * @param[in] code The ISO 4217 currency code the amount represents.
+	 */
+	Money(
+		const UnitStorage& major,
+		const MinorUnit& minor,
+		const Iso4217Codes& code = Iso4217Codes::XXX
+	);
+	/**
+	 * @breif Constructor for setting a monetary value using the native floating-point type.
+	 *
+	 * @note The minor units in a floating-point value cannot be verified and will always fit within
+	 * the currency digits and precision specified, e.g. U.S.A. dollar value with a precision of 0
+	 * will store the value 1.555 as 1.55 when no rounder is supplied.
+	 *
+	 * @exception overflow_error When the major unit is too large to be stored in a positive
+	 * direction.
+	 * @exception overflow_error When the major unit is too small to be stored in a negative
+	 * direction.
+	 * @exception domain_error When the conversion results in the floating-point value dividing by
+	 * zero.
+	 * @exception underflow_error When the floating-point value is too small to fit within the
+	 * FloatingPoint.
+	 * @exception overflow_error When the floating-point value is too large to fit within the
+	 * FloatingPoint.
+	 * @exception domain_error When the conversion results in the floating-point value not being
+	 * valid.
+	 *
+	 * @param[in] value The floating-point value to convert.
+	 * @param[in] code The ISO 4217 currency code the amount represents.
+	 * @param[in] rounder The method for rounding the number when converting the floating-point
+	 * number.
+	 */
+	Money(
+		const FloatingPoint& value,
+		const Iso4217Codes& code,
+		const FloatingPointRounderFunction& rounder =
+			[] (const FloatingPoint& number, const std::uint8_t&)
+			{
+				return number;
+			}
+	);
+	Money(const Money&) =default;
+	Money(Money&&) noexcept =default;
+	/**
+	 * @breif Conversion operator to a native floating-point type.
+	 *
+	 * @exception domain_error When the conversion results in the floating-point value dividing by
+	 * zero.
+	 * @exception underflow_error When the floating-point value is too small to fit within the
+	 * FloatingPoint.
+	 * @exception overflow_error When the floating-point value is too large to fit within the
+	 * FloatingPoint.
+	 * @exception domain_error When the conversion results in the floating-point value not being
+	 * valid.
+	 */
+	explicit operator FloatingPoint() const;
+	~Money() =default;
+	/**
+	 * @breif Negation operator without any loss of precision during the conversion.
+	 *
+	 * @return The negated value of the current object.
+	 */
+	Money operator-() const;
+	/**
+	 * @breif Additive operator. When the supplied monetary object is of a different currency, the
+	 * amount is converted into the current object's currency using the pecunia::currency::converter
+	 * function.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] other The additional value to add to the current object's value.
+	 *
+	 * @return A new object containing the summation of the two values.
+	 */
+	Money operator+(const Money& other) const;
+	/**
+	 * @breif Subtractive operator. When the supplied monetary object is of a different currency,
+	 * the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] other The additional value to subtract from the current object's value.
+	 *
+	 * @return A new object containing the difference of the two values.
+	 */
+	Money operator-(const Money& other) const;
+	Money operator*(const Money&) const =delete;
+	/**
+	 * @breif Multiplicative operator without any loss of precision.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The signed 8-bit integer value to multiply to the current object's value.
+	 *
+	 * @return A new object containing the product of the two values.
+	 */
+	Money operator*(const std::int8_t value) const;
+	/**
+	 * @breif Multiplicative operator without any loss of precision.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The signed 16-bit integer value to multiply to the current object's value.
+	 *
+	 * @return A new object containing the product of the two values.
+	 */
+	Money operator*(const std::int16_t value) const;
+	/**
+	 * @breif Multiplicative operator without any loss of precision.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The signed 32-bit integer value to multiply to the current object's value.
+	 *
+	 * @return A new object containing the product of the two values.
+	 */
+	Money operator*(const std::int32_t value) const;
+	/**
+	 * @breif Multiplicative operator without any loss of precision.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The signed 64-bit integer value to multiply to the current object's value.
+	 *
+	 * @return A new object containing the product of the two values.
+	 */
+	Money operator*(const std::int64_t value) const;
+	/**
+	 * @breif Multiplicative operator without any loss of precision. This only supports as many
+	 * digits as there are minor digits.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional value to multiply to the current object's value.
+	 *
+	 * @return A new object containing the product of the two values.
+	 */
+	Money operator*(const FloatingPoint& value) const;
+	/**
+	 * @breif Division operator for calculating ratios.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 *
+	 * @param[in] other The value to divide by the current object's value.
+	 *
+	 * @return The result of the division between the two, a ratio.
+	 */
+	FloatingPoint operator/(const Money& other) const;
+	/**
+	 * @breif Division operator without any loss of precision.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional signed 8-bit integer value to divide by the current object's
+	 * value.
+	 *
+	 * @return A new object containing the division of the two values.
+	 */
+	Money operator/(const std::int8_t value) const;
+	/**
+	 * @breif Division operator without any loss of precision.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional signed 16-bit integer value to divide by the current object's
+	 * value.
+	 *
+	 * @return A new object containing the division of the two values.
+	 */
+	Money operator/(const std::int16_t value) const;
+	/**
+	 * @breif Division operator without any loss of precision.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional signed 32-bit integer value to divide by the current object's
+	 * value.
+	 *
+	 * @return A new object containing the division of the two values.
+	 */
+	Money operator/(const std::int32_t value) const;
+	/**
+	 * @breif Division operator without any loss of precision.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional signed 64-bit integer value to divide by the current object's
+	 * value.
+	 *
+	 * @return A new object containing the division of the two values.
+	 */
+	Money operator/(const std::int64_t value) const;
+	/**
+	 * @breif Division operator without any loss of precision. This only supports as many digits as
+	 * there are minor digits.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional value to divide by the current object's value.
+	 *
+	 * @return A new object containing the division of the two values.
+	 */
+	Money operator/(const FloatingPoint& value) const;
+	Money operator%(const Money&) const =delete;
+	/**
+	 * @breif Modulus operator performed upon the major units of the object's current value.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 *
+	 * @param[in] value The additional value to perform a "mod" on the current object's value.
+	 *
+	 * @return The value of the modulus operation of the two values.
+	 */
+	UnitStorage operator%(const UnitStorage& value) const;
+	/**
+	 * @breif Assignment Operator with copy. When the supplied monetary object is of a different
+	 * currency, the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function. Note that only the amount is assigned, not the
+	 * currency.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception overflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] other The object whose amount is to be assigned into the current object.
+	 *
+	 * @return The current object with the new amount.
+	 */
+	Money& operator=(const Money& other);
+	/**
+	 * @breif Assignment Operator with move. When the supplied monetary object is of a different
+	 * currency, the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function. Note that only the amount is assigned, not the
+	 * currency.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception overflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] other The object whose amount is to be assigned into the current object.
+	 *
+	 * @return The current object with the new amount.
+	 */
+	Money& operator=(Money&& other);
+	/**
+	 * @breif Less-than Relational Operator. When the supplied monetary object is of a different
+	 * currency, the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function.
+	 *
+	 * @param[in] other The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is less than the supplied object,
+	 * false else-wise.
+	 */
+	bool operator<(const Money& other) const;
+	/**
+	 * @breif Less-than Relational Operator for an 8-bit signed integer. The supplied value is
+	 * expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is less than the supplied object,
+	 * false else-wise.
+	 */
+	bool operator<(const std::int8_t value) const;
+	/**
+	 * @breif Less-than Relational Operator for an 16-bit signed integer. The supplied value is
+	 * expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is less than the supplied object,
+	 * false else-wise.
+	 */
+	bool operator<(const std::int16_t value) const;
+	/**
+	 * @breif Less-than Relational Operator for an 32-bit signed integer. The supplied value is
+	 * expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is less than the supplied object,
+	 * false else-wise.
+	 */
+	bool operator<(const std::int32_t value) const;
+	/**
+	 * @breif Less-than Relational Operator for an 64-bit signed integer. The supplied value is
+	 * expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is less than the supplied object,
+	 * false else-wise.
+	 */
+	bool operator<(const std::int64_t value) const;
+	/**
+	 * @breif Less-than-equal Relational Operator. When the supplied monetary object is of a
+	 * different currency, the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function.
+	 *
+	 * @param[in] other The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is less than or equal to the supplied object,
+	 * false else-wise.
+	 */
+	bool operator<=(const Money& other) const;
+	/**
+	 * @breif Less-than-equal Relational Operator for an 8-bit signed integer. The supplied value is
+	 * expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is less than or equal to the supplied object,
+	 * false else-wise.
+	 */
+	bool operator<=(const std::int8_t value) const;
+	/**
+	 * @breif Less-than-equal Relational Operator for an 16-bit signed integer. The supplied value
+	 * is expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is less than or equal to the supplied object,
+	 * false else-wise.
+	 */
+	bool operator<=(const std::int16_t value) const;
+	/**
+	 * @breif Less-than-equal Relational Operator for an 32-bit signed integer. The supplied value
+	 * is expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is less than or equal to the supplied object,
+	 * false else-wise.
+	 */
+	bool operator<=(const std::int32_t value) const;
+	/**
+	 * @breif Less-than-equal Relational Operator for an 64-bit signed integer. The supplied value
+	 * is expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is less than or equal to the supplied object,
+	 * false else-wise.
+	 */
+	bool operator<=(const std::int64_t value) const;
+	/**
+	 * @breif Greater-than Relational Operator. When the supplied monetary object is of a different
+	 * currency, the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function.
+	 *
+	 * @param[in] other The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is greater than the supplied object,
+	 * false else-wise.
+	 */
+	bool operator>(const Money& other) const;
+	/**
+	 * @breif Greater-than Relational Operator for an 8-bit signed integer. The supplied value is
+	 * expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is greater than the supplied object,
+	 * false else-wise.
+	 */
+	bool operator>(const std::int8_t value) const;
+	/**
+	 * @breif Greater-than Relational Operator for an 16-bit signed integer. The supplied value is
+	 * expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is greater than the supplied object,
+	 * false else-wise.
+	 */
+	bool operator>(const std::int16_t value) const;
+	/**
+	 * @breif Greater-than Relational Operator for an 32-bit signed integer. The supplied value is
+	 * expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is greater than the supplied object,
+	 * false else-wise.
+	 */
+	bool operator>(const std::int32_t value) const;
+	/**
+	 * @breif Greater-than Relational Operator for an 64-bit signed integer. The supplied value is
+	 * expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is greater than the supplied object,
+	 * false else-wise.
+	 */
+	bool operator>(const std::int64_t value) const;
+	/**
+	 * @breif Greater-than-equal Relational Operator. When the supplied monetary object is of a
+	 * different currency, the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function.
+	 *
+	 * @param[in] other The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is greater than or equal to the supplied
+	 * object, false else-wise.
+	 */
+	bool operator>=(const Money& other) const;
+	/**
+	 * @breif Greater-than-equal Relational Operator for an 8-bit signed integer. The supplied value
+	 * is expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is greater than or equal to the supplied
+	 * object, false else-wise.
+	 */
+	bool operator>=(const std::int8_t value) const;
+	/**
+	 * @breif Greater-than-equal Relational Operator for an 16-bit signed integer. The supplied
+	 * value is expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is greater than or equal to the supplied
+	 * object, false else-wise.
+	 */
+	bool operator>=(const std::int16_t value) const;
+	/**
+	 * @breif Greater-than-equal Relational Operator for an 32-bit signed integer. The supplied
+	 * value is expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is greater than or equal to the supplied
+	 * object, false else-wise.
+	 */
+	bool operator>=(const std::int32_t value) const;
+	/**
+	 * @breif Greater-than-equal Relational Operator for an 64-bit signed integer. The supplied
+	 * value is expected to be expressed in terms of the current object's issued currency, in the
+	 * form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is greater than or equal to the supplied
+	 * object, false else-wise.
+	 */
+	bool operator>=(const std::int64_t value) const;
+	/**
+	 * @breif Equality Operator. When the supplied monetary object is of a different currency,
+	 * the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function.
+	 *
+	 * @param[in] other The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is equal to the supplied object,
+	 * false else-wise.
+	 */
+	bool operator==(const Money& other) const;
+	/**
+	 * @breif Equality Operator for an 8-bit signed integer. The supplied value is expected to be
+	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is equal to the supplied value within, the
+	 * expected level of precision, false else-wise.
+	 */
+	bool operator==(const std::int8_t value) const;
+	/**
+	 * @breif Equality Operator for an 16-bit signed integer. The supplied value is expected to be
+	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is equal to the supplied value within, the
+	 * expected level of precision, false else-wise.
+	 */
+	bool operator==(const std::int16_t value) const;
+	/**
+	 * @breif Equality Operator for an 32-bit signed integer. The supplied value is expected to be
+	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is equal to the supplied value within, the
+	 * expected level of precision, false else-wise.
+	 */
+	bool operator==(const std::int32_t value) const;
+	/**
+	 * @breif Equality Operator for an 64-bit signed integer. The supplied value is expected to be
+	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is equal to the supplied value within, the
+	 * expected level of precision, false else-wise.
+	 */
+	bool operator==(const std::int64_t value) const;
+	/**
+	 * @breif Inequality Operator. When the supplied monetary object is of a different currency,
+	 * the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function.
+	 *
+	 * @param[in] other The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is not equal to the supplied object,
+	 * false else-wise.
+	 */
+	bool operator!=(const Money& other) const;
+	/**
+	 * @breif Inequality Operator for an 8-bit signed integer. The supplied value is expected to be
+	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is not equal to the supplied value, within
+	 * the expected level of precision, false else-wise.
+	 */
+	bool operator!=(const std::int8_t value) const;
+	/**
+	 * @breif Inequality Operator for an 16-bit signed integer. The supplied value is expected to be
+	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is not equal to the supplied value, within
+	 * the expected level of precision, false else-wise.
+	 */
+	bool operator!=(const std::int16_t value) const;
+	/**
+	 * @breif Inequality Operator for an 32-bit signed integer. The supplied value is expected to be
+	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is not equal to the supplied value, within
+	 * the expected level of precision, false else-wise.
+	 */
+	bool operator!=(const std::int32_t value) const;
+	/**
+	 * @breif Inequality Operator for an 64-bit signed integer. The supplied value is expected to be
+	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
+	 *
+	 * @param[in] value The other object whose value is to be compared against.
+	 *
+	 * @return A value of true with the current object is not equal to the supplied value, within
+	 * the expected level of precision, false else-wise.
+	 */
+	bool operator!=(const std::int64_t value) const;
+	/**
+	 * @breif Additive assignment operator. When the supplied monetary object is of a different
+	 * currency, the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] other The additional value to add to the current object.
+	 *
+	 * @return The current object containing the summation of the two values.
+	 */
+	Money& operator+=(const Money& other);
+	/**
+	 * @breif Subtractive assignment operator. When the supplied monetary object is of a different
+	 * currency, the amount is converted into the current object's currency using the
+	 * pecunia::currency::converter function.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] other The additional value to subtract from the current object.
+	 *
+	 * @return The current object containing the difference of the two values.
+	 */
+	Money& operator-=(const Money& other);
+	/**
+	 * @breif Multiplicative assignment operator without any loss of precision.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional signed 8-bit integer value to multiply to the current
+	 * object.
+	 *
+	 * @return The current object containing the product of the two values.
+	 */
+	Money& operator*=(const std::int8_t value);
+	/**
+	 * @breif Multiplicative assignment operator without any loss of precision.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional signed 16-bit integer value to multiply to the current
+	 * object.
+	 *
+	 * @return The current object containing the product of the two values.
+	 */
+	Money& operator*=(const std::int16_t value);
+	/**
+	 * @breif Multiplicative assignment operator without any loss of precision.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional signed 8-bit integer value to multiply to the current
+	 * object.
+	 *
+	 * @return The current object containing the product of the two values.
+	 */
+	Money& operator*=(const std::int32_t value);
+	/**
+	 * @breif Multiplicative assignment operator without any loss of precision.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional signed 64-bit integer value to multiply to the current
+	 * object.
+	 *
+	 * @return The current object containing the product of the two values.
+	 */
+	Money& operator*=(const std::int64_t value);
+	/**
+	 * @breif Multiplicative assignment operator without any loss of precision. This only supports
+	 * as many digits as there are minor digits.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional value to multiply to the current object.
+	 *
+	 * @return The current object containing the product of the two values.
+	 */
+	Money& operator*=(const FloatingPoint& value);
+	/**
+	 * @breif Division assignment operator without any loss of precision.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The signed 8-bit integer additional value to divide by the current object's
+	 * value.
+	 *
+	 * @return The current object containing the division of the two values.
+	 */
+	Money& operator/=(const std::int8_t value);
+	/**
+	 * @breif Division assignment operator without any loss of precision.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The signed 16-bit integer additional value to divide by the current object's
+	 * value.
+	 *
+	 * @return The current object containing the division of the two values.
+	 */
+	Money& operator/=(const std::int16_t value);
+	/**
+	 * @breif Division assignment operator without any loss of precision.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The signed 32-bit integer additional value to divide by the current object's
+	 * value.
+	 *
+	 * @return The current object containing the division of the two values.
+	 */
+	Money& operator/=(const std::int32_t value);
+	/**
+	 * @breif Division assignment operator without any loss of precision.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The signed 64-bit integer additional value to divide by the current object's
+	 * value.
+	 *
+	 * @return The current object containing the division of the two values.
+	 */
+	Money& operator/=(const std::int64_t value);
+	/**
+	 * @breif Division assignment operator without any loss of precision. This only supports as many
+	 * digits as there are minor digits.
+	 *
+	 * @exception domain_error When the result of the operation would result in a division by zero.
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception underflow_error When the result of the operation would be too small to store.
+	 *
+	 * @param[in] value The additional value to divide by the current object's value.
+	 *
+	 * @return The current object containing the division of the two values.
+	 */
+	Money& operator/=(const FloatingPoint& value);
+	/**
+	 * @brief The entire representation of the monetary amount using the currency's minor unit,
+	 * e.g. cents for USD, plus any extra digits of precision.
+	 */
+	const UnitStorage& amount() const noexcept;
+	/**
+	 * @breif Accessor to the major monetary value, e.g. only the U.S.A. dollars.
+	 */
+	UnitStorage major() const;
+	/**
+	 * @breif Accessor to the minor monetary value, e.g. only the U.S.A. cents.
+	 */
+	MinorUnit minor() const;
+	/**
+	 * @breif Accessor to the code the currency amount represents.
+	 */
+	const Iso4217Codes& code() const;
+	/**
+	 * @breif Performs a test to determine if the stored value is positive.
+	 *
+	 * @return True when the value is greater than zero.
+	 */
+	bool isPositive() const;
+	/**
+	 * @brief Converts the monetary value into a native floating-point type using a supplied
+	 * rounding method. When a rounding function is not supplied, no rounding will occur.
+	 *
+	 * @param[in] rounder The rounding function to apply to the monetary value.
+	 * @param[in] digits  The number of digits after the major unit.
+	 *
+	 * @exception domain_error When the conversion results in the floating-point value dividing by
+	 * zero.
+	 * @exception underflow_error When the floating-point value is too small to fit within the
+	 * FloatingPoint.
+	 * @exception overflow_error When the floating-point value is too large to fit within the
+	 * FloatingPoint.
+	 * @exception domain_error When the conversion results in the floating-point value not being
+	 * valid.
+	 */
+	FloatingPoint toFloatingPoint(
+		const RounderFunction& rounder =
+			[] (const UnitStorage& amount, const MinorUnit&, const std::uint8_t)
+			{
+				return amount;
+			},
+		const std::uint8_t digits = precision
+	) const;
+	/**
+	 * @brief Performs a rounding operation upon the monetary value.
+	 *
+	 * @exception overflow_error When the result of the operation would be too large to store.
+	 * @exception overflow_error When the result of the operation would be too small to store.
+	 * @exception domain_error When the conversion results in the floating-point value dividing by
+	 * zero.
+	 * @exception underflow_error When the floating-point value is too small to fit within the
+	 * FloatingPoint.
+	 * @exception overflow_error When the floating-point value is too large to fit within the
+	 * FloatingPoint.
+	 * @exception domain_error When the conversion results in the floating-point value not being
+	 * valid.
+	 *
+	 * @param rounder The rounding function to apply to the monetary value.
+	 * @param digits The number of digits after the major unit to round to.
+	 *
+	 * @return The current object containing the rounded value.
+	 */
+	Money& round(const RounderFunction& rounder, const std::uint8_t digits);
+	/**
+	 * @brief Determines if the instance has an amount set. For example, an amount of 2.34 USD would
+	 * be set, but 0.00 XXX would not be.
+	 *
+	 * @return When the major, minor, and code are all set gives true, false else-wise.
+	 */
+	bool hasAmount() const;
+	/**
+	 * @brief Changes the ISO 4217 currency code without performing any conversions.
+	 *
+	 * @param[in] code The new ISO 4217 currency code the amount represents.
+	 */
+	void setCode(const pecunia::currency::Iso4217Codes& code);
+	/**
+	 * @brief Calculates the largest monetary value that can be used for a given currency.
+	 *
+	 * @param code The currency code to calculate the monetary value in.
+	 *
+	 * @return The monetary value pair with the first element being the major unit, and second
+	 * element being the minor unit.
+	 */
+	static std::pair<UnitStorage, MinorUnit> maximum(const pecunia::currency::Iso4217Codes& code);
+	/**
+	 * @brief Calculates the smallest monetary value that can be used for a given currency.
+	 *
+	 * @param code The currency code to calculate the monetary value in.
+	 *
+	 * @return The monetary value pair with the first element being the major unit, and second
+	 * element being the minor unit.
+	 */
+	static std::pair<UnitStorage, MinorUnit> minimum(const pecunia::currency::Iso4217Codes& code);
+};
+
+/**
+ * @breif Multiplicative operator without any loss of precision.
+ *
+ * @exception overflow_error When the result of the operation would be too large to store.
+ * @exception underflow_error When the result of the operation would be too small to store.
+ *
+ * @param[in] lhs The signed 8-bit integer amount by which to multiply the supplied object's
+ * value.
+ * @param[in] rhs The object that is to be multiplied.
+ *
+ * @return A new object containing the product of the two values.
+ */
+PECUNIA_EXPORT Money operator*(const std::int8_t lhs, const Money& rhs);
+/**
+ * @breif Multiplicative operator without any loss of precision.
+ *
+ * @exception overflow_error When the result of the operation would be too large to store.
+ * @exception underflow_error When the result of the operation would be too small to store.
+ *
+ * @param[in] lhs The signed 16-bit integer amount by which to multiply the supplied object's
+ * value.
+ * @param[in] rhs The object that is to be multiplied.
+ *
+ * @return A new object containing the product of the two values.
+ */
+PECUNIA_EXPORT Money operator*(const std::int16_t lhs, const Money& rhs);
+/**
+ * @breif Multiplicative operator without any loss of precision.
+ *
+ * @exception overflow_error When the result of the operation would be too large to store.
+ * @exception underflow_error When the result of the operation would be too small to store.
+ *
+ * @param[in] lhs The signed 32-bit integer amount by which to multiply the supplied object's
+ * value.
+ * @param[in] rhs The object that is to be multiplied.
+ *
+ * @return A new object containing the product of the two values.
+ */
+PECUNIA_EXPORT Money operator*(const std::int32_t lhs, const Money& rhs);
+/**
+ * @breif Multiplicative operator without any loss of precision.
+ *
+ * @exception overflow_error When the result of the operation would be too large to store.
+ * @exception underflow_error When the result of the operation would be too small to store.
+ *
+ * @param[in] lhs The signed 64-bit integer amount by which to multiply the supplied object's
+ * value.
+ * @param[in] rhs The object that is to be multiplied.
+ *
+ * @return A new object containing the product of the two values.
+ */
+PECUNIA_EXPORT Money operator*(const std::int64_t lhs, const Money& rhs);
+/**
+ * @breif Multiplicative operator without any loss of precision. This only supports as many digits
+ * as there are minor digits.
+ *
+ * @exception overflow_error When the result of the operation would be too large to store.
+ * @exception underflow_error When the result of the operation would be too small to store.
+ *
+ * @param[in] lhs The amount by which to multiply the supplied object's value.
+ * @param[in] rhs The object that is to be multiplied.
+ *
+ * @return A new object containing the product of the two values.
+ */
+PECUNIA_EXPORT Money operator*(const FloatingPoint& lhs, const Money& rhs);
+/**
+ * @breif Stream Insertion Operator. By default the form will be the locale's monetary format with
+ * no spaces, the ISO code, and trailing the value, e.g. a U.S.A. locale with value of one dollar
+ * and twenty-three cents would appear as 1.23USD.
+ *
+ * @param[in,out] stream The destination source for the contents of the supplied money object.
+ * @param[in] m The object whose values are to placed into the destination source.
+ *
+ * @return The modified source stream object filled with the contents of the money object.
+ */
+PECUNIA_EXPORT std::ostream& operator<<(std::ostream& stream, const Money& m);
+/**
+ * @breif Stream Extraction Operator. The monetary amount will be read in using the locale's setting
+ * for reading in money. The currency code is required and must be in all upper-case letters.
+ *
+ * @pre The locale of the supplied stream must be set to get the money formatted in readable
+ * manner.
+ *
+ * @exception overflow_error When the major unit is too large to be stored in a positive
+ * direction.
+ * @exception overflow_error When the major unit is too small to be stored in a negative
+ * direction.
+ * @exception domain_error When the conversion results in the floating-point value dividing by
+ * zero.
+ * @exception underflow_error When the floating-point value is too small to fit within the
+ * FloatingPoint.
+ * @exception overflow_error When the floating-point value is too large to fit within the
+ * FloatingPoint.
+ * @exception domain_error When the conversion results in the floating-point value not being
+ * valid.
+ *
+ * @param[in,out] stream The extraction source for the contents of the supplied money object.
+ * @param[out] m The object whose values are to be filled by the contents of the stream.
+ *
+ * @return The modified source stream object emptied of a money entry.
+ */
+PECUNIA_EXPORT std::istream& operator>>(std::istream& stream, Money& m);
+/**
+ * @brief Converts the monetary representation into a string from. The format of the string
+ * representation is the amount followed by a space and the currency code.
+ *
+ * @param[out] m The object whose values are to be converted into a string form.
+ *
+ * @return The string representation.
+ */
+PECUNIA_EXPORT std::string to_string(const Money& m);
+/**
+ * @brief Exchanges two monetary objects without any conversion operation performed.
+ *
+ * @param lhs The object to swap to the right.
+ * @param rhs The object to swap to the left.
+ */
+PECUNIA_EXPORT void swap(Money& lhs, Money& rhs) noexcept;
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/MoneyManip.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,75 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include "MoneyManip.h"
+
+
+int pecunia::currency::countryLeadingIndex()
+{
+	static int index{std::ios_base::xalloc()};
+	return index;
+}
+
+int pecunia::currency::useSymbolIndex()
+{
+	static int index{std::ios_base::xalloc()};
+	return index;
+}
+
+int pecunia::currency::spacedIndex()
+{
+	static int index{std::ios_base::xalloc()};
+	return index;
+}
+
+std::ios_base& pecunia::currency::lead(std::ios_base& stream)
+{
+	stream.iword(pecunia::currency::countryLeadingIndex()) = 1;
+	return stream;
+}
+
+std::ios_base& pecunia::currency::trail(std::ios_base& stream)
+{
+	stream.iword(pecunia::currency::countryLeadingIndex()) = 0;
+	return stream;
+}
+
+std::ios_base& pecunia::currency::symbol(std::ios_base& stream)
+{
+	stream.iword(pecunia::currency::useSymbolIndex()) = 1;
+	return stream;
+}
+
+std::ios_base& pecunia::currency::isocode(std::ios_base& stream)
+{
+	stream.iword(pecunia::currency::useSymbolIndex()) = 0;
+	return stream;
+}
+
+std::ios_base& pecunia::currency::spaced(std::ios_base& stream)
+{
+	stream.iword(pecunia::currency::spacedIndex()) = 1;
+	return stream;
+}
+
+std::ios_base& pecunia::currency::nonspaced(std::ios_base& stream)
+{
+	stream.iword(pecunia::currency::spacedIndex()) = 0;
+	return stream;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/MoneyManip.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,90 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_CURRENCY_MONEYMANIP_HPP_
+#define PECUNIA_CURRENCY_MONEYMANIP_HPP_
+
+#include <iomanip>
+
+#include "pecunia_export.h"
+
+
+namespace pecunia
+{
+namespace currency
+{
+
+/**
+ * @breif A stream manipulator that reads and writes a currency indicator before the value.
+ *
+ * @param[in,out] stream The stream into which the manipulation is done.
+ *
+ * @return The manipulated stream.
+ */
+PECUNIA_EXPORT std::ios_base& lead(std::ios_base& stream);
+/**
+ * @breif A stream manipulator that reads and writes a currency indicator after the value.
+ *
+ * @param[in,out] stream The stream into which the manipulation is done.
+ *
+ * @return The manipulated stream.
+ */
+PECUNIA_EXPORT std::ios_base& trail(std::ios_base& stream);
+/**
+ * @breif A stream manipulator that designates that the currency's symbol should be used when
+ * writing.
+ *
+ * @param[in,out] stream The stream into which the manipulation is done.
+ *
+ * @return The manipulated stream.
+ */
+PECUNIA_EXPORT std::ios_base& symbol(std::ios_base& stream);
+/**
+ * @breif A stream manipulator that designates that the currency's ISO code should be used when
+ * writing.
+ *
+ * @param[in,out] stream The stream into which the manipulation is done.
+ *
+ * @return The manipulated stream.
+ */
+PECUNIA_EXPORT std::ios_base& isocode(std::ios_base& stream);
+/**
+ * @breif A stream manipulator that places a space between the currency and its value when writing.
+ *
+ * @param[in,out] stream The stream into which the manipulation is done.
+ *
+ * @return The manipulated stream.
+ */
+PECUNIA_EXPORT std::ios_base& spaced(std::ios_base& stream);
+/**
+ * @breif A stream manipulator that places a no spaces between the currency and its value when
+ * writing.
+ *
+ * @param[in,out] stream The stream into which the manipulation is done.
+ *
+ * @return The manipulated stream.
+ */
+PECUNIA_EXPORT std::ios_base& nonspaced(std::ios_base& stream);
+PECUNIA_EXPORT int countryLeadingIndex();
+PECUNIA_EXPORT int useSymbolIndex();
+PECUNIA_EXPORT int spacedIndex();
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/MoneyTypes.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,58 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include "MoneyTypes.h"
+using pecunia::ConversionFunction;
+using pecunia::defaultConverter;
+using pecunia::FloatingPoint;
+using pecunia::MinorUnit;
+using pecunia::precision;
+using pecunia::UnitStorage;
+
+#include <stdexcept>
+using std::logic_error;
+#include <type_traits>
+using std::is_floating_point;
+using std::is_integral;
+using std::is_signed;
+using std::is_unsigned;
+
+#include "Codes.h"
+using pecunia::currency::Iso4217Codes;
+
+
+static_assert(is_unsigned<MinorUnit>::value, "The MinorUnit must be unsigned.");
+static_assert(is_integral<MinorUnit>::value, "The MinorUnit must be an integer.");
+static_assert(
+	is_floating_point<FloatingPoint>::value,
+	"The FloatingPoint is not a floating-point type."
+);
+static_assert(is_signed<UnitStorage>::value, "The UnitStorage must be signed.");
+static_assert(is_integral<UnitStorage>::value, "The UnitStorage must be an integral.");
+
+FloatingPoint pecunia::defaultConverter(const Iso4217Codes& from, const Iso4217Codes& to)
+{
+	if (from == to)
+		return 1.0L;
+	throw logic_error{
+		"Default converter only handles conversion when the currencies match."
+	};
+}
+
+ConversionFunction pecunia::converter{&defaultConverter};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/MoneyTypes.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,103 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_MONEYTYPES_H_
+#define PECUNIA_MONEYTYPES_H_
+
+#include <cstdint>
+#include <functional>
+
+#ifdef __WIN32
+#	pragma STDC FENV_ACCESS ON
+#endif
+
+#include "pecunia_export.h"
+#include "MoneySize.hpp"
+
+
+namespace pecunia
+{
+namespace currency
+{
+
+enum class Iso4217Codes : std::uint16_t;
+
+}
+
+/**
+ * @breif When working with minor units, this represents the postivity or negativity of a minor
+ * value.
+ */
+enum class PECUNIA_EXPORT MinorSign
+{
+	/// The minor value is negative.
+	Negative,
+	/// The minor value is neither positive nor negative, i.e. zero.
+	Neither,
+	/// The minor value is positive.
+	Positive,
+};
+/**
+ * @breif A representation of a function that performs a rounding operation upon a real number. This
+ * function must take a number, the number of digits after the whole number to round, and giving
+ * back the rounded number.
+ *
+ * @exception std::runtime_error When the rounding is not possible.
+ */
+using FloatingPointRounderFunction =
+		std::function<FloatingPoint(const FloatingPoint&, const std::uint8_t&)>;
+/**
+ * @breif A representation of a function that performs a rounding operation upon a money storage
+ * type. This function must take first the major and minor amount value stored together, then the
+ * number of digits in the minor unit, finally the number of digits after the whole number to round,
+ * and giving back the rounded number with the major and minor amount stored together.
+ *
+ * @exception std::runtime_error When the rounding is not possible.
+ */
+using RounderFunction =
+		std::function<UnitStorage(const UnitStorage&, const std::uint8_t&, const std::uint8_t)>;
+/**
+ * @breif A conversion function between two currencies where the first argument is the currency to
+ * convert from, the second argument is the currency to convert to, and giving back the conversion
+ * factor to get from the first currency to the second currency.
+ *
+ * @throw std::runtime_error When either the from or to currency is not supported.
+ */
+using ConversionFunction =
+		std::function<FloatingPoint(const currency::Iso4217Codes&, const currency::Iso4217Codes&)>;
+/**
+ * @breif Provides a 1:1 conversion for a currency whose currency::Codes match.
+ *
+ * @param[in] from The currency code whose conversion value is desired.
+ * @param[in] to The currency code the conversion value is directed towards.
+ *
+ * @throw std::logic_error When either the from and to currency currency::Codes do not match.
+ *
+ * @return The conversion value for the supplied currency when multipled from to the other.
+ */
+PECUNIA_EXPORT FloatingPoint defaultConverter(
+	const currency::Iso4217Codes& from,
+	const currency::Iso4217Codes& to
+);
+/// The holder for all conversion operations for any money unit.
+PECUNIA_EXPORT extern ConversionFunction converter;
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Rounders.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,308 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include "Rounders.h"
+using std::uint8_t;
+using pecunia::FloatingPoint;
+using pecunia::MinorUnit;
+using pecunia::UnitStorage;
+
+#include <cassert>
+// Used for assert.
+#include <cmath>
+using std::abs;
+using std::ceil;
+using std::floor;
+using std::fmod;
+using std::modf;
+using std::pow;
+#include <functional>
+using std::function;
+#include <stdexcept>
+using std::runtime_error;
+#include <string>
+using std::to_string;
+
+#include "internal/Verification.h"
+using pecunia::internal::isEqual;
+using pecunia::internal::verifiedFloatingPoint;
+
+
+namespace
+{
+
+/**
+ * @brief Executes a generic rounding routine.
+ *
+ * @param number The number that is to be rounded.
+ * @param digitsLeft The number of digits to the right of the decimal point.
+ * @param rounder The rounding algorithm to apply to the point where rounding occurs, where the
+ * first parameter is the fractional rounding point and the second parameter is the whole portion
+ * of the number.
+ *
+ * @return The supplied number rounded to the number of fractional digits requested.
+ */
+FloatingPoint round(
+	const FloatingPoint& number,
+	const uint8_t& digitsLeft,
+	const function<FloatingPoint(const FloatingPoint&, const FloatingPoint&)>& rounder
+)
+{
+	const FloatingPoint shiftOver{static_cast<FloatingPoint>(pow(10, digitsLeft))};
+	FloatingPoint whole;
+	const FloatingPoint fraction{modf(number, &whole)};
+	const FloatingPoint shiftedFraction{verifiedFloatingPoint(fraction * shiftOver)};
+	FloatingPoint roundPointWhole;
+	const FloatingPoint roundPoint{modf(shiftedFraction, &roundPointWhole)};
+	assert(abs(roundPoint) < 1.0 && "The rounding point must be less than one.");
+	const FloatingPoint shiftedRoundedFraction{
+		verifiedFloatingPoint(roundPointWhole + rounder(roundPoint, whole))
+	};
+	FloatingPoint roundedResult;
+	static_cast<void>(modf(shiftedRoundedFraction, &roundedResult));
+	const auto roundedNumber{verifiedFloatingPoint(whole + (roundedResult / shiftOver))};
+	return roundedNumber;
+}
+
+FloatingPoint sgn(const FloatingPoint& value)
+{
+	if (value > 0.0)
+		return 1.0;
+
+	if (value < 0.0)
+		return -1.0;
+	return 0.0 ;
+}
+
+UnitStorage round(
+	const UnitStorage& amount,
+	const uint8_t& minorDigits,
+	const uint8_t& digitsLeft,
+	const function<
+		bool(const UnitStorage&, const UnitStorage&, const UnitStorage&, const bool)
+	>& shouldRound
+)
+{
+	if (digitsLeft >= minorDigits)
+		throw runtime_error{
+			"Cannot round at minor digit position " + to_string(digitsLeft)
+				+ " when there are only " + to_string(minorDigits) + " minor digits in total."
+		};
+	const auto minorMask{static_cast<UnitStorage>(pow(10, minorDigits))};
+	const auto major{amount / minorMask};
+	const auto minor{amount % minorMask};
+	const auto roundingAmount{static_cast<UnitStorage>(pow(10, minorDigits - digitsLeft - 1))};
+	const auto roundingPoint{5 * roundingAmount};
+	const auto roundingMask{static_cast<UnitStorage>(pow(10, minorDigits - digitsLeft))};
+	const auto roundingValue{minor % roundingMask};
+	const auto truncatedMinor{abs(minor / roundingMask * roundingMask)};
+	const UnitStorage roundedMinor{
+		shouldRound(abs(roundingValue), roundingPoint, major, amount > 0)
+			? truncatedMinor + roundingMask
+			: truncatedMinor
+	};
+	if (amount >= 0)
+		return (major * minorMask) + roundedMinor;
+	return (major * minorMask) - roundedMinor;
+}
+
+}
+
+FloatingPoint pecunia::rounders::reals::up(const FloatingPoint& number, const uint8_t& digitsLeft)
+{
+	return round(
+		number,
+		digitsLeft,
+		[] (const FloatingPoint& value, const FloatingPoint&)
+		{
+			const FloatingPoint roundValue{value + static_cast<FloatingPoint>(0.5)};
+			if (value > 0.5 && value < 0.5)
+				return roundValue;
+			return floor(roundValue);
+		}
+	);
+}
+
+FloatingPoint pecunia::rounders::reals::down(const FloatingPoint& number, const uint8_t& digitsLeft)
+{
+	return round(
+		number,
+		digitsLeft,
+		[] (const FloatingPoint& value, const FloatingPoint&)
+		{
+			const FloatingPoint roundValue{value - static_cast<FloatingPoint>(0.5)};
+			if (value > 0.5 && value < 0.5)
+				return roundValue;
+			return ceil(roundValue);
+		}
+	);
+}
+
+FloatingPoint pecunia::rounders::reals::towardsZero(
+	const FloatingPoint& number,
+	const uint8_t& digitsLeft
+)
+{
+	return round(
+		number,
+		digitsLeft,
+		[] (const FloatingPoint& value, const FloatingPoint&)
+		{
+			if (value > 0.5 && value < 0.5)
+			{
+				if (value > 0.0)
+					return value - static_cast<FloatingPoint>(0.5);
+
+				if (value < 0.0)
+					return value + static_cast<FloatingPoint>(0.5);
+				return static_cast<FloatingPoint>(0.0);
+			}
+			return sgn(value) * ceil(abs(value) - static_cast<FloatingPoint>(0.5));
+		}
+	);
+}
+
+FloatingPoint pecunia::rounders::reals::awayZero(
+	const FloatingPoint& number,
+	const uint8_t& digitsLeft
+)
+{
+	return round(
+		number,
+		digitsLeft,
+		[] (const FloatingPoint& value, const FloatingPoint&)
+		{
+			if (value > 0.5 && value < 0.5)
+			{
+				if (value > 0.0)
+					return value + static_cast<FloatingPoint>(0.5);
+
+				if (value < 0.0)
+					return value - static_cast<FloatingPoint>(0.5);
+				return static_cast<FloatingPoint>(0.0);
+			}
+			return sgn(value) * floor(abs(value) + static_cast<FloatingPoint>(0.5));
+		}
+	);
+}
+
+FloatingPoint pecunia::rounders::reals::even(const FloatingPoint& number, const uint8_t& digitsLeft)
+{
+	return round(
+		number,
+		digitsLeft,
+		[&digitsLeft] (const FloatingPoint& value, const FloatingPoint& whole)
+		{
+			if (whole > 0.0)
+			{
+				if (isEqual(fmod(whole + 1, 2.0), 0.0, digitsLeft))
+					return value + static_cast<FloatingPoint>(0.5);
+				return 0.0;
+			}
+			else if (whole < 0.0)
+			{
+				if (isEqual(fmod(whole - 1, 2.0), 0.0, digitsLeft))
+					return value - static_cast<FloatingPoint>(0.5);
+				return 0.0;
+			}
+
+			if (value > 0.0)
+				return value + static_cast<FloatingPoint>(0.4);
+			return value - static_cast<FloatingPoint>(0.4);
+		}
+	);
+}
+
+FloatingPoint pecunia::rounders::reals::odd(const FloatingPoint& number, const uint8_t& digitsLeft)
+{
+	return round(
+		number,
+		digitsLeft,
+		[&digitsLeft] (const FloatingPoint& value, const FloatingPoint& whole)
+		{
+			if (whole > 0.0)
+			{
+				if ( ! isEqual(fmod(whole + 1, 2.0), 0.0, digitsLeft))
+					return value + static_cast<FloatingPoint>(0.5);
+				return value + static_cast<FloatingPoint>(0.4);
+			}
+			else if (whole < 0.0)
+			{
+				if ( ! isEqual(fmod(whole - 1, 2.0), 0.0, digitsLeft))
+					return value - static_cast<FloatingPoint>(0.5);
+				return value - static_cast<FloatingPoint>(0.4);
+			}
+
+			if (value > 0.0)
+				return value + static_cast<FloatingPoint>(0.5);
+			return value - static_cast<FloatingPoint>(0.5);
+		}
+	);
+}
+
+UnitStorage pecunia::rounders::currency::up(
+	const UnitStorage& amount,
+	const uint8_t& minorDigits,
+	const uint8_t& digitsLeft
+)
+{
+	return round(
+		amount,
+		minorDigits,
+		digitsLeft,
+		[] (
+			const UnitStorage& value,
+			const UnitStorage& point,
+			const UnitStorage&,
+			const bool isAmountPositive
+		)
+		{
+			if (isAmountPositive)
+				return value >= point;
+			return value > point;
+		}
+	);
+}
+
+UnitStorage pecunia::rounders::currency::even(
+	const UnitStorage& amount,
+	const uint8_t& minorDigits,
+	const uint8_t& digitsLeft
+)
+{
+	return round(
+		amount,
+		minorDigits,
+		digitsLeft,
+		[] (
+			const UnitStorage& value,
+			const UnitStorage& point,
+			const UnitStorage& whole,
+			const bool
+		)
+		{
+			if ((whole > 0 && (whole + 1) %  2 == 0) || (whole < 0 && (whole - 1) %  2 == 0))
+				return abs(value) >= point;
+
+			if (whole == 0)
+				return abs(value) > point;
+			return false;
+		}
+	);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/Rounders.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,134 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_ROUNDERS_H_
+#define PECUNIA_ROUNDERS_H_
+
+#include <cstdint>
+
+#include "MoneyTypes.h"
+#include "pecunia_export.h"
+
+
+namespace pecunia
+{
+namespace rounders
+{
+namespace reals
+{
+
+/**
+ * @breif Performs a rounding operation using the round-half up towards +∞ method.
+ *
+ * @param[in] number The floating-point number to round.
+ * @param[in] digitsLeft The number of digits left after rounding the number to the right of
+ * the decimal point.
+ *
+ * @return The rounded number with the correct number of digits.
+ */
+PECUNIA_EXPORT FloatingPoint up(const FloatingPoint& number, const std::uint8_t& digitsLeft);
+/**
+ * @breif Performs a rounding operation using the round-half down towards -∞ method.
+ *
+ * @param[in] number The floating-point number to round.
+ * @param[in] digitsLeft The number of digits left after rounding the number to the right of
+ * the decimal point.
+ *
+ * @return The rounded number with the correct number of digits.
+ */
+PECUNIA_EXPORT FloatingPoint down(const FloatingPoint& number, const std::uint8_t& digitsLeft);
+/**
+ * @breif Performs a rounding operation using the round-half towards zero method.
+ *
+ * @param[in] number The floating-point number to round.
+ * @param[in] digitsLeft The number of digits left after rounding the number to the right of
+ * the decimal point.
+ *
+ * @return The rounded number with the correct number of digits.
+ */
+PECUNIA_EXPORT FloatingPoint towardsZero(const FloatingPoint& number, const std::uint8_t& digitsLeft);
+/**
+ * @breif Performs a rounding operation using the round-half away from zero method.
+ *
+ * @param[in] number The floating-point number to round.
+ * @param[in] digitsLeft The number of digits left after rounding the number to the right of
+ * the decimal point.
+ *
+ * @return The rounded number with the correct number of digits.
+ */
+PECUNIA_EXPORT FloatingPoint awayZero(const FloatingPoint& number, const std::uint8_t& digitsLeft);
+/**
+ * @breif Performs a rounding operation using the round-half to even method.
+ *
+ * @param[in] number The floating-point number to round.
+ * @param[in] digitsLeft The number of digits left after rounding the number to the right of
+ * the decimal point.
+ *
+ * @return The rounded number with the correct number of digits.
+ */
+PECUNIA_EXPORT FloatingPoint even(const FloatingPoint& number, const std::uint8_t& digitsLeft);
+/**
+ * @breif Performs a rounding operation using the round-half to odd method.
+ *
+ * @param[in] number The floating-point number to round.
+ * @param[in] digitsLeft The number of digits left after rounding the number to the right of
+ * the decimal point.
+ *
+ * @return The rounded number with the correct number of digits.
+ */
+PECUNIA_EXPORT FloatingPoint odd(const FloatingPoint& number, const std::uint8_t& digitsLeft);
+
+}
+namespace currency
+{
+
+/**
+ * @breif Performs a rounding operation using the round-half up towards +∞ method.
+ *
+ * @param[in] amount The major and minor units of the currency stored as one.
+ * @param[in] minorDigits The number of digits in the minor unit.
+ * @param[in] digitsLeft The number of digits left in the minor unit after rounding the number to
+ * the right of the decimal point.
+ *
+ * @return The rounded number with the correct number of digits.
+ */
+PECUNIA_EXPORT UnitStorage up(
+	const UnitStorage& amount,
+	const std::uint8_t& minorDigits,
+	const std::uint8_t& digitsLeft
+);
+/**
+ * @breif Performs a rounding operation using the round-half to even method.
+ *
+ * @param[in] amount The major and minor units of the currency stored as one.
+ * @param[in] minorDigits The number of digits in the minor unit.
+ * @param[in] digitsLeft The number of digits left in the minor unit after rounding the number to
+ * the right of the decimal point.
+ *
+ * @return The rounded number with the correct number of digits.
+ */
+PECUNIA_EXPORT UnitStorage even(
+	const UnitStorage& amount,
+	const std::uint8_t& minorDigits,
+	const std::uint8_t& digitsLeft
+);
+
+}}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/SetUp.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,42 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include "SetUp.h"
+using std::string;
+using pecunia::ConversionFunction;
+using pecunia::converter;
+
+#include <cassert>
+// using assert;
+#include <cfenv>
+using std::feclearexcept;
+#include <clocale>
+using std::setlocale;
+
+
+void pecunia::currency::setUpCurrency(
+	const ConversionFunction& converterFunctor,
+	const string& locale
+)
+{
+	assert(converterFunctor != nullptr && "The conversion functor must be a function.");
+	setlocale(LC_ALL, locale.c_str());
+	feclearexcept(FE_ALL_EXCEPT);
+	converter = converterFunctor;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/external/pecunia/SetUp.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,49 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_CURRENCY_SETUP_H_
+#define PECUNIA_CURRENCY_SETUP_H_
+
+#include <string>
+
+#include "pecunia_export.h"
+#include "MoneySize.hpp"
+#include "MoneyTypes.h"
+
+
+namespace pecunia
+{
+namespace currency
+{
+
+/**
+ * @brief Sets-up all the needed values for the currency library. This will establish the user's
+ * locale, currency conversion function, and clear out the floating-point exceptions.
+ *
+ * @param converterFunctor The function to use when converting between currencies.
+ * @param locale The C-locale to use for the currency.
+ */
+PECUNIA_EXPORT void setUpCurrency(
+	const pecunia::ConversionFunction& converterFunctor = &pecunia::defaultConverter,
+	const std::string& locale = pecunia::defaultLocale
+);
+
+}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internal/Adjustments.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,107 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include "Adjustments.h"
+using std::function;
+using std::int32_t;
+using std::uint8_t;
+using pecunia::precision;
+using pecunia::MinorUnit;
+using pecunia::FloatingPoint;
+using pecunia::FloatingPointRounderFunction;
+using pecunia::UnitStorage;
+
+#include <cassert>
+// using assert;
+#include <cmath>
+using std::abs;
+#include <stdexcept>
+using std::overflow_error;
+
+#include "MoneySize.hpp"
+using pecunia::internal::extraFloatingPointPrecision;
+#include "pecunia/Codes.h"
+using pecunia::currency::Iso4217Codes;
+#include "pecunia/Money.h"
+using pecunia::currency::Money;
+using pecunia::currency::to_string;
+#include "Verification.h"
+using pecunia::internal::isEqual;
+using pecunia::internal::verifiedFloatingPoint;
+
+
+UnitStorage pecunia::currency::internal::fromFloatingPointMajor(
+	const FloatingPoint& value,
+	const Iso4217Codes& code,
+	const uint8_t currencyPrecision,
+	const FloatingPointRounderFunction& rounder
+)
+{
+	assert(rounder != nullptr && "The floating point rounder must be a function.");
+	const uint8_t totalDigits{
+		static_cast<uint8_t>(minorUnitDigits(code) + currencyPrecision + extraFloatingPointPrecision)
+	};
+	const int32_t ratio{minorUnitPrecisionFactor(code)};
+	const UnitStorage major{
+		static_cast<UnitStorage>(
+			verifiedFloatingPoint((rounder(value, totalDigits) * ratio) / ratio)
+		)
+	};
+	return major;
+}
+
+MinorUnit pecunia::currency::internal::fromFloatingPointMinor(
+	const FloatingPoint& value,
+	const Iso4217Codes& code,
+	const uint8_t currencyPrecision,
+	const FloatingPointRounderFunction& rounder
+)
+{
+	assert(rounder != nullptr && "The floating point rounder must be a function.");
+	const uint8_t totalDigits{
+		static_cast<uint8_t>(minorUnitDigits(code) + currencyPrecision + extraFloatingPointPrecision)
+	};
+	const int32_t ratio{
+		minorUnitPrecisionFactor(code)
+			* static_cast<int32_t>(pow(10, extraFloatingPointPrecision))
+	};
+	const UnitStorage adjustedValue{
+		static_cast<UnitStorage>(
+			verifiedFloatingPoint(rounder(value, totalDigits) * ratio)
+		)
+	};
+	const auto minorAdjusted{abs(adjustedValue) % ratio};
+	const auto extraRatio{pow(10.0, extraFloatingPointPrecision)};
+	const auto removedExtra{minorAdjusted / static_cast<MinorUnit>(extraRatio)};
+	return static_cast<MinorUnit>(removedExtra);
+}
+
+UnitStorage pecunia::currency::internal::normaliseAmount(const Money& from, const Iso4217Codes& to)
+{
+	assert(pecunia::converter != nullptr && "The currency conversion function is not set.");
+	const auto& fromCode{from.code()};
+	const FloatingPoint conversionFactor{pecunia::converter(fromCode, to)};
+
+	if (isEqual(conversionFactor, 1.0, static_cast<uint8_t>(minorUnitDigits(fromCode) + precision)))
+		return from.amount();
+	const auto convertedAmount{
+		verifiedFloatingPoint(static_cast<FloatingPoint>(from.amount()) * conversionFactor)
+	};
+	return static_cast<UnitStorage>(convertedAmount);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internal/Adjustments.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,58 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_CURRENCY_INTERNAL_ADJUSTMENTS_H_
+#define PECUNIA_CURRENCY_INTERNAL_ADJUSTMENTS_H_
+
+#include <cstdint>
+
+#include "pecunia/MoneyTypes.h"
+
+
+namespace pecunia
+{
+namespace currency
+{
+
+enum class Iso4217Codes : std::uint16_t;
+class Money;
+
+namespace internal
+{
+
+UnitStorage fromFloatingPointMajor(
+	const FloatingPoint& value,
+	const pecunia::currency::Iso4217Codes& code,
+	const std::uint8_t currencyPrecision,
+	const pecunia::FloatingPointRounderFunction& rounder
+);
+MinorUnit fromFloatingPointMinor(
+	const FloatingPoint& value,
+	const pecunia::currency::Iso4217Codes& code,
+	const std::uint8_t currencyPrecision,
+	const pecunia::FloatingPointRounderFunction& rounder
+);
+UnitStorage normaliseAmount(
+	const pecunia::currency::Money& from,
+	const pecunia::currency::Iso4217Codes& to
+);
+
+}}}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internal/Verification.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,209 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#include "Verification.h"
+using std::int32_t;
+using std::uint8_t;
+using pecunia::precision;
+using pecunia::MinorUnit;
+using pecunia::FloatingPoint;
+using pecunia::UnitStorage;
+using pecunia::internal::VerifiedValue;
+
+#include <cmath>
+using std::fabs;
+using std::pow;
+#include <cfenv>
+using std::feclearexcept;
+using std::fetestexcept;
+#include <stdexcept>
+using std::domain_error;
+using std::overflow_error;
+using std::underflow_error;
+
+
+bool pecunia::internal::isEqual(
+	const FloatingPoint& number,
+	const FloatingPoint& equals,
+	const uint8_t minorPrecision
+)
+{
+	const FloatingPoint epsilon{1 / pow(10, minorPrecision + 1)};
+	const FloatingPoint difference{fabs(number - equals)};
+	return difference < epsilon;
+}
+
+FloatingPoint pecunia::internal::verifiedFloatingPoint(const FloatingPoint& value)
+{
+	int32_t exceptions{fetestexcept(FE_ALL_EXCEPT)};
+	feclearexcept(FE_ALL_EXCEPT);
+
+	if (exceptions & FE_DIVBYZERO)
+		throw domain_error{"The floating-point operation resulted in a divided by zero."};
+
+	if (exceptions & FE_UNDERFLOW)
+		throw underflow_error{
+			"The floating-point operation resulted in a value that is too small to fit within "
+				"the FloatingPoint type."
+		};
+
+	if (exceptions & FE_OVERFLOW)
+		throw overflow_error{
+			"The floating-point operation resulted in a value that is too large to fit within "
+				"the FloatingPoint type."
+		};
+
+	if (exceptions & FE_INVALID)
+		throw domain_error{
+			"The floating-point operation resulted in a value that is not valid."
+		};
+	return value;
+}
+
+VerifiedValue pecunia::internal::verifyAdditionFits(
+	const UnitStorage& lhs,
+	const UnitStorage& rhs,
+	const UnitStorage& maximum,
+	const UnitStorage& minimum
+)
+{
+	const UnitStorage maximumDifference{static_cast<UnitStorage>(maximum - rhs)};
+	if ((rhs > 0) && (lhs > maximumDifference))
+		return VerifiedValue::Overflows;
+
+	const UnitStorage minimumDifference{static_cast<UnitStorage>(minimum - rhs)};
+	if ((rhs < 0) && (lhs < minimumDifference))
+		return VerifiedValue::Overflows;
+	return VerifiedValue::Fits;
+}
+
+VerifiedValue pecunia::internal::verifySubtractionFits(
+	const UnitStorage& lhs,
+	const UnitStorage& rhs,
+	const UnitStorage& maximum,
+	const UnitStorage& minimum
+)
+{
+	const UnitStorage maximumDifference{static_cast<UnitStorage>(maximum + rhs)};
+	if ((rhs < 0) && (lhs > maximumDifference))
+		return VerifiedValue::Overflows;
+
+	const UnitStorage minimumDifference{static_cast<UnitStorage>(minimum + rhs)};
+	if ((rhs > 0) && (lhs < minimumDifference))
+		return VerifiedValue::Overflows;
+	return VerifiedValue::Fits;
+}
+
+VerifiedValue pecunia::internal::verifyMultiplicationFits(
+	const UnitStorage& lhs,
+	const FloatingPoint& rhs,
+	const UnitStorage& maximum,
+	const UnitStorage& minimum,
+	const MinorUnit& minorMaximum,
+	const uint8_t minorPrecision
+)
+{
+	if ((lhs == 0) || isEqual(rhs, 0, minorPrecision))
+		return VerifiedValue::Fits;
+
+	if ((lhs == -1) || isEqual(rhs, -1, minorPrecision))
+		return VerifiedValue::Fits;
+
+	const auto fpLhs{static_cast<FloatingPoint>(lhs)};
+	const auto fpMaximum{static_cast<FloatingPoint>(maximum)};
+	if (fpLhs > fpMaximum / rhs)
+		return VerifiedValue::Overflows;
+
+	const auto fpMinimum{static_cast<FloatingPoint>(minimum)};
+	if (fpLhs < fpMinimum / rhs)
+		return VerifiedValue::Overflows;
+
+	if (rhs < 1 && rhs > -1)
+	{
+		const FloatingPoint reciprocal{1 / rhs};
+		return verifyDivisionFits(lhs, reciprocal, maximum, minimum, minorMaximum, minorPrecision);
+	}
+	return VerifiedValue::Fits;
+}
+
+VerifiedValue pecunia::internal::verifyDivisionFits(
+	const UnitStorage& lhs,
+	const FloatingPoint& rhs,
+	const UnitStorage& maximum,
+	const UnitStorage& minimum,
+	const MinorUnit& minorMaximum,
+	const uint8_t minorPrecision
+)
+{
+	if (isEqual(rhs, 0, minorPrecision))
+		return VerifiedValue::Undefined;
+
+	if (rhs < 1 && rhs > -1)
+	{
+		const FloatingPoint reciprocal{1 / rhs};
+		return verifyMultiplicationFits(
+			lhs,
+			reciprocal,
+			maximum,
+			minimum,
+			minorMaximum,
+			minorPrecision
+		);
+	}
+
+	const auto fpLhs{static_cast<FloatingPoint>(lhs)};
+	if ((lhs > 0) && (lhs <= minorMaximum) && (rhs > fpLhs))
+		return VerifiedValue::Underflows;
+	return VerifiedValue::Fits;
+}
+
+VerifiedValue pecunia::internal::verifyMultiplicationFits(
+	const UnitStorage& lhs,
+	const UnitStorage& rhs,
+	const UnitStorage& maximum,
+	const UnitStorage& minimum
+)
+{
+	if ((lhs == 0) || rhs == 0)
+		return VerifiedValue::Fits;
+
+	if ((lhs == -1) || rhs == -1)
+		return VerifiedValue::Fits;
+
+	if (lhs > maximum / rhs)
+		return VerifiedValue::Overflows;
+
+	if (lhs < minimum / rhs)
+		return VerifiedValue::Overflows;
+	return VerifiedValue::Fits;
+}
+
+VerifiedValue pecunia::internal::verifyDivisionFits(
+	const UnitStorage& lhs,
+	const UnitStorage& rhs,
+	const MinorUnit& minorMaximum
+)
+{
+	if (rhs == 0)
+		return VerifiedValue::Undefined;
+
+	if (lhs > 0 && lhs <= minorMaximum && rhs > lhs)
+		return VerifiedValue::Underflows;
+	return VerifiedValue::Fits;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internal/Verification.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,109 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_CURRENCY_INTERNAL_VERIFICATION_H_
+#define PECUNIA_CURRENCY_INTERNAL_VERIFICATION_H_
+
+#include <cstdint>
+
+#include "pecunia/MoneyTypes.h"
+
+
+namespace pecunia
+{
+namespace internal
+{
+
+enum class VerifiedValue
+{
+	Fits,
+	Overflows,
+	Underflows,
+	Undefined
+};
+
+bool isEqual(
+	const FloatingPoint& number,
+	const FloatingPoint& equals,
+	const std::uint8_t minorPrecision
+);
+/**
+ * @brief Verifies that all prior floating-point operations and the value did not result in
+ * an error.
+ *
+ * @pre The floating-point error register must be cleared prior to all floating-point operations
+ * that are desired to be verified.
+ *
+ * @exception std::domain_error When the resulting floating-point operations lead to a
+ * division by zero or some other operation that is not defined.
+ * @exception std::underflow_error When the resulting floating-point operations lead to a case
+ * where the value is too small to be stored in the the FloatingPoint type.
+ * @exception std::overflow_error When the resulting floating-point operations lead to a case
+ * where the value is too large to be stored in the the FloatingPoint type.
+ *
+ * @param[in] value The floating-point value that is to be verified.
+ *
+ * @post The floating-point error register is cleared after invocation.
+ *
+ * @return The supplied value that was checked.
+ */
+FloatingPoint verifiedFloatingPoint(const FloatingPoint& value);
+VerifiedValue verifyAdditionFits(
+	const UnitStorage& lhs,
+	const UnitStorage& rhs,
+	const UnitStorage& maximum,
+	const UnitStorage& minimum
+);
+VerifiedValue verifySubtractionFits(
+	const UnitStorage& lhs,
+	const UnitStorage& rhs,
+	const UnitStorage& maximum,
+	const UnitStorage& minimum
+);
+VerifiedValue verifyMultiplicationFits(
+	const UnitStorage& lhs,
+	const FloatingPoint& rhs,
+	const UnitStorage& maximum,
+	const UnitStorage& minimum,
+	const MinorUnit& minorMaximum,
+	const std::uint8_t minorPrecision
+);
+VerifiedValue verifyDivisionFits(
+	const UnitStorage& lhs,
+	const FloatingPoint& rhs,
+	const UnitStorage& maximum,
+	const UnitStorage& minimum,
+	const MinorUnit& minorMaximum,
+	const std::uint8_t minorPrecision
+);
+VerifiedValue verifyMultiplicationFits(
+	const UnitStorage& lhs,
+	const UnitStorage& rhs,
+	const UnitStorage& maximum,
+	const UnitStorage& minimum
+);
+VerifiedValue verifyDivisionFits(
+	const UnitStorage& lhs,
+	const UnitStorage& rhs,
+	const MinorUnit& minorMaximum
+);
+
+}}
+
+#endif
--- a/src/pecunia/Algorithm.hpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_ALGORITHM_HPP_
-#define PECUNIA_ALGORITHM_HPP_
-
-#include <functional>
-#include <type_traits>
-
-#include "Money.h"
-
-
-namespace pecunia
-{
-
-/**
- * @brief Sorts the container using a less-than comparison operator. The sort is not stable.
- *
- * @tparam ContainerType The type of container holding the monetary values to sort. The container
- * must allow random access.
- *
- * @param container The container holding the monetary values to sort.
- * @param swaperator A function that will swap the contained values using no monetary conversion in
- * the process.
- */
-template<typename ContainerType>
-void sort(
-	ContainerType& container,
-	const std::function<
-		void(typename ContainerType::value_type&, typename ContainerType::value_type&)
-	>& swaperator = pecunia::currency::swap
-);
-
-namespace internal
-{
-
-template<typename RandomIteratorType, typename ContainerValueType>
-void quicksort(
-	RandomIteratorType low,
-	RandomIteratorType high,
-	const std::function<void(ContainerValueType&, ContainerValueType&)>& swaperator
-);
-template<typename RandomIteratorType, typename ContainerValueType>
-RandomIteratorType partition(
-	RandomIteratorType low,
-	RandomIteratorType high,
-	const std::function<void(ContainerValueType&, ContainerValueType&)>& swaperator
-);
-
-}}
-
-template<typename ContainerType>
-void pecunia::sort(
-	ContainerType& container,
-	const std::function<
-		void(typename ContainerType::value_type&, typename ContainerType::value_type&)
-	>& swaperator
-)
-{
-	const auto size{container.size()};
-
-	if (size > 2)
-		internal::quicksort(container.begin(), std::prev(container.end()), swaperator);
-	else if (size == 2)
-	{
-		auto lhs{container.begin()};
-		auto rhs(std::next(lhs));
-
-		if (*rhs < *lhs)
-			swaperator(*lhs, *rhs);
-	}
-
-}
-
-template<typename RandomIteratorType, typename ContainerValueType>
-void pecunia::internal::quicksort(
-	RandomIteratorType low,
-	RandomIteratorType high,
-	const std::function<void(ContainerValueType&, ContainerValueType&)>& swaperator
-)
-{
-	if (low < high)
-	{
-		const auto pivot{partition(low, high, swaperator)};
-		quicksort(low, pivot, swaperator);
-		quicksort(std::next(pivot), high, swaperator);
-	}
-}
-
-template<typename RandomIteratorType, typename ContainerValueType>
-RandomIteratorType pecunia::internal::partition(
-	RandomIteratorType low,
-	RandomIteratorType high,
-	const std::function<void(ContainerValueType&, ContainerValueType&)>& swaperator
-)
-{
-	const auto pivotValue{*std::next(low, std::distance(low, high) / 2)};
-	auto lowIndex{std::prev(low)};
-	auto highIndex{std::next(high)};
-
-	do
-	{
-		do
-			std::advance(lowIndex, 1);
-		while (*lowIndex < pivotValue);
-
-		do
-			std::advance(highIndex, -1);
-		while (*highIndex > pivotValue);
-
-		if (lowIndex >= highIndex)
-			return highIndex;
-		swaperator(*lowIndex, *highIndex);
-	}
-	while (true);
-}
-
-#endif
--- a/src/pecunia/Codes.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "Codes.h"
-using std::array;
-using std::ostream;
-using std::string;
-using std::to_string;
-using pecunia::currency::Codes;
-using pecunia::currency::numberOfCodes;
-
-#include <cassert>
-// Used for assert.
-#include <cmath>
-using std::pow;
-#include <stdexcept>
-using std::runtime_error;
-
-#include "MoneyTypes.h"
-using pecunia::precision;
-
-
-string pecunia::currency::toIso4217(const Codes& code)
-{
-	switch (code)
-	{
-	case Codes::EUR:
-		return "EUR";
-	case Codes::PLN:
-		return "PLN";
-	case Codes::USD:
-		return "USD";
-	case Codes::XXX:
-		return "XXX";
-	default:
-		assert(false && "Unhandled currency code for conversion to an ISO-4217 string.");
-		return "";
-	};
-}
-
-Codes pecunia::currency::toCode(const string& code)
-{
-	if (code == "EUR")
-		return Codes::EUR;
-	if (code == "PLN")
-		return Codes::PLN;
-	if (code == "USD")
-		return Codes::USD;
-	if (code == "XXX")
-		return Codes::XXX;
-	throw runtime_error{
-		"Unhandled currency code '" + code + "' for conversion to its strong type."
-	};
-}
-
-string pecunia::currency::toSymbol(const Codes& code)
-{
-	switch (code)
-	{
-	case Codes::EUR:
-		return "€";
-	case Codes::PLN:
-		return "zł";
-	case Codes::USD:
-		return "$";
-	case Codes::XXX:
-		return "";
-	default:
-		assert(false && "Unhandled currency code for conversion to a symbol.");
-		return "";
-	};
-}
-
-uint8_t pecunia::currency::minorUnitDigits(const Codes& code)
-{
-	switch (code)
-	{
-	case Codes::EUR: // 1 Euro = 100 cents
-	case Codes::PLN: // 1 złoty = 100 groszy
-	case Codes::USD: // 1 dollar = 100 cents
-		return 2u;
-	case Codes::XXX:
-		return 0u;
-	default:
-		assert(false && "Unhandled currency code for minor unit digits.");
-		return 0u;
-	};
-}
-
-ostream& pecunia::currency::operator<<(ostream& stream, const Codes& code)
-{
-	return stream << toIso4217(code);
-}
-
-int32_t pecunia::currency::minorUnitPrecisionFactor(const Codes& code)
-{
-	switch (code)
-	{
-	case Codes::EUR:
-	case Codes::PLN:
-	case Codes::USD:
-		return static_cast<int32_t>(pow(10, minorUnitDigits(code) + precision));
-	case Codes::XXX:
-		return static_cast<int32_t>(pow(10, precision));
-	default:
-		assert(false && "Unhandled currency code for the minor unit precision ratio look-up.");
-		return 0u;
-	};
-}
-
-const array<Codes, numberOfCodes> pecunia::currency::allCodes
-{
-	// N.B. Apart from the unknown code, all other codes should be in alphabetical order.
-	{
-		Codes::XXX,
-		Codes::EUR,
-		Codes::PLN,
-		Codes::USD
-	}
-};
--- a/src/pecunia/Codes.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_CURRENCY_CODES_H_
-#define PECUNIA_CURRENCY_CODES_H_
-
-#include <array>
-#include <cstdint>
-#include <ostream>
-#include <string>
-
-#include "CodesEnum.hpp"
-#include "pecunia_export.h"
-
-
-namespace pecunia
-{
-namespace currency
-{
-
-/**
- * Converter from a strongly-type ISO code to the weak string form.
- *
- * @param[in] code The country's monetary unit whose ISO code is to be converted.
- *
- * @return The weak type form of the ISO code.
- */
-PECUNIA_EXPORT std::string toIso4217(const Codes& code);
-/**
- * Converter from a weakly-type ISO code to the strongly-type form. The code must be all upper-cased
- * for the match to be performed.
- *
- * @exception std::runtime_error When the supplied weak code does not match any known strong code.
- *
- * @param[in] code The country's monetary unit whose ISO code is to be converted.
- *
- * @return The strong type form of the ISO code.
- */
-PECUNIA_EXPORT Codes toCode(const std::string& code);
-/**
- * Provides the native currency symbol used by a currency code. N.B. currency symbols are shared
- * by others and are therefore cannot be unique.
- *
- * @param[in] code The country's monetary unit whose currency symbol is desired.
- *
- * @return The string representation of the currency symbol.
- */
-PECUNIA_EXPORT std::string toSymbol(const Codes& code);
-/**
- * Provides the number of digits used by the minor currency unit using the currency's ISO exponent.
- *
- * @param[in] code The country's monetary unit whose number of digits is desired.
- *
- * @return The number of digits used by the minor currency unit.
- */
-PECUNIA_EXPORT std::uint8_t minorUnitDigits(const currency::Codes& code);
-/**
- * Calculates the currency factor between the major unit and the minor unit accounting for the
- * system precision of the minor monetary unit. The precision is in terms of how many extra digits
- * to add for the minor unit, e.g. USD starts with 2 and a precision of 2 would provide
- * for a total precision of 4 digits.
- *
- * @param[in] code The country's monetary unit to calculate the ratio for.
- *
- * @return The ratio relationship between the major and minor unit with a supplied precision.
- */
-PECUNIA_EXPORT std::int32_t minorUnitPrecisionFactor(const currency::Codes& code);
-/**
-* @brief Performs the stream insertion for displaying the currency code in the ISO-4217 form.
-*
-* @param stream The stream into which the code should be inserted.
-* @param code The code that will be inserted.
-*
-* @return The same stream that was supplied, but now containing the code.
-*/
-PECUNIA_EXPORT std::ostream& operator<<(std::ostream& stream, const currency::Codes& code);
-
-/// @brief The total number of currency codes supported.
-constexpr std::uint8_t numberOfCodes{4};
-/// @brief A container of every currency code supported.
-extern PECUNIA_EXPORT const std::array<Codes, numberOfCodes> allCodes;
-
-}}
-
-#endif
--- a/src/pecunia/CodesEnum.hpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_CURRENCY_CODESENUM_HPP_
-#define PECUNIA_CURRENCY_CODESENUM_HPP_
-
-#include "pecunia_export.h"
-
-
-namespace pecunia
-{
-namespace currency
-{
-
-/**
- * The identifier for a country's currency.
- *
- * @see ISO 4217 https://en.wikipedia.org/wiki/ISO_4217
- */
-enum class PECUNIA_EXPORT Codes
-{
-	/// A non-currency when a country is not known or unspecified.
-	XXX = 0,
-	/// A United States dollar.
-	USD = 840,
-	/// A Polish złoty.
-	PLN = 985,
-	/// A Euro
-	EUR = 978,
-};
-
-}}
-
-#endif
--- a/src/pecunia/Conversion.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "Conversion.h"
-using pecunia::MinorUnit;
-
-#include <cmath>
-using std::pow;
-#include <string>
-using std::string;
-using std::to_string;
-#include <stdexcept>
-using std::overflow_error;
-
-#include "Codes.h"
-using pecunia::currency::Codes;
-using pecunia::currency::minorUnitDigits;
-using pecunia::currency::toIso4217;
-
-
-MinorUnit pecunia::toMinorUnit(const MinorUnit& minor, const Codes& code)
-{
-	const auto digits{minorUnitDigits(code)};
-	const auto conversionFactor{pow(10, digits)};
-
-	if (minor >= conversionFactor)
-		throw overflow_error{
-			string{"The minor unit value "} + to_string(minor) + " is too large for the currency '"
-				+ toIso4217(code) + "'."
-		};
-	return static_cast<MinorUnit>(minor * conversionFactor);
-}
-
--- a/src/pecunia/Conversion.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_CONVERSION_H_
-#define PECUNIA_CONVERSION_H_
-
-#include "MoneyTypes.h"
-#include "pecunia_export.h"
-
-
-namespace pecunia
-{
-namespace currency
-{
-
-enum class Codes;
-
-}}
-
-namespace pecunia
-{
-
-/**
- * @brief Converts a non-precious minor value into an expected minor value, i.e. given a value of
- * USD 25 cents it'll convert it into "2500".
- *
- * @exception std::overflow_error When the supplied minor value is greater than possibly can be
- * stored in a currency's minor value.
- *
- * @param minor The minor value without the extra precision amount.
- * @param code The currency the minor unit is in.
- * @return The minor amount adjusted for the amount of precious and minor digits found in the
- * currency where all the precision is padded with zeros.
- */
-PECUNIA_EXPORT MinorUnit toMinorUnit(const MinorUnit& minor, const currency::Codes& code);
-
-}
-
-#endif
--- a/src/pecunia/Information.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "Information.h"
-
-#include <pecunia/internal/config.hpp>
-// using COPYRIGHT_YEARS
-// using DESCRIPTION
-// using FULL_VERSION
-// using HOMEPAGE_URL
-
-
-const char* pecunia::version()
-{
-	return pecunia_FULL_VERSION;
-}
-
-const char* pecunia::copyright()
-{
-	return "(C) " pecunia_COPYRIGHT_YEARS " John M. Schneiderman";
-}
-
-const char* pecunia::licence()
-{
-	return R"~(This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU Lesser General Public License as published
-by the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-See the GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.)~";
-}
-
-const char* pecunia::url()
-{
-	return pecunia_HOMEPAGE_URL;
-}
-
-const char* pecunia::description()
-{
-	return pecunia_DESCRIPTION;
-}
--- a/src/pecunia/Information.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_INFORMATION_H_
-#define PECUNIA_INFORMATION_H_
-
-#include "pecunia_export.h"
-
-
-namespace pecunia
-{
-
-/**
- * @brief Provides the version of the library.
- */
-PECUNIA_EXPORT const char* version();
-/**
- * @brief Provides the copyright of the library.
- */
-PECUNIA_EXPORT const char* copyright();
-/**
- * @brief Provides the license of the library.
- */
-PECUNIA_EXPORT const char* licence();
-/**
- * @brief Provides the URL of the library.
- */
-PECUNIA_EXPORT const char* url();
-/**
- * @brief Provides the description of the library.
- */
-PECUNIA_EXPORT const char* description();
-
-}
-
-#endif
--- a/src/pecunia/Math.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "Math.h"
-using std::function;
-using std::map;
-using pecunia::currency::Codes;
-using pecunia::currency::Money;
-
-#include <cmath>
-//using std::abs;
-#include <numeric>
-using std::accumulate;
-
-
-Money pecunia::math::abs(const Money& money)
-{
-	auto copy{money};
-	copy.amount_ = std::abs(copy.amount_);
-	return copy;
-}
-
-void pecunia::math::internal::addToRunningTotals(
-	map<Codes, Money>& runningTotals,
-	const Money& amount,
-	const function<Money(const Money &)>& adjustor
-)
-{
-	if (runningTotals.count(amount.code()) == 0)
-		runningTotals[amount.code()].setCode(amount.code());
-	runningTotals[amount.code()] += adjustor == nullptr ? amount : adjustor(amount);
-}
-
-Money pecunia::math::internal::accumulateRunningTotals(
-	const Codes& accumulateCurrency,
-	const map<Codes, Money>& totals
-)
-{
-	const auto total{
-		accumulate(
-			totals.cbegin(),
-			totals.cend(),
-			Money{0, 0u, accumulateCurrency},
-			[] (const auto& accumulator, const auto& currencyRunningTotals)
-			{
-				return accumulator + currencyRunningTotals.second;
-			}
-		)
-	};
-	return total;
-}
--- a/src/pecunia/Math.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_MATH_H_
-#define PECUNIA_MATH_H_
-
-#include <functional>
-#include <map>
-#include <type_traits>
-#include <vector>
-
-#include "Codes.h"
-#include "Money.h"
-#include "pecunia_export.h"
-
-
-namespace pecunia
-{
-namespace math
-{
-namespace internal
-{
-
-PECUNIA_EXPORT void addToRunningTotals(
-	std::map<currency::Codes, currency::Money>& runningTotals,
-	const currency::Money& amount,
-	const std::function<
-		currency::Money(const currency::Money& money)
-	>& adjustor
-);
-PECUNIA_EXPORT currency::Money accumulateRunningTotals(
-	const currency::Codes& accumulateCurrency,
-	const std::map<currency::Codes, currency::Money>& totals
-);
-
-}
-/**
- * Calculates the absolute value of a supplied amount of money.
- *
- * @param money The money whose monetary amount should be an absolute value.
- *
- * @return The absolute value of the monetary amount.
- */
-PECUNIA_EXPORT currency::Money abs(const currency::Money& money);
-/**
- * @brief Accumulates the total of all the supplied monies with the fewest possible number of
- * conversions.
- *
- * @tparam Container The type of container holding the monies.
- * @tparam ValueType This must be the Money type.
- * @tparam Allocator The allocator used by the container.
- *
- * @param accumulateCurrency The currency to accumulate the total in.
- * @param monies The container of the monies to total.
- * @param adjustor When supplied, a functor to apply to each element in the container of monies
- * prior to final summation.
- *
- * @return The sum of all the monies in the requested currency.
- */
-template<template<typename, typename> class Container, typename ValueType, typename Allocator>
-currency::Money accumulate(
-	const currency::Codes& accumulateCurrency,
-	const Container<ValueType, Allocator>& monies,
-	const std::function<
-		currency::Money(const currency::Money& money)
-	>& adjustor = nullptr
-);
-/**
- * @brief Accumulates the total of all the supplied monies with the fewest possible number of
- * conversions.
- *
- * @tparam AssociativeContainer The type of associative container holding the monies.
- * @tparam KeyType The type the monies are keyed against, not used.
- * @tparam ValueType This must be the Money type.
- * @tparam Allocator The allocator used by the container.
- *
- * @param accumulateCurrency The currency to accumulate the total in.
- * @param monies The container of the monies to total.
- * @param adjustor When supplied, a functor to apply to each element in the container of monies
- * prior to final summation.
- *
- * @return The sum of all the monies in the requested currency.
- */
-template<
-	template<typename, typename, typename, typename> class AssociativeContainer,
-	class KeyType,
-	class ValueType,
-	class Compare = std::less<KeyType>,
-	class Allocator = std::allocator<std::pair<const KeyType, ValueType>>
->
-currency::Money accumulate(
-	const currency::Codes& accumulateCurrency,
-	const AssociativeContainer<KeyType, ValueType, Compare, Allocator>& monies,
-	const std::function<
-		currency::Money(const currency::Money& money)
-	>& adjustor = nullptr
-);
-
-}}
-
-template<template<typename, typename> class Container, typename ValueType, typename Allocator>
-pecunia::currency::Money pecunia::math::accumulate(
-	const pecunia::currency::Codes& accumulateCurrency,
-	const Container<ValueType, Allocator>& monies,
-	const std::function<
-		pecunia::currency::Money(const pecunia::currency::Money& money)
-	>& adjustor
-)
-{
-	static_assert(
-		std::is_same<ValueType, pecunia::currency::Money>::value,
-		"The contained type must be Money."
-	);
-	std::map<pecunia::currency::Codes, pecunia::currency::Money> runningTotals{};
-
-	for (const auto& money : monies)
-		internal::addToRunningTotals(runningTotals, money, adjustor);
-	return internal::accumulateRunningTotals(accumulateCurrency, runningTotals);
-}
-
-template<
-	template<typename, typename, typename, typename> class AssociativeContainer,
-	class KeyType,
-	class ValueType,
-	class Compare,
-	class Allocator
->
-pecunia::currency::Money pecunia::math::accumulate(
-	const pecunia::currency::Codes& accumulateCurrency,
-	const AssociativeContainer<KeyType, ValueType, Compare, Allocator>& monies,
-	const std::function<
-		pecunia::currency::Money(const pecunia::currency::Money& money)
-	>& adjustor
-)
-{
-	static_assert(
-		std::is_same<ValueType, pecunia::currency::Money>::value,
-		"The contained type must be Money."
-	);
-	std::map<pecunia::currency::Codes, pecunia::currency::Money> runningTotals{};
-
-	for (const auto& keyMoney : monies)
-		internal::addToRunningTotals(runningTotals, keyMoney.second, adjustor);
-	return internal::accumulateRunningTotals(accumulateCurrency, runningTotals);
-}
-
-#endif
--- a/src/pecunia/Money.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1034 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "Money.h"
-using std::int8_t;
-using std::int16_t;
-using std::int32_t;
-using std::int64_t;
-using std::pair;
-using std::uint8_t;
-using pecunia::currency::Codes;
-using pecunia::currency::Money;
-using pecunia::precision;
-using pecunia::MinorUnit;
-using pecunia::MinorSign;
-using pecunia::FloatingPoint;
-using pecunia::FloatingPointRounderFunction;
-using pecunia::RounderFunction;
-using pecunia::UnitStorage;
-
-#include <cassert>
-// Used for assert.
-#include <cstdlib>
-// Used for lldiv.
-#include <cmath>
-using std::abs;
-using std::pow;
-
-#include <iomanip>
-using std::fixed;
-using std::setprecision;
-#include <istream>
-using std::istream;
-#include <limits>
-using std::logic_error;
-using std::numeric_limits;
-#include <locale>
-#include <ostream>
-using std::ostream;
-#include <stdexcept>
-using std::domain_error;
-using std::exception;
-using std::overflow_error;
-using std::runtime_error;
-using std::underflow_error;
-#include <string>
-using std::string;
-using std::to_string;
-#include <sstream>
-using std::stringstream;
-
-#include "internal/Adjustments.h"
-using pecunia::currency::internal::fromFloatingPointMajor;
-using pecunia::currency::internal::fromFloatingPointMinor;
-using pecunia::currency::internal::normaliseAmount;
-#include "internal/Verification.h"
-using pecunia::internal::isEqual;
-using pecunia::internal::verifiedFloatingPoint;
-using pecunia::internal::VerifiedValue;
-using pecunia::internal::verifyAdditionFits;
-using pecunia::internal::verifyDivisionFits;
-using pecunia::internal::verifyMultiplicationFits;
-using pecunia::internal::verifySubtractionFits;
-#include "MoneyManip.h"
-using pecunia::currency::countryLeadingIndex;
-#include "MoneyTypes.h"
-#include "pecunia/MoneySize.hpp"
-using pecunia::internal::extraFloatingPointPrecision;
-
-
-UnitStorage Money::maximumMajorValue() const
-{
-	UnitStorage rawMaxMajor{
-		static_cast<UnitStorage>(
-			numeric_limits<UnitStorage>::max() - this->maximumMinorValue()
-		)
-	};
-	const int32_t ratio{minorUnitPrecisionFactor(this->iso4217Code_)};
-	UnitStorage maxMajor{static_cast<UnitStorage>(rawMaxMajor / ratio)};
-	return maxMajor;
-}
-
-UnitStorage Money::minimumMajorValue() const
-{
-	const auto maxMinorValue{this->maximumMinorValue()};
-	UnitStorage rawMinMajor{
-		static_cast<UnitStorage>(numeric_limits<UnitStorage>::lowest() + maxMinorValue)
-	};
-	const auto minorPrecisionRatio{minorUnitPrecisionFactor(this->iso4217Code_)};
-	UnitStorage minMajor{static_cast<UnitStorage>(rawMinMajor / minorPrecisionRatio)};
-	return minMajor;
-}
-
-MinorUnit Money::maximumMinorValue() const
-{
-	const int32_t digits{minorUnitDigits(this->iso4217Code_)};
-	const MinorUnit max{static_cast<MinorUnit>(pow(10, digits + precision) - 1.0)};
-	return max;
-}
-
-UnitStorage Money::maximumAmountValue() const
-{
-	const int32_t unitRatio{minorUnitPrecisionFactor(this->iso4217Code_)};
-	const UnitStorage max{
-		static_cast<UnitStorage>(
-			(this->maximumMajorValue() * unitRatio) + this->maximumMinorValue()
-		)
-	};
-	return max;
-}
-
-UnitStorage Money::minimumAmountValue() const
-{
-	const int32_t unitRatio{minorUnitPrecisionFactor(this->iso4217Code_)};
-	const auto minimumMajorValue{this->minimumMajorValue()};
-	const auto maximumMinorValue{this->maximumMinorValue()};
-	const UnitStorage min{
-		static_cast<UnitStorage>((minimumMajorValue * unitRatio) - maximumMinorValue)
-	};
-	return min;
-}
-
-Money::Money() :
-	Money{Codes::XXX}
-{}
-
-Money::Money(const Codes code) :
-	Money{0, 0, code}
-{}
-
-Money::Money(const MinorUnit& minor, const MinorSign sign, const Codes code) :
-	Money{0, minor, code}
-{
-	assert(
-		(minor > 0 || (minor == 0 && sign == MinorSign::Neither))
-		&& "The value of zero has no sign."
-	);
-
-	if (sign == MinorSign::Negative)
-		this->amount_ *= -1;
-}
-
-Money::Money(const UnitStorage& major, const MinorUnit& minor, const Codes code) :
-	amount_{0},
-	iso4217Code_{code}
-{
-	assert(
-		pow(10, minorUnitDigits(code) + precision) - 1.0 <= numeric_limits<MinorUnit>::max()
-		&& "The number of digits with precision is too large and cannot fit inside the minor type."
-	);
-	const int32_t unitRatio{minorUnitPrecisionFactor(code)};
-
-	if (major > this->maximumMajorValue())
-		throw overflow_error{
-			"The major money value, " + std::to_string(major)
-				+ ", is too large to store within the currency."
-		};
-
-	if (major < this->minimumMajorValue())
-		throw overflow_error{
-			"The major money value, " + std::to_string(major)
-				+ ", is too small to store within the currency."
-		};
-
-	if (minor > this->maximumMinorValue())
-		throw overflow_error{
-			"The minor money value, " + std::to_string(minor)
-				+ ", is too large to store within the currency."
-		};
-
-	if (major >= 0)
-		this->amount_ = (major * unitRatio) + minor;
-	else
-		this->amount_ = (major * unitRatio) - minor;
-}
-
-Money::Money(
-	const FloatingPoint& value,
-	const Codes code,
-	const FloatingPointRounderFunction& rounder
-) :
-	Money{
-		fromFloatingPointMajor(value, code, precision, rounder),
-		fromFloatingPointMinor(value, code, precision, rounder),
-		code
-	}
-{
-	if (
-		this->amount_ == 0
-		&& ! isEqual(value, 0.0, static_cast<uint8_t>(minorUnitDigits(code) + precision))
-	)
-		throw underflow_error{
-			"The value " + std::to_string(value)
-				+ " is too small to store within the supplied precision."
-		};
-}
-
-Money::operator FloatingPoint() const
-{
-	return this->toFloatingPoint();
-}
-
-Money Money::operator-() const
-{
-	Money m{*this};
-	m.amount_ *= -1;
-	return m;
-}
-
-Money Money::operator+(const Money& other) const
-{
-	Money m{*this};
-	m += other;
-	return m;
-}
-
-Money Money::operator-(const Money& other) const
-{
-	Money m{*this};
-	m -= other;
-	return m;
-}
-
-Money Money::operator*(const int8_t value) const
-{
-	Money m{*this};
-	m *= static_cast<int64_t>(value);
-	return m;
-}
-
-Money Money::operator*(const int16_t value) const
-{
-	Money m{*this};
-	m *= static_cast<int64_t>(value);
-	return m;
-}
-
-Money Money::operator*(const int32_t value) const
-{
-	Money m{*this};
-	m *= static_cast<int64_t>(value);
-	return m;
-}
-
-Money Money::operator*(const int64_t value) const
-{
-	Money m{*this};
-	m *= value;
-	return m;
-}
-
-Money Money::operator*(const FloatingPoint& value) const
-{
-	Money m{*this};
-	m *= value;
-	return m;
-}
-
-FloatingPoint Money::operator/(const Money& other) const
-{
-	if (other.amount_ == 0)
-		throw domain_error{
-			"The division operation of " + std::to_string(this->amount_) + " and "
-				+ std::to_string(other.amount_) + " result is undefined."
-		};
-	const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
-	return static_cast<FloatingPoint>(this->amount_) / static_cast<FloatingPoint>(normalisedAmount);
-}
-
-Money Money::operator/(const int8_t value) const
-{
-	Money m{*this};
-	m /= static_cast<int64_t>(value);
-	return m;
-}
-
-Money Money::operator/(const int16_t value) const
-{
-	Money m{*this};
-	m /= static_cast<int64_t>(value);
-	return m;
-}
-
-Money Money::operator/(const int32_t value) const
-{
-	Money m{*this};
-	m /= static_cast<int64_t>(value);
-	return m;
-}
-
-Money Money::operator/(const int64_t value) const
-{
-	Money m{*this};
-	m /= value;
-	return m;
-}
-
-Money Money::operator/(const FloatingPoint& value) const
-{
-	Money m{*this};
-	m /= value;
-	return m;
-}
-
-UnitStorage Money::operator%(const UnitStorage& value) const
-{
-	if (value == 0)
-		throw domain_error{
-			"The modulus operation of " + std::to_string(this->amount_) + " and "
-			+ std::to_string(value) + " result is undefined."
-		};
-	return this->major() % value;
-}
-
-Money& Money::operator=(const Money& other)
-{
-	if (this != &other)
-	{
-		const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
-		const auto maximumAmountValue{this->maximumAmountValue()};
-		const auto minimumAmountValue{this->minimumAmountValue()};
-
-		if (normalisedAmount <= maximumAmountValue && normalisedAmount >= minimumAmountValue)
-			this->amount_ = normalisedAmount;
-		else
-			throw overflow_error{
-				"The assignment operation of " + std::to_string(other.amount_) + " to "
-					+ std::to_string(this->amount_) + " is too large to fit within the precision."
-			};
-	}
-	return *this;
-}
-
-Money& Money::operator=(Money&& other)
-{
-	if (this != &other)
-	{
-		const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
-		const auto maximumAmountValue{this->maximumAmountValue()};
-		const auto minimumAmountValue{this->minimumAmountValue()};
-
-		if (normalisedAmount <= maximumAmountValue && normalisedAmount >= minimumAmountValue)
-			this->amount_ = normalisedAmount;
-		else
-			throw overflow_error{
-				"The assignment operation of " + std::to_string(other.amount_) + " to "
-					+ std::to_string(this->amount_) + " is too large to fit within the precision."
-			};
-	}
-	return *this;
-}
-
-bool Money::operator<(const Money& other) const
-{
-	try
-	{
-		const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
-		return this->amount_ < normalisedAmount;
-	}
-	catch (const logic_error&)
-	{
-		throw;
-	}
-	catch (const exception&)
-	{
-		if (other.amount_ > 0) // other.amount_ is too large positive.
-			return true;
-
-		if (other.amount_ < 0) // other.amount_ is too large negative.
-			return false;
-		throw; // Something strange has occurred.
-	}
-}
-
-bool Money::operator<(const int8_t value) const
-{
-	return this->amount_ < static_cast<int64_t>(value);
-}
-
-bool Money::operator<(const int16_t value) const
-{
-	return this->amount_ < static_cast<int64_t>(value);
-}
-
-bool Money::operator<(const int32_t value) const
-{
-	return this->amount_ < static_cast<int64_t>(value);
-}
-
-bool Money::operator<(const int64_t value) const
-{
-	return this->amount_ < value;
-}
-
-bool Money::operator<=(const Money& other) const
-{
-	return (*this < other) || (*this == other);
-}
-
-bool Money::operator<=(const int8_t value) const
-{
-	return this->amount_ <= static_cast<int64_t>(value);
-}
-
-bool Money::operator<=(const int16_t value) const
-{
-	return this->amount_ <= static_cast<int64_t>(value);
-}
-
-bool Money::operator<=(const int32_t value) const
-{
-	return this->amount_ <= static_cast<int64_t>(value);
-}
-
-bool Money::operator<=(const int64_t value) const
-{
-	return this->amount_ <= value;
-}
-
-bool Money::operator>(const Money& other) const
-{
-	try
-	{
-		const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
-		return this->amount_ > normalisedAmount;
-	}
-	catch (const logic_error&)
-	{
-		throw;
-	}
-	catch (const exception&)
-	{
-		if (other.amount_ > 0) // other.amount_ is too large positive.
-			return false;
-
-		if (other.amount_ < 0) // other.amount_ is too large negative.
-			return true;
-		throw; // Something strange has occurred.
-	}
-}
-
-bool Money::operator>(const int8_t value) const
-{
-	return this->amount_ > static_cast<int8_t>(value);
-}
-
-bool Money::operator>(const int16_t value) const
-{
-	return this->amount_ > static_cast<int64_t>(value);
-}
-
-bool Money::operator>(const int32_t value) const
-{
-	return this->amount_ > static_cast<int64_t>(value);
-}
-
-bool Money::operator>(const int64_t value) const
-{
-	return this->amount_ > value;
-}
-
-bool Money::operator>=(const Money& other) const
-{
-	return (*this > other) || (*this == other);
-}
-
-bool Money::operator>=(const int8_t value) const
-{
-	return this->amount_ >= static_cast<int64_t>(value);
-}
-
-bool Money::operator>=(const int16_t value) const
-{
-	return this->amount_ >= static_cast<int64_t>(value);
-}
-
-bool Money::operator>=(const int32_t value) const
-{
-	return this->amount_ >= static_cast<int64_t>(value);
-}
-
-bool Money::operator>=(const int64_t value) const
-{
-	return this->amount_ >= value;
-}
-
-bool Money::operator==(const Money& other) const
-{
-	try
-	{
-		const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
-		return this->amount_ == normalisedAmount;
-	}
-	catch (const exception&)
-	{
-		// Doesn't matter why we threw, e.g. overflow, underflow, different codes, the error itself
-		// is enough to know that the two values are not equal.
-		return false;
-	}
-}
-
-bool Money::operator==(const int8_t value) const
-{
-	return this->amount_ == static_cast<int8_t>(value);
-}
-
-bool Money::operator==(const int16_t value) const
-{
-	return this->amount_ == static_cast<int16_t>(value);
-}
-
-bool Money::operator==(const int32_t value) const
-{
-	return this->amount_ == static_cast<int64_t>(value);
-}
-
-bool Money::operator==(const int64_t value) const
-{
-	return this->amount_ == value;
-}
-
-bool Money::operator!=(const Money& other) const
-{
-	return ! (*this == other);
-}
-
-bool Money::operator!=(const int8_t other) const
-{
-	return ! (*this == static_cast<int64_t>(other));
-}
-
-bool Money::operator!=(const int16_t other) const
-{
-	return ! (*this == static_cast<int64_t>(other));
-}
-
-bool Money::operator!=(const int32_t other) const
-{
-	return ! (*this == static_cast<int64_t>(other));
-}
-
-bool Money::operator!=(const int64_t other) const
-{
-	return ! (*this == other);
-}
-
-Money& Money::operator+=(const Money& other)
-{
-	const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
-	const VerifiedValue verified{
-		verifyAdditionFits(
-			this->amount_,
-			normalisedAmount,
-			this->maximumAmountValue(),
-			this->minimumAmountValue()
-		)
-	};
-	switch (verified)
-	{
-	case VerifiedValue::Fits:
-		this->amount_ += normalisedAmount;
-		return *this;
-	case VerifiedValue::Overflows:
-		throw overflow_error{
-			"The addition operation of " + std::to_string(this->amount_) + ' '
-				+ toIso4217(this->iso4217Code_) + " and " + std::to_string(other.amount_) + ' '
-				+ toIso4217(other.iso4217Code_) + " cannot be safely stored."
-		};
-	case VerifiedValue::Underflows:
-		throw underflow_error{
-			"The addition operation of " + std::to_string(this->amount_) + ' '
-				+ toIso4217(this->iso4217Code_) + " and " + std::to_string(other.amount_) + ' '
-				+ toIso4217(other.iso4217Code_) + " cannot be safely stored."
-		};
-	case VerifiedValue::Undefined:
-	default:
-		throw logic_error{"Incorrect addition verification result."};
-	};
-}
-
-Money& Money::operator-=(const Money& other)
-{
-	const UnitStorage normalisedAmount{normaliseAmount(other, this->iso4217Code_)};
-	const VerifiedValue verified{
-		verifySubtractionFits(
-			this->amount_,
-			normalisedAmount,
-			this->maximumAmountValue(),
-			this->minimumAmountValue()
-		)
-	};
-	switch (verified)
-	{
-	case VerifiedValue::Fits:
-		this->amount_ -= normalisedAmount;
-		return *this;
-	case VerifiedValue::Overflows:
-		throw overflow_error{
-			"The subtraction operation of " + std::to_string(this->amount_) + ' '
-				+ toIso4217(this->iso4217Code_) + " and " + std::to_string(other.amount_) + ' '
-				+ toIso4217(other.iso4217Code_) + " cannot be safely stored."
-		};
-	case VerifiedValue::Underflows:
-		throw underflow_error{
-			"The subtraction operation of " + std::to_string(this->amount_) + ' '
-				+ toIso4217(this->iso4217Code_) + " and " + std::to_string(other.amount_) + ' '
-				+ toIso4217(other.iso4217Code_) + " cannot be safely stored."
-		};
-	case VerifiedValue::Undefined:
-	default:
-		throw logic_error{"Incorrect subtraction verification result."};
-	};
-}
-
-Money& Money::operator*=(const int8_t value)
-{
-	return *this *= static_cast<int64_t>(value);
-}
-
-Money& Money::operator*=(const int16_t value)
-{
-	return *this *= static_cast<int64_t>(value);
-}
-
-Money& Money::operator*=(const int32_t value)
-{
-	return *this *= static_cast<int64_t>(value);
-}
-
-Money& Money::operator*=(const int64_t value)
-{
-	const VerifiedValue verified{
-		verifyMultiplicationFits(
-			this->amount_,
-			value,
-			this->maximumAmountValue(),
-			this->minimumAmountValue()
-		)
-	};
-
-	switch (verified)
-	{
-	case VerifiedValue::Fits:
-		this->amount_ = this->amount_ * value;
-		return *this;
-	case VerifiedValue::Overflows:
-		throw overflow_error{
-			"The multiplication operation of " + std::to_string(this->amount_) + " and "
-			+ std::to_string(value) + " cannot be safely stored."
-		};
-	case VerifiedValue::Underflows:
-		throw underflow_error{
-			"The multiplication operation of " + std::to_string(this->amount_) + " and "
-			+ std::to_string(value) + " cannot be safely stored."
-		};
-	case VerifiedValue::Undefined:
-	default:
-		throw logic_error{"Incorrect multiplication verification result."};
-	};
-}
-
-Money& Money::operator*=(const FloatingPoint& value)
-{
-	// Need to verify before adjustment and during the multiplication.
-	const VerifiedValue verified{
-		verifyMultiplicationFits(
-			this->amount_,
-			value,
-			this->maximumAmountValue(),
-			this->minimumAmountValue(),
-			this->maximumMinorValue(),
-			static_cast<uint8_t>(
-				minorUnitDigits(this->iso4217Code_) + precision + extraFloatingPointPrecision
-			)
-		)
-	};
-
-	switch (verified)
-	{
-	case VerifiedValue::Fits:
-		break;
-	case VerifiedValue::Overflows:
-		throw overflow_error{
-			"The multiplication operation of " + std::to_string(this->amount_) + " and "
-			+ std::to_string(value) + " cannot be safely stored."
-		};
-	case VerifiedValue::Underflows:
-		throw underflow_error{
-			"The multiplication operation of " + std::to_string(this->amount_) + " and "
-			+ std::to_string(value) + " cannot be safely stored."
-		};
-	case VerifiedValue::Undefined:
-	default:
-		throw logic_error{"Incorrect multiplication verification result."};
-	};
-	const int32_t unitRatio{
-		minorUnitPrecisionFactor(this->iso4217Code_)
-			* static_cast<int32_t>(pow(10, extraFloatingPointPrecision))
-	};
-	const auto adjustedValue{verifiedFloatingPoint(value * unitRatio)};
-	*this *= static_cast<int64_t>(adjustedValue);
-	this->amount_ /= unitRatio;
-	return *this;
-}
-
-Money& Money::operator/=(const int8_t value)
-{
-	return *this /= static_cast<int64_t>(value);
-}
-
-Money& Money::operator/=(const int16_t value)
-{
-	return *this /= static_cast<int64_t>(value);
-}
-
-Money& Money::operator/=(const int32_t value)
-{
-	return *this /= static_cast<int64_t>(value);
-}
-
-Money& Money::operator/=(const int64_t value)
-{
-	const VerifiedValue verified{
-		verifyDivisionFits(
-			this->amount_,
-			value,
-			static_cast<uint8_t>(minorUnitDigits(this->iso4217Code_) + precision)
-		)
-	};
-
-	switch (verified)
-	{
-	case VerifiedValue::Fits:
-		this->amount_ = this->amount_ / value;
-		return *this;
-	case VerifiedValue::Overflows:
-		throw overflow_error{
-			"The division operation of " + std::to_string(this->amount_) + " and "
-				+ std::to_string(value) + " cannot be safely stored."
-		};
-	case VerifiedValue::Undefined:
-		throw domain_error{
-			"The division operation of " + std::to_string(this->amount_) + " and "
-				+ std::to_string(value) + " result is undefined."
-		};
-	case VerifiedValue::Underflows:
-		throw underflow_error{
-			"The division operation of " + std::to_string(this->amount_) + " and "
-				+ std::to_string(value) + " cannot be safely stored."
-		};
-	default:
-		throw logic_error{"Incorrect division verification result."};
-	};
-}
-
-Money& Money::operator/=(const FloatingPoint& value)
-{
-	// Need to verify before adjustment, during the multiplication, and division.
-	const VerifiedValue preVerified{
-		verifyDivisionFits(
-			this->amount_,
-			value,
-			this->maximumAmountValue(),
-			this->minimumAmountValue(),
-			this->maximumMinorValue(),
-			static_cast<uint8_t>(
-				minorUnitDigits(this->iso4217Code_) + precision + extraFloatingPointPrecision
-			)
-		)
-	};
-
-	switch (preVerified)
-	{
-	case VerifiedValue::Fits:
-		break;
-	case VerifiedValue::Overflows:
-		throw overflow_error{
-			"The division operation of " + std::to_string(this->amount_) + " and "
-				+ std::to_string(value) + " cannot be safely stored."
-		};
-	case VerifiedValue::Undefined:
-		throw domain_error{
-			"The division operation of " + std::to_string(this->amount_) + " and "
-				+ std::to_string(value) + " result is undefined."
-		};
-	case VerifiedValue::Underflows:
-		throw underflow_error{
-			"The division operation of " + std::to_string(this->amount_) + " and "
-				+ std::to_string(value) + " cannot be safely stored."
-		};
-	default:
-		throw logic_error{"Incorrect division verification result."};
-	};
-	const int64_t unitRatio{
-		minorUnitPrecisionFactor(this->iso4217Code_)
-			* static_cast<int64_t>(pow(10, extraFloatingPointPrecision))
-	};
-	const VerifiedValue verifiedMultiplication{
-		verifyMultiplicationFits(
-			this->amount_,
-			unitRatio,
-			this->maximumAmountValue(),
-			this->minimumAmountValue()
-		)
-	};
-
-	switch (verifiedMultiplication)
-	{
-	case VerifiedValue::Fits:
-		break;
-	case VerifiedValue::Overflows:
-		throw overflow_error{
-			"The multiplication operation of " + std::to_string(this->amount_) + " and "
-				+ std::to_string(value) + " cannot be safely stored during division."
-		};
-	case VerifiedValue::Underflows:
-		throw underflow_error{
-			"The multiplication operation of " + std::to_string(this->amount_) + " and "
-				+ std::to_string(value) + " cannot be safely stored during division."
-		};
-	case VerifiedValue::Undefined:
-	default:
-		throw logic_error{"Incorrect multiplication verification result during division."};
-	};
-	const auto adjustedValue{
-		static_cast<UnitStorage>(
-			verifiedFloatingPoint(value * static_cast<FloatingPoint>(unitRatio))
-		)
-	};
-	const auto adjustedAmount{this->amount_ * unitRatio};
-	const auto preAmount{this->amount_};
-
-	try
-	{
-		this->amount_ = adjustedAmount;
-		*this /= adjustedValue;
-		return *this;
-	}
-	catch (const exception&)
-	{
-		this->amount_ = preAmount;
-		throw;
-	}
-}
-
-const UnitStorage& Money::amount() const noexcept
-{
-	return this->amount_;
-}
-
-UnitStorage Money::major() const
-{
-	return this->amount_ / minorUnitPrecisionFactor(this->iso4217Code_);
-}
-
-MinorUnit Money::minor() const
-{
-	return static_cast<MinorUnit>(
-		abs(this->amount_ % minorUnitPrecisionFactor(this->iso4217Code_))
-	);
-}
-
-const Codes& Money::code() const
-{
-	return this->iso4217Code_;
-}
-
-bool Money::isPositive() const
-{
-	return this->amount_ > 0;
-}
-
-FloatingPoint Money::toFloatingPoint(const RounderFunction& rounder, const uint8_t digits) const
-{
-	const auto minorDigits{
-		static_cast<uint8_t>(minorUnitDigits(this->iso4217Code_) + precision)
-	};
-	const auto rounded{rounder(this->amount_, minorDigits, digits)};
-	const int32_t ratio{minorUnitPrecisionFactor(this->iso4217Code_)};
-	const FloatingPoint converted{
-		static_cast<FloatingPoint>(rounded) / static_cast<FloatingPoint>(ratio)
-	};
-	return converted;
-}
-
-Money& Money::round(const RounderFunction& rounder, const uint8_t digits)
-{
-	const auto minorDigits{
-		static_cast<uint8_t>(minorUnitDigits(this->iso4217Code_) + precision)
-	};
-	const auto roundedAmount{rounder(this->amount_, minorDigits, digits)};
-	const auto maximumAmountValue{this->maximumAmountValue()};
-	const auto minimumAmountValue{this->minimumAmountValue()};
-
-	if (roundedAmount <= maximumAmountValue && roundedAmount >= minimumAmountValue)
-		this->amount_ = roundedAmount;
-	else
-		throw overflow_error{
-			"The result of the rounding operation " + std::to_string(roundedAmount) + " from "
-				+ std::to_string(this->amount_) + " is too large to fit within the precision."
-		};
-	return *this;
-}
-
-bool Money::hasAmount() const
-{
-	return this->amount_ != 0 && this->iso4217Code_ != Codes::XXX;
-}
-
-void Money::setCode(const pecunia::currency::Codes& code)
-{
-	this->iso4217Code_ = code;
-}
-
-pair<UnitStorage, MinorUnit> Money::maximum(const Codes& code)
-{
-	const auto ratio{minorUnitPrecisionFactor(code)};
-	const Money test{code};
-	const auto value{test.maximumAmountValue()};
-	const UnitStorage max{value / ratio};
-	const auto minor{static_cast<MinorUnit>(value % ratio)};
-	return {max, minor};
-}
-
-pair<UnitStorage, MinorUnit> Money::minimum(const Codes& code)
-{
-	const auto ratio{minorUnitPrecisionFactor(code)};
-	const Money test{code};
-	const auto value{test.minimumAmountValue()};
-	const UnitStorage min{value / ratio};
-	const auto minor{static_cast<MinorUnit>(-value % ratio)};
-	return {min, minor};
-}
-
-Money pecunia::currency::operator*(const int8_t lhs, const Money& rhs)
-{
-	return rhs * lhs;
-}
-
-Money pecunia::currency::operator*(const int16_t lhs, const Money& rhs)
-{
-	return rhs * lhs;
-}
-
-Money pecunia::currency::operator*(const int32_t lhs, const Money& rhs)
-{
-	return rhs * lhs;
-}
-
-Money pecunia::currency::operator*(const int64_t lhs, const Money& rhs)
-{
-	return rhs * lhs;
-}
-
-Money pecunia::currency::operator*(const FloatingPoint& lhs, const Money& rhs)
-{
-	return rhs * lhs;
-}
-
-ostream& pecunia::currency::operator<<(ostream& stream, const Money& m)
-{
-	const bool isSymbolUsed{stream.iword(pecunia::currency::useSymbolIndex()) == 1};
-	const string currencyMarker{
-		isSymbolUsed ? toSymbol(m.iso4217Code_) : toIso4217(m.iso4217Code_)
-	};
-	const bool isCountryLeading{stream.iword(countryLeadingIndex()) == 1};
-	const bool isSpaced{stream.iword(pecunia::currency::spacedIndex()) == 1};
-	const FloatingPoint value{m};
-	stream << setprecision(minorUnitDigits(m.iso4217Code_) + precision) << fixed
-			<< (isCountryLeading ? currencyMarker : "")
-			<< (isSpaced && isCountryLeading ? " " : "")
-			<< value
-			<< (isSpaced && ! isCountryLeading ? " " : "")
-			<< ( ! isCountryLeading ? currencyMarker : "");
-	return stream;
-}
-
-istream& pecunia::currency::operator>>(istream& stream, Money& m)
-{
-	const bool isCountryLeading{stream.iword(countryLeadingIndex()) == 1};
-	long double rawAmount;
-	string rawCode;
-
-	if (isCountryLeading)
-		stream >> rawCode >> std::get_money(rawAmount);
-	else
-		stream >> std::get_money(rawAmount) >> rawCode;
-
-	if ( ! stream)
-		throw runtime_error{
-			"Failed to read valid input for the monetary amount and/or code."
-		};
-
-	m.iso4217Code_ = toCode(rawCode);
-	const auto amount{
-		static_cast<FloatingPoint>(
-			rawAmount / pow(10, pecunia::currency::minorUnitDigits(m.iso4217Code_))
-		)
-	};
-	m = Money{amount, m.iso4217Code_};
-	return stream;
-}
-
-string pecunia::currency::to_string(const Money& m)
-{
-	stringstream ss;
-	ss << pecunia::currency::spaced << pecunia::currency::trail << m;
-	return ss.str();
-}
-
-void pecunia::currency::swap(Money& lhs, Money& rhs)
-{
-	const Money temp{lhs};
-	lhs.amount_ = rhs.amount_;
-	lhs.iso4217Code_ = rhs.iso4217Code_;
-	rhs.amount_ = temp.amount_;
-	rhs.iso4217Code_ = temp.iso4217Code_;
-}
--- a/src/pecunia/Money.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1079 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_CURRENCY_MONEY_H_
-#define PECUNIA_CURRENCY_MONEY_H_
-
-#include <cstdint>
-#include <functional>
-#include <iomanip>
-#include <istream>
-#include <locale>
-#include <ostream>
-#include <string>
-#include <utility>
-
-#include "Codes.h"
-#include "MoneyTypes.h"
-
-
-namespace pecunia
-{
-namespace currency
-{
-
-class Money;
-
-}
-namespace math
-{
-
-PECUNIA_EXPORT currency::Money abs(const currency::Money& money);
-
-}
-namespace currency
-{
-
-/**
- * A representation of a country's currency supporting basic arithmetic usage and guaranteeing all
- * operations succeed without a loss of precision, overflow, or underflow. This version allows for
- * reading in an arbitrary currency.
- */
-class PECUNIA_EXPORT Money
-{
-	friend PECUNIA_EXPORT Money math::abs(const Money&);
-	friend PECUNIA_EXPORT void swap(Money& lhs, Money& rhs);
-
-	/**
-	 * Calculates the largest storable monetary major value.
-	 */
-	UnitStorage maximumMajorValue() const;
-	/**
-	 * Calculates the smallest storable monetary major value.
-	 */
-	UnitStorage minimumMajorValue() const;
-	/**
-	 * Calculates the largest storable monetary minor value.
-	 */
-	MinorUnit maximumMinorValue() const;
-	/**
-	 * Calculates the largest storable monetary amount value.
-	 */
-	UnitStorage maximumAmountValue() const;
-	/**
-	 * Calculates the smallest storable monetary amount value.
-	 */
-	UnitStorage minimumAmountValue() const;
-
-	/// The entire representation of the monetary amount using the currency's minor unit, e.g. cents
-	/// for USD, plus any extra digits of precision.
-	UnitStorage amount_;
-	/// The ISO 4217 currency code the monetary amount represents.
-	Codes iso4217Code_;
-
-public:
-	/**
-	 * Constructor for a fully formed object that initialises the stored amount to zero unknown
-	 * currency.
-	 */
-	Money();
-	/**
-	 * Constructor for a fully formed object that initialises the stored amount to zero.
-	 *
-	 * @param[in] code The ISO 4217 currency code the amount represents.
-	 */
-	explicit Money(const Codes code);
-	/**
-	 * Constructor for setting an exact minor monetary value whose major value is zero. The minor
-	 * value is expected to be adjusted for the level of precision the object is expecting, e.g.
-	 * U.S.A. dollars with a precision of two would enter twelve cents as 1200.
-	 *
-	 * @pre When the minor value is zero, the sign must be Sign::Neither.
-	 *
-	 * @exception overflow_error When the minor unit is too large to be stored.
-	 *
-	 * @param[in] minor The amount of minor currency to store, e.g. U.S.A. cents.
-	 * @param[in] sign The associated signedness of the minor value, e.g. negative.
-	 * @param[in] code The ISO 4217 currency code the amount represents.
-	 */
-	Money(const MinorUnit& minor, const MinorSign sign, const Codes code = Codes::XXX);
-	/**
-	 * Constructor for setting an exact monetary value of a fully formed object. The minor value is
-	 * expected to be adjusted for the level of precision the object is expecting, e.g. U.S.A.
-	 * dollars with a precision of two would enter twelve cents as 1200.
-	 *
-	 * @pre The maximum minor value must fit within the MinorUnit.
-	 *
-	 * @exception overflow_error When the major unit is too large to be stored in a positive
-	 * direction.
-	 * @exception overflow_error When the major unit is too small to be stored in a negative
-	 * direction.
-	 * @exception overflow_error When the minor unit is too large to be stored.
-	 *
-	 * @param[in] major The amount of major currency to store, e.g. U.S.A. dollars.
-	 * @param[in] minor The amount of minor currency to store, e.g. U.S.A. cents.
-	 * @param[in] code The ISO 4217 currency code the amount represents.
-	 */
-	Money(const UnitStorage& major, const MinorUnit& minor, const Codes code = Codes::XXX);
-	/**
-	 * Constructor for setting a monetary value using the native floating-point type. @note The
-	 * minor units in a floating-point value cannot be verified and will always fit within the
-	 * currency digits and precision specified, e.g. U.S.A. dollar value with a precision of 0 will
-	 * store the value 1.555 as 1.55 when no rounder is supplied.
-	 *
-	 * @exception overflow_error When the major unit is too large to be stored in a positive
-	 * direction.
-	 * @exception overflow_error When the major unit is too small to be stored in a negative
-	 * direction.
-	 * @exception domain_error When the conversion results in the floating-point value dividing by
-	 * zero.
-	 * @exception underflow_error When the floating-point value is too small to fit within the
-	 * FloatingPoint.
-	 * @exception overflow_error When the floating-point value is too large to fit within the
-	 * FloatingPoint.
-	 * @exception domain_error When the conversion results in the floating-point value not being
-	 * valid.
-	 *
-	 * @param[in] value The floating-point value to convert.
-	 * @param[in] code The ISO 4217 currency code the amount represents.
-	 * @param[in] rounder The method for rounding the number when converting the floating-point
-	 * number.
-	 */
-	Money(
-		const FloatingPoint& value,
-		const Codes code,
-		const FloatingPointRounderFunction& rounder =
-			[] (const FloatingPoint& number, const std::uint8_t&)
-			{
-				return number;
-			}
-	);
-	Money(const Money&) =default;
-	Money(Money&&) noexcept =default;
-	/**
-	 * Conversion operator to a native floating-point type.
-	 *
-	 * @exception domain_error When the conversion results in the floating-point value dividing by
-	 * zero.
-	 * @exception underflow_error When the floating-point value is too small to fit within the
-	 * FloatingPoint.
-	 * @exception overflow_error When the floating-point value is too large to fit within the
-	 * FloatingPoint.
-	 * @exception domain_error When the conversion results in the floating-point value not being
-	 * valid.
-	 */
-	explicit operator FloatingPoint() const;
-	~Money() =default;
-	/**
-	 * Negation operator without any loss of precision during the conversion.
-	 *
-	 * @return The negated value of the current object.
-	 */
-	Money operator-() const;
-	/**
-	 * Additive operator. When the supplied monetary object is of a different currency, the amount
-	 * is converted into the current object's currency using the pecunia::currency::converter
-	 * function.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] other The additional value to add to the current object's value.
-	 *
-	 * @return A new object containing the summation of the two values.
-	 */
-	Money operator+(const Money& other) const;
-	/**
-	 * Subtractive operator. When the supplied monetary object is of a different currency, the
-	 * amount is converted into the current object's currency using the pecunia::currency::converter
-	 * function.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] other The additional value to subtract from the current object's value.
-	 *
-	 * @return A new object containing the difference of the two values.
-	 */
-	Money operator-(const Money& other) const;
-	Money operator*(const Money&) const =delete;
-	/**
-	 * Multiplicative operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The signed 8-bit integer value to multiply to the current object's value.
-	 *
-	 * @return A new object containing the product of the two values.
-	 */
-	Money operator*(const std::int8_t value) const;
-	/**
-	 * Multiplicative operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The signed 16-bit integer value to multiply to the current object's value.
-	 *
-	 * @return A new object containing the product of the two values.
-	 */
-	Money operator*(const std::int16_t value) const;
-	/**
-	 * Multiplicative operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The signed 32-bit integer value to multiply to the current object's value.
-	 *
-	 * @return A new object containing the product of the two values.
-	 */
-	Money operator*(const std::int32_t value) const;
-	/**
-	 * Multiplicative operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The signed 64-bit integer value to multiply to the current object's value.
-	 *
-	 * @return A new object containing the product of the two values.
-	 */
-	Money operator*(const std::int64_t value) const;
-	/**
-	 * Multiplicative operator without any loss of precision. This only supports as many digits
-	 * as there are minor digits.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional value to multiply to the current object's value.
-	 *
-	 * @return A new object containing the product of the two values.
-	 */
-	Money operator*(const FloatingPoint& value) const;
-	/**
-	 * Multiplicative operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] lhs The signed 8-bit integer amount by which to multiply the supplied object's
-	 * value.
-	 * @param[in] rhs The object that is to be multiplied.
-	 *
-	 * @return A new object containing the product of the two values.
-	 */
-	friend PECUNIA_EXPORT Money operator*(const std::int8_t lhs, const Money& rhs);
-	/**
-	 * Multiplicative operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] lhs The signed 16-bit integer amount by which to multiply the supplied object's
-	 * value.
-	 * @param[in] rhs The object that is to be multiplied.
-	 *
-	 * @return A new object containing the product of the two values.
-	 */
-	friend PECUNIA_EXPORT Money operator*(const std::int16_t lhs, const Money& rhs);
-	/**
-	 * Multiplicative operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] lhs The signed 32-bit integer amount by which to multiply the supplied object's
-	 * value.
-	 * @param[in] rhs The object that is to be multiplied.
-	 *
-	 * @return A new object containing the product of the two values.
-	 */
-	friend PECUNIA_EXPORT Money operator*(const std::int32_t lhs, const Money& rhs);
-	/**
-	 * Multiplicative operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] lhs The signed 64-bit integer amount by which to multiply the supplied object's
-	 * value.
-	 * @param[in] rhs The object that is to be multiplied.
-	 *
-	 * @return A new object containing the product of the two values.
-	 */
-	friend PECUNIA_EXPORT Money operator*(const std::int64_t lhs, const Money& rhs);
-	/**
-	 * Multiplicative operator without any loss of precision. This only supports as many digits
-	 * as there are minor digits.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] lhs The amount by which to multiply the supplied object's value.
-	 * @param[in] rhs The object that is to be multiplied.
-	 *
-	 * @return A new object containing the product of the two values.
-	 */
-	friend PECUNIA_EXPORT Money operator*(const FloatingPoint& lhs, const Money& rhs);
-	/**
-	 * Division operator for calculating ratios.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 *
-	 * @param[in] other The value to divide by the current object's value.
-	 *
-	 * @return The result of the division between the two, a ratio.
-	 */
-	FloatingPoint operator/(const Money& other) const;
-	/**
-	 * Division operator without any loss of precision.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional signed 8-bit integer value to divide by the current object's
-	 * value.
-	 *
-	 * @return A new object containing the division of the two values.
-	 */
-	Money operator/(const std::int8_t value) const;
-	/**
-	 * Division operator without any loss of precision.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional signed 16-bit integer value to divide by the current object's
-	 * value.
-	 *
-	 * @return A new object containing the division of the two values.
-	 */
-	Money operator/(const std::int16_t value) const;
-	/**
-	 * Division operator without any loss of precision.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional signed 32-bit integer value to divide by the current object's
-	 * value.
-	 *
-	 * @return A new object containing the division of the two values.
-	 */
-	Money operator/(const std::int32_t value) const;
-	/**
-	 * Division operator without any loss of precision.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional signed 64-bit integer value to divide by the current object's
-	 * value.
-	 *
-	 * @return A new object containing the division of the two values.
-	 */
-	Money operator/(const std::int64_t value) const;
-	/**
-	 * Division operator without any loss of precision. This only supports as many digits as there
-	 * are minor digits.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional value to divide by the current object's value.
-	 *
-	 * @return A new object containing the division of the two values.
-	 */
-	Money operator/(const FloatingPoint& value) const;
-	Money operator%(const Money&) const =delete;
-	/**
-	 * Modulus operator performed upon the major units of the object's current value.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 *
-	 * @param[in] value The additional value to perform a "mod" on the current object's value.
-	 *
-	 * @return The value of the modulus operation of the two values.
-	 */
-	UnitStorage operator%(const UnitStorage& value) const;
-	/**
-	 * Assignment Operator with copy. When the supplied monetary object is of a different currency,
-	 * the amount is converted into the current object's currency using the
-	 * pecunia::currency::converter function. Note that only the amount is assigned, not the
-	 * currency.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception overflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] other The object whose amount is to be assigned into the current object.
-	 *
-	 * @return The current object with the new amount.
-	 */
-	Money& operator=(const Money& other);
-	/**
-	 * Assignment Operator with move. When the supplied monetary object is of a different currency,
-	 * the amount is converted into the current object's currency using the
-	 * pecunia::currency::converter function. Note that only the amount is assigned, not the
-	 * currency.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception overflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] other The object whose amount is to be assigned into the current object.
-	 *
-	 * @return The current object with the new amount.
-	 */
-	Money& operator=(Money&& other);
-	/**
-	 * Less-than Relational Operator. When the supplied monetary object is of a different currency,
-	 * the amount is converted into the current object's currency using the
-	 * pecunia::currency::converter function.
-	 *
-	 * @param[in] other The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is less than the supplied object,
-	 * false else-wise.
-	 */
-	bool operator<(const Money& other) const;
-	/**
-	 * Less-than Relational Operator for an 8-bit signed integer. The supplied value is expected to
-	 * be expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is less than the supplied object,
-	 * false else-wise.
-	 */
-	bool operator<(const std::int8_t value) const;
-	/**
-	 * Less-than Relational Operator for an 16-bit signed integer. The supplied value is expected to
-	 * be expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is less than the supplied object,
-	 * false else-wise.
-	 */
-	bool operator<(const std::int16_t value) const;
-	/**
-	 * Less-than Relational Operator for an 32-bit signed integer. The supplied value is expected to
-	 * be expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is less than the supplied object,
-	 * false else-wise.
-	 */
-	bool operator<(const std::int32_t value) const;
-	/**
-	 * Less-than Relational Operator for an 64-bit signed integer. The supplied value is expected to
-	 * be expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is less than the supplied object,
-	 * false else-wise.
-	 */
-	bool operator<(const std::int64_t value) const;
-	/**
-	 * Less-than-equal Relational Operator. When the supplied monetary object is of a different
-	 * currency, the amount is converted into the current object's currency using the
-	 * pecunia::currency::converter function.
-	 *
-	 * @param[in] other The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is less than or equal to the supplied object,
-	 * false else-wise.
-	 */
-	bool operator<=(const Money& other) const;
-	/**
-	 * Less-than-equal Relational Operator for an 8-bit signed integer. The supplied value is
-	 * expected to be expressed in terms of the current object's issued currency, in the form
-	 * MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is less than or equal to the supplied object,
-	 * false else-wise.
-	 */
-	bool operator<=(const std::int8_t value) const;
-	/**
-	 * Less-than-equal Relational Operator for an 16-bit signed integer. The supplied value is
-	 * expected to be expressed in terms of the current object's issued currency, in the form
-	 * MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is less than or equal to the supplied object,
-	 * false else-wise.
-	 */
-	bool operator<=(const std::int16_t value) const;
-	/**
-	 * Less-than-equal Relational Operator for an 32-bit signed integer. The supplied value is
-	 * expected to be expressed in terms of the current object's issued currency, in the form
-	 * MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is less than or equal to the supplied object,
-	 * false else-wise.
-	 */
-	bool operator<=(const std::int32_t value) const;
-	/**
-	 * Less-than-equal Relational Operator for an 64-bit signed integer. The supplied value is
-	 * expected to be expressed in terms of the current object's issued currency, in the form
-	 * MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is less than or equal to the supplied object,
-	 * false else-wise.
-	 */
-	bool operator<=(const std::int64_t value) const;
-	/**
-	 * Greater-than Relational Operator. When the supplied monetary object is of a different
-	 * currency, the amount is converted into the current object's currency using the
-	 * pecunia::currency::converter function.
-	 *
-	 * @param[in] other The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is greater than the supplied object,
-	 * false else-wise.
-	 */
-	bool operator>(const Money& other) const;
-	/**
-	 * Greater-than Relational Operator for an 8-bit signed integer. The supplied value is expected
-	 * to be expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is greater than the supplied object,
-	 * false else-wise.
-	 */
-	bool operator>(const std::int8_t value) const;
-	/**
-	 * Greater-than Relational Operator for an 16-bit signed integer. The supplied value is expected
-	 * to be expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is greater than the supplied object,
-	 * false else-wise.
-	 */
-	bool operator>(const std::int16_t value) const;
-	/**
-	 * Greater-than Relational Operator for an 32-bit signed integer. The supplied value is expected
-	 * to be expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is greater than the supplied object,
-	 * false else-wise.
-	 */
-	bool operator>(const std::int32_t value) const;
-	/**
-	 * Greater-than Relational Operator for an 64-bit signed integer. The supplied value is expected
-	 * to be expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is greater than the supplied object,
-	 * false else-wise.
-	 */
-	bool operator>(const std::int64_t value) const;
-	/**
-	 * Greater-than-equal Relational Operator. When the supplied monetary object is of a
-	 * different currency, the amount is converted into the current object's currency using the
-	 * pecunia::currency::converter function.
-	 *
-	 * @param[in] other The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is greater than or equal to the supplied
-	 * object, false else-wise.
-	 */
-	bool operator>=(const Money& other) const;
-	/**
-	 * Greater-than-equal Relational Operator for an 8-bit signed integer. The supplied value is
-	 * expected to be expressed in terms of the current object's issued currency, in the form
-	 * MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is greater than or equal to the supplied
-	 * object, false else-wise.
-	 */
-	bool operator>=(const std::int8_t value) const;
-	/**
-	 * Greater-than-equal Relational Operator for an 16-bit signed integer. The supplied value is
-	 * expected to be expressed in terms of the current object's issued currency, in the form
-	 * MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is greater than or equal to the supplied
-	 * object, false else-wise.
-	 */
-	bool operator>=(const std::int16_t value) const;
-	/**
-	 * Greater-than-equal Relational Operator for an 32-bit signed integer. The supplied value is
-	 * expected to be expressed in terms of the current object's issued currency, in the form
-	 * MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is greater than or equal to the supplied
-	 * object, false else-wise.
-	 */
-	bool operator>=(const std::int32_t value) const;
-	/**
-	 * Greater-than-equal Relational Operator for an 64-bit signed integer. The supplied value is
-	 * expected to be expressed in terms of the current object's issued currency, in the form
-	 * MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is greater than or equal to the supplied
-	 * object, false else-wise.
-	 */
-	bool operator>=(const std::int64_t value) const;
-	/**
-	 * Equality Operator. When the supplied monetary object is of a different currency,
-	 * the amount is converted into the current object's currency using the
-	 * pecunia::currency::converter function.
-	 *
-	 * @param[in] other The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is equal to the supplied object,
-	 * false else-wise.
-	 */
-	bool operator==(const Money& other) const;
-	/**
-	 * Equality Operator for an 8-bit signed integer. The supplied value is expected to be
-	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is equal to the supplied value within, the
-	 * expected level of precision, false else-wise.
-	 */
-	bool operator==(const std::int8_t value) const;
-	/**
-	 * Equality Operator for an 16-bit signed integer. The supplied value is expected to be
-	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is equal to the supplied value within, the
-	 * expected level of precision, false else-wise.
-	 */
-	bool operator==(const std::int16_t value) const;
-	/**
-	 * Equality Operator for an 32-bit signed integer. The supplied value is expected to be
-	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is equal to the supplied value within, the
-	 * expected level of precision, false else-wise.
-	 */
-	bool operator==(const std::int32_t value) const;
-	/**
-	 * Equality Operator for an 64-bit signed integer. The supplied value is expected to be
-	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is equal to the supplied value within, the
-	 * expected level of precision, false else-wise.
-	 */
-	bool operator==(const std::int64_t value) const;
-	/**
-	 * Inequality Operator. When the supplied monetary object is of a different currency,
-	 * the amount is converted into the current object's currency using the
-	 * pecunia::currency::converter function.
-	 *
-	 * @param[in] other The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is not equal to the supplied object,
-	 * false else-wise.
-	 */
-	bool operator!=(const Money& other) const;
-	/**
-	 * Inequality Operator for an 8-bit signed integer. The supplied value is expected to be
-	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is not equal to the supplied value, within
-	 * the expected level of precision, false else-wise.
-	 */
-	bool operator!=(const std::int8_t value) const;
-	/**
-	 * Inequality Operator for an 16-bit signed integer. The supplied value is expected to be
-	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is not equal to the supplied value, within
-	 * the expected level of precision, false else-wise.
-	 */
-	bool operator!=(const std::int16_t value) const;
-	/**
-	 * Inequality Operator for an 32-bit signed integer. The supplied value is expected to be
-	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is not equal to the supplied value, within
-	 * the expected level of precision, false else-wise.
-	 */
-	bool operator!=(const std::int32_t value) const;
-	/**
-	 * Inequality Operator for an 64-bit signed integer. The supplied value is expected to be
-	 * expressed in terms of the current object's issued currency, in the form MMMMmmpp.
-	 *
-	 * @param[in] value The other object whose value is to be compared against.
-	 *
-	 * @return A value of true with the current object is not equal to the supplied value, within
-	 * the expected level of precision, false else-wise.
-	 */
-	bool operator!=(const std::int64_t value) const;
-	/**
-	 * Additive assignment operator. When the supplied monetary object is of a different currency,
-	 * the amount is converted into the current object's currency using the
-	 * pecunia::currency::converter function.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] other The additional value to add to the current object.
-	 *
-	 * @return The current object containing the summation of the two values.
-	 */
-	Money& operator+=(const Money& other);
-	/**
-	 * Subtractive assignment operator. When the supplied monetary object is of a different
-	 * currency, the amount is converted into the current object's currency using the
-	 * pecunia::currency::converter function.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] other The additional value to subtract from the current object.
-	 *
-	 * @return The current object containing the difference of the two values.
-	 */
-	Money& operator-=(const Money& other);
-	/**
-	 * Multiplicative assignment operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional signed 8-bit integer value to multiply to the current
-	 * object.
-	 *
-	 * @return The current object containing the product of the two values.
-	 */
-	Money& operator*=(const std::int8_t value);
-	/**
-	 * Multiplicative assignment operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional signed 16-bit integer value to multiply to the current
-	 * object.
-	 *
-	 * @return The current object containing the product of the two values.
-	 */
-	Money& operator*=(const std::int16_t value);
-	/**
-	 * Multiplicative assignment operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional signed 8-bit integer value to multiply to the current
-	 * object.
-	 *
-	 * @return The current object containing the product of the two values.
-	 */
-	Money& operator*=(const std::int32_t value);
-	/**
-	 * Multiplicative assignment operator without any loss of precision.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional signed 64-bit integer value to multiply to the current
-	 * object.
-	 *
-	 * @return The current object containing the product of the two values.
-	 */
-	Money& operator*=(const std::int64_t value);
-	/**
-	 * Multiplicative assignment operator without any loss of precision. This only supports as many
-	 * digits as there are minor digits.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional value to multiply to the current object.
-	 *
-	 * @return The current object containing the product of the two values.
-	 */
-	Money& operator*=(const FloatingPoint& value);
-	/**
-	 * Division assignment operator without any loss of precision.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The signed 8-bit integer additional value to divide by the current object's
-	 * value.
-	 *
-	 * @return The current object containing the division of the two values.
-	 */
-	Money& operator/=(const std::int8_t value);
-	/**
-	 * Division assignment operator without any loss of precision.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The signed 16-bit integer additional value to divide by the current object's
-	 * value.
-	 *
-	 * @return The current object containing the division of the two values.
-	 */
-	Money& operator/=(const std::int16_t value);
-	/**
-	 * Division assignment operator without any loss of precision.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The signed 32-bit integer additional value to divide by the current object's
-	 * value.
-	 *
-	 * @return The current object containing the division of the two values.
-	 */
-	Money& operator/=(const std::int32_t value);
-	/**
-	 * Division assignment operator without any loss of precision.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The signed 64-bit integer additional value to divide by the current object's
-	 * value.
-	 *
-	 * @return The current object containing the division of the two values.
-	 */
-	Money& operator/=(const std::int64_t value);
-	/**
-	 * Division assignment operator without any loss of precision. This only supports as many digits
-	 * as there are minor digits.
-	 *
-	 * @exception domain_error When the result of the operation would result in a division by zero.
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception underflow_error When the result of the operation would be too small to store.
-	 *
-	 * @param[in] value The additional value to divide by the current object's value.
-	 *
-	 * @return The current object containing the division of the two values.
-	 */
-	Money& operator/=(const FloatingPoint& value);
-	/**
-	 * Stream Insertion Operator. By default the form will be the locale's monetary format with no
-	 * spaces, the ISO code, and trailing the value, e.g. a U.S.A. locale with value of one dollar
-	 * and twenty-three cents would appear as 1.23USD.
-	 *
-	 * @param[in,out] stream The destination source for the contents of the supplied money object.
-	 * @param[in] m The object whose values are to placed into the destination source.
-	 *
-	 * @return The modified source stream object filled with the contents of the money object.
-	 */
-	friend PECUNIA_EXPORT std::ostream& operator<<(std::ostream& stream, const Money& m);
-	/**
-	 * Stream Extraction Operator. The monetary amount will be read in using the locale's setting
-	 * for reading in money. The currency code is required and must be in all upper-case letters.
-	 *
-	 * @pre The locale of the supplied stream must be set to get the money formatted in readable
-	 * manner.
-	 *
-	 * @exception overflow_error When the major unit is too large to be stored in a positive
-	 * direction.
-	 * @exception overflow_error When the major unit is too small to be stored in a negative
-	 * direction.
-	 * @exception domain_error When the conversion results in the floating-point value dividing by
-	 * zero.
-	 * @exception underflow_error When the floating-point value is too small to fit within the
-	 * FloatingPoint.
-	 * @exception overflow_error When the floating-point value is too large to fit within the
-	 * FloatingPoint.
-	 * @exception domain_error When the conversion results in the floating-point value not being
-	 * valid.
-	 *
-	 * @param[in,out] stream The extraction source for the contents of the supplied money object.
-	 * @param[out] m The object whose values are to be filled by the contents of the stream.
-	 *
-	 * @return The modified source stream object emptied of a money entry.
-	 */
-	friend PECUNIA_EXPORT std::istream& operator>>(std::istream& stream, Money& m);
-	/**
-	 * @brief The entire representation of the monetary amount using the currency's minor unit,
-	 * e.g. cents for USD, plus any extra digits of precision.
-	 */
-	const UnitStorage& amount() const noexcept;
-	/**
-	 * Accessor to the major monetary value, e.g. only the U.S.A. dollars.
-	 */
-	UnitStorage major() const;
-	/**
-	 * Accessor to the minor monetary value, e.g. only the U.S.A. cents.
-	 */
-	MinorUnit minor() const;
-	/**
-	 * Accessor to the code the currency amount represents.
-	 */
-	const Codes& code() const;
-	/**
-	 * Performs a test to determine if the stored value is positive.
-	 *
-	 * @return True when the value is greater than zero.
-	 */
-	bool isPositive() const;
-	/**
-	 * @brief Converts the monetary value into a native floating-point type using a supplied
-	 * rounding method. When a rounding function is not supplied, no rounding will occur.
-	 *
-	 * @param[in] rounder The rounding function to apply to the monetary value.
-	 * @param[in] digits  The number of digits after the major unit.
-	 *
-	 * @exception domain_error When the conversion results in the floating-point value dividing by
-	 * zero.
-	 * @exception underflow_error When the floating-point value is too small to fit within the
-	 * FloatingPoint.
-	 * @exception overflow_error When the floating-point value is too large to fit within the
-	 * FloatingPoint.
-	 * @exception domain_error When the conversion results in the floating-point value not being
-	 * valid.
-	 */
-	FloatingPoint toFloatingPoint(
-		const RounderFunction& rounder =
-			[] (const UnitStorage& amount, const MinorUnit&, const std::uint8_t)
-			{
-				return amount;
-			},
-		const std::uint8_t digits = precision
-	) const;
-	/**
-	 * @brief Performs a rounding operation upon the monetary value.
-	 *
-	 * @exception overflow_error When the result of the operation would be too large to store.
-	 * @exception overflow_error When the result of the operation would be too small to store.
-	 * @exception domain_error When the conversion results in the floating-point value dividing by
-	 * zero.
-	 * @exception underflow_error When the floating-point value is too small to fit within the
-	 * FloatingPoint.
-	 * @exception overflow_error When the floating-point value is too large to fit within the
-	 * FloatingPoint.
-	 * @exception domain_error When the conversion results in the floating-point value not being
-	 * valid.
-	 *
-	 * @param rounder The rounding function to apply to the monetary value.
-	 * @param digits The number of digits after the major unit to round to.
-	 *
-	 * @return The current object containing the rounded value.
-	 */
-	Money& round(const RounderFunction& rounder, const std::uint8_t digits);
-	/**
-	 * @brief Determines if the instance has an amount set. For example, an amount of 2.34 USD would
-	 * be set, but 0.00 XXX would not be.
-	 *
-	 * @return When the major, minor, and code are all set gives true, false else-wise.
-	 */
-	bool hasAmount() const;
-	/**
-	 * @brief Changes the ISO 4217 currency code without performing any conversions.
-	 *
-	 * @param[in] code The new ISO 4217 currency code the amount represents.
-	 */
-	void setCode(const pecunia::currency::Codes& code);
-	/**
-	 * @brief Calculates the largest monetary value that can be used for a given currency.
-	 *
-	 * @param code The currency code to calculate the monetary value in.
-	 *
-	 * @return The monetary value pair with the first element being the major unit, and second
-	 * element being the minor unit.
-	 */
-	static std::pair<UnitStorage, MinorUnit> maximum(const pecunia::currency::Codes& code);
-	/**
-	 * @brief Calculates the smallest monetary value that can be used for a given currency.
-	 *
-	 * @param code The currency code to calculate the monetary value in.
-	 *
-	 * @return The monetary value pair with the first element being the major unit, and second
-	 * element being the minor unit.
-	 */
-	static std::pair<UnitStorage, MinorUnit> minimum(const pecunia::currency::Codes& code);
-};
-
-PECUNIA_EXPORT Money operator*(const std::int8_t lhs, const Money& rhs);
-PECUNIA_EXPORT Money operator*(const std::int16_t lhs, const Money& rhs);
-PECUNIA_EXPORT Money operator*(const std::int32_t lhs, const Money& rhs);
-PECUNIA_EXPORT Money operator*(const std::int64_t lhs, const Money& rhs);
-PECUNIA_EXPORT Money operator*(const FloatingPoint& lhs, const Money& rhs);
-PECUNIA_EXPORT std::ostream& operator<<(std::ostream& stream, const Money& m);
-PECUNIA_EXPORT std::istream& operator>>(std::istream& stream, Money& m);
-/**
- * @brief Converts the monetary representation into a string from. The format of the string
- * representation is the amount followed by a space and the currency code.
- *
- * @param[out] m The object whose values are to be converted into a string form.
- *
- * @return The string representation.
- */
-PECUNIA_EXPORT std::string to_string(const Money& m);
-/**
- * @brief Exchanges two monetary objects without any conversion operation performed.
- *
- * @param lhs The object to swap to the right.
- * @param rhs The object to swap to the left.
- */
-PECUNIA_EXPORT void swap(Money& lhs, Money& rhs);
-
-}}
-
-#endif
--- a/src/pecunia/MoneyManip.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "MoneyManip.h"
-
-
-int pecunia::currency::countryLeadingIndex()
-{
-	static int index{std::ios_base::xalloc()};
-	return index;
-}
-
-int pecunia::currency::useSymbolIndex()
-{
-	static int index{std::ios_base::xalloc()};
-	return index;
-}
-
-int pecunia::currency::spacedIndex()
-{
-	static int index{std::ios_base::xalloc()};
-	return index;
-}
-
-std::ios_base& pecunia::currency::lead(std::ios_base& stream)
-{
-	stream.iword(pecunia::currency::countryLeadingIndex()) = 1;
-	return stream;
-}
-
-std::ios_base& pecunia::currency::trail(std::ios_base& stream)
-{
-	stream.iword(pecunia::currency::countryLeadingIndex()) = 0;
-	return stream;
-}
-
-std::ios_base& pecunia::currency::symbol(std::ios_base& stream)
-{
-	stream.iword(pecunia::currency::useSymbolIndex()) = 1;
-	return stream;
-}
-
-std::ios_base& pecunia::currency::isocode(std::ios_base& stream)
-{
-	stream.iword(pecunia::currency::useSymbolIndex()) = 0;
-	return stream;
-}
-
-std::ios_base& pecunia::currency::spaced(std::ios_base& stream)
-{
-	stream.iword(pecunia::currency::spacedIndex()) = 1;
-	return stream;
-}
-
-std::ios_base& pecunia::currency::nonspaced(std::ios_base& stream)
-{
-	stream.iword(pecunia::currency::spacedIndex()) = 0;
-	return stream;
-}
--- a/src/pecunia/MoneyManip.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_CURRENCY_MONEYMANIP_HPP_
-#define PECUNIA_CURRENCY_MONEYMANIP_HPP_
-
-#include <iomanip>
-
-#include "pecunia_export.h"
-
-
-namespace pecunia
-{
-namespace currency
-{
-
-/**
- * A stream manipulator that reads and writes a currency indicator before the value.
- *
- * @param[in,out] stream The stream into which the manipulation is done.
- *
- * @return The manipulated stream.
- */
-PECUNIA_EXPORT std::ios_base& lead(std::ios_base& stream);
-/**
- * A stream manipulator that reads and writes a currency indicator after the value.
- *
- * @param[in,out] stream The stream into which the manipulation is done.
- *
- * @return The manipulated stream.
- */
-PECUNIA_EXPORT std::ios_base& trail(std::ios_base& stream);
-/**
- * A stream manipulator that designates that the currency's symbol should be used when writing.
- *
- * @param[in,out] stream The stream into which the manipulation is done.
- *
- * @return The manipulated stream.
- */
-PECUNIA_EXPORT std::ios_base& symbol(std::ios_base& stream);
-/**
- * A stream manipulator that designates that the currency's ISO code should be used when writing.
- *
- * @param[in,out] stream The stream into which the manipulation is done.
- *
- * @return The manipulated stream.
- */
-PECUNIA_EXPORT std::ios_base& isocode(std::ios_base& stream);
-/**
- * A stream manipulator that places a space between the currency and its value when writing.
- *
- * @param[in,out] stream The stream into which the manipulation is done.
- *
- * @return The manipulated stream.
- */
-PECUNIA_EXPORT std::ios_base& spaced(std::ios_base& stream);
-/**
- * A stream manipulator that places a no spaces between the currency and its value when writing.
- *
- * @param[in,out] stream The stream into which the manipulation is done.
- *
- * @return The manipulated stream.
- */
-PECUNIA_EXPORT std::ios_base& nonspaced(std::ios_base& stream);
-PECUNIA_EXPORT int countryLeadingIndex();
-PECUNIA_EXPORT int useSymbolIndex();
-PECUNIA_EXPORT int spacedIndex();
-
-}}
-
-#endif
--- a/src/pecunia/MoneyTypes.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "MoneyTypes.h"
-using pecunia::ConversionFunction;
-using pecunia::defaultConverter;
-using pecunia::FloatingPoint;
-using pecunia::MinorUnit;
-using pecunia::precision;
-using pecunia::UnitStorage;
-
-#include <stdexcept>
-using std::logic_error;
-#include <type_traits>
-using std::is_floating_point;
-using std::is_integral;
-using std::is_signed;
-using std::is_unsigned;
-
-#include "Codes.h"
-using pecunia::currency::Codes;
-
-
-static_assert(is_unsigned<MinorUnit>::value, "The MinorUnit must be unsigned.");
-static_assert(is_integral<MinorUnit>::value, "The MinorUnit must be an integer.");
-static_assert(
-	is_floating_point<FloatingPoint>::value,
-	"The FloatingPoint is not a floating-point type."
-);
-static_assert(is_signed<UnitStorage>::value, "The UnitStorage must be signed.");
-static_assert(is_integral<UnitStorage>::value, "The UnitStorage must be an integral.");
-
-FloatingPoint pecunia::defaultConverter(const Codes& from, const Codes& to)
-{
-	if (from == to)
-		return 1.0L;
-	throw logic_error{
-		"Default converter only handles conversion when the currencies match."
-	};
-}
-
-ConversionFunction pecunia::converter{&defaultConverter};
--- a/src/pecunia/MoneyTypes.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_MONEYTYPES_H_
-#define PECUNIA_MONEYTYPES_H_
-
-#include <cstdint>
-#include <functional>
-
-#ifdef __WIN32
-#	pragma STDC FENV_ACCESS ON
-#endif
-
-#include "pecunia_export.h"
-#include "pecunia/MoneySize.hpp"
-
-
-namespace pecunia
-{
-namespace currency
-{
-
-enum class Codes;
-
-}
-
-/**
- * When working with minor units, this represents the postivity or negativity of a minor value.
- */
-enum class PECUNIA_EXPORT MinorSign
-{
-	/// The minor value is negative.
-	Negative,
-	/// The minor value is neither positive nor negative, i.e. zero.
-	Neither,
-	/// The minor value is positive.
-	Positive,
-};
-/**
- * A representation of a function that performs a rounding operation upon a real number. This
- * function must take a number, the number of digits after the whole number to round, and giving
- * back the rounded number.
- *
- * @exception std::runtime_error When the rounding is not possible.
- */
-using FloatingPointRounderFunction =
-		std::function<FloatingPoint(const FloatingPoint&, const std::uint8_t&)>;
-/**
- * A representation of a function that performs a rounding operation upon a money storage type. This
- * function must take first the major and minor amount value stored together, then the number of
- * digits in the minor unit, finally the number of digits after the whole number to round, and
- * giving back the rounded number with the major and minor amount stored together.
- *
- * @exception std::runtime_error When the rounding is not possible.
- */
-using RounderFunction =
-		std::function<UnitStorage(const UnitStorage&, const std::uint8_t&, const std::uint8_t)>;
-/**
- * A conversion function between two currencies where the first argument is the currency to convert
- * from, the second argument is the currency to convert to, and giving back the conversion factor
- * to get from the first currency to the second currency.
- *
- * @throw std::runtime_error When either the from or to currency is not supported.
- */
-using ConversionFunction =
-		std::function<FloatingPoint(const currency::Codes&, const currency::Codes&)>;
-/**
- * Provides a 1:1 conversion for a currency whose currency::Codes match.
- *
- * @param[in] from The currency code whose conversion value is desired.
- * @param[in] to The currency code the conversion value is directed towards.
- *
- * @throw std::logic_error When either the from and to currency currency::Codes do not match.
- *
- * @return The conversion value for the supplied currency when multipled from to the other.
- */
-PECUNIA_EXPORT FloatingPoint defaultConverter(
-	const currency::Codes& from,
-	const currency::Codes& to
-);
-/// The holder for all conversion operations for any money unit.
-PECUNIA_EXPORT extern ConversionFunction converter;
-
-}
-
-#endif
--- a/src/pecunia/Rounders.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,308 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "Rounders.h"
-using std::uint8_t;
-using pecunia::FloatingPoint;
-using pecunia::MinorUnit;
-using pecunia::UnitStorage;
-
-#include <cassert>
-// Used for assert.
-#include <cmath>
-using std::abs;
-using std::ceil;
-using std::floor;
-using std::fmod;
-using std::modf;
-using std::pow;
-#include <functional>
-using std::function;
-#include <stdexcept>
-using std::runtime_error;
-#include <string>
-using std::to_string;
-
-#include "internal/Verification.h"
-using pecunia::internal::isEqual;
-using pecunia::internal::verifiedFloatingPoint;
-
-
-namespace
-{
-
-/**
- * @brief Executes a generic rounding routine.
- *
- * @param number The number that is to be rounded.
- * @param digitsLeft The number of digits to the right of the decimal point.
- * @param rounder The rounding algorithm to apply to the point where rounding occurs, where the
- * first parameter is the fractional rounding point and the second parameter is the whole portion
- * of the number.
- *
- * @return The supplied number rounded to the number of fractional digits requested.
- */
-FloatingPoint round(
-	const FloatingPoint& number,
-	const uint8_t& digitsLeft,
-	const function<FloatingPoint(const FloatingPoint&, const FloatingPoint&)>& rounder
-)
-{
-	const FloatingPoint shiftOver{static_cast<FloatingPoint>(pow(10, digitsLeft))};
-	FloatingPoint whole;
-	const FloatingPoint fraction{modf(number, &whole)};
-	const FloatingPoint shiftedFraction{verifiedFloatingPoint(fraction * shiftOver)};
-	FloatingPoint roundPointWhole;
-	const FloatingPoint roundPoint{modf(shiftedFraction, &roundPointWhole)};
-	assert(abs(roundPoint) < 1.0 && "The rounding point must be less than one.");
-	const FloatingPoint shiftedRoundedFraction{
-		verifiedFloatingPoint(roundPointWhole + rounder(roundPoint, whole))
-	};
-	FloatingPoint roundedResult;
-	static_cast<void>(modf(shiftedRoundedFraction, &roundedResult));
-	const auto roundedNumber{verifiedFloatingPoint(whole + (roundedResult / shiftOver))};
-	return roundedNumber;
-}
-
-FloatingPoint sgn(const FloatingPoint& value)
-{
-	if (value > 0.0)
-		return 1.0;
-
-	if (value < 0.0)
-		return -1.0;
-	return 0.0 ;
-}
-
-UnitStorage round(
-	const UnitStorage& amount,
-	const uint8_t& minorDigits,
-	const uint8_t& digitsLeft,
-	const function<
-		bool(const UnitStorage&, const UnitStorage&, const UnitStorage&, const bool)
-	>& shouldRound
-)
-{
-	if (digitsLeft >= minorDigits)
-		throw runtime_error{
-			"Cannot round at minor digit position " + to_string(digitsLeft)
-				+ " when there are only " + to_string(minorDigits) + " minor digits in total."
-		};
-	const auto minorMask{static_cast<UnitStorage>(pow(10, minorDigits))};
-	const auto major{amount / minorMask};
-	const auto minor{amount % minorMask};
-	const auto roundingAmount{static_cast<UnitStorage>(pow(10, minorDigits - digitsLeft - 1))};
-	const auto roundingPoint{5 * roundingAmount};
-	const auto roundingMask{static_cast<UnitStorage>(pow(10, minorDigits - digitsLeft))};
-	const auto roundingValue{minor % roundingMask};
-	const auto truncatedMinor{abs(minor / roundingMask * roundingMask)};
-	const UnitStorage roundedMinor{
-		shouldRound(abs(roundingValue), roundingPoint, major, amount > 0)
-			? truncatedMinor + roundingMask
-			: truncatedMinor
-	};
-	if (amount >= 0)
-		return (major * minorMask) + roundedMinor;
-	return (major * minorMask) - roundedMinor;
-}
-
-}
-
-FloatingPoint pecunia::rounders::reals::up(const FloatingPoint& number, const uint8_t& digitsLeft)
-{
-	return round(
-		number,
-		digitsLeft,
-		[] (const FloatingPoint& value, const FloatingPoint&)
-		{
-			const FloatingPoint roundValue{value + static_cast<FloatingPoint>(0.5)};
-			if (value > 0.5 && value < 0.5)
-				return roundValue;
-			return floor(roundValue);
-		}
-	);
-}
-
-FloatingPoint pecunia::rounders::reals::down(const FloatingPoint& number, const uint8_t& digitsLeft)
-{
-	return round(
-		number,
-		digitsLeft,
-		[] (const FloatingPoint& value, const FloatingPoint&)
-		{
-			const FloatingPoint roundValue{value - static_cast<FloatingPoint>(0.5)};
-			if (value > 0.5 && value < 0.5)
-				return roundValue;
-			return ceil(roundValue);
-		}
-	);
-}
-
-FloatingPoint pecunia::rounders::reals::towardsZero(
-	const FloatingPoint& number,
-	const uint8_t& digitsLeft
-)
-{
-	return round(
-		number,
-		digitsLeft,
-		[] (const FloatingPoint& value, const FloatingPoint&)
-		{
-			if (value > 0.5 && value < 0.5)
-			{
-				if (value > 0.0)
-					return value - static_cast<FloatingPoint>(0.5);
-
-				if (value < 0.0)
-					return value + static_cast<FloatingPoint>(0.5);
-				return static_cast<FloatingPoint>(0.0);
-			}
-			return sgn(value) * ceil(abs(value) - static_cast<FloatingPoint>(0.5));
-		}
-	);
-}
-
-FloatingPoint pecunia::rounders::reals::awayZero(
-	const FloatingPoint& number,
-	const uint8_t& digitsLeft
-)
-{
-	return round(
-		number,
-		digitsLeft,
-		[] (const FloatingPoint& value, const FloatingPoint&)
-		{
-			if (value > 0.5 && value < 0.5)
-			{
-				if (value > 0.0)
-					return value + static_cast<FloatingPoint>(0.5);
-
-				if (value < 0.0)
-					return value - static_cast<FloatingPoint>(0.5);
-				return static_cast<FloatingPoint>(0.0);
-			}
-			return sgn(value) * floor(abs(value) + static_cast<FloatingPoint>(0.5));
-		}
-	);
-}
-
-FloatingPoint pecunia::rounders::reals::even(const FloatingPoint& number, const uint8_t& digitsLeft)
-{
-	return round(
-		number,
-		digitsLeft,
-		[&digitsLeft] (const FloatingPoint& value, const FloatingPoint& whole)
-		{
-			if (whole > 0.0)
-			{
-				if (isEqual(fmod(whole + 1, 2.0), 0.0, digitsLeft))
-					return value + static_cast<FloatingPoint>(0.5);
-				return 0.0;
-			}
-			else if (whole < 0.0)
-			{
-				if (isEqual(fmod(whole - 1, 2.0), 0.0, digitsLeft))
-					return value - static_cast<FloatingPoint>(0.5);
-				return 0.0;
-			}
-
-			if (value > 0.0)
-				return value + static_cast<FloatingPoint>(0.4);
-			return value - static_cast<FloatingPoint>(0.4);
-		}
-	);
-}
-
-FloatingPoint pecunia::rounders::reals::odd(const FloatingPoint& number, const uint8_t& digitsLeft)
-{
-	return round(
-		number,
-		digitsLeft,
-		[&digitsLeft] (const FloatingPoint& value, const FloatingPoint& whole)
-		{
-			if (whole > 0.0)
-			{
-				if ( ! isEqual(fmod(whole + 1, 2.0), 0.0, digitsLeft))
-					return value + static_cast<FloatingPoint>(0.5);
-				return value + static_cast<FloatingPoint>(0.4);
-			}
-			else if (whole < 0.0)
-			{
-				if ( ! isEqual(fmod(whole - 1, 2.0), 0.0, digitsLeft))
-					return value - static_cast<FloatingPoint>(0.5);
-				return value - static_cast<FloatingPoint>(0.4);
-			}
-
-			if (value > 0.0)
-				return value + static_cast<FloatingPoint>(0.5);
-			return value - static_cast<FloatingPoint>(0.5);
-		}
-	);
-}
-
-UnitStorage pecunia::rounders::currency::up(
-	const UnitStorage& amount,
-	const uint8_t& minorDigits,
-	const uint8_t& digitsLeft
-)
-{
-	return round(
-		amount,
-		minorDigits,
-		digitsLeft,
-		[] (
-			const UnitStorage& value,
-			const UnitStorage& point,
-			const UnitStorage&,
-			const bool isAmountPositive
-		)
-		{
-			if (isAmountPositive)
-				return value >= point;
-			return value > point;
-		}
-	);
-}
-
-UnitStorage pecunia::rounders::currency::even(
-	const UnitStorage& amount,
-	const uint8_t& minorDigits,
-	const uint8_t& digitsLeft
-)
-{
-	return round(
-		amount,
-		minorDigits,
-		digitsLeft,
-		[] (
-			const UnitStorage& value,
-			const UnitStorage& point,
-			const UnitStorage& whole,
-			const bool
-		)
-		{
-			if ((whole > 0 && (whole + 1) %  2 == 0) || (whole < 0 && (whole - 1) %  2 == 0))
-				return abs(value) >= point;
-
-			if (whole == 0)
-				return abs(value) > point;
-			return false;
-		}
-	);
-}
--- a/src/pecunia/Rounders.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_ROUNDERS_H_
-#define PECUNIA_ROUNDERS_H_
-
-#include <cstdint>
-
-#include "MoneyTypes.h"
-#include "pecunia_export.h"
-
-
-namespace pecunia
-{
-namespace rounders
-{
-namespace reals
-{
-
-/**
- * Performs a rounding operation using the round-half up towards +∞ method.
- *
- * @param[in] number The floating-point number to round.
- * @param[in] digitsLeft The number of digits left after rounding the number to the right of
- * the decimal point.
- *
- * @return The rounded number with the correct number of digits.
- */
-PECUNIA_EXPORT FloatingPoint up(const FloatingPoint& number, const std::uint8_t& digitsLeft);
-/**
- * Performs a rounding operation using the round-half down towards -∞ method.
- *
- * @param[in] number The floating-point number to round.
- * @param[in] digitsLeft The number of digits left after rounding the number to the right of
- * the decimal point.
- *
- * @return The rounded number with the correct number of digits.
- */
-PECUNIA_EXPORT FloatingPoint down(const FloatingPoint& number, const std::uint8_t& digitsLeft);
-/**
- * Performs a rounding operation using the round-half towards zero method.
- *
- * @param[in] number The floating-point number to round.
- * @param[in] digitsLeft The number of digits left after rounding the number to the right of
- * the decimal point.
- *
- * @return The rounded number with the correct number of digits.
- */
-PECUNIA_EXPORT FloatingPoint towardsZero(const FloatingPoint& number, const std::uint8_t& digitsLeft);
-/**
- * Performs a rounding operation using the round-half away from zero method.
- *
- * @param[in] number The floating-point number to round.
- * @param[in] digitsLeft The number of digits left after rounding the number to the right of
- * the decimal point.
- *
- * @return The rounded number with the correct number of digits.
- */
-PECUNIA_EXPORT FloatingPoint awayZero(const FloatingPoint& number, const std::uint8_t& digitsLeft);
-/**
- * Performs a rounding operation using the round-half to even method.
- *
- * @param[in] number The floating-point number to round.
- * @param[in] digitsLeft The number of digits left after rounding the number to the right of
- * the decimal point.
- *
- * @return The rounded number with the correct number of digits.
- */
-PECUNIA_EXPORT FloatingPoint even(const FloatingPoint& number, const std::uint8_t& digitsLeft);
-/**
- * Performs a rounding operation using the round-half to odd method.
- *
- * @param[in] number The floating-point number to round.
- * @param[in] digitsLeft The number of digits left after rounding the number to the right of
- * the decimal point.
- *
- * @return The rounded number with the correct number of digits.
- */
-PECUNIA_EXPORT FloatingPoint odd(const FloatingPoint& number, const std::uint8_t& digitsLeft);
-
-}
-namespace currency
-{
-
-/**
- * Performs a rounding operation using the round-half up towards +∞ method.
- *
- * @param[in] amount The major and minor units of the currency stored as one.
- * @param[in] minorDigits The number of digits in the minor unit.
- * @param[in] digitsLeft The number of digits left in the minor unit after rounding the number to
- * the right of the decimal point.
- *
- * @return The rounded number with the correct number of digits.
- */
-PECUNIA_EXPORT UnitStorage up(
-	const UnitStorage& amount,
-	const std::uint8_t& minorDigits,
-	const std::uint8_t& digitsLeft
-);
-/**
- * Performs a rounding operation using the round-half to even method.
- *
- * @param[in] amount The major and minor units of the currency stored as one.
- * @param[in] minorDigits The number of digits in the minor unit.
- * @param[in] digitsLeft The number of digits left in the minor unit after rounding the number to
- * the right of the decimal point.
- *
- * @return The rounded number with the correct number of digits.
- */
-PECUNIA_EXPORT UnitStorage even(
-	const UnitStorage& amount,
-	const std::uint8_t& minorDigits,
-	const std::uint8_t& digitsLeft
-);
-
-}}}
-
-#endif
--- a/src/pecunia/SetUp.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "SetUp.h"
-using std::string;
-using pecunia::ConversionFunction;
-using pecunia::converter;
-
-#include <cfenv>
-using std::feclearexcept;
-#include <clocale>
-using std::setlocale;
-
-
-void pecunia::currency::setUpCurrency(
-	const ConversionFunction& converterFunctor,
-	const string& locale
-)
-{
-	setlocale(LC_ALL, locale.c_str());
-	feclearexcept(FE_ALL_EXCEPT);
-	converter = converterFunctor;
-}
--- a/src/pecunia/SetUp.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_CURRENCY_SETUP_H_
-#define PECUNIA_CURRENCY_SETUP_H_
-
-#include <string>
-
-#include "pecunia_export.h"
-#include "MoneyTypes.h"
-
-namespace pecunia
-{
-namespace currency
-{
-
-/**
- * @brief Sets-up all the needed values for the currency library. This will establish the user's
- * locale, currency conversion function, and clear out the floating-point exceptions.
- *
- * @param converterFunctor The function to use when converting between currencies.
- * @param locale The C-locale to use for the currency.
- */
-PECUNIA_EXPORT void setUpCurrency(
-	const pecunia::ConversionFunction& converterFunctor = &pecunia::defaultConverter,
-	const std::string& locale =
-#ifdef _WIN32
-	"English_United States.1251"
-#else
-	"C.UTF-8"
-#endif
-);
-
-}}
-
-#endif
--- a/src/pecunia/internal/Adjustments.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "Adjustments.h"
-using std::function;
-using std::int32_t;
-using std::uint8_t;
-using pecunia::precision;
-using pecunia::MinorUnit;
-using pecunia::FloatingPoint;
-using pecunia::FloatingPointRounderFunction;
-using pecunia::UnitStorage;
-
-#include <cassert>
-// using assert;
-#include <cmath>
-using std::abs;
-#include <stdexcept>
-using std::overflow_error;
-
-#include "../Codes.h"
-using pecunia::currency::Codes;
-#include "../Money.h"
-using pecunia::currency::Money;
-using pecunia::currency::to_string;
-#include "pecunia/MoneySize.hpp"
-using pecunia::internal::extraFloatingPointPrecision;
-#include "Verification.h"
-using pecunia::internal::isEqual;
-using pecunia::internal::verifiedFloatingPoint;
-
-
-UnitStorage pecunia::currency::internal::fromFloatingPointMajor(
-	const FloatingPoint& value,
-	const Codes& code,
-	const uint8_t currencyPrecision,
-	const FloatingPointRounderFunction& rounder
-)
-{
-	const uint8_t totalDigits{
-		static_cast<uint8_t>(minorUnitDigits(code) + currencyPrecision + extraFloatingPointPrecision)
-	};
-	const int32_t ratio{minorUnitPrecisionFactor(code)};
-	const UnitStorage major{
-		static_cast<UnitStorage>(
-			verifiedFloatingPoint((rounder(value, totalDigits) * ratio) / ratio)
-		)
-	};
-	return major;
-}
-
-MinorUnit pecunia::currency::internal::fromFloatingPointMinor(
-	const FloatingPoint& value,
-	const Codes& code,
-	const uint8_t currencyPrecision,
-	const FloatingPointRounderFunction& rounder
-)
-{
-	const uint8_t totalDigits{
-		static_cast<uint8_t>(minorUnitDigits(code) + currencyPrecision + extraFloatingPointPrecision)
-	};
-	const int32_t ratio{
-		minorUnitPrecisionFactor(code)
-			* static_cast<int32_t>(pow(10, extraFloatingPointPrecision))
-	};
-	const UnitStorage adjustedValue{
-		static_cast<UnitStorage>(
-			verifiedFloatingPoint(rounder(value, totalDigits) * ratio)
-		)
-	};
-	const auto minorAdjusted{abs(adjustedValue) % ratio};
-	const auto extraRatio{pow(10.0, extraFloatingPointPrecision)};
-	const auto removedExtra{minorAdjusted / static_cast<MinorUnit>(extraRatio)};
-	return static_cast<MinorUnit>(removedExtra);
-}
-
-UnitStorage pecunia::currency::internal::normaliseAmount(const Money& from, const Codes& to)
-{
-	assert(pecunia::converter != nullptr && "The currency conversion function is not set.");
-	const auto& fromCode{from.code()};
-	const FloatingPoint conversionFactor{pecunia::converter(fromCode, to)};
-
-	if (isEqual(conversionFactor, 1.0, static_cast<uint8_t>(minorUnitDigits(fromCode) + precision)))
-		return from.amount();
-	const auto convertedAmount{
-		verifiedFloatingPoint(static_cast<FloatingPoint>(from.amount()) * conversionFactor)
-	};
-	return static_cast<UnitStorage>(convertedAmount);
-}
--- a/src/pecunia/internal/Adjustments.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_CURRENCY_INTERNAL_ADJUSTMENTS_H_
-#define PECUNIA_CURRENCY_INTERNAL_ADJUSTMENTS_H_
-
-#include <cstdint>
-
-#include "../MoneyTypes.h"
-
-
-namespace pecunia
-{
-namespace currency
-{
-
-enum class Codes;
-class Money;
-
-namespace internal
-{
-
-UnitStorage fromFloatingPointMajor(
-	const FloatingPoint& value,
-	const pecunia::currency::Codes& code,
-	const std::uint8_t currencyPrecision,
-	const pecunia::FloatingPointRounderFunction& rounder
-);
-MinorUnit fromFloatingPointMinor(
-	const FloatingPoint& value,
-	const pecunia::currency::Codes& code,
-	const std::uint8_t currencyPrecision,
-	const pecunia::FloatingPointRounderFunction& rounder
-);
-UnitStorage normaliseAmount(
-	const pecunia::currency::Money& from,
-	const pecunia::currency::Codes& to
-);
-
-}}}
-
-#endif
--- a/src/pecunia/internal/Verification.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#include "Verification.h"
-using std::int32_t;
-using std::uint8_t;
-using pecunia::precision;
-using pecunia::MinorUnit;
-using pecunia::FloatingPoint;
-using pecunia::UnitStorage;
-using pecunia::internal::VerifiedValue;
-
-#include <cmath>
-using std::fabs;
-using std::pow;
-#include <cfenv>
-using std::feclearexcept;
-using std::fetestexcept;
-#include <stdexcept>
-using std::domain_error;
-using std::overflow_error;
-using std::underflow_error;
-
-
-bool pecunia::internal::isEqual(
-	const FloatingPoint& number,
-	const FloatingPoint& equals,
-	const uint8_t minorPrecision
-)
-{
-	const FloatingPoint epsilon{1 / pow(10, minorPrecision + 1)};
-	const FloatingPoint difference{fabs(number - equals)};
-	return difference < epsilon;
-}
-
-FloatingPoint pecunia::internal::verifiedFloatingPoint(const FloatingPoint& value)
-{
-	int32_t exceptions{fetestexcept(FE_ALL_EXCEPT)};
-	feclearexcept(FE_ALL_EXCEPT);
-
-	if (exceptions & FE_DIVBYZERO)
-		throw domain_error{"The floating-point operation resulted in a divided by zero."};
-
-	if (exceptions & FE_UNDERFLOW)
-		throw underflow_error{
-			"The floating-point operation resulted in a value that is too small to fit within "
-				"the FloatingPoint type."
-		};
-
-	if (exceptions & FE_OVERFLOW)
-		throw overflow_error{
-			"The floating-point operation resulted in a value that is too large to fit within "
-				"the FloatingPoint type."
-		};
-
-/* TODO: This leads to a lot of false errors. Needs to be investigated.
-	if (exceptions & FE_INVALID)
-		throw domain_error{
-			"The floating-point operation resulted in a value that is not valid."
-		};*/
-	return value;
-}
-
-VerifiedValue pecunia::internal::verifyAdditionFits(
-	const UnitStorage& lhs,
-	const UnitStorage& rhs,
-	const UnitStorage& maximum,
-	const UnitStorage& minimum
-)
-{
-	const UnitStorage maximumDifference{static_cast<UnitStorage>(maximum - rhs)};
-	if ((rhs > 0) && (lhs > maximumDifference))
-		return VerifiedValue::Overflows;
-
-	const UnitStorage minimumDifference{static_cast<UnitStorage>(minimum - rhs)};
-	if ((rhs < 0) && (lhs < minimumDifference))
-		return VerifiedValue::Overflows;
-	return VerifiedValue::Fits;
-}
-
-VerifiedValue pecunia::internal::verifySubtractionFits(
-	const UnitStorage& lhs,
-	const UnitStorage& rhs,
-	const UnitStorage& maximum,
-	const UnitStorage& minimum
-)
-{
-	const UnitStorage maximumDifference{static_cast<UnitStorage>(maximum + rhs)};
-	if ((rhs < 0) && (lhs > maximumDifference))
-		return VerifiedValue::Overflows;
-
-	const UnitStorage minimumDifference{static_cast<UnitStorage>(minimum + rhs)};
-	if ((rhs > 0) && (lhs < minimumDifference))
-		return VerifiedValue::Overflows;
-	return VerifiedValue::Fits;
-}
-
-VerifiedValue pecunia::internal::verifyMultiplicationFits(
-	const UnitStorage& lhs,
-	const FloatingPoint& rhs,
-	const UnitStorage& maximum,
-	const UnitStorage& minimum,
-	const MinorUnit& minorMaximum,
-	const uint8_t minorPrecision
-)
-{
-	if ((lhs == 0) || isEqual(rhs, 0, minorPrecision))
-		return VerifiedValue::Fits;
-
-	if ((lhs == -1) || isEqual(rhs, -1, minorPrecision))
-		return VerifiedValue::Fits;
-
-	const auto fpLhs{static_cast<FloatingPoint>(lhs)};
-	const auto fpMaximum{static_cast<FloatingPoint>(maximum)};
-	if (fpLhs > fpMaximum / rhs)
-		return VerifiedValue::Overflows;
-
-	const auto fpMinimum{static_cast<FloatingPoint>(minimum)};
-	if (fpLhs < fpMinimum / rhs)
-		return VerifiedValue::Overflows;
-
-	if (rhs < 1 && rhs > -1)
-	{
-		const FloatingPoint reciprocal{1 / rhs};
-		return verifyDivisionFits(lhs, reciprocal, maximum, minimum, minorMaximum, minorPrecision);
-	}
-	return VerifiedValue::Fits;
-}
-
-VerifiedValue pecunia::internal::verifyDivisionFits(
-	const UnitStorage& lhs,
-	const FloatingPoint& rhs,
-	const UnitStorage& maximum,
-	const UnitStorage& minimum,
-	const MinorUnit& minorMaximum,
-	const uint8_t minorPrecision
-)
-{
-	if (isEqual(rhs, 0, minorPrecision))
-		return VerifiedValue::Undefined;
-
-	if (rhs < 1 && rhs > -1)
-	{
-		const FloatingPoint reciprocal{1 / rhs};
-		return verifyMultiplicationFits(
-			lhs,
-			reciprocal,
-			maximum,
-			minimum,
-			minorMaximum,
-			minorPrecision
-		);
-	}
-
-	const auto fpLhs{static_cast<FloatingPoint>(lhs)};
-	if ((lhs > 0) && (lhs <= minorMaximum) && (rhs > fpLhs))
-		return VerifiedValue::Underflows;
-	return VerifiedValue::Fits;
-}
-
-VerifiedValue pecunia::internal::verifyMultiplicationFits(
-	const UnitStorage& lhs,
-	const UnitStorage& rhs,
-	const UnitStorage& maximum,
-	const UnitStorage& minimum
-)
-{
-	if ((lhs == 0) || rhs == 0)
-		return VerifiedValue::Fits;
-
-	if ((lhs == -1) || rhs == -1)
-		return VerifiedValue::Fits;
-
-	if (lhs > maximum / rhs)
-		return VerifiedValue::Overflows;
-
-	if (lhs < minimum / rhs)
-		return VerifiedValue::Overflows;
-	return VerifiedValue::Fits;
-}
-
-VerifiedValue pecunia::internal::verifyDivisionFits(
-	const UnitStorage& lhs,
-	const UnitStorage& rhs,
-	const MinorUnit& minorMaximum
-)
-{
-	if (rhs == 0)
-		return VerifiedValue::Undefined;
-
-	if (lhs > 0 && lhs <= minorMaximum && rhs > lhs)
-		return VerifiedValue::Underflows;
-	return VerifiedValue::Fits;
-}
--- a/src/pecunia/internal/Verification.h	Sat Dec 12 15:09:09 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*******************************************************************************
-***  This file is part of Pecunia.                                           ***
-***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
-***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
-***                                                                          ***
-***  This program is free software: you can redistribute it and/or modify it ***
-***  under the terms of the GNU Lesser General Public License as published   ***
-***  by the Free Software Foundation, either version 3 of the License, or    ***
-***  (at your option) any later version.                                     ***
-***                                                                          ***
-***  This program is distributed in the hope that it will be useful, but     ***
-***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
-***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
-***  See the GNU Lesser General Public License for more details.             ***
-***                                                                          ***
-***  You should have received a copy of the GNU Lesser General Public License***
-***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
-*******************************************************************************/
-#ifndef PECUNIA_CURRENCY_INTERNAL_VERIFICATION_H_
-#define PECUNIA_CURRENCY_INTERNAL_VERIFICATION_H_
-
-#include <cstdint>
-
-#include "../MoneyTypes.h"
-
-
-namespace pecunia
-{
-namespace internal
-{
-
-enum class VerifiedValue
-{
-	Fits,
-	Overflows,
-	Underflows,
-	Undefined
-};
-
-bool isEqual(
-	const FloatingPoint& number,
-	const FloatingPoint& equals,
-	const std::uint8_t minorPrecision
-);
-/**
- * @brief Verifies that all prior floating-point operations and the value did not result in
- * an error.
- *
- * @pre The floating-point error register must be cleared prior to all floating-point operations
- * that are desired to be verified.
- *
- * @exception std::domain_error When the resulting floating-point operations lead to a
- * division by zero or a number that is not valid.
- * @exception std::underflow_error When the resulting floating-point operations lead to a case
- * where the value is too small to be stored in the the FloatingPoint type.
- * @exception std::overflow_error When the resulting floating-point operations lead to a case
- * where the value is too large to be stored in the the FloatingPoint type.
- *
- * @param[in] value The floating-point value that is to be verified.
- *
- * @return The supplied value that was checked.
- */
-FloatingPoint verifiedFloatingPoint(const FloatingPoint& value);
-VerifiedValue verifyAdditionFits(
-	const UnitStorage& lhs,
-	const UnitStorage& rhs,
-	const UnitStorage& maximum,
-	const UnitStorage& minimum
-);
-VerifiedValue verifySubtractionFits(
-	const UnitStorage& lhs,
-	const UnitStorage& rhs,
-	const UnitStorage& maximum,
-	const UnitStorage& minimum
-);
-VerifiedValue verifyMultiplicationFits(
-	const UnitStorage& lhs,
-	const FloatingPoint& rhs,
-	const UnitStorage& maximum,
-	const UnitStorage& minimum,
-	const MinorUnit& minorMaximum,
-	const std::uint8_t minorPrecision
-);
-VerifiedValue verifyDivisionFits(
-	const UnitStorage& lhs,
-	const FloatingPoint& rhs,
-	const UnitStorage& maximum,
-	const UnitStorage& minimum,
-	const MinorUnit& minorMaximum,
-	const std::uint8_t minorPrecision
-);
-VerifiedValue verifyMultiplicationFits(
-	const UnitStorage& lhs,
-	const UnitStorage& rhs,
-	const UnitStorage& maximum,
-	const UnitStorage& minimum
-);
-VerifiedValue verifyDivisionFits(
-	const UnitStorage& lhs,
-	const UnitStorage& rhs,
-	const MinorUnit& minorMaximum
-);
-
-}}
-
-#endif
--- a/src/pecuniaConfig.cmake.in	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/pecuniaConfig.cmake.in	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 #*******************************************************************************
 #**  This file is part of Pecunia.                                           ***
 #**                                                                          ***
-#**  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 #**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 #**                                                                          ***
 #**  This program is free software: you can redistribute it and/or modify it ***
@@ -18,9 +18,3 @@
 #**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
 #*******************************************************************************
 include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
-
-if (EXISTS "@CMAKE_INSTALL_PREFIX@/include/@PROJECT_NAME@")
-	include_directories("@CMAKE_INSTALL_PREFIX@/include")
-else ()
-	MESSAGE(AUTHOR_WARNING "Failed to find the @PROJECT_NAME@ library header directory.")
-endif (EXISTS "@CMAKE_INSTALL_PREFIX@/include/@PROJECT_NAME@")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/project.vcxproj.user.in	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+		<LocalDebuggerEnvironment>PATH=@PROJECT_BINARY_DIR@/../Debug;@qt-mocks_DIR@/../../../bin;@Qt5_DIR@/../../../bin;%PATH%</LocalDebuggerEnvironment>
+		<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+	</PropertyGroup>
+	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">
+		<LocalRelWithDebInfogerEnvironment>PATH=@PROJECT_BINARY_DIR@/../RelWithDebInfo;@qt-mocks_DIR@/../../../bin;@Qt5_DIR@/../../../bin;%PATH%</LocalRelWithDebInfogerEnvironment>
+		<RelWithDebInfogerFlavor>WindowsLocalRelWithDebInfoger</RelWithDebInfogerFlavor>
+		<LocalDebuggerEnvironment>PATH=@PROJECT_BINARY_DIR@/../RelWithDebInfo;@qt-mocks_DIR@/../../../bin;@Qt5_DIR@/../../../bin;%PATH%</LocalDebuggerEnvironment>
+		<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+	</PropertyGroup>
+</Project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/scripts/Iso4217.py	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,94 @@
+'''*****************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*****************************************************************************'''
+
+
+class Currency(object):
+	"""
+	Represents all the information regarding a currency in the ISO-4217 format.
+	"""
+
+	def __init__(self, country: str, name: str, code: str, number: int, minor: int,
+			  symbol: str):
+		"""
+		Full initialisation constructor.
+
+		:param country: The name of the country that uses the currency.
+		:param name: The name of the currency itself.
+		:param code: The code for the currency in the ISO 4217 format.
+		:param number: The number for the currency given by ISO 4217.
+		:param minor: The number of minor units in the currency.
+		"""
+		self.__country = country
+		self.__name = name
+		self.__code = code
+		self.__number = number
+		self.__minor = minor
+		self.__symbol = symbol
+
+	@property
+	def country(self) -> str:
+		"""
+		The name of the country that uses this currency.
+		"""
+		return self.__country
+
+	@property
+	def name(self) -> str:
+		"""
+		The name of the currency itself.
+		"""
+		return self.__name
+
+	@property
+	def code(self) -> str:
+		"""
+		The ISO 4217 code for the currency.
+		"""
+		return self.__code
+
+	@property
+	def number(self) -> int:
+		"""
+		The ISO 4217 number for the currency.
+		"""
+		return self.__number
+
+	@property
+	def minor(self) -> int:
+		"""
+		The number of minor digits in the currency.
+		"""
+		return self.__minor
+
+	@property
+	def symbol(self) -> str:
+		"""
+		The symbol of the currency.
+		"""
+		return self.__symbol
+
+	def __str__(self):
+		return "Country ({}), Name ({}), Code ({}), Number ({}), Minor ({})".format(
+			self.__country,
+			self.__name,
+			self.__code,
+			self.__number,
+			self.__minor
+		)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/scripts/IsoOrgParser.py	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,63 @@
+'''*****************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*****************************************************************************'''
+from xml.etree import ElementTree
+
+from Iso4217 import Currency
+
+
+def parse(filePathName: str):
+	"""
+	Parses the XML file supplied by the ISO from https://www.iso.org/iso-4217-currency-codes.html .
+	This file does not contain the currency's symobl information.
+
+	:raises ValueError: When an unexpected element tag is encountered.
+
+	:param filePathName: The file-name with the absolute or relative path to the XML file to parse.
+
+	:return list[Currency]: The extracted currencies from the XML file.
+	"""
+	currencies = []
+	tree = ElementTree.parse(filePathName)
+
+	for elements in tree.getroot().iter('CcyNtry'):
+		country = None
+		currency = None
+		code = None
+		number = None
+		minor = None
+
+		for info in elements.iter():
+
+			if info.tag == 'CcyNtry':
+				continue
+			elif info.tag == 'CtryNm':
+				country = info.text
+			elif info.tag == 'CcyNm':
+				currency = info.text
+			elif info.tag == 'Ccy':
+				code = info.text
+			elif info.tag == 'CcyNbr':
+				number = int(info.text)
+			elif info.tag == 'CcyMnrUnts':
+				minor = None if info.text == 'N.A.' else int(info.text)
+			else:
+				raise ValueError("Failed to process tag '{}'.".format(info.tag))
+		currencies.append(Currency(country, currency, code, number, minor, None))
+	return currencies
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/scripts/Templates.py	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,197 @@
+'''*****************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*****************************************************************************'''
+from Iso4217 import Currency
+
+
+class CodesTemplateFiller(object):
+	"""
+	Fills in the template variables for the Codes declaration and definition files.
+	"""
+
+	def __init__(self, currencies):
+		self.__currencies = currencies
+		self.__codes_set = set()
+
+		for currency in self.__currencies:
+			if currency.code is None:
+				continue
+			self.__codes_set.add(currency.code)
+		self.__codes_set = sorted(self.__codes_set)
+
+	def filled_to_string(self):
+		template = """	case Iso4217Codes::{code}:
+		return "{code}";
+"""
+		to_iso4217 = ""
+
+		for iso_code in self.__codes_set:
+			to_iso4217 += template.format(code=iso_code)
+		return to_iso4217[0:-1]
+
+
+	def filled_to_code(self):
+		template = """
+	if ("{code}" == code)
+		return Iso4217Codes::{code};
+"""
+		to_code = ""
+
+		for iso_code in self.__codes_set:
+			to_code += template.format(code=iso_code)
+		return to_code[1:-1]
+
+
+	def filled_to_symbol(self):
+		map_code_to_symbol = {}
+
+		for currency in self.__currencies:
+			# HACK: symbols for the self.__currencies I use.
+			if currency.symbol is not None and currency.code is not None:
+				map_code_to_symbol[currency.code] = currency.symbol
+			elif currency.code == "USD":
+				map_code_to_symbol[currency.code] = "$"
+			elif currency.code == "PLN":
+				map_code_to_symbol[currency.code] = "zł"
+			elif currency.code == "EUR":
+				map_code_to_symbol[currency.code] = "€"
+		template = """	case Iso4217Codes::{code}:
+		return "{symbol}";
+"""
+		to_symbol = ""
+
+		for (code, symbol) in sorted(map_code_to_symbol.items()):
+			to_symbol += template.format(code=code, symbol=symbol)
+		return to_symbol[0:-1]
+
+
+	def filled_minor_unit_digits(self):
+		map_minor_to_codes = {}
+
+		for currency in self.__currencies:
+			if currency.code is None:
+				continue
+			elif currency.minor is None:
+				if 0 not in map_minor_to_codes:
+					map_minor_to_codes[0] = set()
+				map_minor_to_codes[0].add(currency.code)
+				continue
+			elif currency.minor not in map_minor_to_codes:
+				map_minor_to_codes[currency.minor] = set()
+			map_minor_to_codes[currency.minor].add(currency.code)
+		template = """{codes}
+		return {minor_unit}u;
+"""
+		minor_unit_digits = ""
+
+		for minor, codes in sorted(map_minor_to_codes.items()):
+			codeCases = ""
+
+			for code in sorted(codes):
+				codeCases += "\tcase Iso4217Codes::{code}:\n".format(code=code)
+
+			minor_unit_digits += template.format(minor_unit=minor, codes=codeCases[0:-1])
+		return minor_unit_digits[0:-1]
+
+
+	def filled_all_iso_codes(self):
+		template = """		Iso4217Codes::{code},
+"""
+		all_iso_codes = ""
+
+		for iso_code in self.__codes_set:
+			all_iso_codes += template.format(code=iso_code)
+		return all_iso_codes[0:-2]
+
+
+	def filled_enum_codes(self):
+		template = """	/// The currency code for the "{name}" used in: {countries}.
+	{code} = {number},
+"""
+		map_code_to_name = {}
+		map_code_to_countries = {}
+		map_code_to_number = {}
+
+		for currency in self.__currencies:
+			if currency.code is None:
+				continue
+			elif currency.code not in map_code_to_countries:
+				map_code_to_countries[currency.code] = set()
+			map_code_to_countries[currency.code].add(currency.country)
+			map_code_to_number[currency.code] = currency.number
+			map_code_to_name[currency.code] = currency.name
+		enum_codes = ""
+
+		for code, countries in sorted(map_code_to_countries.items()):
+			enum_codes += template.format(
+				name=map_code_to_name[code],
+				countries='; '.join(sorted(countries)),
+				code=code,
+				number=map_code_to_number[code]
+			)
+		return enum_codes[0:-1]
+
+
+	def filled_all_codes_to_countries(self):
+		template = """		{{
+			Iso4217Codes::{code},
+			{{
+				{{"{countries}"s}}
+			}}
+		}},
+"""
+		map_code_to_countries = {}
+
+		for currency in self.__currencies:
+			if currency.code is None:
+				continue
+			elif currency.code not in map_code_to_countries:
+				map_code_to_countries[currency.code] = set()
+			map_code_to_countries[currency.code].add(currency.country.replace('"', '\\"'))
+		all_codes_to_countries = ""
+
+		for code, countries in sorted(map_code_to_countries.items()):
+			all_codes_to_countries += template.format(
+				countries='"s, "'.join(sorted(countries)),
+				code=code
+			)
+		return all_codes_to_countries [0:-2]
+
+
+	def filled_all_codes_to_names(self):
+		template = """		{{
+			Iso4217Codes::{code},
+			"{name}"s
+		}},
+"""
+		map_code_to_names = {}
+
+		for currency in self.__currencies:
+			if currency.code is None:
+				continue
+			map_code_to_names[currency.code] = currency.name
+		all_codes_to_names = ""
+
+		for code, name in sorted(map_code_to_names.items()):
+			all_codes_to_names += template.format(name=name, code=code)
+		return all_codes_to_names [0:-2]
+
+
+	def filled_number_of_codes(self):
+		return len(self.__codes_set)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/scripts/gpcf.py	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,99 @@
+#!/usr/bin/env python3
+'''*****************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*****************************************************************************'''
+from argparse import ArgumentParser
+from datetime import datetime
+from os import getcwd, path
+from sys import stderr
+from traceback import format_exc
+
+from Iso4217 import Currency
+from IsoOrgParser import parse
+from Templates import CodesTemplateFiller
+
+
+def __process_arguments():
+	parser = ArgumentParser(description="Creates the auto-generated C++ files.")
+	parser.add_argument('-c', '--codes', action='store', type=str,
+					 default=path.join(getcwd(), "list_one.xml"),
+					 help='The file and directory path containing information on ISO 4217 '
+					 'currencies. Defaulting to the current directory and the XML file supplied '
+					 'by ISO.org')
+	return parser.parse_args()
+
+
+def __generate_codes_files(script_directory_path, currencies):
+	codes_filler = CodesTemplateFiller(currencies)
+	timestamp = datetime.now()
+
+	with open(path.join(script_directory_path, 'templates', 'Codes.h'), 'r') as \
+			code_declaration_template:
+		declaration = code_declaration_template.read()
+	declaration = declaration.replace('@TIMESTAMP@', timestamp.isoformat())
+	declaration = declaration.replace('@ENUM_CODES@', codes_filler.filled_enum_codes())
+	declaration = declaration.replace('@NUMBER_OF_CODES@', "{}".format(
+		codes_filler.filled_number_of_codes()))
+
+	with open(path.join(script_directory_path, '..', 'external', 'pecunia', 'Codes.h'), 'w') as \
+			code_declaration:
+		code_declaration.write(declaration)
+
+	with open(path.join(script_directory_path, 'templates', 'Codes.cpp'), 'r') as \
+			code_definition_template:
+		definition = code_definition_template.read()
+	definition = definition.replace('@TIMESTAMP@', timestamp.isoformat())
+	definition = definition.replace('@TO_STRING@', codes_filler.filled_to_string())
+	definition = definition.replace('@TO_CODE@', codes_filler.filled_to_code())
+	definition = definition.replace('@TO_SYMBOL@', codes_filler.filled_to_symbol())
+	definition = definition.replace('@MINOR_UNIT_DIGITS@', codes_filler.filled_minor_unit_digits())
+	definition = definition.replace(
+		'@ALL_CODES_TO_COUNTRIES@',
+		codes_filler.filled_all_codes_to_countries()
+	)
+	definition = definition.replace('@ALL_CODES_TO_NAME@', codes_filler.filled_all_codes_to_names())
+	definition = definition.replace('@ALL_ISO_CODES@', codes_filler.filled_all_iso_codes())
+
+	with open(path.join(script_directory_path, '..', 'external', 'pecunia', 'Codes.cpp'), 'w') as \
+			code_definition:
+		code_definition.write(definition)
+
+
+if __name__ == "__main__":
+	try:
+		print("""Generate Pecunia C++ Files Copyright (C) 2020 John Schneiderman
+GPCF comes with ABSOLUTELY NO WARRANTY;
+This is free software, and you are welcome to redistribute it
+under certain conditions; see the COPYING file for details,
+or the Free Software Foundation's LGPL.
+"""
+		)
+		args = __process_arguments()
+		script_directory_path = path.dirname(__file__)
+		currencies = parse(args.codes)
+		__generate_codes_files(script_directory_path, currencies)
+	except (ValueError, RuntimeError, FileNotFoundError) as error:
+		print("Execution Failed: {}".format(error), file=stderr)
+		exit(2)
+	except Exception as error:
+		print("Unexpected error: {err}\n{banner}\n{trace}{banner}".format(err=error,
+																		banner='-' * 60,
+																		trace=format_exc()),
+		file=stderr)
+		exit(3)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/scripts/templates/Codes.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,145 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+
+//  ██████╗  ██████╗     ███╗   ██╗ ██████╗ ████████╗    ███████╗██████╗ ██╗████████╗██╗
+//  ██╔══██╗██╔═══██╗    ████╗  ██║██╔═══██╗╚══██╔══╝    ██╔════╝██╔══██╗██║╚══██╔══╝██║
+//  ██║  ██║██║   ██║    ██╔██╗ ██║██║   ██║   ██║       █████╗  ██║  ██║██║   ██║   ██║
+//  ██║  ██║██║   ██║    ██║╚██╗██║██║   ██║   ██║       ██╔══╝  ██║  ██║██║   ██║   ╚═╝
+//  ██████╔╝╚██████╔╝    ██║ ╚████║╚██████╔╝   ██║       ███████╗██████╔╝██║   ██║   ██╗
+//  ╚═════╝  ╚═════╝     ╚═╝  ╚═══╝ ╚═════╝    ╚═╝       ╚══════╝╚═════╝ ╚═╝   ╚═╝   ╚═╝
+//
+//  ███████╗██╗██╗     ███████╗     ██████╗ ██████╗ ███╗   ██╗████████╗███████╗███╗   ██╗████████╗
+//  ██╔════╝██║██║     ██╔════╝    ██╔════╝██╔═══██╗████╗  ██║╚══██╔══╝██╔════╝████╗  ██║╚══██╔══╝
+//  █████╗  ██║██║     █████╗      ██║     ██║   ██║██╔██╗ ██║   ██║   █████╗  ██╔██╗ ██║   ██║
+//  ██╔══╝  ██║██║     ██╔══╝      ██║     ██║   ██║██║╚██╗██║   ██║   ██╔══╝  ██║╚██╗██║   ██║
+//  ██║     ██║███████╗███████╗    ╚██████╗╚██████╔╝██║ ╚████║   ██║   ███████╗██║ ╚████║   ██║
+//  ╚═╝     ╚═╝╚══════╝╚══════╝     ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝   ╚═╝   ╚══════╝╚═╝  ╚═══╝   ╚═╝
+//
+//   ██████╗██████╗ ███████╗ █████╗ ████████╗██╗ ██████╗ ███╗   ██╗    ██╗███████╗
+//  ██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗  ██║    ██║██╔════╝
+//  ██║     ██████╔╝█████╗  ███████║   ██║   ██║██║   ██║██╔██╗ ██║    ██║███████╗
+//  ██║     ██╔══██╗██╔══╝  ██╔══██║   ██║   ██║██║   ██║██║╚██╗██║    ██║╚════██║
+//  ╚██████╗██║  ██║███████╗██║  ██║   ██║   ██║╚██████╔╝██║ ╚████║    ██║███████║
+//   ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝    ╚═╝╚══════╝
+//
+//   █████╗ ██╗   ██╗████████╗ ██████╗ ███╗   ███╗ █████╗ ████████╗███████╗██████╗
+//  ██╔══██╗██║   ██║╚══██╔══╝██╔═══██╗████╗ ████║██╔══██╗╚══██╔══╝██╔════╝██╔══██╗
+//  ███████║██║   ██║   ██║   ██║   ██║██╔████╔██║███████║   ██║   █████╗  ██║  ██║
+//  ██╔══██║██║   ██║   ██║   ██║   ██║██║╚██╔╝██║██╔══██║   ██║   ██╔══╝  ██║  ██║
+//  ██║  ██║╚██████╔╝   ██║   ╚██████╔╝██║ ╚═╝ ██║██║  ██║   ██║   ███████╗██████╔╝██╗
+//  ╚═╝  ╚═╝ ╚═════╝    ╚═╝    ╚═════╝ ╚═╝     ╚═╝╚═╝  ╚═╝   ╚═╝   ╚══════╝╚═════╝ ╚═╝
+// Generated At: @TIMESTAMP@
+
+#include "Codes.h"
+using namespace std::string_literals;
+using std::array;
+using std::ostream;
+using std::string;
+using std::to_string;
+using std::vector;
+using pecunia::currency::Iso4217Codes;
+using pecunia::currency::numberOfIso4217Codes;
+
+#include <cassert>
+// Used for assert.
+#include <cmath>
+using std::pow;
+#include <map>
+using std::map;
+#include <stdexcept>
+using std::runtime_error;
+
+#include "MoneyTypes.h"
+using pecunia::precision;
+
+
+string pecunia::currency::toStdString(const Iso4217Codes& code)
+{
+	switch (code)
+	{
+@TO_STRING@
+	default:
+		assert(false && "Unhandled currency code for conversion to an ISO-4217 string.");
+		return "";
+	};
+}
+
+Iso4217Codes pecunia::currency::toIso4217Code(const string& code)
+{
+@TO_CODE@
+	throw runtime_error{
+		"Unhandled currency code '" + code + "' for conversion to its strong type."
+	};
+}
+
+string pecunia::currency::currencySymbol(const Iso4217Codes& code)
+{
+	switch (code)
+	{
+@TO_SYMBOL@
+	default:
+		assert(false && "Unhandled currency code for conversion to a symbol.");
+		return "";
+	};
+}
+
+uint8_t pecunia::currency::minorUnitDigits(const Iso4217Codes& code)
+{
+	switch (code)
+	{
+@MINOR_UNIT_DIGITS@
+	default:
+		assert(false && "Unhandled currency code for minor unit digits.");
+		return 0u;
+	};
+}
+
+int32_t pecunia::currency::minorUnitPrecisionFactor(const Iso4217Codes& code)
+{
+	return static_cast<int32_t>(pow(10, minorUnitDigits(code) + precision));
+}
+
+ostream& pecunia::currency::operator<<(ostream& stream, const Iso4217Codes& code)
+{
+	return stream << toStdString(code);
+}
+
+vector<string> pecunia::currency::countriesUsing(const Iso4217Codes& code)
+{
+	static const map<Iso4217Codes, vector<string>> codeCountries{
+@ALL_CODES_TO_COUNTRIES@
+	};
+	return codeCountries.at(code);
+}
+
+string pecunia::currency::currencyName(const Iso4217Codes& code)
+{
+	static const map<Iso4217Codes, string> codeNames{
+@ALL_CODES_TO_NAME@
+	};
+	return codeNames.at(code);
+}
+
+const array<Iso4217Codes, numberOfIso4217Codes> pecunia::currency::allIso4217Codes
+{
+	{
+@ALL_ISO_CODES@
+	}
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/scripts/templates/Codes.h	Mon Mar 01 16:17:10 2021 +0100
@@ -0,0 +1,160 @@
+/*******************************************************************************
+***  This file is part of Pecunia.                                           ***
+***                                                                          ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
+***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
+***                                                                          ***
+***  This program is free software: you can redistribute it and/or modify it ***
+***  under the terms of the GNU Lesser General Public License as published   ***
+***  by the Free Software Foundation, either version 3 of the License, or    ***
+***  (at your option) any later version.                                     ***
+***                                                                          ***
+***  This program is distributed in the hope that it will be useful, but     ***
+***  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
+***  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
+***  See the GNU Lesser General Public License for more details.             ***
+***                                                                          ***
+***  You should have received a copy of the GNU Lesser General Public License***
+***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
+*******************************************************************************/
+#ifndef PECUNIA_CURRENCY_CODES_H_
+#define PECUNIA_CURRENCY_CODES_H_
+
+//  ██████╗  ██████╗     ███╗   ██╗ ██████╗ ████████╗    ███████╗██████╗ ██╗████████╗██╗
+//  ██╔══██╗██╔═══██╗    ████╗  ██║██╔═══██╗╚══██╔══╝    ██╔════╝██╔══██╗██║╚══██╔══╝██║
+//  ██║  ██║██║   ██║    ██╔██╗ ██║██║   ██║   ██║       █████╗  ██║  ██║██║   ██║   ██║
+//  ██║  ██║██║   ██║    ██║╚██╗██║██║   ██║   ██║       ██╔══╝  ██║  ██║██║   ██║   ╚═╝
+//  ██████╔╝╚██████╔╝    ██║ ╚████║╚██████╔╝   ██║       ███████╗██████╔╝██║   ██║   ██╗
+//  ╚═════╝  ╚═════╝     ╚═╝  ╚═══╝ ╚═════╝    ╚═╝       ╚══════╝╚═════╝ ╚═╝   ╚═╝   ╚═╝
+//
+//  ███████╗██╗██╗     ███████╗     ██████╗ ██████╗ ███╗   ██╗████████╗███████╗███╗   ██╗████████╗
+//  ██╔════╝██║██║     ██╔════╝    ██╔════╝██╔═══██╗████╗  ██║╚══██╔══╝██╔════╝████╗  ██║╚══██╔══╝
+//  █████╗  ██║██║     █████╗      ██║     ██║   ██║██╔██╗ ██║   ██║   █████╗  ██╔██╗ ██║   ██║
+//  ██╔══╝  ██║██║     ██╔══╝      ██║     ██║   ██║██║╚██╗██║   ██║   ██╔══╝  ██║╚██╗██║   ██║
+//  ██║     ██║███████╗███████╗    ╚██████╗╚██████╔╝██║ ╚████║   ██║   ███████╗██║ ╚████║   ██║
+//  ╚═╝     ╚═╝╚══════╝╚══════╝     ╚═════╝ ╚═════╝ ╚═╝  ╚═══╝   ╚═╝   ╚══════╝╚═╝  ╚═══╝   ╚═╝
+//
+//   ██████╗██████╗ ███████╗ █████╗ ████████╗██╗ ██████╗ ███╗   ██╗    ██╗███████╗
+//  ██╔════╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗  ██║    ██║██╔════╝
+//  ██║     ██████╔╝█████╗  ███████║   ██║   ██║██║   ██║██╔██╗ ██║    ██║███████╗
+//  ██║     ██╔══██╗██╔══╝  ██╔══██║   ██║   ██║██║   ██║██║╚██╗██║    ██║╚════██║
+//  ╚██████╗██║  ██║███████╗██║  ██║   ██║   ██║╚██████╔╝██║ ╚████║    ██║███████║
+//   ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝    ╚═╝╚══════╝
+//
+//   █████╗ ██╗   ██╗████████╗ ██████╗ ███╗   ███╗ █████╗ ████████╗███████╗██████╗
+//  ██╔══██╗██║   ██║╚══██╔══╝██╔═══██╗████╗ ████║██╔══██╗╚══██╔══╝██╔════╝██╔══██╗
+//  ███████║██║   ██║   ██║   ██║   ██║██╔████╔██║███████║   ██║   █████╗  ██║  ██║
+//  ██╔══██║██║   ██║   ██║   ██║   ██║██║╚██╔╝██║██╔══██║   ██║   ██╔══╝  ██║  ██║
+//  ██║  ██║╚██████╔╝   ██║   ╚██████╔╝██║ ╚═╝ ██║██║  ██║   ██║   ███████╗██████╔╝██╗
+//  ╚═╝  ╚═╝ ╚═════╝    ╚═╝    ╚═════╝ ╚═╝     ╚═╝╚═╝  ╚═╝   ╚═╝   ╚══════╝╚═════╝ ╚═╝
+// Generated At: @TIMESTAMP@
+
+#include <array>
+#include <cstdint>
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "pecunia_export.h"
+
+
+namespace pecunia
+{
+namespace currency
+{
+
+/**
+ * @brief The unique identifier for a country's currency, monetary market, etc..
+ *
+ * @see ISO 4217 https://en.wikipedia.org/wiki/ISO_4217
+ */
+enum class PECUNIA_EXPORT Iso4217Codes : std::uint16_t
+{
+@ENUM_CODES@
+};
+
+/**
+ * @brief Converts from a strongly-typed ISO code to a weak string form.
+ *
+ * @param[in] code The country's monetary unit whose ISO code is to be converted.
+ *
+ * @return The weak type form of the ISO code.
+ */
+PECUNIA_EXPORT std::string toStdString(const Iso4217Codes& code);
+/**
+ * @brief Converts from a weakly-typed ISO code to the strongly-typed form. The code must be all
+ * upper-cased for the match to be performed.
+ *
+ * @exception std::runtime_error When the supplied weak code does not match any known strong code.
+ *
+ * @param[in] code The country's monetary unit whose ISO code is to be converted.
+ *
+ * @return The strong type form of the ISO code.
+ */
+PECUNIA_EXPORT Iso4217Codes toIso4217Code(const std::string& code);
+/**
+ * @brief Provides the native currency symbol used by a currency code. N.B. currency symbols are
+ * shared by others and are therefore cannot be unique.
+ *
+ * @note Currently not all codes are supported.
+ *
+ * @param[in] code The country's monetary unit whose currency symbol is desired.
+ *
+ * @return The string representation of the currency symbol.
+ */
+PECUNIA_EXPORT std::string currencySymbol(const Iso4217Codes& code);
+/**
+ * @brief Provides the number of digits used by the minor currency unit using the currency's
+ * ISO exponent.
+ *
+ * @param[in] code The country's monetary unit whose number of digits is desired.
+ *
+ * @return The number of digits used by the minor currency unit.
+ */
+PECUNIA_EXPORT std::uint8_t minorUnitDigits(const Iso4217Codes& code);
+/**
+ * @brief Calculates the currency factor between the major unit and the minor unit accounting for
+ * the system precision of the minor monetary unit. The precision is in terms of how many extra
+ * digits to add for the minor unit, e.g. USD starts with 2 and a precision of 2 would provide
+ * for a total precision of 4 digits.
+ *
+ * @param[in] code The country's monetary unit to calculate the ratio for.
+ *
+ * @return The multiplicative factor between the major and minor unit with a supplied precision.
+ */
+PECUNIA_EXPORT std::int32_t minorUnitPrecisionFactor(const Iso4217Codes& code);
+/**
+* @brief Performs the stream insertion for displaying the currency code in the ISO-4217 form.
+*
+* @param stream The stream into which the code should be inserted.
+* @param code The code that will be inserted.
+*
+* @return The same stream that was supplied, but now containing the code.
+*/
+PECUNIA_EXPORT std::ostream& operator<<(std::ostream& stream, const Iso4217Codes& code);
+/**
+ * @brief Looks-up the countries which are using a given currency.
+ *
+ * @param code The code of the currency to look-up for all the countries.
+ *
+ * @return All the countries found.
+ */
+PECUNIA_EXPORT std::vector<std::string> countriesUsing(const Iso4217Codes& code);
+/**
+ * @brief Looks-up the name of a currency using a given currency code.
+ *
+ * @param code The code of the currency to look-up for its name.
+ *
+ * @return The name of the currency in English.
+ */
+PECUNIA_EXPORT std::string currencyName(const Iso4217Codes& code);
+
+/// The total number of currency codes supported.
+constexpr std::uint8_t numberOfIso4217Codes{@NUMBER_OF_CODES@};
+/// A container of every currency code supported. The codes are all other codes in alphabetical
+/// order.
+extern PECUNIA_EXPORT const std::array<Iso4217Codes, numberOfIso4217Codes> allIso4217Codes;
+
+}}
+
+#endif
--- a/src/unit-tests/CMakeLists.txt	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/unit-tests/CMakeLists.txt	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 #*******************************************************************************
 #**  This file is part of Pecunia.                                           ***
 #**                                                                          ***
-#**  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+#**  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 #**  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 #**                                                                          ***
 #**  This program is free software: you can redistribute it and/or modify it ***
@@ -17,7 +17,7 @@
 #**  You should have received a copy of the GNU Lesser General Public License***
 #**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
 #*******************************************************************************
-cmake_minimum_required (VERSION 3.0 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
 project(pecunia-unit-tests)
 
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
@@ -30,15 +30,24 @@
 	set(Test_File_Name "${testName}-unit-tests")
 
 	add_executable(${Test_Project_Name} ${Test_File_Name}.cpp)
-	target_link_libraries(${Test_Project_Name} pecunia)
-	target_link_libraries(${Test_Project_Name} Qt5::Test)
+	# Adds the includes for the auto-generated files.
+	target_include_directories(${Test_Project_Name}
+		PRIVATE
+			$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>/..
+			$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>/../external
+			$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>/../external/pecunia
+	)
+	target_link_libraries(${Test_Project_Name} PRIVATE pecunia)
+	target_link_libraries(${Test_Project_Name} PRIVATE Qt5::Test)
 	add_test(
 		NAME ${Test_Project_Name}
 		COMMAND "${testName}-tests"
 		WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
 	)
-	include_directories(../../src)
-	remove_definitions(-DPECUNIA_EXPORT)
+	configure_file(
+		"${CMAKE_SOURCE_DIR}/src/project.vcxproj.user.in"
+		${PROJECT_BINARY_DIR}/${Test_Project_Name}.vcxproj.user @ONLY
+	)
 
 	unset(Test_Project_Name)
 	unset(Test_File_Name)
--- a/src/unit-tests/algorithm-unit-tests.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/unit-tests/algorithm-unit-tests.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 /*******************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -34,7 +34,7 @@
 #include <pecunia/Algorithm.hpp>
 using pecunia::sort;
 #include <pecunia/Codes.h>
-using pecunia ::currency::Codes;
+using pecunia ::currency::Iso4217Codes;
 #include <pecunia/Money.h>
 using pecunia::FloatingPoint;
 using pecunia::currency::Money;
@@ -51,7 +51,7 @@
 #endif
 };
 
-FloatingPoint testConverter(const Codes from, const Codes to)
+FloatingPoint testConverter(const Iso4217Codes& from, const Iso4217Codes& to)
 {
 	/*
 	 1 PLN = 0.238928 USD
@@ -66,52 +66,52 @@
 
 	switch (from)
 	{
-	case Codes::EUR:
+	case Iso4217Codes::EUR:
 		switch (to)
 		{
-		case Codes::XXX:
-		case Codes::EUR:
+		case Iso4217Codes::XXX:
+		case Iso4217Codes::EUR:
 			return 1.0;
-		case Codes::PLN:
+		case Iso4217Codes::PLN:
 			qDebug() << "EUR->PLN" << 4.44702;
 			return 4.44702;
-		case Codes::USD:
+		case Iso4217Codes::USD:
 			qDebug() << "EUR->USD" << 1.06252;
 			return 1.06252;
 		default:
 			throw runtime_error{"Unknown to currency."};
 		};
-	case Codes::PLN:
+	case Iso4217Codes::PLN:
 		switch (to)
 		{
-		case Codes::EUR:
+		case Iso4217Codes::EUR:
 			qDebug() << "PLN->EUR" << 0.22487;
 			return 0.22487;
-		case Codes::XXX:
-		case Codes::PLN:
+		case Iso4217Codes::XXX:
+		case Iso4217Codes::PLN:
 			return 1.0;
-		case Codes::USD:
+		case Iso4217Codes::USD:
 			qDebug() << "PLN->USD" << 0.238928;
 			return 0.238928;
 		default:
 			throw runtime_error{"Unknown to currency."};
 		};
-	case Codes::USD:
+	case Iso4217Codes::USD:
 		switch (to)
 		{
-		case Codes::EUR:
+		case Iso4217Codes::EUR:
 			qDebug() << "USD->EUR" << 0.941161;
 			return 0.941161;
-		case Codes::PLN:
+		case Iso4217Codes::PLN:
 			qDebug() << "USD->PLN" << 4.18536;
 			return 4.18536;
-		case Codes::XXX:
-		case Codes::USD:
+		case Iso4217Codes::XXX:
+		case Iso4217Codes::USD:
 			return 1.0;
 		default:
 			throw runtime_error{"Unknown to currency."};
 		};
-	case Codes::XXX:
+	case Iso4217Codes::XXX:
 		return 1.0;
 	default:
 		throw runtime_error{"Unknown from currency."};
@@ -146,7 +146,7 @@
 
 	void sort_oneElement_ShouldBeSorted()
 	{
-		const Money m0{30, 0u, Codes::USD};
+		const Money m0{30, 0u, Iso4217Codes::USD};
 		vector<Money> monies{{m0}};
 		sort(monies);
 		QCOMPARE(monies.at(0), m0);
@@ -154,8 +154,8 @@
 
 	void sort_twoElements_ShouldBeSorted()
 	{
-		const Money m0{30, 0u, Codes::USD};
-		const Money m1{10, 0u, Codes::USD};
+		const Money m0{30, 0u, Iso4217Codes::USD};
+		const Money m1{10, 0u, Iso4217Codes::USD};
 		vector<Money> monies{{m0, m1}};
 		sort(monies);
 		QCOMPARE(monies.at(0), m1);
@@ -164,12 +164,12 @@
 
 	void sort_sameCurrencyValuesUnsorted_ShouldBeSorted()
 	{
-		const Money m0{30, 0u, Codes::USD};
-		const Money m1{10, 0u, Codes::USD};
-		const Money m2{20, 0u, Codes::USD};
-		const Money m3{60, 0u, Codes::USD};
-		const Money m4{40, 0u, Codes::USD};
-		const Money m5{50, 0u, Codes::USD};
+		const Money m0{30, 0u, Iso4217Codes::USD};
+		const Money m1{10, 0u, Iso4217Codes::USD};
+		const Money m2{20, 0u, Iso4217Codes::USD};
+		const Money m3{60, 0u, Iso4217Codes::USD};
+		const Money m4{40, 0u, Iso4217Codes::USD};
+		const Money m5{50, 0u, Iso4217Codes::USD};
 		vector<Money> monies{{m0, m1, m2, m3, m4, m5}};
 		sort(monies);
 		QCOMPARE(monies.at(0), m1);
@@ -182,15 +182,15 @@
 
 	void sort_sameCurrencyValuesUnsortedWithDuplicates_ShouldBeSorted()
 	{
-		const Money m0{30, 0u, Codes::USD};
-		const Money m1{30, 0u, Codes::USD};
-		const Money m2{10, 0u, Codes::USD};
-		const Money m3{20, 0u, Codes::USD};
-		const Money m4{20, 0u, Codes::USD};
-		const Money m5{60, 0u, Codes::USD};
-		const Money m6{40, 0u, Codes::USD};
-		const Money m7{50, 0u, Codes::USD};
-		const Money m8{40, 0u, Codes::USD};
+		const Money m0{30, 0u, Iso4217Codes::USD};
+		const Money m1{30, 0u, Iso4217Codes::USD};
+		const Money m2{10, 0u, Iso4217Codes::USD};
+		const Money m3{20, 0u, Iso4217Codes::USD};
+		const Money m4{20, 0u, Iso4217Codes::USD};
+		const Money m5{60, 0u, Iso4217Codes::USD};
+		const Money m6{40, 0u, Iso4217Codes::USD};
+		const Money m7{50, 0u, Iso4217Codes::USD};
+		const Money m8{40, 0u, Iso4217Codes::USD};
 		vector<Money> monies{{m0, m1, m2, m3, m4, m5, m6, m7, m8}};
 		sort(monies);
 		QCOMPARE(monies.at(0), m2);
@@ -204,41 +204,59 @@
 		QCOMPARE(monies.at(8), m5);
 	}
 
+	void sort_sameCurrencyValuesUnsortedReversed_ShouldBeSorted()
+	{
+		const Money m0{60, 0u, Iso4217Codes::USD};
+		const Money m1{50, 0u, Iso4217Codes::USD};
+		const Money m2{40, 0u, Iso4217Codes::USD};
+		const Money m3{30, 0u, Iso4217Codes::USD};
+		const Money m4{20, 0u, Iso4217Codes::USD};
+		const Money m5{10, 0u, Iso4217Codes::USD};
+		vector<Money> monies{{m0, m1, m2, m3, m4, m5}};
+		sort(monies);
+		QCOMPARE(monies.at(0), m5);
+		QCOMPARE(monies.at(1), m4);
+		QCOMPARE(monies.at(2), m3);
+		QCOMPARE(monies.at(3), m2);
+		QCOMPARE(monies.at(4), m1);
+		QCOMPARE(monies.at(5), m0);
+	}
+
 	void sort_mixedCurrencyValuesUnsorted_ShouldBeSortedAndKeepCurrency()
 	{
-		const Money m0{30, 0u, Codes::USD};
-		const Money m1{36, 8600u, Codes::PLN}; // Converted 10 USD
-		const Money m2{16, 5000u, Codes::EUR}; // Converted 20 USD
+		const Money m0{30, 0u, Iso4217Codes::USD};
+		const Money m1{36, 8600u, Iso4217Codes::PLN}; // Converted 10 USD
+		const Money m2{16, 5000u, Iso4217Codes::EUR}; // Converted 20 USD
 		vector<Money> monies{{m0, m1, m2}};
 		sort(monies);
 		QCOMPARE(monies.at(0), m1);
-		QCOMPARE(monies.at(0).code(), Codes::PLN);
+		QCOMPARE(monies.at(0).code(), Iso4217Codes::PLN);
 		QCOMPARE(monies.at(1), m2);
-		QCOMPARE(monies.at(1).code(), Codes::EUR);
+		QCOMPARE(monies.at(1).code(), Iso4217Codes::EUR);
 		QCOMPARE(monies.at(2), m0);
-		QCOMPARE(monies.at(2).code(), Codes::USD);
+		QCOMPARE(monies.at(2).code(), Iso4217Codes::USD);
 	}
 
 	void sort_mixedCurrencyValuesSorted_ShouldBeSortedAndKeepCurrency()
 	{
-		const Money m0{36, 8600u, Codes::PLN}; // Converted 10 USD
-		const Money m1{16, 5000u, Codes::EUR}; // Converted 20 USD
-		const Money m2{30, 0u, Codes::USD};
+		const Money m0{36, 8600u, Iso4217Codes::PLN}; // Converted 10 USD
+		const Money m1{16, 5000u, Iso4217Codes::EUR}; // Converted 20 USD
+		const Money m2{30, 0u, Iso4217Codes::USD};
 		vector<Money> monies{{m0, m1, m2}};
 		sort(monies);
 		QCOMPARE(monies.at(0), m0);
-		QCOMPARE(monies.at(0).code(), Codes::PLN);
+		QCOMPARE(monies.at(0).code(), Iso4217Codes::PLN);
 		QCOMPARE(monies.at(1), m1);
-		QCOMPARE(monies.at(1).code(), Codes::EUR);
+		QCOMPARE(monies.at(1).code(), Iso4217Codes::EUR);
 		QCOMPARE(monies.at(2), m2);
-		QCOMPARE(monies.at(2).code(), Codes::USD);
+		QCOMPARE(monies.at(2).code(), Iso4217Codes::USD);
 	}
 
 	void sort_sameValuesSorted_ShouldBeSorted()
 	{
-		const Money m0{10, 0u, Codes::USD};
-		const Money m1{10, 0u, Codes::USD};
-		const Money m2{10, 0u, Codes::USD};
+		const Money m0{10, 0u, Iso4217Codes::USD};
+		const Money m1{10, 0u, Iso4217Codes::USD};
+		const Money m2{10, 0u, Iso4217Codes::USD};
 		vector<Money> monies{{m0, m1, m2}};
 		sort(monies);
 		QCOMPARE(monies.at(0), m0);
--- a/src/unit-tests/codes-unit-tests.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/unit-tests/codes-unit-tests.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 /*******************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -17,12 +17,28 @@
 ***  You should have received a copy of the GNU Lesser General Public License***
 ***  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
 *******************************************************************************/
+#include <QObject>
+using ::QObject;
 #include <QTest>
+// using QTEST_MAIN;
 
-#include <cstdint>
+#include <exception>
+using std::exception;
 #include <string>
+using std::string;
+#include <vector>
+using std::vector;
 
 #include <pecunia/Codes.h>
+using pecunia::currency::allIso4217Codes;
+using pecunia::currency::Iso4217Codes;
+using pecunia::currency::countriesUsing;
+using pecunia::currency::currencyName;
+using pecunia::currency::minorUnitPrecisionFactor;
+using pecunia::currency::numberOfIso4217Codes;
+using pecunia::currency::toStdString;
+using pecunia::currency::toIso4217Code;
+using pecunia::currency::currencySymbol;
 
 
 namespace pecunia
@@ -37,87 +53,145 @@
 	Q_OBJECT
 
 private slots:
-	//{ toIso4217 unit tests
+	//{ toStdString tests
 
-	void toIso4217_XXX_ShouldBeXXX()
+	void toStdString_XXX_ShouldBeXXX()
 	{
-		std::string iso4217{currency::toIso4217(currency::Codes::XXX)};
-		QCOMPARE(iso4217.c_str(), std::string{"XXX"}.c_str());
+		string iso4217{toStdString(Iso4217Codes::XXX)};
+		QCOMPARE(iso4217.c_str(), string{"XXX"}.c_str());
 	}
-	void toIso4217_USD_ShouldBeUSD()
+	void toStdString_USD_ShouldBeUSD()
 	{
-		std::string iso4217{currency::toIso4217(currency::Codes::USD)};
-		QCOMPARE(iso4217.c_str(), std::string{"USD"}.c_str());
+		string iso4217{toStdString(Iso4217Codes::USD)};
+		QCOMPARE(iso4217.c_str(), string{"USD"}.c_str());
 	}
-	void toIso4217_PLN_ShouldBePLN()
+	void toStdString_PLN_ShouldBePLN()
 	{
-		std::string iso4217{currency::toIso4217(currency::Codes::PLN)};
-		QCOMPARE(iso4217.c_str(), std::string{"PLN"}.c_str());
+		string iso4217{toStdString(Iso4217Codes::PLN)};
+		QCOMPARE(iso4217.c_str(), string{"PLN"}.c_str());
 	}
 
 	//}
 
-	//{ minorUnitPrecisionFactor unit tests
+	//{ minorUnitPrecisionFactor tests
 
 	void minorUnitPrecisionFactorXxxPrecision2_ShouldBe100()
 	{
-		const auto ratio(currency::minorUnitPrecisionFactor(currency::Codes::XXX));
+		const auto ratio(minorUnitPrecisionFactor(Iso4217Codes::XXX));
 		// 0 for minor and 2 for precision.
 		QCOMPARE(ratio, 100);
 	}
 	void minorUnitPrecisionFactorUsdPrecision2_ShouldBe10000()
 	{
-		const auto ratio(currency::minorUnitPrecisionFactor(currency::Codes::USD));
+		const auto ratio(minorUnitPrecisionFactor(Iso4217Codes::USD));
 		// 2 for minor and 2 for precision.
 		QCOMPARE(ratio, 10000);
 	}
 
 	//}
 
-	//{ toSymbol unit tests
+	//{ currencySymbol tests
 
-	void toSymbol_XXX_ShouldBeEmpty()
+	void currencySymbol_USD_ShouldBeDollarSign()
 	{
-		std::string iso4217{currency::toSymbol(currency::Codes::XXX)};
-		QCOMPARE(iso4217.c_str(), "");
+		string iso4217{currencySymbol(Iso4217Codes::USD)};
+		QCOMPARE(iso4217.c_str(), string{"$"}.c_str());
+	}
+	void currencySymbol_PLN_ShouldBeZloty()
+	{
+		string iso4217{currencySymbol(Iso4217Codes::PLN)};
+		QCOMPARE(iso4217.c_str(), string{"zł"}.c_str());
 	}
-	void toSymbol_USD_ShouldBeDollarSign()
+
+	//}
+
+	//{ toIso4217Code tests
+
+	void toIso4217Code_XXX_ShouldBeNoCurrencyInvolved()
 	{
-		std::string iso4217{currency::toSymbol(currency::Codes::USD)};
-		QCOMPARE(iso4217.c_str(), std::string{"$"}.c_str());
+		Iso4217Codes iso4217{toIso4217Code("XXX")};
+		QCOMPARE(iso4217, Iso4217Codes::XXX);
 	}
-	void toSymbol_PLN_ShouldBeZloty()
+	void toIso4217Code_USD_ShouldBeDollarSign()
+	{
+		Iso4217Codes iso4217{toIso4217Code("USD")};
+		QCOMPARE(iso4217, Iso4217Codes::USD);
+	}
+	void toIso4217Code_PLN_ShouldBeZloty()
 	{
-		std::string iso4217{currency::toSymbol(currency::Codes::PLN)};
-		QCOMPARE(iso4217.c_str(), std::string{"zł"}.c_str());
+		Iso4217Codes iso4217{toIso4217Code("PLN")};
+		QCOMPARE(iso4217, Iso4217Codes::PLN);
+	}
+	void toIso4217Code_Invalid_ShouldThrow()
+	{
+		QVERIFY_EXCEPTION_THROWN(toIso4217Code("I am a fake code"), std::runtime_error);
+	}
+	void toIso4217Code_usd_ShouldThrow()
+	{
+		QVERIFY_EXCEPTION_THROWN(toIso4217Code("usd"), std::runtime_error);
 	}
 
 	//}
 
-	//{ toCode unit tests
+	//{ allCodes tests
 
-	void toCode_XXX_ShouldBeEmpty()
+	void allCodes_InterateThroughAll_ShouldNotThrow()
+	{
+		for (size_t index{0}; index < numberOfIso4217Codes; ++index)
+			Q_UNUSED(allIso4217Codes.at(index))
+	}
+
+	void allCodes_PastLastOne_ShouldThrow()
 	{
-		currency::Codes iso4217{currency::toCode("XXX")};
-		QCOMPARE(iso4217, currency::Codes::XXX);
-	}
-	void toCode_USD_ShouldBeDollarSign()
-	{
-		currency::Codes iso4217{currency::toCode("USD")};
-		QCOMPARE(iso4217, currency::Codes::USD);
+		try
+		{
+			Q_UNUSED(allIso4217Codes.at(numberOfIso4217Codes));
+			QVERIFY2(false, "Expected exception did not throw.");
+		}
+		catch (const exception&)
+		{
+			QVERIFY(true);
+		}
 	}
-	void toCode_PLN_ShouldBeZloty()
+
+	//}
+
+	//{ countriesUsing tests
+
+	void countriesUsing_knownCurrency_ShouldGive()
 	{
-		currency::Codes iso4217{currency::toCode("PLN")};
-		QCOMPARE(iso4217, currency::Codes::PLN);
+		const vector<string> expected{
+			"AMERICAN SAMOA",
+			"BONAIRE, SINT EUSTATIUS AND SABA",
+			"BRITISH INDIAN OCEAN TERRITORY (THE)",
+			"ECUADOR",
+			"EL SALVADOR",
+			"GUAM",
+			"HAITI",
+			"MARSHALL ISLANDS (THE)",
+			"MICRONESIA (FEDERATED STATES OF)",
+			"NORTHERN MARIANA ISLANDS (THE)",
+			"PALAU",
+			"PANAMA",
+			"PUERTO RICO",
+			"TIMOR-LESTE",
+			"TURKS AND CAICOS ISLANDS (THE)",
+			"UNITED STATES MINOR OUTLYING ISLANDS (THE)",
+			"UNITED STATES OF AMERICA (THE)",
+			"VIRGIN ISLANDS (BRITISH)",
+			"VIRGIN ISLANDS (U.S.)"
+		};
+		QCOMPARE(countriesUsing(Iso4217Codes::USD), expected);
 	}
-	void toCode_Invalid_ShouldThrow()
+
+	//}
+
+	//{ currencyName tests
+
+	void currencyName_knownCurrency_ShouldGive()
 	{
-		QVERIFY_EXCEPTION_THROWN(currency::toCode("I am a fake code"), std::runtime_error);
-	}
-	void toCode_Usd_ShouldThrow()
-	{
-		QVERIFY_EXCEPTION_THROWN(currency::toCode("usd"), std::runtime_error);
+		const string expected{"US Dollar"};
+		QCOMPARE(currencyName(Iso4217Codes::USD), expected);
 	}
 
 	//}
--- a/src/unit-tests/conversion-unit-tests.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/unit-tests/conversion-unit-tests.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 /*******************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -26,7 +26,7 @@
 using std::overflow_error;
 
 #include <pecunia/Codes.h>
-using pecunia::currency::Codes;
+using pecunia::currency::Iso4217Codes;
 #include <pecunia/Conversion.h>
 using pecunia::toMinorUnit;
 #include <pecunia/MoneyTypes.h>
@@ -47,22 +47,22 @@
 
 	void toMinorUnit_validValue_ShouldConvert()
 	{
-		QCOMPARE(toMinorUnit(25, Codes::USD), static_cast<MinorUnit>(2500));
+		QCOMPARE(toMinorUnit(25, Iso4217Codes::USD), static_cast<MinorUnit>(2500));
 	}
 
 	void toMinorUnit_minimumValue_ShouldConvert()
 	{
-		QCOMPARE(toMinorUnit(0, Codes::USD), static_cast<MinorUnit>(0));
+		QCOMPARE(toMinorUnit(0, Iso4217Codes::USD), static_cast<MinorUnit>(0));
 	}
 
 	void toMinorUnit_maximumValue_ShouldConvert()
 	{
-		QCOMPARE(toMinorUnit(99, Codes::USD), static_cast<MinorUnit>(9900));
+		QCOMPARE(toMinorUnit(99, Iso4217Codes::USD), static_cast<MinorUnit>(9900));
 	}
 
 	void toMinorUnit_toLargeValue_ShouldThrow()
 	{
-		QVERIFY_EXCEPTION_THROWN(toMinorUnit(100, Codes::USD), overflow_error);
+		QVERIFY_EXCEPTION_THROWN(toMinorUnit(100, Iso4217Codes::USD), overflow_error);
 	}
 
 	//}
--- a/src/unit-tests/math-unit-tests.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/unit-tests/math-unit-tests.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 /*******************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -36,10 +36,10 @@
 using std::vector;
 
 #include <pecunia/Codes.h>
-using pecunia::currency::Codes;
+using pecunia::currency::Iso4217Codes;
 #include <pecunia/Math.h>
-using pecunia::math::abs;
-using pecunia::math::accumulate;
+using pecunia::math::absoluteValue;
+using pecunia::math::sum;
 #include <pecunia/Money.h>
 using pecunia::currency::Money;
 #include <pecunia/MoneyTypes.h>
@@ -49,7 +49,7 @@
 namespace
 {
 
-FloatingPoint testConverter(const Codes from, const Codes to)
+FloatingPoint testConverter(const Iso4217Codes& from, const Iso4217Codes& to)
 {
 	/*
 	 1 PLN = 0.238928 USD
@@ -64,52 +64,52 @@
 
 	switch (from)
 	{
-	case Codes::EUR:
+	case Iso4217Codes::EUR:
 		switch (to)
 		{
-		case Codes::XXX:
-		case Codes::EUR:
+		case Iso4217Codes::XXX:
+		case Iso4217Codes::EUR:
 			return 1.0;
-		case Codes::PLN:
+		case Iso4217Codes::PLN:
 			qDebug() << "EUR->PLN" << 4.44702;
 			return 4.44702;
-		case Codes::USD:
+		case Iso4217Codes::USD:
 			qDebug() << "EUR->USD" << 1.06252;
 			return 1.06252;
 		default:
 			throw runtime_error{"Unknown to currency."};
 		};
-	case Codes::PLN:
+	case Iso4217Codes::PLN:
 		switch (to)
 		{
-		case Codes::EUR:
+		case Iso4217Codes::EUR:
 			qDebug() << "PLN->EUR" << 0.22487;
 			return 0.22487;
-		case Codes::XXX:
-		case Codes::PLN:
+		case Iso4217Codes::XXX:
+		case Iso4217Codes::PLN:
 			return 1.0;
-		case Codes::USD:
+		case Iso4217Codes::USD:
 			qDebug() << "PLN->USD" << 0.238928;
 			return 0.238928;
 		default:
 			throw runtime_error{"Unknown to currency."};
 		};
-	case Codes::USD:
+	case Iso4217Codes::USD:
 		switch (to)
 		{
-		case Codes::EUR:
+		case Iso4217Codes::EUR:
 			qDebug() << "USD->EUR" << 0.941161;
 			return 0.941161;
-		case Codes::PLN:
+		case Iso4217Codes::PLN:
 			qDebug() << "USD->PLN" << 4.18536;
 			return 4.18536;
-		case Codes::XXX:
-		case Codes::USD:
+		case Iso4217Codes::XXX:
+		case Iso4217Codes::USD:
 			return 1.0;
 		default:
 			throw runtime_error{"Unknown to currency."};
 		};
-	case Codes::XXX:
+	case Iso4217Codes::XXX:
 		return 1.0;
 	default:
 		throw runtime_error{"Unknown from currency."};
@@ -130,120 +130,142 @@
 	Q_OBJECT
 
 private slots:
-	//{ abs Tests
+	//{ absoluteValue Tests
 
-	void abs_Positive_ShouldBeSame()
+	void absoluteValue_Positive_ShouldBeSame()
 	{
-		const Money sm{100, 23u, Codes::XXX};
-		const auto actual{abs(sm)};
-		const Money expected{100, 23u, Codes::XXX};
+		const Money sm{100, 23u, Iso4217Codes::XXX};
+		const auto actual{absoluteValue(sm)};
+		const Money expected{100, 23u, Iso4217Codes::XXX};
 		QCOMPARE(actual, expected);
 	}
-	void abs_Negative_ShouldBePositive()
+	void absoluteValue_Negative_ShouldBePositive()
 	{
-		const Money sm{-100, 23u, Codes::XXX};
-		const auto actual{abs(sm)};
-		const Money expected{100, 23u, Codes::XXX};
+		const Money sm{-100, 23u, Iso4217Codes::XXX};
+		const auto actual{absoluteValue(sm)};
+		const Money expected{100, 23u, Iso4217Codes::XXX};
 		QCOMPARE(actual, expected);
 	}
 
 	//}
 
-	//{ accumulate Tests
+	//{ sum Tests
 
-	void accumulate_SameCurrencies_ShouldBeTotal()
+	void sum_Empty_ShouldBeTotal()
+	{
+		const vector<Money> monies{};
+		const Money actual{sum(Iso4217Codes::XXX, monies)};
+		QCOMPARE(actual, Money(0, 0u, Iso4217Codes::XXX));
+		QCOMPARE(actual.code(), Iso4217Codes::XXX);
+	}
+	void sum_SameCurrencies_ShouldBeTotal()
 	{
 		const vector<Money> monies{
-			{100, 15u, Codes::XXX},
-			{100, 15u, Codes::XXX},
-			{100, 15u, Codes::XXX}
+			{100, 15u, Iso4217Codes::XXX},
+			{100, 15u, Iso4217Codes::XXX},
+			{100, 15u, Iso4217Codes::XXX}
 		};
-		const Money actual{accumulate(Codes::XXX, monies)};
-		QCOMPARE(actual, Money(300, 45u, Codes::XXX));
+		const Money actual{sum(Iso4217Codes::XXX, monies)};
+		QCOMPARE(actual, Money(300, 45u, Iso4217Codes::XXX));
+		QCOMPARE(actual.code(), Iso4217Codes::XXX);
 	}
-	void accumulate_SameCurrenciesWithFunctor_ShouldBeTotalDoubled()
+	void sum_SameCurrenciesWithDoublingFunctor_ShouldBeTotalDoubled()
 	{
 		const vector<Money> monies{
-			{100, 15u, Codes::XXX},
-			{100, 15u, Codes::XXX},
-			{100, 15u, Codes::XXX}
+			{100, 15u, Iso4217Codes::XXX},
+			{100, 15u, Iso4217Codes::XXX},
+			{100, 15u, Iso4217Codes::XXX}
 		};
 		const Money actual{
-			accumulate(Codes::XXX, monies, [] (const auto& money) { return money * 2; })
+			sum(Iso4217Codes::XXX, monies, [] (const auto& money) { return money * 2; })
 		};
-		QCOMPARE(actual, Money(600, 90u, Codes::XXX));
+		QCOMPARE(actual, Money(600, 90u, Iso4217Codes::XXX));
+		QCOMPARE(actual.code(), Iso4217Codes::XXX);
 	}
-	void accumulate_DifferentCurrenciesSharedOneAccumulator_ShouldBeTotal()
+	void sum_DifferentCurrenciesSharedOneAccumulator_ShouldBeTotal()
 	{
 		pecunia::converter = testConverter;
 		const vector<Money> monies{
-			{100, 1500u, Codes::USD},
-			{100, 1500u, Codes::EUR},
-			{100, 1500u, Codes::USD}
+			{100, 1500u, Iso4217Codes::USD},
+			{100, 1500u, Iso4217Codes::EUR},
+			{100, 1500u, Iso4217Codes::USD}
 		};
-		const Money actual{accumulate(Codes::EUR, monies)};
+		const Money actual{sum(Iso4217Codes::EUR, monies)};
 		// 200,30 USD -> 188,5145483 EUR
 		//            -> 100,1500 EUR
-		QCOMPARE(actual, Money(288, 6645u, Codes::EUR));
+		QCOMPARE(actual, Money(288, 6645u, Iso4217Codes::EUR));
+		QCOMPARE(actual.code(), Iso4217Codes::EUR);
 	}
-	void accumulate_DifferentCurrenciesDifferentAccumulator_ShouldBeTotal()
+	void sum_DifferentCurrenciesDifferentAccumulator_ShouldBeTotal()
 	{
 		const vector<Money> monies{
-			{100, 1500u, Codes::USD},
-			{100, 1500u, Codes::EUR},
-			{100, 1500u, Codes::USD}
+			{100, 1500u, Iso4217Codes::USD},
+			{100, 1500u, Iso4217Codes::EUR},
+			{100, 1500u, Iso4217Codes::USD}
 		};
-		const Money actual{accumulate(Codes::PLN, monies)};
+		const Money actual{sum(Iso4217Codes::PLN, monies)};
 		// 200,30 USD -> 838,327608 PLN
 		// 100,15 USD -> 445,369053 PLN
-		QCOMPARE(actual, Money(1283, 6966u, Codes::PLN));
+		QCOMPARE(actual, Money(1283, 6966u, Iso4217Codes::PLN));
+		QCOMPARE(actual.code(), Iso4217Codes::PLN);
 	}
-	void accumulate_AssociativeContainerSameCurrencies_ShouldBeTotal()
+	void sum_AssociativeContainerEmpty_ShouldBeTotal()
+	{
+		const map<qint32, Money> monies{};
+		const Money actual{sum(Iso4217Codes::XXX, monies)};
+		QCOMPARE(actual, Money(0, 0u, Iso4217Codes::XXX));
+		QCOMPARE(actual.code(), Iso4217Codes::XXX);
+	}
+	void sum_AssociativeContainerSameCurrencies_ShouldBeTotal()
 	{
 		const map<qint32, Money> monies{
-			{1, {100, 15u, Codes::XXX}},
-			{2, {100, 15u, Codes::XXX}},
-			{3, {100, 15u, Codes::XXX}}
+			{1, {100, 15u, Iso4217Codes::XXX}},
+			{2, {100, 15u, Iso4217Codes::XXX}},
+			{3, {100, 15u, Iso4217Codes::XXX}}
 		};
-		const Money actual{accumulate(Codes::XXX, monies)};
-		QCOMPARE(actual, Money(300, 45u, Codes::XXX));
+		const Money actual{sum(Iso4217Codes::XXX, monies)};
+		QCOMPARE(actual, Money(300, 45u, Iso4217Codes::XXX));
+		QCOMPARE(actual.code(), Iso4217Codes::XXX);
 	}
-	void accumulate_AssociativeContainerSameCurrenciesWithFunctor_ShouldBeTotalDoubled()
+	void sum_AssociativeContainerSameCurrenciesWithFunctor_ShouldBeTotalDoubled()
 	{
 		const map<qint32, Money> monies{
-			{1, {100, 15u, Codes::XXX}},
-			{2, {100, 15u, Codes::XXX}},
-			{3, {100, 15u, Codes::XXX}}
+			{1, {100, 15u, Iso4217Codes::XXX}},
+			{2, {100, 15u, Iso4217Codes::XXX}},
+			{3, {100, 15u, Iso4217Codes::XXX}}
 		};
 		const Money actual{
-			accumulate(Codes::XXX, monies, [] (const auto& money) { return money * 2; })
+			sum(Iso4217Codes::XXX, monies, [] (const auto& money) { return money * 2; })
 		};
-		QCOMPARE(actual, Money(600, 90u, Codes::XXX));
+		QCOMPARE(actual, Money(600, 90u, Iso4217Codes::XXX));
+		QCOMPARE(actual.code(), Iso4217Codes::XXX);
 	}
-	void accumulate_AssociativeContainerDifferentCurrenciesSharedOneAccumulator_ShouldBeTotal()
+	void sum_AssociativeContainerDifferentCurrenciesSharedOneAccumulator_ShouldBeTotal()
 	{
 		pecunia::converter = testConverter;
 		const map<qint32, Money> monies{
-			{1, {100, 1500u, Codes::USD}},
-			{2, {100, 1500u, Codes::EUR}},
-			{3, {100, 1500u, Codes::USD}}
+			{1, {100, 1500u, Iso4217Codes::USD}},
+			{2, {100, 1500u, Iso4217Codes::EUR}},
+			{3, {100, 1500u, Iso4217Codes::USD}}
 		};
-		const Money actual{accumulate(Codes::EUR, monies)};
+		const Money actual{sum(Iso4217Codes::EUR, monies)};
 		// 200,30 USD -> 188,5145483 EUR
 		//            -> 100,1500 EUR
-		QCOMPARE(actual, Money(288, 6645u, Codes::EUR));
+		QCOMPARE(actual, Money(288, 6645u, Iso4217Codes::EUR));
+		QCOMPARE(actual.code(), Iso4217Codes::EUR);
 	}
-	void accumulate_AssociativeContainerDifferentCurrenciesDifferentAccumulator_ShouldBeTotal()
+	void sum_AssociativeContainerDifferentCurrenciesDifferentAccumulator_ShouldBeTotal()
 	{
 		const map<qint32, Money> monies{
-			{1, {100, 1500u, Codes::USD}},
-			{2, {100, 1500u, Codes::EUR}},
-			{3, {100, 1500u, Codes::USD}}
+			{1, {100, 1500u, Iso4217Codes::USD}},
+			{2, {100, 1500u, Iso4217Codes::EUR}},
+			{3, {100, 1500u, Iso4217Codes::USD}}
 		};
-		const Money actual{accumulate(Codes::PLN, monies)};
+		const Money actual{sum(Iso4217Codes::PLN, monies)};
 		// 200,30 USD -> 838,327608 PLN
 		// 100,15 USD -> 445,369053 PLN
-		QCOMPARE(actual, Money(1283, 6966u, Codes::PLN));
+		QCOMPARE(actual, Money(1283, 6966u, Iso4217Codes::PLN));
+		QCOMPARE(actual.code(), Iso4217Codes::PLN);
 	}
 
 	//}
--- a/src/unit-tests/money-unit-tests.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/unit-tests/money-unit-tests.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 /*******************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -36,17 +36,19 @@
 #include <string>
 
 #include <pecunia/Codes.h>
-using pecunia::currency::Codes;
+using pecunia::currency::Iso4217Codes;
 #include <pecunia/Money.h>
 using pecunia::currency::Money;
 #include <pecunia/MoneyManip.h>
+#include <pecunia/MoneySize.hpp>
+using pecunia::defaultLocale;
 #include <pecunia/MoneyTypes.h>
 using pecunia::precision;
 using pecunia::UnitStorage;
 using pecunia::MinorUnit;
 using pecunia::FloatingPoint;
 #include <pecunia/Rounders.h>
-#include <pecunia/internal/config.hpp>
+#include <internal/config.hpp>
 // using FULL_VERSION
 #include <pecunia/Information.h>
 using pecunia::version;
@@ -56,15 +58,8 @@
 {
 
 const std::uint8_t smallExtraDigits{2};
-const std::string testLocale{
-#ifdef _WIN32
-	"English_United States.1251"
-#else
-	"en_US.UTF-8"
-#endif
-};
 
-FloatingPoint testConverter(const Codes from, const Codes to)
+FloatingPoint testConverter(const Iso4217Codes& from, const Iso4217Codes& to)
 {
 	/*
 	 1 PLN = 0.238928 USD
@@ -79,52 +74,52 @@
 
 	switch (from)
 	{
-	case Codes::EUR:
+	case Iso4217Codes::EUR:
 		switch (to)
 		{
-		case Codes::XXX:
-		case Codes::EUR:
+		case Iso4217Codes::XXX:
+		case Iso4217Codes::EUR:
 			return 1.0;
-		case Codes::PLN:
+		case Iso4217Codes::PLN:
 			qDebug() << "EUR->PLN" << 4.44702;
 			return 4.44702;
-		case Codes::USD:
+		case Iso4217Codes::USD:
 			qDebug() << "EUR->USD" << 1.06252;
 			return 1.06252;
 		default:
 			throw runtime_error{"Unknown to currency."};
 		};
-	case Codes::PLN:
+	case Iso4217Codes::PLN:
 		switch (to)
 		{
-		case Codes::EUR:
+		case Iso4217Codes::EUR:
 			qDebug() << "PLN->EUR" << 0.22487;
 			return 0.22487;
-		case Codes::XXX:
-		case Codes::PLN:
+		case Iso4217Codes::XXX:
+		case Iso4217Codes::PLN:
 			return 1.0;
-		case Codes::USD:
+		case Iso4217Codes::USD:
 			qDebug() << "PLN->USD" << 0.238928;
 			return 0.238928;
 		default:
 			throw runtime_error{"Unknown to currency."};
 		};
-	case Codes::USD:
+	case Iso4217Codes::USD:
 		switch (to)
 		{
-		case Codes::EUR:
+		case Iso4217Codes::EUR:
 			qDebug() << "USD->EUR" << 0.941161;
 			return 0.941161;
-		case Codes::PLN:
+		case Iso4217Codes::PLN:
 			qDebug() << "USD->PLN" << 4.18536;
 			return 4.18536;
-		case Codes::XXX:
-		case Codes::USD:
+		case Iso4217Codes::XXX:
+		case Iso4217Codes::USD:
 			return 1.0;
 		default:
 			throw runtime_error{"Unknown to currency."};
 		};
-	case Codes::XXX:
+	case Iso4217Codes::XXX:
 		return 1.0;
 	default:
 		throw runtime_error{"Unknown from currency."};
@@ -169,7 +164,7 @@
 		Money money{};
 		QCOMPARE(money.major(), static_cast<UnitStorage>(0));
 		QCOMPARE(money.minor(), static_cast<MinorUnit>(0));
-		QCOMPARE(money.code(), Codes::XXX);
+		QCOMPARE(money.code(), Iso4217Codes::XXX);
 		QVERIFY2( ! money.isPositive(), "The value should not be positive.");
 		QVERIFY2( ! money.hasAmount(), "Default constructed value is not set.");
 	}
@@ -178,7 +173,7 @@
 		Money money{
 			static_cast<UnitStorage>(9876543210),
 			static_cast<MinorUnit>(1234),
-			Codes::USD
+			Iso4217Codes::USD
 		};
 		QCOMPARE(money.major(), static_cast<UnitStorage>(9876543210));
 		QCOMPARE(money.minor(), static_cast<MinorUnit>(1234));
@@ -187,14 +182,14 @@
 	}
 	void constructorPositiveMinor_ShouldMatch()
 	{
-		Money money{0, 3300, Codes::USD}; // Two digits of precision.
+		Money money{0, 3300, Iso4217Codes::USD}; // Two digits of precision.
 		QCOMPARE(money.major(), static_cast<UnitStorage>(0));
 		QCOMPARE(money.minor(), static_cast<MinorUnit>(3300));
 		QVERIFY2(money.isPositive(), "The value should be positive.");
 	}
 	void constructorNegativeMinor_ShouldMatch()
 	{
-		Money money{3300, pecunia::MinorSign::Negative, Codes::USD};
+		Money money{pecunia::MinorSign::Negative, 3300, Iso4217Codes::USD};
 		QCOMPARE(money.major(), static_cast<UnitStorage>(0));
 		QCOMPARE(money.minor(), static_cast<MinorUnit>(3300));
 		QVERIFY2( ! money.isPositive(), "The value should be negative.");
@@ -228,20 +223,20 @@
 	}
 	void constructorFloatingPoint_ShouldMatch()
 	{
-		Money money{1.2345, Codes::USD};
+		Money money{1.2345, Iso4217Codes::USD};
 		QCOMPARE(money.major(), static_cast<UnitStorage>(1));
 		QCOMPARE(money.minor(), static_cast<MinorUnit>(2345));
 	}
 	void constructorFloatingPointNegative_ShouldMatch()
 	{
-		Money money{-1.2345, Codes::USD};
+		Money money{-1.2345, Iso4217Codes::USD};
 		QCOMPARE(money.major(), static_cast<UnitStorage>(-1));
 		QCOMPARE(money.minor(), static_cast<MinorUnit>(2345));
 	}
 	void constructorFloatingPointMajorTooLarge_ShouldThrowOverflow()
 	{
 		QVERIFY_EXCEPTION_THROWN(
-			Money(static_cast<FloatingPoint>(majorMaxValue) + 1.0, Codes::XXX),
+			Money(static_cast<FloatingPoint>(majorMaxValue) + 1.0, Iso4217Codes::XXX),
 			std::overflow_error
 		);
 	}
@@ -252,7 +247,7 @@
 		};
 		const FloatingPoint majorFp{static_cast<FloatingPoint>(majorMinValue)};
 		QVERIFY_EXCEPTION_THROWN(
-			Money(majorFp - minorFp - 1.0, Codes::XXX),
+			Money(majorFp - minorFp - 1.0, Iso4217Codes::XXX),
 			std::overflow_error
 		);
 	}
@@ -266,7 +261,7 @@
 		};
 		Money money{
 			70368744177662 + minorFp, // Expect the major to round up by one.
-			Codes::XXX,
+			Iso4217Codes::XXX,
 			[] (const FloatingPoint value, const std::uint8_t digits)
 			{
 				const double power{pow(10, digits)};
@@ -284,7 +279,7 @@
 		// majorFp.99
 		Money money{
 			static_cast<FloatingPoint>(1234 / 6.0), // 1234.166666666667...
-			Codes::XXX,
+			Iso4217Codes::XXX,
 			[] (const FloatingPoint value, const std::uint8_t digits)
 			{
 				const double power{pow(10, digits)};
@@ -301,7 +296,7 @@
 	{
 		Money money{
 			static_cast<FloatingPoint>(1.66555),
-			Codes::XXX,
+			Iso4217Codes::XXX,
 			&pecunia::rounders::reals::even
 		};
 		QCOMPARE(money.major(), static_cast<UnitStorage>(1));
@@ -312,7 +307,7 @@
 		QVERIFY_EXCEPTION_THROWN(
 			Money(
 				static_cast<FloatingPoint>(1 / (minorMaxValue + 2.0)),
-				Codes::XXX
+				Iso4217Codes::XXX
 			),
 			std::underflow_error
 		);
@@ -326,45 +321,45 @@
 	void maximumMajorValue_ShouldCalculate()
 	{
 		QCOMPARE(
-			Money(0, 0u, Codes::PLN).maximumMajorValue(),
+			Money(0, 0u, Iso4217Codes::PLN).maximumMajorValue(),
 			922337203685476l
 		);
 	}
 	void minimumMajorValue_ShouldCalculate()
 	{
 		QCOMPARE(
-			Money(0, 0u, Codes::PLN).minimumMajorValue(),
+			Money(0, 0u, Iso4217Codes::PLN).minimumMajorValue(),
 			-922337203685476l
 		);
 	}
 	void maximumMinorValue_ShouldCalculate()
 	{
 		QCOMPARE(
-			Money(0, 0u, Codes::PLN).maximumMinorValue(),
+			Money(0, 0u, Iso4217Codes::PLN).maximumMinorValue(),
 			static_cast<MinorUnit>(9999u)
 		);
 	}
 	void maximumAmountValue_ShouldCalculate()
 	{
 		QCOMPARE(
-			Money(0, 0u, Codes::PLN).maximumAmountValue(),
+			Money(0, 0u, Iso4217Codes::PLN).maximumAmountValue(),
 			9223372036854769999l
 		);
 	}
 	void minimumAmountValue_ShouldCalculate()
 	{
 		QCOMPARE(
-			Money(0, 0u, Codes::PLN).minimumAmountValue(),
+			Money(0, 0u, Iso4217Codes::PLN).minimumAmountValue(),
 			-9223372036854769999l
 		);
 	}
 	void maximum_ShouldCalculate()
 	{
-		QCOMPARE(Money::maximum(Codes::PLN), 922337203685476.9999);
+		QCOMPARE(Money::maximum(Iso4217Codes::PLN), 922337203685476.9999);
 	}
 	void minimum_ShouldCalculate()
 	{
-		QCOMPARE(Money::minimum(Codes::PLN), -922337203685476.9999);
+		QCOMPARE(Money::minimum(Iso4217Codes::PLN), -922337203685476.9999);
 	}
 */
 
@@ -411,14 +406,14 @@
 	}
 	void operatorFloatingPointPositiveMinor33_ShouldMatch()
 	{
-		Money money{33, pecunia::MinorSign::Positive};
+		Money money{pecunia::MinorSign::Positive, 33};
 		FloatingPoint expected{0.33};
 		FloatingPoint actual{money};
 		QCOMPARE(actual, expected);
 	}
 	void operatorFloatingPointNegativeMinor33_ShouldMatch()
 	{
-		Money money{33, pecunia::MinorSign::Negative};
+		Money money{pecunia::MinorSign::Negative, 33};
 		FloatingPoint expected{-0.33};
 		FloatingPoint actual{money};
 		QCOMPARE(actual, expected);
@@ -464,7 +459,7 @@
 	void additiveAssignmentOperatorFloatingPoint_ShouldBeCorrect()
 	{
 		Money test0{3, 5};
-		test0 += Money{2.03, Codes::XXX};
+		test0 += Money{2.03, Iso4217Codes::XXX};
 		QCOMPARE(test0.major(), static_cast<UnitStorage>(5));
 		QCOMPARE(test0.minor(), static_cast<MinorUnit>(7));
 	}
@@ -475,13 +470,13 @@
 	}
 	void additiveOperatorMinimumPlusOneNegative_ShouldThrowOverflow()
 	{
-		Money test0{majorMinValue, minorMaxValue}, test1{1, pecunia::MinorSign::Negative};
+		Money test0{majorMinValue, minorMaxValue}, test1{pecunia::MinorSign::Negative, 1};
 		QVERIFY_EXCEPTION_THROWN(test0 + test1, std::overflow_error);
 	}
 	void additiveOperatorTwoDifferentCurrencies_ShouldConvert()
 	{
 		pecunia::converter = testConverter;
-		Money test0{15, 3500, Codes::USD}, test1{25, 6500, Codes::PLN};
+		Money test0{15, 3500, Iso4217Codes::USD}, test1{25, 6500, Iso4217Codes::PLN};
 		test0 = test0 + test1;
 		QCOMPARE(test0.major(), static_cast<UnitStorage>(21));
 		QCOMPARE(test0.minor(), static_cast<MinorUnit>(4785));
@@ -489,7 +484,7 @@
 	void additiveOperatorThreeDifferentCurrencies_ShouldConvert()
 	{
 		pecunia::converter = testConverter;
-		Money test0{15, 3500, Codes::USD}, test1{25, 6500, Codes::PLN}, test2{Codes::EUR};
+		Money test0{15, 3500, Iso4217Codes::USD}, test1{25, 6500, Iso4217Codes::PLN}, test2{Iso4217Codes::EUR};
 		test2 = test0 + test1;
 		QCOMPARE(test2.major(), static_cast<UnitStorage>(20));
 		QCOMPARE(test2.minor(), static_cast<MinorUnit>(2147));
@@ -516,24 +511,24 @@
 	void subtractiveAssignmentOperatorFloatingPoint_ShouldBeCorrect()
 	{
 		Money test0{3, 5};
-		test0 -= Money{2.03, Codes::XXX};
+		test0 -= Money{2.03, Iso4217Codes::XXX};
 		QCOMPARE(test0.major(), static_cast<UnitStorage>(1));
 		QCOMPARE(test0.minor(), static_cast<MinorUnit>(3));
 	}
 	void subtractiveOperatorMaximumMinusMaximumMinorNegative_ShouldThrowOverflow()
 	{
-		Money test0{majorMaxValue, minorMaxValue}, test1{1, pecunia::MinorSign::Negative};
+		Money test0{majorMaxValue, minorMaxValue}, test1{pecunia::MinorSign::Negative, 1};
 		QVERIFY_EXCEPTION_THROWN(test0 - test1, std::overflow_error);
 	}
 	void subtractiveOperatorMinimumMinusOne_ShouldThrowOverflow()
 	{
-		Money test0{majorMinValue, minorMaxValue}, test1{1, pecunia::MinorSign::Positive};
+		Money test0{majorMinValue, minorMaxValue}, test1{pecunia::MinorSign::Positive, 1};
 		QVERIFY_EXCEPTION_THROWN(test0 - test1, std::overflow_error);
 	}
 	void subtractiveOperatorTwoDifferentCurrencies_ShouldConvert()
 	{
 		pecunia::converter = testConverter;
-		Money test0{15, 3500, Codes::USD}, test1{25, 6500, Codes::PLN};
+		Money test0{15, 3500, Iso4217Codes::USD}, test1{25, 6500, Iso4217Codes::PLN};
 		test0 = test0 - test1;
 		QCOMPARE(test0.major(), static_cast<UnitStorage>(9));
 		QCOMPARE(test0.minor(), static_cast<MinorUnit>(2215));
@@ -541,7 +536,7 @@
 	void subtractiveOperatorThreeDifferentCurrencies_ShouldConvert()
 	{
 		pecunia::converter = testConverter;
-		Money test0{15, 3500, Codes::USD}, test1{25, 6500, Codes::PLN}, test2{Codes::EUR};
+		Money test0{15, 3500, Iso4217Codes::USD}, test1{25, 6500, Iso4217Codes::PLN}, test2{Iso4217Codes::EUR};
 		test2 = test0 - test1;
 		QCOMPARE(test2.major(), static_cast<UnitStorage>(8));
 		QCOMPARE(test2.minor(), static_cast<MinorUnit>(6789));
@@ -677,8 +672,8 @@
 	}
 	void divisionOperator_Ratio_DifferentCurrencies_ShouldBeCorrect()
 	{
-		const Money test0{1, 0, Codes::USD};
-		const Money test1{2, 0, Codes::EUR};
+		const Money test0{1, 0, Iso4217Codes::USD};
+		const Money test1{2, 0, Iso4217Codes::EUR};
 		const FloatingPoint value{test0 / test1};
 		QCOMPARE(value, 0.47058823529411764);
 	}
@@ -795,31 +790,31 @@
 	void assignmentOperatorDifferentCurrency_ShouldAssign()
 	{
 		pecunia::converter = testConverter;
-		Money usd{5, 5, Codes::USD}, pln{Codes::PLN};
+		Money usd{5, 5, Iso4217Codes::USD}, pln{Iso4217Codes::PLN};
 		pln = usd;
 		QCOMPARE(pln.major(), static_cast<UnitStorage>(20));
 		QCOMPARE(pln.minor(), static_cast<MinorUnit>(9288));
-		QCOMPARE(pln.code(), Codes::PLN);
+		QCOMPARE(pln.code(), Iso4217Codes::PLN);
 	}
 	void assignmentOperator_DefaultToPolishCurrency_ShouldAssign()
 	{
 		pecunia::converter = testConverter;
-		const Money polish{30, 5296u, Codes::PLN};
+		const Money polish{30, 5296u, Iso4217Codes::PLN};
 		Money toSet{};
 		toSet = polish;
-		toSet.setCode(Codes::PLN);
+		toSet.setCode(Iso4217Codes::PLN);
 		QCOMPARE(toSet.major(), static_cast<UnitStorage>(30));
 		QCOMPARE(toSet.minor(), static_cast<MinorUnit>(5296u));
-		QCOMPARE(toSet.code(), Codes::PLN);
+		QCOMPARE(toSet.code(), Iso4217Codes::PLN);
 	}
 	void assignmentOperatorDifferentCurrencyTooLargePositive_ShouldThrowOverflow()
 	{
-		Money test0{majorMaxValue, minorMaxValue}, test1{Codes::PLN};
+		Money test0{majorMaxValue, minorMaxValue}, test1{Iso4217Codes::PLN};
 		QVERIFY_EXCEPTION_THROWN(test1 = test0, std::overflow_error);
 	}
 	void assignmentOperatorDifferentCurrencyTooLargeNegative_ShouldThrowOverflow()
 	{
-		Money test0{majorMinValue, minorMaxValue}, test1{Codes::PLN};
+		Money test0{majorMinValue, minorMaxValue}, test1{Iso4217Codes::PLN};
 		QVERIFY_EXCEPTION_THROWN(test1 = test0, std::overflow_error);
 	}
 
@@ -851,7 +846,7 @@
 	}
 	void lessThanFourFiveUsdToFiveFivePln_ShouldBeFalse()
 	{
-		Money test0{4, 5, Codes::USD}, test1{5, 5, Codes::PLN};
+		Money test0{4, 5, Iso4217Codes::USD}, test1{5, 5, Iso4217Codes::PLN};
 		QVERIFY( ! (test0 < test1));
 	}
 	void lessThanEqualFiveFiveToFiveFifty_ShouldBeTrue()
@@ -878,7 +873,7 @@
 	}
 	void lessThanEqualFiveFiveUsdToFiveFivePln_ShouldBeFalse()
 	{
-		Money test0{5, 5, Codes::USD}, test1{5, 5, Codes::PLN};
+		Money test0{5, 5, Iso4217Codes::USD}, test1{5, 5, Iso4217Codes::PLN};
 		QVERIFY( ! (test0 <= test1));
 	}
 	void greaterThanFiveFiftyToFiveFive_ShouldBeTrue()
@@ -899,7 +894,7 @@
 	}
 	void greaterThanSixFiveUsdToFifteenFivePln_ShouldBeTrue()
 	{
-		Money test0{6, 5, Codes::USD}, test1{15, 5, Codes::PLN};
+		Money test0{6, 5, Iso4217Codes::USD}, test1{15, 5, Iso4217Codes::PLN};
 		QVERIFY(test0 > test1);
 	}
 	void greaterThanEqualFiveFiftyTOFiveFive_ShouldBeTrue()
@@ -920,7 +915,7 @@
 	}
 	void greaterThanEqualSixFiveUsdToFifteenFivePln_ShouldBeTrue()
 	{
-		Money test0{6, 5, Codes::USD}, test1{15, 5, Codes::PLN};
+		Money test0{6, 5, Iso4217Codes::USD}, test1{15, 5, Iso4217Codes::PLN};
 		QVERIFY(test0 >= test1);
 	}
 
@@ -942,7 +937,7 @@
 	}
 	void equalFiveFiveUsdToTwentyNinetwoeightninePln_ShouldBeTrue()
 	{
-		Money test0{5, 5, Codes::USD}, test1{20, 9289, Codes::PLN};
+		Money test0{5, 5, Iso4217Codes::USD}, test1{20, 9289, Iso4217Codes::PLN};
 		QVERIFY(test0 == test1);
 	}
 
@@ -958,7 +953,7 @@
 	}
 	void inequalFiveFiveUsdToFiveFivePln_ShouldBeTrue()
 	{
-		Money test0{5, 5, Codes::USD}, test1{5, 5, Codes::PLN};
+		Money test0{5, 5, Iso4217Codes::USD}, test1{5, 5, Iso4217Codes::PLN};
 		QVERIFY(test0 != test1);
 	}
 	void inequalFiveFiftyToFiveSixInteger_ShouldBeTrue()
@@ -975,7 +970,7 @@
 	void streamInsertionPositive_ShouldInsert()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
+		ss.imbue(std::locale{defaultLocale});
 		Money test0{11, 45};
 		ss << test0;
 		// N.B. The "XXX" currency doesn't have minor units.
@@ -984,7 +979,7 @@
 	void streamInsertionNegative_ShouldInsert()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
+		ss.imbue(std::locale{defaultLocale});
 		Money test0{-11, 45};
 		ss << test0;
 		// N.B. The "XXX" currency doesn't have minor units.
@@ -993,88 +988,88 @@
 	void streamInsertionNegativeUsdLead_ShouldInsert()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
-		Money test0{-11, 4524, Codes::USD};
+		ss.imbue(std::locale{defaultLocale});
+		Money test0{-11, 4524, Iso4217Codes::USD};
 		ss << pecunia::currency::lead << test0;
 		QCOMPARE(ss.str().c_str(), std::string{"USD-11.4524"}.c_str());
 	}
 	void streamInsertionNegativeUsdTail_ShouldInsert()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
-		Money test0{-11, 4524, Codes::USD};
+		ss.imbue(std::locale{defaultLocale});
+		Money test0{-11, 4524, Iso4217Codes::USD};
 		ss << pecunia::currency::trail << test0;
 		QCOMPARE(ss.str().c_str(), std::string{"-11.4524USD"}.c_str());
 	}
 	void streamInsertionNegativeUsdLeadSymbol_ShouldInsert()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
-		Money test0{-11, 4524, Codes::USD};
+		ss.imbue(std::locale{defaultLocale});
+		Money test0{-11, 4524, Iso4217Codes::USD};
 		ss << pecunia::currency::lead << pecunia::currency::symbol << test0;
 		QCOMPARE(ss.str().c_str(), std::string{"$-11.4524"}.c_str());
 	}
 	void streamInsertionNegativeUsdTrailSymbol_ShouldInsert()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
-		Money test0{-11, 4524, Codes::USD};
+		ss.imbue(std::locale{defaultLocale});
+		Money test0{-11, 4524, Iso4217Codes::USD};
 		ss << pecunia::currency::trail << pecunia::currency::symbol << test0;
 		QCOMPARE(ss.str().c_str(), std::string{"-11.4524$"}.c_str());
 	}
 	void streamInsertionNegativeUsdLeadSymbolSpace_ShouldInsert()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
-		Money test0{-11, 4524, Codes::USD};
+		ss.imbue(std::locale{defaultLocale});
+		Money test0{-11, 4524, Iso4217Codes::USD};
 		ss << pecunia::currency::lead << pecunia::currency::symbol << pecunia::currency::spaced << test0;
 		QCOMPARE(ss.str().c_str(), std::string{"$ -11.4524"}.c_str());
 	}
 	void streamInsertionNegativeUsdTrailSymbolSpace_ShouldInsert()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
-		Money test0{-11, 4524, Codes::USD};
+		ss.imbue(std::locale{defaultLocale});
+		Money test0{-11, 4524, Iso4217Codes::USD};
 		ss << pecunia::currency::trail << pecunia::currency::symbol << pecunia::currency::spaced << test0;
 		QCOMPARE(ss.str().c_str(), std::string{"-11.4524 $"}.c_str());
 	}
 	void streamExtractionUsdTrail_ShouldExtract()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
+		ss.imbue(std::locale{defaultLocale});
 		Money test0;
 		ss << "11.45 USD";
 		ss >> test0;
 		QCOMPARE(test0.major(), static_cast<UnitStorage>(11));
 		QCOMPARE(test0.minor(), static_cast<MinorUnit>(4500));
-		QCOMPARE(test0.code(),  Codes::USD);
+		QCOMPARE(test0.code(),  Iso4217Codes::USD);
 	}
 	void streamExtractionUsdLead_ShouldExtract()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
+		ss.imbue(std::locale{defaultLocale});
 		Money test0;
 		ss << "USD 11.45";
 		ss >> pecunia::currency::lead >> test0;
 		QCOMPARE(test0.major(), static_cast<UnitStorage>(11));
 		QCOMPARE(test0.minor(), static_cast<MinorUnit>(4500));
-		QCOMPARE(test0.code(),  Codes::USD);
+		QCOMPARE(test0.code(),  Iso4217Codes::USD);
 	}
 	void streamExtractionNegative_ShouldExtract()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
+		ss.imbue(std::locale{defaultLocale});
 		Money test0;
 		ss << "-11.45 USD";
 		ss >> test0;
 		QCOMPARE(test0.major(), static_cast<UnitStorage>(-11));
 		QCOMPARE(test0.minor(), static_cast<MinorUnit>(4500));
-		QCOMPARE(test0.code(),  Codes::USD);
+		QCOMPARE(test0.code(),  Iso4217Codes::USD);
 	}
 	void streamExtractionInvalidAmountData_ShouldThrowRuntime()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
+		ss.imbue(std::locale{defaultLocale});
 		Money test0;
 		ss << "dsfa USD";
 		QVERIFY_EXCEPTION_THROWN(ss >> test0, std::runtime_error);
@@ -1082,7 +1077,7 @@
 	void streamExtractionInvalidCodeData_ShouldThrowRuntime()
 	{
 		std::stringstream ss;
-		ss.imbue(std::locale{testLocale});
+		ss.imbue(std::locale{defaultLocale});
 		Money test0;
 		ss << "11.45 dsaf";
 		QVERIFY_EXCEPTION_THROWN(ss >> test0, std::runtime_error);
@@ -1101,14 +1096,14 @@
 
 	void toStringDefaultUsd_ShouldConvert()
 	{
-		Money test0{0, 0, Codes::USD};
+		Money test0{0, 0, Iso4217Codes::USD};
 		std::string str{pecunia::currency::to_string(test0)};
 		QCOMPARE(str.c_str(), "0.0000 USD");
 	}
 
 	void toStringNegativeAmount_ShouldConvert()
 	{
-		Money test0{-11, 4500, Codes::USD};
+		Money test0{-11, 4500, Iso4217Codes::USD};
 		std::string str{pecunia::currency::to_string(test0)};
 		QCOMPARE(str.c_str(), "-11.4500 USD");
 	}
@@ -1119,7 +1114,7 @@
 
 	void toFloatingPoint_defaultRound_ShouldBeSame()
 	{
-		const Money money{12, 66u, Codes::XXX};
+		const Money money{12, 66u, Iso4217Codes::XXX};
 		const FloatingPoint expected{12.66};
 		QCOMPARE(money.toFloatingPoint(), expected);
 	}
@@ -1152,25 +1147,25 @@
 	}
 	void toFloatingPoint_defaultRound_PositiveMinor33_ShouldMatch()
 	{
-		Money money{33, pecunia::MinorSign::Positive};
+		Money money{pecunia::MinorSign::Positive, 33};
 		FloatingPoint expected{0.33};
 		QCOMPARE(money.toFloatingPoint(), expected);
 	}
 	void toFloatingPoint_defaultRound_NegativeMinor33_ShouldMatch()
 	{
-		Money money{33, pecunia::MinorSign::Negative};
+		Money money{pecunia::MinorSign::Negative, 33};
 		FloatingPoint expected{-0.33};
 		QCOMPARE(money.toFloatingPoint(), expected);
 	}
 	void toFloatingPoint_evenRound_ShouldRoundUp()
 	{
-		Money money{1, 66u, Codes::XXX};
+		Money money{1, 66u, Iso4217Codes::XXX};
 		FloatingPoint expected{1.7};
 		QCOMPARE(money.toFloatingPoint(&pecunia::rounders::currency::even, 1), expected);
 	}
 	void toFloatingPoint_evenRound_ShouldDown()
 	{
-		Money money{1, 64u, Codes::XXX};
+		Money money{1, 64u, Iso4217Codes::XXX};
 		FloatingPoint expected{1.6};
 		QCOMPARE(money.toFloatingPoint(&pecunia::rounders::currency::even, 1), expected);
 	}
@@ -1181,35 +1176,35 @@
 
 	void round_Round_ShouldRoundUp()
 	{
-		Money money{3, 66u, Codes::XXX};
-		Money expected{3, 70u, Codes::XXX};
+		Money money{3, 66u, Iso4217Codes::XXX};
+		Money expected{3, 70u, Iso4217Codes::XXX};
 		money.round(&pecunia::rounders::currency::even, 1);
 		QCOMPARE(money, expected);
 	}
 	void round_Round_ShouldRoundDown()
 	{
-		Money money{8, 65u, Codes::XXX};
-		Money expected{8, 60u, Codes::XXX};
+		Money money{8, 65u, Iso4217Codes::XXX};
+		Money expected{8, 60u, Iso4217Codes::XXX};
 		money.round(&pecunia::rounders::currency::even, 1);
 		QCOMPARE(money, expected);
 	}
 	void round_RoundMajor_ShouldRoundUp()
 	{
-		Money money{7, 99u, Codes::XXX};
-		Money expected{8, 00u, Codes::XXX};
+		Money money{7, 99u, Iso4217Codes::XXX};
+		Money expected{8, 00u, Iso4217Codes::XXX};
 		money.round(&pecunia::rounders::currency::even, 1);
 		QCOMPARE(money, expected);
 	}
 	void round_RoundMaxMajor_ShouldRoundUp()
 	{
-		Money money{majorMaxValue - 1, 99u, Codes::XXX};
-		Money expected{majorMaxValue, 00u, Codes::XXX};
+		Money money{majorMaxValue - 1, 99u, Iso4217Codes::XXX};
+		Money expected{majorMaxValue, 00u, Iso4217Codes::XXX};
 		money.round(&pecunia::rounders::currency::up, 1);
 		QCOMPARE(money, expected);
 	}
 	void round_RoundAtMaxMajor_ShouldThrow()
 	{
-		Money money{majorMaxValue, 99u, Codes::XXX};
+		Money money{majorMaxValue, 99u, Iso4217Codes::XXX};
 		QVERIFY_EXCEPTION_THROWN(
 			money.round(&pecunia::rounders::currency::up, 1),
 			std::overflow_error
@@ -1222,9 +1217,9 @@
 
 	void setCode_ValidParam_ShouldSet()
 	{
-		Money test{-11, 4500, Codes::USD};
-		test.setCode(Codes::PLN);
-		QCOMPARE(test.code(), Codes::PLN);
+		Money test{-11, 4500, Iso4217Codes::USD};
+		test.setCode(Iso4217Codes::PLN);
+		QCOMPARE(test.code(), Iso4217Codes::PLN);
 	}
 
 	//}
@@ -1233,7 +1228,7 @@
 
 	void minimum_ValidParam_ShouldHaveValue()
 	{
-		const auto min{Money::minimum(Codes::USD)};
+		const auto min{Money::minimum(Iso4217Codes::USD)};
 		QCOMPARE(min.first, static_cast<UnitStorage>(-922337203685476));
 		QCOMPARE(min.second, static_cast<MinorUnit>(9999));
 	}
@@ -1244,7 +1239,7 @@
 
 	void maximum_ValidParam_ShouldHaveValue()
 	{
-		const auto max{Money::maximum(Codes::USD)};
+		const auto max{Money::maximum(Iso4217Codes::USD)};
 		QCOMPARE(max.first, static_cast<UnitStorage>(922337203685476));
 		QCOMPARE(max.second, static_cast<MinorUnit>(9999));
 	}
--- a/src/unit-tests/range-unit-tests.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/unit-tests/range-unit-tests.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 /*******************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
@@ -35,7 +35,7 @@
 using std::tuple;
 
 #include <pecunia/Codes.h>
-using pecunia::currency::Codes;
+using pecunia::currency::Iso4217Codes;
 #include <pecunia/Money.h>
 using pecunia::currency::Money;
 #include <pecunia/MoneyTypes.h>
@@ -72,7 +72,7 @@
 
 			try
 			{
-				const Money _{test, minorMaxValue, Codes::XXX}; // XXX does not have any minor units.
+				const Money _{test, minorMaxValue, Iso4217Codes::XXX}; // XXX does not have any minor units.
 //				cout << " -- within range" << endl;
 
 				if (test > maximum)
@@ -102,7 +102,7 @@
 
 			try
 			{
-				const Money _{test, minorMaxValue, Codes::XXX}; // XXX does not have any minor units.
+				const Money _{test, minorMaxValue, Iso4217Codes::XXX}; // XXX does not have any minor units.
 //				cout << " -- within range" << endl;
 
 				if (test < minimum)
@@ -152,7 +152,7 @@
 			try
 			{
 				// XXX does not have any minor units.
-				Money money{static_cast<FloatingPoint>(test) + minorFp, Codes::XXX};
+				Money money{static_cast<FloatingPoint>(test) + minorFp, Iso4217Codes::XXX};
 //				cout << " -- within range" << endl;
 
 				if (money.major() != test)
@@ -198,7 +198,7 @@
 			try
 			{
 				// XXX does not have any minor units.
-				Money money{static_cast<FloatingPoint>(test) - minorFp, Codes::XXX};
+				Money money{static_cast<FloatingPoint>(test) - minorFp, Iso4217Codes::XXX};
 //				cout << " -- within range" << endl;
 
 				if (money.major() != test)
--- a/src/unit-tests/rounders-currency-unit-tests.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/unit-tests/rounders-currency-unit-tests.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 /*******************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***
--- a/src/unit-tests/rounders-floating-point-unit-tests.cpp	Sat Dec 12 15:09:09 2020 +0100
+++ b/src/unit-tests/rounders-floating-point-unit-tests.cpp	Mon Mar 01 16:17:10 2021 +0100
@@ -1,7 +1,7 @@
 /*******************************************************************************
 ***  This file is part of Pecunia.                                           ***
 ***                                                                          ***
-***  Copyright (C) 2016, 2017, 2018, 2019, 2020                              ***
+***  Copyright (C) 2017, 2018, 2019, 2020, 2021                              ***
 ***  John Schneiderman <Licensing _AT_ Schneiderman _DOT_ me>                ***
 ***                                                                          ***
 ***  This program is free software: you can redistribute it and/or modify it ***