diff --git a/examples/chapter04_04a/target/micros/avr/make/avr.ld b/examples/chapter04_04a/target/micros/avr/make/avr.ld index dbc793da7..f4a3a0cef 100644 --- a/examples/chapter04_04a/target/micros/avr/make/avr.ld +++ b/examples/chapter04_04a/target/micros/avr/make/avr.ld @@ -1,5 +1,5 @@ /* - Copyright Christopher Kormanyos 2007 - 2023. + Copyright Christopher Kormanyos 2007 - 2025. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -12,6 +12,10 @@ INPUT(libc.a libm.a libgcc.a) OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr") OUTPUT_ARCH(avr:5) +/* The beginning and end of the program ROM area. */ +_rom_begin = 0x00000000; +_rom_end = 0x00007FFC; + /* The beginning and end (i.e., top) of the stack */ /* Set up a stack with a size of 0x180=(3/8)K */ _stack_begin = 0x00800780; @@ -22,9 +26,8 @@ __initial_stack_pointer = 0x00800900 - 2; MEMORY { - VEC(rx) : ORIGIN = 0x00000000, LENGTH = 0x00000080 - ROM(rx) : ORIGIN = 0x00000080, LENGTH = 32K - 0x00000080 - RAM(rwx) : ORIGIN = 0x00800100, LENGTH = 0x00000780 - 0x00000100 + ROM(rx) : ORIGIN = 0, LENGTH = 32K - 4 + RAM(rw!x) : ORIGIN = 0x00800100, LENGTH = 0x00000780 - 0x00000100 } SECTIONS @@ -38,7 +41,7 @@ SECTIONS *(.isr_vector) . = ALIGN(0x10); KEEP(*(.isr_vector)) - } > VEC = 0x5555 + } > ROM = 0xAAAA /* Startup code */ .startup : @@ -67,6 +70,11 @@ SECTIONS . = ALIGN(2); } > ROM + .text : + { + . = ALIGN(0x10); + } > ROM = 0xAAAA + . = 0x00800100; . = ALIGN(2); @@ -80,7 +88,7 @@ SECTIONS *(.data*) . = ALIGN(2); KEEP (*(.data*)) - *(.rodata) /* Use special handling of rodata (i.e., as part of data since _const_ variables are stored in RAM for AVR arch). */ + *(.rodata) /* Do *NOT* move this! Include .rodata here if gcc is used with -fdata-sections. */ . = ALIGN(2); KEEP (*(.rodata)) *(.rodata*) diff --git a/examples/chapter04_04a/target/micros/avr/make/avr_flags.gmk b/examples/chapter04_04a/target/micros/avr/make/avr_flags.gmk index a17883461..22ab34f02 100644 --- a/examples/chapter04_04a/target/micros/avr/make/avr_flags.gmk +++ b/examples/chapter04_04a/target/micros/avr/make/avr_flags.gmk @@ -12,6 +12,7 @@ ifneq ($(MAKE),make) GCC_VERSION = 15.1.0 endif + GCC_TARGET = avr GCC_PREFIX = avr @@ -33,7 +34,7 @@ endif TGT_CFLAGS = -std=c11 \ $(TGT_ALLFLAGS) -TGT_CXXFLAGS = -std=c++14 \ +TGT_CXXFLAGS = -std=c++20 \ $(TGT_ALLFLAGS) TGT_INCLUDES = -I$(PATH_APP)/util/STL diff --git a/examples/chapter09_08/src/mcal/avr/mcal_led_sys_start_interface.cpp b/examples/chapter09_08/src/mcal/avr/mcal_led_sys_start_interface.cpp index 39be0176b..f3a8e9f2a 100644 --- a/examples/chapter09_08/src/mcal/avr/mcal_led_sys_start_interface.cpp +++ b/examples/chapter09_08/src/mcal/avr/mcal_led_sys_start_interface.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2017 - 2018. +// Copyright Christopher Kormanyos 2017 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/examples/chapter09_08/src/sys/start/sys_start.cpp b/examples/chapter09_08/src/sys/start/sys_start.cpp index 82c576600..7f7e613d4 100644 --- a/examples/chapter09_08/src/sys/start/sys_start.cpp +++ b/examples/chapter09_08/src/sys/start/sys_start.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/examples/chapter09_08/target/app/make/app_make.gmk b/examples/chapter09_08/target/app/make/app_make.gmk index 07e0bffbe..fd3cb2d95 100644 --- a/examples/chapter09_08/target/app/make/app_make.gmk +++ b/examples/chapter09_08/target/app/make/app_make.gmk @@ -1,12 +1,12 @@ # -# Copyright Christopher Kormanyos 2007 - 2024. +# Copyright Christopher Kormanyos 2007 - 2025. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) # # ------------------------------------------------------------------------------ -# +# # Makefile # # Build file for the reference application using the GNU tools @@ -15,14 +15,32 @@ # # 07-April-2010 # +# See also a definitive list of GCC command line options +# (for numerous target systems) here: +# https://man7.org/linux/man-pages/man1/gcc.1.html +# +# ------------------------------------------------------------------------------ + + +# ------------------------------------------------------------------------------ +# punctuation # ------------------------------------------------------------------------------ +DQUOTE := \" +$(DQUOTE) := \" + +SEMICOLON := ; +$(SEMICOLON) := ; + +DOLLAR := $$ +$(DOLLAR) := $$ # ------------------------------------------------------------------------------ -# compiler location, build from GCC version and GCC target +# null device # ------------------------------------------------------------------------------ -COMPILER_DIRECTORY = gcc-$(GCC_VERSION)-$(GCC_TARGET) +NULL_DEVICE := NUL +$(NULL_DEVICE) := NUL # ------------------------------------------------------------------------------ # paths @@ -40,16 +58,19 @@ PATH_TGT_MAKE = $(PATH_TGT)/make PATH_BIN = bin PATH_TMP = tmp PATH_OBJ = $(PATH_TMP)/obj -PATH_SRC = $(PATH_TMP)/src +PATH_LST = $(PATH_TMP)/lst PATH_ERR = $(PATH_TMP)/err # ------------------------------------------------------------------------------ -# include files +# standard shell tools # ------------------------------------------------------------------------------ -include $(PATH_APP_MAKE)/app_files.gmk # Application file list -include $(PATH_TGT_MAKE)/$(TGT)_files.gmk # Target filelist -include $(PATH_TGT_MAKE)/$(TGT)_flags.gmk # Target compiler flags + +ECHO = $(PATH_TOOLS_MINGW_BIN)\echo.exe +MAKE = $(PATH_TOOLS_MINGW_BIN)\make.exe +MKDIR = $(PATH_TOOLS_MINGW_BIN)\mkdir.exe +RM = $(PATH_TOOLS_MINGW_BIN)\rm.exe +SED = $(PATH_TOOLS_MINGW_BIN)\sed.exe # ------------------------------------------------------------------------------ @@ -57,12 +78,12 @@ include $(PATH_TGT_MAKE)/$(TGT)_flags.gmk # Target compiler flags # ------------------------------------------------------------------------------ APP = $(PATH_BIN)/chapter09_08 -# ------------------------------------------------------------------------------ -# object files -# ------------------------------------------------------------------------------ -FILES_TMP = $(FILES_CPP) $(FILES_TGT) -FILES_O = $(addprefix $(PATH_OBJ)/, $(notdir $(addsuffix .o, $(FILES_TMP)))) +IMAGE_FILE = $(APP).bin + +RULE_SPECIAL_MAKE_IMAGE_FILE = +RULE_SPECIAL_MAKE_FLASH_BATCH = +WARN_FLAGS = # ------------------------------------------------------------------------------ # linker definition file @@ -70,6 +91,21 @@ FILES_O = $(addprefix $(PATH_OBJ)/, $(notdir $(addsuffix .o, $(FILES_TMP)))) LINKER_DEFINITION_FILE = $(PATH_TGT_MAKE)/$(TGT).ld +# ------------------------------------------------------------------------------ +# include the target-specific make files +# ------------------------------------------------------------------------------ +include $(PATH_APP_MAKE)/app_files.gmk # Application file list +include $(PATH_TGT_MAKE)/$(TGT)_files.gmk # Target filelist +include $(PATH_TGT_MAKE)/$(TGT)_flags.gmk # Target compiler flags + + +# ------------------------------------------------------------------------------ +# object files +# ------------------------------------------------------------------------------ +FILES_TMP = $(FILES_CPP) $(FILES_TGT) +FILES_O = $(addprefix $(PATH_OBJ)/, $(notdir $(addsuffix .o, $(FILES_TMP)))) + + # ------------------------------------------------------------------------------ # VPATH definition # @@ -85,22 +121,29 @@ VPATH := $(sort $(dir $(FILES_TMP))) # ------------------------------------------------------------------------------ # Development tools # ------------------------------------------------------------------------------ -AR = $(PATH_TOOLS_CC)\$(GCC_TARGET)-ar.exe -AS = $(PATH_TOOLS_CC)\$(GCC_TARGET)-g++.exe -CC = $(PATH_TOOLS_CC)\$(GCC_TARGET)-g++.exe -CPPFILT = $(PATH_TOOLS_CC)\$(GCC_TARGET)-c++filt.exe -NM = $(PATH_TOOLS_CC)\$(GCC_TARGET)-nm.exe -OBJDUMP = $(PATH_TOOLS_CC)\$(GCC_TARGET)-objdump.exe -OBJCOPY = $(PATH_TOOLS_CC)\$(GCC_TARGET)-objcopy.exe -READELF = $(PATH_TOOLS_CC)\$(GCC_TARGET)-readelf.exe -SIZE = $(PATH_TOOLS_CC)\$(GCC_TARGET)-size.exe - -ECHO = $(PATH_TOOLS_MINGW_BIN)\echo.exe -MAKE = $(PATH_TOOLS_MINGW_BIN)\make.exe -MKDIR = $(PATH_TOOLS_MINGW_BIN)\mkdir.exe -RM = $(PATH_TOOLS_MINGW_BIN)\rm.exe -SED = $(PATH_TOOLS_MINGW_BIN)\sed.exe - +ifeq ($(GCC_PREFIX),) +AR = $(PATH_TOOLS_CC)\ar.exe +AS = $(PATH_TOOLS_CC)\g++.exe +CC = $(PATH_TOOLS_CC)\g++.exe +CPPFILT = $(PATH_TOOLS_CC)\c++filt.exe +NM = $(PATH_TOOLS_CC)\nm.exe +OBJDUMP = $(PATH_TOOLS_CC)\objdump.exe +OBJCOPY = $(PATH_TOOLS_CC)\objcopy.exe +READELF = $(PATH_TOOLS_CC)\readelf.exe +SIZE = $(PATH_TOOLS_CC)\size.exe +else +AR = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-ar.exe +AS = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-g++.exe +CC = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-g++.exe +CPPFILT = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-c++filt.exe +NM = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-nm.exe +OBJDUMP = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-objdump.exe +ifeq ($(OBJCOPY),) +OBJCOPY = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-objcopy.exe +endif +READELF = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-readelf.exe +SIZE = $(PATH_TOOLS_CC)\$(GCC_PREFIX)-size.exe +endif # ------------------------------------------------------------------------------ # Tool parameters @@ -109,47 +152,33 @@ C_INCLUDES = $(TGT_INCLUDES) \ -I$(PATH_APP) \ -I$(PATH_APP)/mcal/$(TGT) -GCCFLAGS = $(TGT_CFLAGS) \ - -g \ - -Wall \ +ifeq ($(WARN_FLAGS),) +WARN_FLAGS = -Wall \ -Wextra \ - -pedantic \ - -Wmain \ - -Wundef \ - -Wsign-conversion \ - -Wunused-parameter \ - -Wuninitialized \ - -Wmissing-declarations \ - -Wshadow \ - -Wunreachable-code \ - -Wswitch-default \ - -Wswitch-enum \ - -Wcast-align \ - -Wmissing-include-dirs \ - -Winit-self \ - -Wfloat-equal \ - -Wdouble-promotion \ + -Wpedantic +endif + +GCCFLAGS = -g \ + $(WARN_FLAGS) \ + -Wno-comment \ -gdwarf-2 \ -fno-exceptions \ -ffunction-sections \ -fdata-sections CFLAGS = $(GCCFLAGS) \ - -Wunsuffixed-float-constants \ - -x c \ - -std=c99 + $(TGT_CFLAGS) \ + -x c -CPPFLAGS = $(GCCFLAGS) \ - $(TGT_CPPFLAGS) \ +CXXFLAGS = $(GCCFLAGS) \ + $(TGT_CXXFLAGS) \ -x c++ \ -fno-rtti \ - -fstrict-enums \ -fno-use-cxa-atexit \ - -fno-use-cxa-get-exception-ptr \ -fno-nonansi-builtins \ -fno-threadsafe-statics \ -fno-enforce-eh-specs \ - -ftemplate-depth=32 \ + -ftemplate-depth=128 \ -Wzero-as-null-pointer-constant AFLAGS = $(GCCFLAGS) \ @@ -157,11 +186,9 @@ AFLAGS = $(GCCFLAGS) \ $(TGT_AFLAGS) \ -x assembler -LDFLAGS = $(GCCFLAGS) \ +LDFLAGS = $(CXXFLAGS) \ $(TGT_LDFLAGS) \ -x none \ - -Wl,--gc-sections \ - -Wl,-Map,$(APP).map \ -Wl,--print-memory-usage # ------------------------------------------------------------------------------ @@ -187,8 +214,8 @@ clean_prj: @-$(MKDIR) -p $(PATH_BIN) @-$(MKDIR) -p $(PATH_OBJ) @-$(MKDIR) -p $(PATH_ERR) - @-$(MKDIR) -p $(PATH_SRC) - @-$(RM) -r $(PATH_BIN) > NUL 2> NUL + @-$(MKDIR) -p $(PATH_LST) + @-$(RM) -r $(PATH_BIN) 2>$(NULL_DEVICE) @-$(MKDIR) -p $(PATH_BIN) @@ -201,11 +228,11 @@ clean_all: @-$(MKDIR) -p $(PATH_BIN) @-$(MKDIR) -p $(PATH_OBJ) @-$(MKDIR) -p $(PATH_ERR) - @-$(MKDIR) -p $(PATH_SRC) - @-$(RM) -r $(PATH_OBJ) > NUL 2> NUL - @-$(RM) -r $(PATH_ERR) > NUL 2> NUL - @-$(RM) -r $(PATH_SRC) > NUL 2> NUL - @-$(RM) -r $(PATH_BIN) > NUL 2> NUL + @-$(MKDIR) -p $(PATH_LST) + @-$(RM) -r $(PATH_OBJ) 2>$(NULL_DEVICE) + @-$(RM) -r $(PATH_ERR) 2>$(NULL_DEVICE) + @-$(RM) -r $(PATH_LST) 2>$(NULL_DEVICE) + @-$(RM) -r $(PATH_BIN) 2>$(NULL_DEVICE) @-$(MKDIR) -p $(PATH_BIN) @@ -215,6 +242,7 @@ clean_all: .PHONY: version version: # Print the GNU make version and the compiler version + @$(ECHO) @$(ECHO) +++ Print GNUmake version @$(MAKE) --version @$(ECHO) @@ -225,11 +253,14 @@ version: @$(ECHO) $(C_INCLUDES) @$(ECHO) @$(ECHO) +++ Print compiler include paths (for VisualStudio(R) browsing) - @$(ECHO) $(subst /,\, $(subst -I,$$\(SolutionDir\), $(C_INCLUDES))) + @$(ECHO) $(addsuffix $(SEMICOLON),$(subst -I,$$\(ProjectDir\)/, $(C_INCLUDES))) @$(ECHO) @$(ECHO) +++ Print compiler definitions @$(ECHO) $(C_DEFINES) @$(ECHO) + @$(ECHO) +++ Print compiler CXXFLAGS flags + @$(ECHO) $(CXXFLAGS) + @$(ECHO) # ------------------------------------------------------------------------------ @@ -238,8 +269,6 @@ version: $(APP).$(TGT_SUFFIX) : $(LINKER_DEFINITION_FILE) $(FILES_O) @-$(ECHO) +++ linking application to generate: $(APP).$(TGT_SUFFIX) @-$(CC) $(LDFLAGS) $(FILES_O) -o $(APP).$(TGT_SUFFIX) - @-$(ECHO) +++ generating assembly list file: $(APP).lss - @-$(OBJDUMP) -h -S $(APP).$(TGT_SUFFIX) > $(APP).lss # ------------------------------------------------------------------------------ @@ -251,7 +280,11 @@ $(APP)_nm.txt : $(APP).$(TGT_SUFFIX) @-$(ECHO) +++ demangling symbols with c++filt to generate: $(APP)_cppfilt.txt @-$(NM) --numeric-sort --print-size $(APP).$(TGT_SUFFIX) | $(CPPFILT) > $(APP)_cppfilt.txt @-$(ECHO) +++ parsing symbols with readelf to generate: $(APP)_readelf.txt +ifeq ($(TGT_SUFFIX),elf) @-$(READELF) --syms $(APP).$(TGT_SUFFIX) > $(APP)_readelf.txt +else + @-$(ECHO) +++ not available for: $(APP).$(TGT_SUFFIX). +endif @-$(ECHO) +++ creating size summary table with size to generate: $(APP)_size.txt @-$(SIZE) -A -t $(APP).$(TGT_SUFFIX) > $(APP)_size.txt @@ -260,9 +293,29 @@ $(APP)_nm.txt : $(APP).$(TGT_SUFFIX) # create hex mask # ------------------------------------------------------------------------------ $(APP)_flash.hex : $(APP).$(TGT_SUFFIX) + @-$(ECHO) +++ creating hex module: $(APP).$(TGT_SUFFIX) +ifeq ($(TGT_SUFFIX),elf) @-$(ECHO) +++ creating hex module: $(APP).hex. - @-$(OBJCOPY) -O ihex $(APP).$(TGT_SUFFIX) $(APP).hex - @-$(OBJCOPY) -S -O binary $(APP).$(TGT_SUFFIX) $(APP).bin + @-$(OBJCOPY) $(APP).$(TGT_SUFFIX) -O ihex $(APP).hex + @-$(ECHO) +++ creating srec module: $(APP).s19 + @-$(OBJCOPY) $(APP).$(TGT_SUFFIX) -O srec --srec-forceS3 --srec-len=16 $(APP).s19 +else + @-$(ECHO) +++ creating hex module disabled for non-ELF absolute objet file. +endif +ifeq ($(RULE_SPECIAL_MAKE_IMAGE_FILE),) + @-$(ECHO) +++ creating special image file + @-$(ECHO) +++ disabled because there is no special image file +else + @-$(ECHO) +++ creating special image file + @-$(RULE_SPECIAL_MAKE_IMAGE_FILE) +endif +ifeq ($(RULE_SPECIAL_MAKE_FLASH_BATCH),) + @-$(ECHO) +++ creating special flash batch file + @-$(ECHO) +++ disabled because there is no special flash batch file +else + @-$(ECHO) +++ creating special flash batch file + @-$(RULE_SPECIAL_MAKE_FLASH_BATCH) +endif # ------------------------------------------------------------------------------ # Dependencyfile include (build) @@ -271,7 +324,7 @@ $(APP)_flash.hex : $(APP).$(TGT_SUFFIX) # If the files do not exist then the includes will be ignored. # ------------------------------------------------------------------------------ ifneq ($(MAKECMDGOALS),rebuild) --include $(subst .o,.d,$(FILES_O)) # for example tmp/obj/sys_start.d, tmp/obj/mcal_cpu.d, etc +-include $(subst .o,.d,$(FILES_O)) endif diff --git a/examples/chapter09_08/target/app/make/app_rules.gmk b/examples/chapter09_08/target/app/make/app_rules.gmk index 9a0de5e83..4a7bca584 100644 --- a/examples/chapter09_08/target/app/make/app_rules.gmk +++ b/examples/chapter09_08/target/app/make/app_rules.gmk @@ -1,5 +1,5 @@ # -# Copyright Christopher Kormanyos 2007 - 2018. +# Copyright Christopher Kormanyos 2007 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -11,13 +11,20 @@ # # Generic pattern rules # -# Based on GNU Make 3.81 +# Based on GNU Make 4.2.1 # # 07-April-2010 # # ------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ +# GCC dependency flags. +# ------------------------------------------------------------------------------ + +DEP_FLAGS = -MMD -MF $(PATH_OBJ)/$(basename $(@F)).d + + # ------------------------------------------------------------------------------ # Rule to compile C++ source file (*.cpp) to object file (*.o). # ------------------------------------------------------------------------------ @@ -30,12 +37,29 @@ $(PATH_OBJ)/%.o : %.cpp # ...and create an assembly listing using objdump, # ...and generate a dependency file (using the -MM flag), # ...and be sure to include the path in the dependency file. - @-$(CC) $(CPPFLAGS) $(C_INCLUDES) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err - @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|:\([0-9]*\):|(\1) :|' $(PATH_ERR)/$(basename $(@F)).err - @-$(OBJDUMP) -S -C $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_SRC)/$(basename $(@F)).lst - @-$(ECHO) -n $(PATH_OBJ)/ > $(PATH_OBJ)/$(basename $(@F)).d - @-$(CC) $(CPPFLAGS) $< -MM >> $(PATH_OBJ)/$(basename $(@F)).d + @-$(CC) $(CXXFLAGS) $(C_INCLUDES) $(DEP_FLAGS) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err + @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|.hpp:\([0-9]*\),|.hpp(\1) :|' -e 's|.cpp:\([0-9]*\),|.cpp(\1) :|' $(PATH_ERR)/$(basename $(@F)).err +ifneq ($(findstr risc,$(GCC_TARGET)),) + @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst +endif + +# ------------------------------------------------------------------------------ +# Rule to compile C++ source file (*.cc) to object file (*.o). +# ------------------------------------------------------------------------------ +$(PATH_OBJ)/%.o : %.cc + @$(ECHO) +++ compile: $< to $@ + # Compile the source file, + # ...and reformat (using sed) any possible error/warning messages + # for the VisualStudio(R) output window, + # ...and create an assembly listing using objdump, + # ...and generate a dependency file (using the -MM flag), + # ...and be sure to include the path in the dependency file. + @-$(CC) $(CXXFLAGS) $(C_INCLUDES) $(DEP_FLAGS) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err + @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|.hpp:\([0-9]*\),|.hpp(\1) :|' -e 's|.cc:\([0-9]*\),|.cc(\1) :|' $(PATH_ERR)/$(basename $(@F)).err +ifneq ($(findstr risc,$(GCC_TARGET)),) + @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst +endif # ------------------------------------------------------------------------------ # Rule to compile C source file (*.c) to object file (*.o). @@ -49,11 +73,9 @@ $(PATH_OBJ)/%.o : %.c # ...and create an assembly listing using objdump, # ...and generate a dependency file (using the -MM flag), # ...and be sure to include the path in the dependency file. - @-$(CC) $(CFLAGS) $(C_INCLUDES) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err - @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|:\([0-9]*\):|(\1) :|' $(PATH_ERR)/$(basename $(@F)).err - @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_SRC)/$(basename $(@F)).lst - @-$(ECHO) -n $(PATH_OBJ)/ > $(PATH_OBJ)/$(basename $(@F)).d - @-$(CC) $(CFLAGS) $< -MM >> $(PATH_OBJ)/$(basename $(@F)).d + @-$(CC) $(CFLAGS) $(C_INCLUDES) $(DEP_FLAGS) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err + @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|.c:\([0-9]*\),|.c(\1) :|' $(PATH_ERR)/$(basename $(@F)).err + @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst # ------------------------------------------------------------------------------ @@ -68,4 +90,4 @@ $(PATH_OBJ)/%.o : %.s # ...and create an assembly listing using objdump @-$(CC) $(AFLAGS) $(C_INCLUDES) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err @-$(SED) -e 's|:\([0-9]*\):|(\1) :|' $(PATH_ERR)/$(basename $(@F)).err - @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_SRC)/$(basename $(@F)).lst + @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst diff --git a/examples/chapter09_08/target/micros/avr/make/avr.ld b/examples/chapter09_08/target/micros/avr/make/avr.ld index ceace1c6a..f4a3a0cef 100644 --- a/examples/chapter09_08/target/micros/avr/make/avr.ld +++ b/examples/chapter09_08/target/micros/avr/make/avr.ld @@ -1,6 +1,5 @@ - /* - Copyright Christopher Kormanyos 2007 - 2021. + Copyright Christopher Kormanyos 2007 - 2025. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -18,17 +17,17 @@ _rom_begin = 0x00000000; _rom_end = 0x00007FFC; /* The beginning and end (i.e., top) of the stack */ -/* Set up a stack with a size of (1/2)K */ -_stack_begin = 0x00800600; -_stack_end = 0x00800800; +/* Set up a stack with a size of 0x180=(3/8)K */ +_stack_begin = 0x00800780; +_stack_end = 0x00800900; /* The initial stack pointer (top of stack) is at the top of the 2K RAM */ -__initial_stack_pointer = 0x800800; +__initial_stack_pointer = 0x00800900 - 2; MEMORY { ROM(rx) : ORIGIN = 0, LENGTH = 32K - 4 - RAM(rw!x) : ORIGIN = 0x00800100, LENGTH = 0x00000600 - 0x00000100 + RAM(rw!x) : ORIGIN = 0x00800100, LENGTH = 0x00000780 - 0x00000100 } SECTIONS diff --git a/examples/chapter09_08/target/micros/avr/make/avr_flags.gmk b/examples/chapter09_08/target/micros/avr/make/avr_flags.gmk index c485981b4..22ab34f02 100644 --- a/examples/chapter09_08/target/micros/avr/make/avr_flags.gmk +++ b/examples/chapter09_08/target/micros/avr/make/avr_flags.gmk @@ -1,5 +1,5 @@ # -# Copyright Christopher Kormanyos 2007 - 2024. +# Copyright Christopher Kormanyos 2007 - 2025. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,23 +9,35 @@ # compiler flags for the target architecture # ------------------------------------------------------------------------------ -# See also: https://blog.zakkemble.net/avr-gcc-builds/ - +ifneq ($(MAKE),make) GCC_VERSION = 15.1.0 +endif + GCC_TARGET = avr GCC_PREFIX = avr TGT_SUFFIX = elf -TGT_CFLAGS = -Os \ - -mmcu=atmega328p \ - -fsigned-char \ - -mrelax +TGT_ALLFLAGS = -O2 \ + -mmcu=atmega328p \ + -mrelax \ + -finline-functions \ + -finline-limit=32 \ + -fsigned-char + +ifeq ($(GCC_VERSION),15.1.0) +TGT_ALLFLAGS := $(TGT_ALLFLAGS) \ + -mdouble=32 \ + -mlong-double=64 +endif + +TGT_CFLAGS = -std=c11 \ + $(TGT_ALLFLAGS) -TGT_CPPFLAGS = -std=c++20 +TGT_CXXFLAGS = -std=c++20 \ + $(TGT_ALLFLAGS) -TGT_INCLUDES = -I$(PATH_APP)/util/STL_C++XX_stdfloat \ - -I$(PATH_APP)/util/STL +TGT_INCLUDES = -I$(PATH_APP)/util/STL TGT_AFLAGS = diff --git a/examples/chapter09_08a/build.bat b/examples/chapter09_08a/build.bat index 4f321bb19..7d8f3b968 100644 --- a/examples/chapter09_08a/build.bat +++ b/examples/chapter09_08a/build.bat @@ -1,6 +1,6 @@ @rem -@rem Copyright Christopher Kormanyos 2014 - 2021. +@rem Copyright Christopher Kormanyos 2014 - 2025. @rem Distributed under the Boost Software License, @rem Version 1.0. (See accompanying file LICENSE_1_0.txt @rem or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -27,7 +27,7 @@ @set TOOL_PATH=%1 @set TOOL_PREFIX=%2 -@set CFLAGS=-C -Wall -Wextra -pedantic -mmcu=atmega328p -fsigned-char -O2 -fno-exceptions -gdwarf-2 -ffunction-sections -fdata-sections +@set CFLAGS=-Wall -Wextra -Wpedantic -mmcu=atmega328p -fsigned-char -O2 -fno-exceptions @set CPPFLAGS=-std=c++14 -fno-rtti -fstrict-enums -fno-use-cxa-atexit -fno-use-cxa-get-exception-ptr -fno-nonansi-builtins -fno-threadsafe-statics -fno-enforce-eh-specs @set CINCLUDES=-Isrc/util/STL_C++XX_stdfloat -Isrc/util/STL -Isrc -Isrc/mcal/avr diff --git a/examples/chapter09_08a/build.sh b/examples/chapter09_08a/build.sh index 28cf733ec..3cfd4fef6 100755 --- a/examples/chapter09_08a/build.sh +++ b/examples/chapter09_08a/build.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright Christopher Kormanyos 2014 - 2020. +# Copyright Christopher Kormanyos 2014 - 2025. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/examples/chapter09_08a/chapter09_08a.vcxproj b/examples/chapter09_08a/chapter09_08a.vcxproj index dc8891183..8c179aeac 100644 --- a/examples/chapter09_08a/chapter09_08a.vcxproj +++ b/examples/chapter09_08a/chapter09_08a.vcxproj @@ -232,8 +232,8 @@ true - - + + @@ -362,6 +362,10 @@ true true + + true + true + true true @@ -438,6 +442,10 @@ true true + + true + true + true true @@ -458,6 +466,10 @@ true true + + true + true + diff --git a/examples/chapter09_08a/chapter09_08a.vcxproj.filters b/examples/chapter09_08a/chapter09_08a.vcxproj.filters index 2aa9d6a78..270792a69 100644 --- a/examples/chapter09_08a/chapter09_08a.vcxproj.filters +++ b/examples/chapter09_08a/chapter09_08a.vcxproj.filters @@ -164,9 +164,6 @@ src\mcal - - src\mcal - src\os @@ -176,9 +173,6 @@ src\os - - src\mcal - src\util\STL_C++XX_stdfloat @@ -257,9 +251,6 @@ src\util\STL\impl\avr - - src\util\STL - src\util\utility @@ -368,11 +359,35 @@ src\mcal\win32 + + src\mcal + + + src\mcal + + + src\util\STL + src\util\STL_C++XX_stdfloat + + _doc + + + src\util\STL + + + src\util\STL + + + src\util\STL + + + src\util\STL + src\util\STL @@ -388,6 +403,9 @@ src\util\STL + + src\util\STL + src\util\STL @@ -403,6 +421,9 @@ src\util\STL + + src\util\STL + src\util\STL @@ -439,6 +460,9 @@ src\util\STL + + src\util\STL + src\util\STL @@ -469,21 +493,6 @@ src\util\STL - - src\util\STL - - - src\util\STL - - - src\util\STL - - - src\util\STL - - - _doc - diff --git a/examples/chapter09_08a/src/app/led/app_led.cpp b/examples/chapter09_08a/src/app/led/app_led.cpp index a51c3d39c..41deb245b 100644 --- a/examples/chapter09_08a/src/app/led/app_led.cpp +++ b/examples/chapter09_08a/src/app/led/app_led.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -26,12 +26,12 @@ namespace using app_led_monochrome_timer_type = util::timer; using app_led_rgb_timer_type = util::timer; - auto app_led_monochrome_timer = static_cast(app_led_monochrome_timer_type::seconds(1U)); - auto app_led_rgb_timer = static_cast(app_led_rgb_timer_type::milliseconds(30U)); + auto app_led_monochrome_timer = static_cast(app_led_monochrome_timer_type::seconds(UINT8_C(1))); + auto app_led_rgb_timer = static_cast(app_led_rgb_timer_type::milliseconds(UINT8_C(30))); - auto app_led_hue_r = static_cast(UINT8_C(255)); - auto app_led_hue_g = static_cast(UINT8_C(0)); - auto app_led_hue_b = static_cast(UINT8_C(0)); + std::uint_fast8_t app_led_hue_r { UINT8_C(255) }; + std::uint_fast8_t app_led_hue_g { UINT8_C(0) }; + std::uint_fast8_t app_led_hue_b { UINT8_C(0) }; } auto app::led::task_init() -> void diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_cpu.cpp b/examples/chapter09_08a/src/mcal/avr/mcal_cpu.cpp index 563fa3ca9..3f5184e27 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_cpu.cpp +++ b/examples/chapter09_08a/src/mcal/avr/mcal_cpu.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,7 +10,7 @@ #include #include -void mcal::cpu::init() +auto mcal::cpu::init() -> void { mcal::wdg::init(nullptr); mcal::port::init(nullptr); diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_cpu.h b/examples/chapter09_08a/src/mcal/avr/mcal_cpu.h index 628cdd28e..0c8cb16c9 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_cpu.h +++ b/examples/chapter09_08a/src/mcal/avr/mcal_cpu.h @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef MCAL_CPU_2009_02_14_H_ - #define MCAL_CPU_2009_02_14_H_ +#ifndef MCAL_CPU_2009_02_14_H + #define MCAL_CPU_2009_02_14_H #include @@ -16,10 +16,10 @@ { void init(); - inline void post_init() { } + inline auto post_init() -> void { } - inline void nop() noexcept { asm volatile("nop"); } + inline auto nop() noexcept -> void { asm volatile("nop"); } } } -#endif // MCAL_CPU_2009_02_14_H_ +#endif // MCAL_CPU_2009_02_14_H diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_irq.cpp b/examples/chapter09_08a/src/mcal/avr/mcal_irq.cpp index 41307e71a..5e60cf497 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_irq.cpp +++ b/examples/chapter09_08a/src/mcal/avr/mcal_irq.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,7 +7,7 @@ #include -void mcal::irq::init(const config_type*) +auto mcal::irq::init(const config_type*) -> void { mcal::irq::enable_all(); } diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_irq.h b/examples/chapter09_08a/src/mcal/avr/mcal_irq.h index 7dc173d65..1adbd9536 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_irq.h +++ b/examples/chapter09_08a/src/mcal/avr/mcal_irq.h @@ -1,24 +1,24 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef MCAL_IRQ_2010_04_10_H_ - #define MCAL_IRQ_2010_04_10_H_ +#ifndef MCAL_IRQ_2010_04_10_H + #define MCAL_IRQ_2010_04_10_H namespace mcal { namespace irq { - typedef void config_type; + using config_type = void; - void init(const config_type*); + auto init(const config_type*) -> void; - inline void enable_all () noexcept { asm volatile("sei"); } - inline void disable_all() noexcept { asm volatile("cli"); } + inline auto enable_all () noexcept -> void { asm volatile("sei"); } + inline auto disable_all() noexcept -> void { asm volatile("cli"); } } } -#endif // MCAL_IRQ_2010_04_10_H_ +#endif // MCAL_IRQ_2010_04_10_H diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_led_sys_start_interface.cpp b/examples/chapter09_08a/src/mcal/avr/mcal_led_sys_start_interface.cpp index db169c6f9..f3a8e9f2a 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_led_sys_start_interface.cpp +++ b/examples/chapter09_08a/src/mcal/avr/mcal_led_sys_start_interface.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2017 - 2018. +// Copyright Christopher Kormanyos 2017 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,9 +7,9 @@ #include -bool& mcal::led::sys_start_interface::my_exit_pc_api_flag() +auto mcal::led::sys_start_interface::my_exit_pc_api_flag() -> bool& { - static bool my_flag; + static bool my_flag { }; return my_flag; } diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_led_sys_start_interface.h b/examples/chapter09_08a/src/mcal/avr/mcal_led_sys_start_interface.h index b2673691c..232bf70ee 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_led_sys_start_interface.h +++ b/examples/chapter09_08a/src/mcal/avr/mcal_led_sys_start_interface.h @@ -1,22 +1,22 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2017 - 2018. +// Copyright Christopher Kormanyos 2017 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef MCAL_LED_SYS_START_INTERFACE_2017_11_21_H_ - #define MCAL_LED_SYS_START_INTERFACE_2017_11_21_H_ +#ifndef MCAL_LED_SYS_START_INTERFACE_2017_11_21_H + #define MCAL_LED_SYS_START_INTERFACE_2017_11_21_H namespace mcal { namespace led { struct sys_start_interface { - static void my_sys_start(); + static auto my_sys_start() -> void; - static bool& my_exit_pc_api_flag(); + static auto my_exit_pc_api_flag() -> bool&; }; } } // namespace mcal::led -#endif // MCAL_LED_SYS_START_INTERFACE_2017_11_21_H_ +#endif // MCAL_LED_SYS_START_INTERFACE_2017_11_21_H diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_memory_progmem.h b/examples/chapter09_08a/src/mcal/avr/mcal_memory_progmem.h index 50df07fa1..69812a21a 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_memory_progmem.h +++ b/examples/chapter09_08a/src/mcal/avr/mcal_memory_progmem.h @@ -1,17 +1,17 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2019 - 2023. +// Copyright Christopher Kormanyos 2019 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef MCAL_MEMORY_PROGMEM_2019_08_17_H_ - #define MCAL_MEMORY_PROGMEM_2019_08_17_H_ - - #include +#ifndef MCAL_MEMORY_PROGMEM_2019_08_17_H + #define MCAL_MEMORY_PROGMEM_2019_08_17_H #include + #include + #define MY_PROGMEM PROGMEM #if defined(__cplusplus) @@ -59,4 +59,4 @@ } #endif -#endif // MCAL_MEMORY_PROGMEM_2019_08_17_H_ +#endif // MCAL_MEMORY_PROGMEM_2019_08_17_H diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_osc.cpp b/examples/chapter09_08a/src/mcal/avr/mcal_osc.cpp index ccfd6831f..6ae0b6324 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_osc.cpp +++ b/examples/chapter09_08a/src/mcal/avr/mcal_osc.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,6 +7,6 @@ #include -void mcal::osc::init(const config_type*) +auto mcal::osc::init(const config_type*) -> void { } diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_osc.h b/examples/chapter09_08a/src/mcal/avr/mcal_osc.h index f433c4e0e..cb8944d84 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_osc.h +++ b/examples/chapter09_08a/src/mcal/avr/mcal_osc.h @@ -1,21 +1,21 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef MCAL_OSC_2011_10_20_H_ - #define MCAL_OSC_2011_10_20_H_ +#ifndef MCAL_OSC_2011_10_20_H + #define MCAL_OSC_2011_10_20_H namespace mcal { namespace osc { - typedef void config_type; + using config_type = void; - void init(const config_type*); + auto init(const config_type*) -> void; } } -#endif // MCAL_OSC_2011_10_20_H_ +#endif // MCAL_OSC_2011_10_20_H diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_port.cpp b/examples/chapter09_08a/src/mcal/avr/mcal_port.cpp index a774691e7..e19b30c3b 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_port.cpp +++ b/examples/chapter09_08a/src/mcal/avr/mcal_port.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,6 +7,6 @@ #include -void mcal::port::init(const config_type*) +auto mcal::port::init(const config_type*) -> void { } diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_port.h b/examples/chapter09_08a/src/mcal/avr/mcal_port.h index 077cb66c2..fbe2a2bd2 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_port.h +++ b/examples/chapter09_08a/src/mcal/avr/mcal_port.h @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2020. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef MCAL_PORT_2012_06_27_H_ - #define MCAL_PORT_2012_06_27_H_ +#ifndef MCAL_PORT_2012_06_27_H + #define MCAL_PORT_2012_06_27_H #include @@ -14,9 +14,9 @@ { namespace port { - typedef void config_type; + using config_type = void; - void init(const config_type*); + auto init(const config_type*) -> void; template void { // Set the port pin's direction to output. // C++: @@ -46,7 +46,7 @@ asm volatile("sbi %[myport],%[mybit]" : : [myport]"I"(pdir_address - sfr_offset), [mybit]"I"(bpos_value)); } - static void set_direction_input() + static auto set_direction_input() -> void { // Set the port pin's direction to input. // C++: @@ -57,7 +57,7 @@ asm volatile("cbi %[myport],%[mybit]" : : [myport]"I"(pdir_address - sfr_offset), [mybit]"I"(bpos_value)); } - static void set_pin_high() + static auto set_pin_high() -> void { // Set the port output value to high. // C++: @@ -68,7 +68,7 @@ asm volatile("sbi %[myport],%[mybit]" : : [myport]"I"(port_address - sfr_offset), [mybit]"I"(bpos_value)); } - static void set_pin_low() + static auto set_pin_low() -> void { // Set the port output value to low. // C++: @@ -79,7 +79,7 @@ asm volatile("cbi %[myport],%[mybit]" : : [myport]"I"(port_address - sfr_offset), [mybit]"I"(bpos_value)); } - static bool read_input_value() + static auto read_input_value() -> bool { // Read the port input value. return mcal::reg::reg_access_static::bit_get(); } - static void toggle_pin() + static auto toggle_pin() -> void { // Toggle the port output value. mcal::reg::reg_access_static @@ -17,76 +17,91 @@ constexpr std::uint8_t sfr_offset = 0x20U; // Bit-position values. - constexpr std::uint8_t bval0 = 1U; - constexpr std::uint8_t bval1 = 1U << 1U; - constexpr std::uint8_t bval2 = 1U << 2U; - constexpr std::uint8_t bval3 = 1U << 3U; - constexpr std::uint8_t bval4 = 1U << 4U; - constexpr std::uint8_t bval5 = 1U << 5U; - constexpr std::uint8_t bval6 = 1U << 6U; - constexpr std::uint8_t bval7 = 1U << 7U; + constexpr std::uint8_t bval0 { 1U }; + constexpr std::uint8_t bval1 { 1U << 1U }; + constexpr std::uint8_t bval2 { 1U << 2U }; + constexpr std::uint8_t bval3 { 1U << 3U }; + constexpr std::uint8_t bval4 { 1U << 4U }; + constexpr std::uint8_t bval5 { 1U << 5U }; + constexpr std::uint8_t bval6 { 1U << 6U }; + constexpr std::uint8_t bval7 { 1U << 7U }; // System registers. - constexpr std::uint8_t mcusr = 0x14U + sfr_offset; - constexpr std::uint8_t prr = 0x64U; + constexpr std::uint8_t mcusr { 0x14U + sfr_offset }; + constexpr std::uint8_t prr { 0x64U }; // Port registers. - constexpr std::uint8_t pinb = 0x03U + sfr_offset; - constexpr std::uint8_t ddrb = 0x04U + sfr_offset; - constexpr std::uint8_t portb = 0x05U + sfr_offset; - constexpr std::uint8_t pinc = 0x06U + sfr_offset; - constexpr std::uint8_t ddrc = 0x07U + sfr_offset; - constexpr std::uint8_t portc = 0x08U + sfr_offset; - constexpr std::uint8_t pind = 0x09U + sfr_offset; - constexpr std::uint8_t ddrd = 0x0AU + sfr_offset; - constexpr std::uint8_t portd = 0x0BU + sfr_offset; - constexpr std::uint8_t pine = 0x0CU + sfr_offset; - constexpr std::uint8_t ddre = 0x0DU + sfr_offset; - constexpr std::uint8_t porte = 0x0EU + sfr_offset; + constexpr std::uint8_t pinb { 0x03U + sfr_offset }; + constexpr std::uint8_t ddrb { 0x04U + sfr_offset }; + constexpr std::uint8_t portb { 0x05U + sfr_offset }; + constexpr std::uint8_t pinc { 0x06U + sfr_offset }; + constexpr std::uint8_t ddrc { 0x07U + sfr_offset }; + constexpr std::uint8_t portc { 0x08U + sfr_offset }; + constexpr std::uint8_t pind { 0x09U + sfr_offset }; + constexpr std::uint8_t ddrd { 0x0AU + sfr_offset }; + constexpr std::uint8_t portd { 0x0BU + sfr_offset }; + constexpr std::uint8_t pine { 0x0CU + sfr_offset }; + constexpr std::uint8_t ddre { 0x0DU + sfr_offset }; + constexpr std::uint8_t porte { 0x0EU + sfr_offset }; + + // Timer register values + constexpr std::uint8_t cs10 = 0U; + constexpr std::uint8_t cs11 = 1U; + constexpr std::uint8_t cs12 = 2U; + constexpr std::uint8_t wgm12 = 3U; + constexpr std::uint8_t toie1 = 0U; + constexpr std::uint8_t ocie0a = 1U; + constexpr std::uint8_t ocie0b = 2U; + constexpr std::uint8_t toie0 = 0U; + constexpr std::uint8_t ocie1a = 1U; + constexpr std::uint8_t ocie1b = 2U; + constexpr std::uint8_t toie2 = 0U; + constexpr std::uint8_t ocie2a = 1U; + constexpr std::uint8_t ocie2b = 2U; // Timer registers - constexpr std::uint8_t tifr0 = 0x15U + sfr_offset; - constexpr std::uint8_t tccr0a = 0x24U + sfr_offset; - constexpr std::uint8_t tccr0b = 0x25U + sfr_offset; - constexpr std::uint8_t tcnt0 = 0x26U + sfr_offset; - constexpr std::uint8_t ocr0a = 0x27U + sfr_offset; - constexpr std::uint8_t timsk0 = 0x6EU; + constexpr std::uint8_t tifr0 { 0x15U + sfr_offset }; + constexpr std::uint8_t tccr0a { 0x24U + sfr_offset }; + constexpr std::uint8_t tccr0b { 0x25U + sfr_offset }; + constexpr std::uint8_t tcnt0 { 0x26U + sfr_offset }; + constexpr std::uint8_t ocr0a { 0x27U + sfr_offset }; + constexpr std::uint8_t timsk0 { 0x6EU }; - constexpr std::uint8_t tifr1 = 0x16U + sfr_offset; - constexpr std::uint8_t tccr1a = 0x80U; - constexpr std::uint8_t tccr1b = 0x81U; - constexpr std::uint8_t tcnt1l = 0x84U; - constexpr std::uint8_t tcnt1h = 0x85U; - constexpr std::uint8_t icr1 = 0x86U; // 16-bit register - constexpr std::uint8_t ocr1a = 0x88U; // 16-bit register - constexpr std::uint8_t ocr1b = 0x8AU; // 16-bit register - constexpr std::uint8_t timsk1 = 0x6FU; + constexpr std::uint8_t tifr1 { 0x16U + sfr_offset }; + constexpr std::uint8_t tccr1a { 0x80U }; + constexpr std::uint8_t tccr1b { 0x81U }; + constexpr std::uint8_t tcnt1l { 0x84U }; + constexpr std::uint8_t tcnt1h { 0x85U }; + constexpr std::uint8_t icr1 { 0x86U }; // 16-bit register + constexpr std::uint8_t ocr1a { 0x88U }; // 16-bit register + constexpr std::uint8_t ocr1b { 0x8AU }; // 16-bit register + constexpr std::uint8_t timsk1 { 0x6FU }; - constexpr std::uint8_t tifr2 = 0x17U + sfr_offset; - constexpr std::uint8_t tccr2a = 0xB0U; - constexpr std::uint8_t tccr2b = 0xB1U; - constexpr std::uint8_t tcnt2 = 0xB2U; - constexpr std::uint8_t ocr2a = 0xB3U; - constexpr std::uint8_t timsk2 = 0x70U; + constexpr std::uint8_t tifr2 { 0x17U + sfr_offset }; + constexpr std::uint8_t tccr2a { 0xB0U }; + constexpr std::uint8_t tccr2b { 0xB1U }; + constexpr std::uint8_t tcnt2 { 0xB2U }; + constexpr std::uint8_t ocr2a { 0xB3U }; + constexpr std::uint8_t timsk2 { 0x70U }; // SPI(TM) registers. - constexpr std::uint8_t spcr = 0x2CU + sfr_offset; - constexpr std::uint8_t spsr = 0x2DU + sfr_offset; - constexpr std::uint8_t spdr = 0x2EU + sfr_offset; + constexpr std::uint8_t spcr { 0x2CU + sfr_offset }; + constexpr std::uint8_t spsr { 0x2DU + sfr_offset }; + constexpr std::uint8_t spdr { 0x2EU + sfr_offset }; // Watchdog registers - constexpr std::uint8_t wdtcsr = 0x60U; + constexpr std::uint8_t wdtcsr { 0x60U }; // Eeprom registers - constexpr std::uint8_t eecr = 0x1FU + sfr_offset; - constexpr std::uint8_t eedr = 0x20U + sfr_offset; - constexpr std::uint8_t eear = 0x21U + sfr_offset; - constexpr std::uint8_t eearl = 0x21U + sfr_offset; - constexpr std::uint8_t eearh = 0x22U + sfr_offset; + constexpr std::uint8_t eecr { 0x1FU + sfr_offset }; + constexpr std::uint8_t eedr { 0x20U + sfr_offset }; + constexpr std::uint8_t eear { 0x21U + sfr_offset }; + constexpr std::uint8_t eearl { 0x21U + sfr_offset }; + constexpr std::uint8_t eearh { 0x22U + sfr_offset }; } } #include #include -#endif // MCAL_REG_2010_04_10_H_ +#endif // MCAL_REG_2010_04_10_H diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_wdg.cpp b/examples/chapter09_08a/src/mcal/avr/mcal_wdg.cpp index dd57b568b..2165648cd 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_wdg.cpp +++ b/examples/chapter09_08a/src/mcal/avr/mcal_wdg.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,7 +8,7 @@ #include #include -void mcal::wdg::init(const config_type*) +auto mcal::wdg::init(const config_type*) -> void { // Read the MCU status register. volatile const std::uint8_t mcu_status_register = @@ -29,22 +29,31 @@ void mcal::wdg::init(const config_type*) // Reset the watchdog timer. asm volatile("wdr"); - // Set the watchdog timer period and activate the watchdog timer. + // Start timed sequence in order to set the watchdog + // timer period and activate the watchdog timer. mcal::reg::reg_access_static::reg_set(); - // See Chapter 11.9.2, Table 11-2: Watchdog Timer Prescale Select. - // Select WDP3:WDP0 in WDTCSR to binary 0b0111, resulting - // in a watchdog period of approximately 2s. + // In "Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf", + // see Chapter 10.9.2, Table 10-3: Watchdog Timer Prescale Select. + // Set WDP3 (bit 5) and clear WDP2:WDP0 (bits 0, 1 and 2) in WDTCSR + // (i.e., set to hex 0x20). This results in a watchdog period + // of approximately 4s. mcal::reg::reg_access_static::reg_set(); + std::uint8_t(0x20U)>::reg_set(); + + // Set WDRF in the MCU status register. + mcal::reg::reg_access_static::bit_set(); } -void mcal::wdg::secure::trigger() +auto mcal::wdg::secure::trigger() -> void { asm volatile("wdr"); } diff --git a/examples/chapter09_08a/src/mcal/avr/mcal_wdg.h b/examples/chapter09_08a/src/mcal/avr/mcal_wdg.h index a03229a51..8e8141310 100644 --- a/examples/chapter09_08a/src/mcal/avr/mcal_wdg.h +++ b/examples/chapter09_08a/src/mcal/avr/mcal_wdg.h @@ -1,39 +1,34 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef MCAL_WDT_2010_04_10_H_ - #define MCAL_WDT_2010_04_10_H_ +#ifndef MCAL_WDT_2010_04_10_H + #define MCAL_WDT_2010_04_10_H extern "C" void __my_startup() __attribute__((section(".startup"), used, noinline)); - namespace sys { namespace idle { void task_func(); } } - - namespace util { template class timer; } + namespace sys { namespace idle { auto task_func() -> void; } } namespace mcal { namespace wdg { - typedef void config_type; + using config_type = void; - void init(const config_type*); + auto init(const config_type*) -> void; struct secure final { private: - friend void ::sys::idle::task_func(); - friend void ::__my_startup(); - - template - friend class util::timer; + static auto trigger() -> void; - static void trigger(); + friend auto ::sys::idle::task_func() -> void; + friend auto ::__my_startup() -> void; }; } } -#endif // MCAL_WDT_2010_04_10_H_ +#endif // MCAL_WDT_2010_04_10_H diff --git a/examples/chapter09_08a/src/mcal/mcal_gcc_cxx_completion.cpp b/examples/chapter09_08a/src/mcal/mcal_gcc_cxx_completion.cpp index 1aaa4b8e8..ed32e0112 100644 --- a/examples/chapter09_08a/src/mcal/mcal_gcc_cxx_completion.cpp +++ b/examples/chapter09_08a/src/mcal/mcal_gcc_cxx_completion.cpp @@ -1,22 +1,28 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include -#include #include #include +#include +#include + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-declarations" +#endif + // Implement std::chrono::high_resolution_clock::now() // for the standard library's high-resolution clock. namespace std { namespace chrono { - high_resolution_clock::time_point high_resolution_clock::now() UTIL_NOEXCEPT + high_resolution_clock::time_point high_resolution_clock::now() noexcept { // The source of the high-resolution clock is microseconds. using microsecond_time_point_type = @@ -37,12 +43,7 @@ namespace std } } -void operator delete(void*) UTIL_NOEXCEPT; -void operator delete(void*, void*) UTIL_NOEXCEPT; - -void* operator new(std::size_t size) UTIL_NOEXCEPT; - -void* operator new(std::size_t size) UTIL_NOEXCEPT +void* operator new(std::size_t size) { // This is a naive and not completely functional // implementation of operator new(). In particular, there is @@ -51,10 +52,10 @@ void* operator new(std::size_t size) UTIL_NOEXCEPT volatile static std::uint8_t* get_ptr = buffer; // Get the newly allocated pointer. - volatile std::uint8_t* p = get_ptr; + volatile std::uint8_t* p { get_ptr }; // Does this allocation overflow the top of the buffer? - const bool is_overflow = ((get_ptr + size) >= (buffer + sizeof(buffer))); + const bool is_overflow { ((get_ptr + size) >= (buffer + sizeof(buffer))) }; // Increment the pointer for next time. // But only do this if the buffer does *not* overflow. @@ -70,10 +71,13 @@ void* operator new(std::size_t size) UTIL_NOEXCEPT return static_cast(const_cast(p)); } -void operator delete(void*) UTIL_NOEXCEPT { } -void operator delete(void*, void*) UTIL_NOEXCEPT { } +void operator delete(void*) noexcept { } +#if (defined(__GNUC__) && (__GNUC__ >= 12)) +#else +void operator delete(void*, void*) noexcept { } +#endif #if(__cplusplus >= 201400L) -void operator delete(void*, std::size_t) UTIL_NOEXCEPT { } +void operator delete(void*, std::size_t) noexcept { } #endif extern "C" @@ -84,15 +88,13 @@ extern "C" // Also provide stubbed copies of certain empirically found library functions // and objects. - typedef struct struct_unwind_exception_type { unsigned dummy; } _Unwind_Exception; - - void abort () UTIL_NOEXCEPT __attribute__((noreturn)); - int atexit (void (*)()) UTIL_NOEXCEPT; - int at_quick_exit (void (*)()) UTIL_NOEXCEPT; - void _Exit (int) UTIL_NOEXCEPT __attribute__((noreturn)); - void exit (int) __attribute__((noreturn)); - void quick_exit (int) __attribute__((noreturn)); - int _exit (int); + void abort () __attribute__((noreturn)); + int atexit (void (*)()); + int at_quick_exit (void (*)()); + void _Exit (int) __attribute__((noreturn)); + void exit (int) __attribute__((noreturn)); + void quick_exit (int) __attribute__((noreturn)); + void _exit (int) __attribute__((noreturn)); int _isatty (int); int _lseek (int, int, int); int _open (const char*, int, int); @@ -105,17 +107,16 @@ extern "C" int _kill (int, int); void __cxa_pure_virtual (); char* __cxa_demangle (const char*, char*, size_t*, int*); - void __cxa_call_terminate(_Unwind_Exception*); // Implementations of patched functions. - void abort () UTIL_NOEXCEPT { for(;;) { mcal::cpu::nop(); } } - int atexit (void (*)()) UTIL_NOEXCEPT { return 0; } - int at_quick_exit (void (*)()) UTIL_NOEXCEPT { return 0; } - void _Exit (int) UTIL_NOEXCEPT { for(;;) { mcal::cpu::nop(); } } + void abort () { for(;;) { mcal::cpu::nop(); } } + int atexit (void (*)()) { return 0; } + int at_quick_exit (void (*)()) { return 0; } + void _Exit (int) { for(;;) { mcal::cpu::nop(); } } void exit (int) { for(;;) { mcal::cpu::nop(); } } void quick_exit (int) { _Exit(0); } - int _exit (int) { return -1; } + void _exit (int) { for(;;) { mcal::cpu::nop(); } } int _isatty (int) { return 1; } int _lseek (int, int, int) { return 0; } int _open (const char*, int, int) { return -1; } @@ -128,22 +129,40 @@ extern "C" int _kill (int, int) { return -1; } void __cxa_pure_virtual () { } char* __cxa_demangle (const char*, char*, size_t*, int*) { return nullptr; } - void __cxa_call_terminate(_Unwind_Exception*) { } + + #if defined(environ) + #undef environ + #endif // Provide some patched data values. - const char* const __env[1U] = { nullptr }; - const char** const environ = { nullptr }; + const char* const __env[1U] = { nullptr }; + + char** environ { nullptr }; + + #if (defined(__GNUC__) && defined(__v850__)) + #else + extern int* __errno(); + int* __errno() { return nullptr; } + #endif + + std::uint8_t __fdlib_version; - int __errno = 0; - std::uint8_t __fdlib_version = UINT8_C(0); + // Patched DSO label. + void* __dso_handle; +} + +void mcal_gcc_cxx_dummy() +{ + static_cast(__env); + static_cast(environ); } -// Provide some stubs for specific GCC error handling mechanisms. namespace std { - void __throw_length_error(char const*); - void __throw_logic_error (char const*); + [[noreturn]] + void __throw_out_of_range_fmt(char const*, ...) { for(;;) { ; } } } -void std::__throw_length_error(char const*) { } -void std::__throw_logic_error (char const*) { } +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif diff --git a/examples/chapter09_08a/src/mcal/mcal_reg_access_dynamic.h b/examples/chapter09_08a/src/mcal/mcal_reg_access_dynamic.h index 85cd37341..dd121cff7 100644 --- a/examples/chapter09_08a/src/mcal/mcal_reg_access_dynamic.h +++ b/examples/chapter09_08a/src/mcal/mcal_reg_access_dynamic.h @@ -1,37 +1,60 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2013 - 2019. +// Copyright Christopher Kormanyos 2013 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef MCAL_REG_ACCESS_DYNAMIC_2013_12_13_H_ - #define MCAL_REG_ACCESS_DYNAMIC_2013_12_13_H_ +#ifndef MCAL_REG_ACCESS_DYNAMIC_2013_12_13_H + #define MCAL_REG_ACCESS_DYNAMIC_2013_12_13_H + + #if defined(__GNUC__) && (__GNUC__ >= 12) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Warray-bounds" + #endif namespace mcal { namespace reg { - template + template struct reg_access_dynamic final { - static register_value_type - reg_get(const register_address_type address) { return *reinterpret_cast(address); } - - static void reg_set(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) = value; } - static void reg_and(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) &= value; } - static void reg_or (const register_address_type address, const register_value_type value) { *reinterpret_cast(address) |= value; } - static void reg_not(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) &= register_value_type(~value); } - static void reg_msk(const register_address_type address, const register_value_type value, - const register_value_type mask_value) { *reinterpret_cast(address) = register_value_type(register_value_type(reg_get(address) & register_value_type(~mask_value)) | register_value_type(value & mask_value)); } - - static void bit_set(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) |= static_cast(1UL << value); } - static void bit_clr(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) &= static_cast(~static_cast(1UL << value)); } - static void bit_not(const register_address_type address, const register_value_type value) { *reinterpret_cast(address) ^= static_cast(1UL << value); } - static bool bit_get(const register_address_type address, const register_value_type value) { return (static_cast(reg_get(address) & static_cast(1UL << value)) != static_cast(0U)); } + using register_address_type = RegisterAddressType; + using register_value_type = RegisterValueType; + + static auto reg_get(const register_address_type address) -> register_value_type { return *reinterpret_cast(address); } + static auto reg_set(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = value; } + static auto reg_and(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & value); } + static auto reg_or (const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa | value); } + static auto reg_not(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & static_cast(~value)); } + + static auto reg_msk(const register_address_type address, + const register_value_type value, + const register_value_type mask_value) -> void + { + volatile register_value_type* pa = reinterpret_cast(address); + + *pa = + static_cast + ( + static_cast(reg_get(address) & static_cast(~mask_value)) + | value + ); + } + + static auto bit_set(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa | static_cast(1UL << value)); } + static auto bit_clr(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & static_cast(~static_cast(1UL << value))); } + static auto bit_not(const register_address_type address, const register_value_type value) -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa ^ static_cast(1UL << value)); } + static auto bit_get(const register_address_type address, const register_value_type value) -> bool { return (static_cast(reg_get(address) & static_cast(1UL << value)) != static_cast(0U)); } }; } } -#endif // MCAL_REG_ACCESS_DYNAMIC_2013_12_13_H_ + #if defined(__GNUC__) && (__GNUC__ >= 12) + // -Warray-bounds + #pragma GCC diagnostic pop + #endif + +#endif // MCAL_REG_ACCESS_DYNAMIC_2013_12_13_H diff --git a/examples/chapter09_08a/src/mcal/mcal_reg_access_static.h b/examples/chapter09_08a/src/mcal/mcal_reg_access_static.h index 457ffa60a..a444f183f 100644 --- a/examples/chapter09_08a/src/mcal/mcal_reg_access_static.h +++ b/examples/chapter09_08a/src/mcal/mcal_reg_access_static.h @@ -1,39 +1,60 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2019. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef MCAL_REG_ACCESS_STATIC_2010_12_01_H_ - #define MCAL_REG_ACCESS_STATIC_2010_12_01_H_ +#ifndef MCAL_REG_ACCESS_STATIC_2010_12_01_H + #define MCAL_REG_ACCESS_STATIC_2010_12_01_H + + #if defined(__GNUC__) && (__GNUC__ >= 12) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Warray-bounds" + #endif namespace mcal { namespace reg { - template(0)> + template(0U)> struct reg_access_static final { - static void reg_set() { *reinterpret_cast(address) = value; } - static void reg_and() { *reinterpret_cast(address) &= value; } - static void reg_or () { *reinterpret_cast(address) |= value; } - static void reg_not() { *reinterpret_cast(address) &= register_value_type(~value); } - static register_value_type - reg_get() { return *reinterpret_cast(address); } + using register_value_type = RegisterValueType; + using register_address_type = RegisterAddressType; + + static auto reg_get() -> register_value_type { volatile register_value_type* pa = reinterpret_cast(address); return *pa; } + static auto reg_set() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = value; } + static auto reg_and() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & value); } + static auto reg_or () -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa | value); } + static auto reg_not() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & static_cast(~value)); } template - static void reg_msk() { *reinterpret_cast(address) = register_value_type(register_value_type(reg_get() & register_value_type(~mask_value)) | register_value_type(value & mask_value)); } + static auto reg_msk() -> void + { + volatile register_value_type* pa = reinterpret_cast(address); - static void bit_set() { *reinterpret_cast(address) |= static_cast(1ULL << value); } - static void bit_clr() { *reinterpret_cast(address) &= static_cast(~static_cast(1ULL << value)); } - static void bit_not() { *reinterpret_cast(address) ^= static_cast(1ULL << value); } - static bool bit_get() { return (static_cast(reg_get() & static_cast(1ULL << value)) != static_cast(0U)); } + *pa = + static_cast + ( + static_cast(reg_get() & static_cast(~mask_value)) + | value + ); + } + + static auto bit_set() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa | static_cast(1ULL << value)); } + static auto bit_clr() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa & static_cast(~static_cast(1ULL << value))); } + static auto bit_not() -> void { volatile register_value_type* pa = reinterpret_cast(address); *pa = static_cast(*pa ^ static_cast(1ULL << value)); } + static auto bit_get() -> bool { return (static_cast(reg_get() & static_cast(1ULL << value)) != static_cast(0U)); } }; } } -#endif // MCAL_REG_ACCESS_STATIC_2010_12_01_H_ + #if defined(__GNUC__) && (__GNUC__ >= 12) + #pragma GCC diagnostic pop + #endif + +#endif // MCAL_REG_ACCESS_STATIC_2010_12_01_H diff --git a/examples/chapter09_08a/src/mcal_memory/mcal_memory_progmem_array.h b/examples/chapter09_08a/src/mcal_memory/mcal_memory_progmem_array.h index be302e2d9..508c2c1c9 100644 --- a/examples/chapter09_08a/src/mcal_memory/mcal_memory_progmem_array.h +++ b/examples/chapter09_08a/src/mcal_memory/mcal_memory_progmem_array.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2019 - 2020. +// Copyright Christopher Kormanyos 2019 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -103,7 +103,7 @@ template bool operator!=(const array& left, const array& right) { - return ((left == right) == false); + return (!(left == right)); } template @@ -115,13 +115,13 @@ template bool operator>=(const array& left, const array& right) { - return ((left < right) == false); + return (!(left < right)); } template bool operator<=(const array& left, const array& right) { - return ((right < left) == false); + return (!(right < left)); } template diff --git a/examples/chapter09_08a/src/sys/start/sys_start.cpp b/examples/chapter09_08a/src/sys/start/sys_start.cpp index e7bd4bb74..7f7e613d4 100644 --- a/examples/chapter09_08a/src/sys/start/sys_start.cpp +++ b/examples/chapter09_08a/src/sys/start/sys_start.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2023. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -24,7 +24,9 @@ void mcal::led::sys_start_interface::my_sys_start() } #if !defined(_MSC_VER) -extern "C" int main() +auto main() -> int; + +auto main() -> int { mcal::led::sys_start_interface::my_sys_start(); } diff --git a/examples/chapter09_08a/src/util/STL/algorithm b/examples/chapter09_08a/src/util/STL/algorithm index c78174fba..b00919672 100644 --- a/examples/chapter09_08a/src/util/STL/algorithm +++ b/examples/chapter09_08a/src/util/STL/algorithm @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2018. +// Copyright Christopher Kormanyos 2007 - 2024. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -207,22 +207,20 @@ input_iterator2 first2, input_iterator2 last2) { - while(first1 != last1) + for( ; (first1 != last1) && (first2 != last2); static_cast(++first1), static_cast(++first2)) { - if((first2 == last2) || (*first2 < *first1)) - { - return false; - } - else if(*first1 < *first2) + if(*first1 < *first2) { return true; } - ++first1; - ++first2; + if(*first2 < *first1) + { + return false; + } } - return (first2 != last2); + return ((first1 == last1) && (first2 != last2)); } template::value_type; + + *result = result_value_type(*first); } return result; @@ -247,10 +247,12 @@ { while (first1 != last1) { + using out2_value_type = typename std::iterator_traits::value_type; + --last1; --last2; - *last2 = *last1; + *last2 = out2_value_type(*last1); } return last2; @@ -264,12 +266,12 @@ output_iterator result, unary_function_type unary_function) { - using output_value_type = typename std::iterator_traits::value_type; - while(first != last) { if(unary_function(*first)) { + using output_value_type = typename std::iterator_traits::value_type; + *result = output_value_type(*first); ++result; @@ -287,10 +289,10 @@ forward_iterator last, const value_type& value) { - using forward_value_type = typename std::iterator_traits::value_type; - for( ; first != last; ++first) { + using forward_value_type = typename std::iterator_traits::value_type; + *first = forward_value_type(value); } } @@ -315,10 +317,10 @@ forward_iterator last, generator_type generator) { - using forward_value_type = typename std::iterator_traits::value_type; - while(first != last) { + using forward_value_type = typename std::iterator_traits::value_type; + *first = forward_value_type(generator()); ++first; @@ -332,10 +334,10 @@ size_type count, generator_type generator) { - using output_value_type = typename std::iterator_traits::value_type; - for(size_type i = size_type(0); i < count; ++i) { + using output_value_type = typename std::iterator_traits::value_type; + *first = output_value_type(generator()); ++first; @@ -361,10 +363,10 @@ output_iterator result, unary_function_type unary_function) { - using output_value_type = typename std::iterator_traits::value_type; - for( ; first != last; ++first, ++result) { + using output_value_type = typename std::iterator_traits::value_type; + *result = output_value_type(unary_function(*first)); } @@ -381,10 +383,10 @@ output_iterator result, binary_function_type binary_function) { - using output_value_type = typename std::iterator_traits::value_type; - for( ; first1 != last1; ++first1, ++first2, ++result) { + using output_value_type = typename std::iterator_traits::value_type; + *result = output_value_type(binary_function(*first1, *first2)); } @@ -421,7 +423,7 @@ { while(first1 != last1) { - if(binary_function(*first1, *first2) == false) + if(!binary_function(*first1, *first2)) { break; } @@ -453,7 +455,7 @@ iterator_type last, unary_function_type unary_function) { - while((first != last) && (unary_function(*first) == false)) + while((first != last) && (!unary_function(*first))) { ++first; } @@ -467,7 +469,7 @@ iterator_type last, unary_function_type unary_function) { - while((first != last) && (unary_function(*first) == false)) + while((first != last) && (!unary_function(*first))) { ++first; } @@ -765,8 +767,8 @@ } template - void swap(swap_type& left, - swap_type& right) + STL_LOCAL_CONSTEXPR_ALGORITHMS void swap(swap_type& left, + swap_type& right) { if(&left != &right) { @@ -777,6 +779,16 @@ } } + template + STL_LOCAL_CONSTEXPR_ALGORITHMS void swap(swap_type&& left, + swap_type&& right) + { + const swap_type tmp(left); + + left = right; + right = tmp; + } + template STL_LOCAL_CONSTEXPR_ALGORITHMS void iter_swap(input_iterator1 left, @@ -793,9 +805,9 @@ template - input_iterator2 swap_ranges(input_iterator1 first1, - input_iterator1 last1, - input_iterator2 first2) + STL_LOCAL_CONSTEXPR_ALGORITHMS input_iterator2 swap_ranges(input_iterator1 first1, + input_iterator1 last1, + input_iterator2 first2) { while(first1 != last1) { @@ -810,8 +822,8 @@ template - void swap(value_type(&left) [N], - value_type(&right)[N]) + STL_LOCAL_CONSTEXPR_ALGORITHMS void swap(value_type(&left) [N], + value_type(&right)[N]) { swap_ranges(&left[0U], &left[N], &right[0U]); } @@ -824,7 +836,7 @@ { for( ; ; ++first) { - for( ; (first != last) && (unary_function(*first) == true); ++first) + for( ; (first != last) && unary_function(*first); ++first) { ; } @@ -834,7 +846,7 @@ break; } - for( ; (first != --last) && (unary_function(*last) == false); ) + for( ; (first != --last) && (!unary_function(*last)); ) { ; } diff --git a/examples/chapter09_08a/src/util/STL/array b/examples/chapter09_08a/src/util/STL/array index d409196a9..334327a5f 100644 --- a/examples/chapter09_08a/src/util/STL/array +++ b/examples/chapter09_08a/src/util/STL/array @@ -41,8 +41,8 @@ static STL_LOCAL_CONSTEXPR size_type static_size = N; - STL_LOCAL_CONSTEXPR_ALGORITHMS iterator begin() { return elems; } - STL_LOCAL_CONSTEXPR_ALGORITHMS iterator end () { return elems + N; } + STL_LOCAL_CONSTEXPR iterator begin() { return elems; } + STL_LOCAL_CONSTEXPR iterator end () { return elems + N; } STL_LOCAL_CONSTEXPR const_iterator begin() const { return elems; } STL_LOCAL_CONSTEXPR const_iterator end () const { return elems + N; } @@ -50,8 +50,8 @@ STL_LOCAL_CONSTEXPR const_iterator cbegin() const { return elems; } STL_LOCAL_CONSTEXPR const_iterator cend () const { return elems + N; } - STL_LOCAL_CONSTEXPR_ALGORITHMS reverse_iterator rbegin() { return reverse_iterator(elems + N); } - STL_LOCAL_CONSTEXPR_ALGORITHMS reverse_iterator rend () { return reverse_iterator(elems); } + STL_LOCAL_CONSTEXPR reverse_iterator rbegin() { return reverse_iterator(elems + N); } + STL_LOCAL_CONSTEXPR reverse_iterator rend () { return reverse_iterator(elems); } STL_LOCAL_CONSTEXPR const_reverse_iterator rbegin() const { return const_reverse_iterator(elems + N); } STL_LOCAL_CONSTEXPR const_reverse_iterator rend () const { return const_reverse_iterator(elems); } @@ -59,54 +59,54 @@ STL_LOCAL_CONSTEXPR const_reverse_iterator crbegin() const { return const_reverse_iterator(elems + N); } STL_LOCAL_CONSTEXPR const_reverse_iterator crend () const { return const_reverse_iterator(elems); } - STL_LOCAL_CONSTEXPR_ALGORITHMS reference operator[](const size_type i) { return elems[i]; } - STL_LOCAL_CONSTEXPR const_reference operator[](const size_type i) const { return elems[i]; } + STL_LOCAL_CONSTEXPR reference operator[](const size_type i) { return elems[i]; } + STL_LOCAL_CONSTEXPR const_reference operator[](const size_type i) const { return elems[i]; } - STL_LOCAL_CONSTEXPR_ALGORITHMS reference at(const size_type i) { return elems[i]; } - STL_LOCAL_CONSTEXPR const_reference at(const size_type i) const { return elems[i]; } + STL_LOCAL_CONSTEXPR reference at(const size_type i) { return elems[i]; } + STL_LOCAL_CONSTEXPR const_reference at(const size_type i) const { return elems[i]; } - STL_LOCAL_CONSTEXPR_ALGORITHMS reference front() { return elems[0U]; } - STL_LOCAL_CONSTEXPR const_reference front() const { return elems[0U]; } + STL_LOCAL_CONSTEXPR reference front() { return elems[0U]; } + STL_LOCAL_CONSTEXPR const_reference front() const { return elems[0U]; } - STL_LOCAL_CONSTEXPR_ALGORITHMS reference back() { return elems[N - 1U]; } - STL_LOCAL_CONSTEXPR const_reference back() const { return elems[N - 1U]; } + STL_LOCAL_CONSTEXPR reference back() { return elems[N - 1U]; } + STL_LOCAL_CONSTEXPR const_reference back() const { return elems[N - 1U]; } static STL_LOCAL_CONSTEXPR size_type size() { return N; } static STL_LOCAL_CONSTEXPR bool empty() { return false; } static STL_LOCAL_CONSTEXPR size_type max_size() { return N; } template - STL_LOCAL_CONSTEXPR_ALGORITHMS void swap(array& y) + STL_LOCAL_CONSTEXPR void swap(array& y) { std::swap_ranges(begin(), end(), y.begin()); } - STL_LOCAL_CONSTEXPR const_pointer data() const { return elems; } - STL_LOCAL_CONSTEXPR_ALGORITHMS pointer data() { return elems; } + STL_LOCAL_CONSTEXPR const_pointer data() const { return elems; } + STL_LOCAL_CONSTEXPR pointer data() { return elems; } pointer c_array() { return elems; } template - STL_LOCAL_CONSTEXPR_ALGORITHMS array& operator=(const array& y) + STL_LOCAL_CONSTEXPR array& operator=(const array& y) { std::copy(y.begin(), y.end(), begin()); return *this; } - STL_LOCAL_CONSTEXPR_ALGORITHMS void assign(const value_type& value) + STL_LOCAL_CONSTEXPR void assign(const value_type& value) { std::fill_n(elems, N, value); } - STL_LOCAL_CONSTEXPR_ALGORITHMS void fill(const value_type& value) + STL_LOCAL_CONSTEXPR void fill(const value_type& value) { std::fill_n(elems, N, value); } }; template - STL_LOCAL_CONSTEXPR_ALGORITHMS bool operator==(const array& left, const array& right) + STL_LOCAL_CONSTEXPR bool operator==(const array& left, const array& right) { return std::equal(left.begin(), left.end(), right.begin()); } @@ -121,31 +121,31 @@ } template - STL_LOCAL_CONSTEXPR_ALGORITHMS bool operator!=(const array& left, const array& right) + STL_LOCAL_CONSTEXPR bool operator!=(const array& left, const array& right) { - return ((left == right) == false); + return (!(left == right)); } template - STL_LOCAL_CONSTEXPR_ALGORITHMS bool operator>(const array& left, const array& right) + STL_LOCAL_CONSTEXPR bool operator>(const array& left, const array& right) { return (right < left); } template - STL_LOCAL_CONSTEXPR_ALGORITHMS bool operator>=(const array& left, const array& right) + STL_LOCAL_CONSTEXPR bool operator>=(const array& left, const array& right) { - return ((left < right) == false); + return (!(left < right)); } template - STL_LOCAL_CONSTEXPR_ALGORITHMS bool operator<=(const array& left, const array& right) + STL_LOCAL_CONSTEXPR bool operator<=(const array& left, const array& right) { - return ((right < left) == false); + return (!(right < left)); } template - STL_LOCAL_CONSTEXPR_ALGORITHMS void swap(array& x, array& y) + STL_LOCAL_CONSTEXPR void swap(array& x, array& y) { swap_ranges(x.begin(), x.end(), y.begin()); } diff --git a/examples/chapter09_08a/src/util/STL/charconv b/examples/chapter09_08a/src/util/STL/charconv index 6182e2f93..1cb80c4ec 100644 --- a/examples/chapter09_08a/src/util/STL/charconv +++ b/examples/chapter09_08a/src/util/STL/charconv @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2021 - 2022. +// Copyright Christopher Kormanyos 2021 - 2024. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,7 +8,9 @@ #ifndef CHARCONV_2021_04_12_ #define CHARCONV_2021_04_12_ - // Implement std::time_t of for compilers that do not yet support it. + // Implement some of for compilers that do not yet support it. + // At the moment, this contains nothing more than the implementation + // of the struct std::to_chars_result. #include @@ -37,13 +39,9 @@ to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete; - inline to_chars_result to_chars(char* first, char* last, float value) { return to_chars_result{ }; } - inline to_chars_result to_chars(char* first, char* last, double value) { return to_chars_result{ }; } - inline to_chars_result to_chars(char* first, char* last, long double value) { return to_chars_result{ }; } - - //to_chars_result to_chars(char* first, char* last, float value, chars_format fmt); - //to_chars_result to_chars(char* first, char* last, double value, chars_format fmt); - //to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt); + inline to_chars_result to_chars(char* first, char* last, float value) { static_cast(first); static_cast(last); static_cast(value); return to_chars_result{ }; } + inline to_chars_result to_chars(char* first, char* last, double value) { static_cast(first); static_cast(last); static_cast(value); return to_chars_result{ }; } + inline to_chars_result to_chars(char* first, char* last, long double value) { static_cast(first); static_cast(last); static_cast(value); return to_chars_result{ }; } } #endif // CHARCONV_2021_04_12_ diff --git a/examples/chapter09_08a/src/util/STL/chrono b/examples/chapter09_08a/src/util/STL/chrono index f2bd53724..0b047620a 100644 --- a/examples/chapter09_08a/src/util/STL/chrono +++ b/examples/chapter09_08a/src/util/STL/chrono @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2011 - 2022. +// Copyright Christopher Kormanyos 2011 - 2024. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -575,7 +575,7 @@ static const bool is_steady = false; // !!! PLATFORM AND OS SPECIFIC IMPLEMENTATION !!! - static time_point now() STL_LOCAL_NOEXCEPT; + static time_point now() noexcept; }; @@ -605,7 +605,7 @@ static const bool is_steady = true; // !!! PLATFORM AND OS SPECIFIC IMPLEMENTATION !!! - static time_point now() STL_LOCAL_NOEXCEPT; + static time_point now() noexcept; }; diff --git a/examples/chapter09_08a/src/util/STL/cinttypes b/examples/chapter09_08a/src/util/STL/cinttypes index 2c06e0981..168731795 100644 --- a/examples/chapter09_08a/src/util/STL/cinttypes +++ b/examples/chapter09_08a/src/util/STL/cinttypes @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2021. +// Copyright Christopher Kormanyos 2021 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,7 +8,11 @@ #ifndef CINTTYPES_2021_10_19_ #define CINTTYPES_2021_10_19_ + #if (defined(__GNUC__) && (defined(__RL78__) || defined(__v850__))) + #include + #else #include + #endif #include namespace std diff --git a/examples/chapter09_08a/src/util/STL/ciso646 b/examples/chapter09_08a/src/util/STL/ciso646 new file mode 100644 index 000000000..9d7087bec --- /dev/null +++ b/examples/chapter09_08a/src/util/STL/ciso646 @@ -0,0 +1,15 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2023. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef CISO646_2023_08_15 + #define CISO646_2023_08_15 + + // Implement some of for compilers that do not yet support it. + + #include + +#endif // CISO646_2023_08_15 diff --git a/examples/chapter09_08a/src/util/STL/cmath b/examples/chapter09_08a/src/util/STL/cmath index dc1d8ccdc..c8debf968 100644 --- a/examples/chapter09_08a/src/util/STL/cmath +++ b/examples/chapter09_08a/src/util/STL/cmath @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2022. +// Copyright Christopher Kormanyos 2007 - 2025. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,298 +9,416 @@ #define CMATH_2010_02_23_ #include + #include // Implement most of for compilers that do not yet support it. - #if defined(__GNUC__) && defined(__AVR__) + #if (defined(__GNUC__) && defined(__AVR__)) + #include - static_assert(__SIZEOF_LONG_DOUBLE__ >= __SIZEOF_DOUBLE__, + #if !defined(_HUGE_ENUF) + #define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow + #endif + + #if !defined(INFINITY) + #define INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) + #endif + + #if !defined(HUGE_VAL) + #define HUGE_VAL ((double)INFINITY) + #endif + + #if !defined(HUGE_VALF) + #define HUGE_VALF ((float)INFINITY) + #endif + + #if !defined(HUGE_VALL) + #define HUGE_VALL ((long double)INFINITY) + #endif + + #if !defined(NAN) + #define NAN (-(float)(INFINITY * 0.0F)) + #endif + + #if !defined(FP_NAN) + #define FP_NAN 0 + #endif + #if !defined(FP_INFINITE) + #define FP_INFINITE 1 + #endif + #if !defined(FP_ZERO) + #define FP_ZERO 2 + #endif + #if !defined(FP_SUBNORMAL) + #define FP_SUBNORMAL 3 + #endif + #if !defined(FP_NORMAL) + #define FP_NORMAL 4 + #endif + + #define _C2 1L // 0 if not 2's complement + #define FP_ILOGB0 (-0x7fffffffL - _C2) + #define FP_ILOGBNAN 0x7fffffffL + + static_assert((__SIZEOF_LONG_DOUBLE__ > 0) && (__SIZEOF_LONG_DOUBLE__ >= __SIZEOF_DOUBLE__), "Error: Configuration error regarding 64-bit double/long-double for AVR"); #if(__SIZEOF_DOUBLE__ == 4) - #define __BUILTIN_ISNANF __builtin_isnan - #define __BUILTIN_ISNAN __builtin_isnan - #define __BUILTIN_ISNANL __builtin_isnanl - #define __BUILTIN_FABSF __builtin_fabs - #define __BUILTIN_FABS __builtin_fabs - #define __BUILTIN_FABSL __builtin_fabsl - #define __BUILTIN_FMODF __builtin_fmod - #define __BUILTIN_FMOD __builtin_fmod - #define __BUILTIN_FMODL __builtin_fmodl - #define __BUILTIN_MODFF __builtin_modff - #define __BUILTIN_MODF __builtin_modf - #define __BUILTIN_MODFL __builtin_modfl - #define __BUILTIN_FLOORF __builtin_floor - #define __BUILTIN_FLOOR __builtin_floor - #define __BUILTIN_FLOORL __builtin_floorl - #define __BUILTIN_CEILF __builtin_ceil - #define __BUILTIN_CEIL __builtin_ceil - #define __BUILTIN_CEILL __builtin_ceill - #define __BUILTIN_FREXPF __builtin_frexp - #define __BUILTIN_FREXP __builtin_frexp - #define __BUILTIN_FREXPL __builtin_frexpl - #define __BUILTIN_LDEXPF __builtin_ldexp - #define __BUILTIN_LDEXP __builtin_ldexp - #define __BUILTIN_LDEXPL __builtin_ldexpl - #define __BUILTIN_LROUNDF __builtin_lround - #define __BUILTIN_LROUND __builtin_lround - #define __BUILTIN_LROUNDL __builtin_lroundl - #define __BUILTIN_SQRTF __builtin_sqrt - #define __BUILTIN_SQRT __builtin_sqrt - #define __BUILTIN_SQRTL __builtin_sqrtl - #define __BUILTIN_CBRTF __builtin_cbrt - #define __BUILTIN_CBRT __builtin_cbrt - #define __BUILTIN_CBRTL __builtin_cbrtl - #define __BUILTIN_SINF __builtin_sin - #define __BUILTIN_SIN __builtin_sin - #define __BUILTIN_SINL __builtin_sinl - #define __BUILTIN_COSF __builtin_cos - #define __BUILTIN_COS __builtin_cos - #define __BUILTIN_COSL __builtin_cosl - #define __BUILTIN_TANF __builtin_tan - #define __BUILTIN_TAN __builtin_tan - #define __BUILTIN_TANL __builtin_tanl - #define __BUILTIN_ASINF __builtin_asin - #define __BUILTIN_ASIN __builtin_asin - #define __BUILTIN_ASINL __builtin_asinl - #define __BUILTIN_ACOSF __builtin_acos - #define __BUILTIN_ACOS __builtin_acos - #define __BUILTIN_ACOSL __builtin_acosl - #define __BUILTIN_ATANF __builtin_atan - #define __BUILTIN_ATAN __builtin_atan - #define __BUILTIN_ATANL __builtin_atanl - #define __BUILTIN_ATAN2F __builtin_atan2 - #define __BUILTIN_ATAN2 __builtin_atan2 - #define __BUILTIN_ATAN2L __builtin_atan2l - #define __BUILTIN_EXPF __builtin_exp - #define __BUILTIN_EXP __builtin_exp - #define __BUILTIN_EXPL __builtin_expl - #define __BUILTIN_POWF __builtin_pow - #define __BUILTIN_POW __builtin_pow - #define __BUILTIN_POWL __builtin_powl - #define __BUILTIN_LOGF __builtin_log - #define __BUILTIN_LOG __builtin_log - #define __BUILTIN_LOGL __builtin_logl - #define __BUILTIN_LOG10F __builtin_log10 - #define __BUILTIN_LOG10 __builtin_log10 - #define __BUILTIN_LOG10L __builtin_log10l - #define __BUILTIN_SINHF __builtin_sinh - #define __BUILTIN_SINH __builtin_sinh - #define __BUILTIN_SINHL __builtin_sinhl - #define __BUILTIN_COSHF __builtin_cosh - #define __BUILTIN_COSH __builtin_cosh - #define __BUILTIN_COSHL __builtin_coshl - #define __BUILTIN_TANHF __builtin_tanh - #define __BUILTIN_TANH __builtin_tanh - #define __BUILTIN_TANHL __builtin_tanhl + #define __BUILTIN_ISNANF __builtin_isnan + #define __BUILTIN_ISNAN __builtin_isnan + #define __BUILTIN_ISNANL __builtin_isnanl + #define __BUILTIN_ISINFF __builtin_isinf + #define __BUILTIN_ISINF __builtin_isinf + #define __BUILTIN_ISINFL __builtin_isinfl + #define __BUILTIN_FABSF __builtin_fabs + #define __BUILTIN_FABS __builtin_fabs + #define __BUILTIN_FABSL __builtin_fabsl + #define __BUILTIN_FMODF __builtin_fmod + #define __BUILTIN_FMOD __builtin_fmod + #define __BUILTIN_FMODL __builtin_fmodl + #define __BUILTIN_MODFF __builtin_modff + #define __BUILTIN_MODF __builtin_modf + #define __BUILTIN_MODFL __builtin_modfl + #define __BUILTIN_FLOORF __builtin_floor + #define __BUILTIN_FLOOR __builtin_floor + #define __BUILTIN_FLOORL __builtin_floorl + #define __BUILTIN_CEILF __builtin_ceil + #define __BUILTIN_CEIL __builtin_ceil + #define __BUILTIN_CEILL __builtin_ceill + #define __BUILTIN_FREXPF __builtin_frexp + #define __BUILTIN_FREXP __builtin_frexp + #define __BUILTIN_FREXPL __builtin_frexpl + #define __BUILTIN_LDEXPF __builtin_ldexp + #define __BUILTIN_LDEXP __builtin_ldexp + #define __BUILTIN_LDEXPL __builtin_ldexpl + #define __BUILTIN_LROUNDF __builtin_lround + #define __BUILTIN_LROUND __builtin_lround + #define __BUILTIN_LROUNDL __builtin_lroundl + #define __BUILTIN_SQRTF __builtin_sqrt + #define __BUILTIN_SQRT __builtin_sqrt + #define __BUILTIN_SQRTL __builtin_sqrtl + #define __BUILTIN_CBRTF __builtin_cbrt + #define __BUILTIN_CBRT __builtin_cbrt + #define __BUILTIN_CBRTL __builtin_cbrtl + #define __BUILTIN_SINF __builtin_sin + #define __BUILTIN_SIN __builtin_sin + #define __BUILTIN_SINL __builtin_sinl + #define __BUILTIN_COSF __builtin_cos + #define __BUILTIN_COS __builtin_cos + #define __BUILTIN_COSL __builtin_cosl + #define __BUILTIN_TANF __builtin_tan + #define __BUILTIN_TAN __builtin_tan + #define __BUILTIN_TANL __builtin_tanl + #define __BUILTIN_ASINF __builtin_asin + #define __BUILTIN_ASIN __builtin_asin + #define __BUILTIN_ASINL __builtin_asinl + #define __BUILTIN_ACOSF __builtin_acos + #define __BUILTIN_ACOS __builtin_acos + #define __BUILTIN_ACOSL __builtin_acosl + #define __BUILTIN_ATANF __builtin_atan + #define __BUILTIN_ATAN __builtin_atan + #define __BUILTIN_ATANL __builtin_atanl + #define __BUILTIN_ATAN2F __builtin_atan2 + #define __BUILTIN_ATAN2 __builtin_atan2 + #define __BUILTIN_ATAN2L __builtin_atan2l + #define __BUILTIN_EXPF __builtin_exp + #define __BUILTIN_EXP __builtin_exp + #define __BUILTIN_EXPL __builtin_expl + #define __BUILTIN_POWF __builtin_pow + #define __BUILTIN_POW __builtin_pow + #define __BUILTIN_POWL __builtin_powl + #define __BUILTIN_LOGF __builtin_log + #define __BUILTIN_LOG __builtin_log + #define __BUILTIN_LOGL __builtin_logl + #define __BUILTIN_LOG10F __builtin_log10 + #define __BUILTIN_LOG10 __builtin_log10 + #define __BUILTIN_LOG10L __builtin_log10l + #define __BUILTIN_SINHF __builtin_sinh + #define __BUILTIN_SINH __builtin_sinh + #define __BUILTIN_SINHL __builtin_sinhl + #define __BUILTIN_COSHF __builtin_cosh + #define __BUILTIN_COSH __builtin_cosh + #define __BUILTIN_COSHL __builtin_coshl + #define __BUILTIN_TANHF __builtin_tanh + #define __BUILTIN_TANH __builtin_tanh + #define __BUILTIN_TANHL __builtin_tanhl #elif(__SIZEOF_DOUBLE__ == 8) - #define __BUILTIN_ISNANF __builtin_isnanf - #define __BUILTIN_ISNAN __builtin_isnanl - #define __BUILTIN_ISNANL __builtin_isnanl - #define __BUILTIN_FABSF __builtin_fabsf - #define __BUILTIN_FABS __builtin_fabsl - #define __BUILTIN_FABSL __builtin_fabsl - #define __BUILTIN_FMODF __builtin_fmodf - #define __BUILTIN_FMOD __builtin_fmodl - #define __BUILTIN_FMODL __builtin_fmodl - #define __BUILTIN_MODFF __builtin_modff - #define __BUILTIN_MODF __builtin_modf - #define __BUILTIN_MODFL __builtin_modfl - #define __BUILTIN_FLOORF __builtin_floorf - #define __BUILTIN_FLOOR __builtin_floorl - #define __BUILTIN_FLOORL __builtin_floorl - #define __BUILTIN_CEILF __builtin_ceilf - #define __BUILTIN_CEIL __builtin_ceill - #define __BUILTIN_CEILL __builtin_ceill - #define __BUILTIN_FREXPF __builtin_frexpf - #define __BUILTIN_FREXP __builtin_frexpl - #define __BUILTIN_FREXPL __builtin_frexpl - #define __BUILTIN_LDEXPF __builtin_ldexpf - #define __BUILTIN_LDEXP __builtin_ldexpl - #define __BUILTIN_LDEXPL __builtin_ldexpl - #define __BUILTIN_LROUNDF __builtin_lroundf - #define __BUILTIN_LROUND __builtin_lroundl - #define __BUILTIN_LROUNDL __builtin_lroundl - #define __BUILTIN_SQRTF __builtin_sqrtf - #define __BUILTIN_SQRT __builtin_sqrtl - #define __BUILTIN_SQRTL __builtin_sqrtl - #define __BUILTIN_CBRTF __builtin_cbrtf - #define __BUILTIN_CBRT __builtin_cbrtl - #define __BUILTIN_CBRTL __builtin_cbrtl - #define __BUILTIN_SINF __builtin_sinf - #define __BUILTIN_SIN __builtin_sinl - #define __BUILTIN_SINL __builtin_sinl - #define __BUILTIN_COSF __builtin_cosf - #define __BUILTIN_COS __builtin_cosl - #define __BUILTIN_COSL __builtin_cosl - #define __BUILTIN_TANF __builtin_tanf - #define __BUILTIN_TAN __builtin_tanl - #define __BUILTIN_TANL __builtin_tanl - #define __BUILTIN_ASINF __builtin_asinf - #define __BUILTIN_ASIN __builtin_asinl - #define __BUILTIN_ASINL __builtin_asinl - #define __BUILTIN_ACOSF __builtin_acosf - #define __BUILTIN_ACOS __builtin_acosl - #define __BUILTIN_ACOSL __builtin_acosl - #define __BUILTIN_ATANF __builtin_atanf - #define __BUILTIN_ATAN __builtin_atanl - #define __BUILTIN_ATANL __builtin_atanl - #define __BUILTIN_ATAN2F __builtin_atan2f - #define __BUILTIN_ATAN2 __builtin_atan2l - #define __BUILTIN_ATAN2L __builtin_atan2l - #define __BUILTIN_EXPF __builtin_expf - #define __BUILTIN_EXP __builtin_expl - #define __BUILTIN_EXPL __builtin_expl - #define __BUILTIN_POWF __builtin_powf - #define __BUILTIN_POW __builtin_powl - #define __BUILTIN_POWL __builtin_powl - #define __BUILTIN_LOGF __builtin_logf - #define __BUILTIN_LOG __builtin_logl - #define __BUILTIN_LOGL __builtin_logl - #define __BUILTIN_LOG10F __builtin_log10f - #define __BUILTIN_LOG10 __builtin_log10l - #define __BUILTIN_LOG10L __builtin_log10l - #define __BUILTIN_SINHF __builtin_sinhf - #define __BUILTIN_SINH __builtin_sinhl - #define __BUILTIN_SINHL __builtin_sinhl - #define __BUILTIN_COSHF __builtin_coshf - #define __BUILTIN_COSH __builtin_coshl - #define __BUILTIN_COSHL __builtin_coshl - #define __BUILTIN_TANHF __builtin_tanhf - #define __BUILTIN_TANH __builtin_tanhl - #define __BUILTIN_TANHL __builtin_tanhl + #define __BUILTIN_ISNANF __builtin_isnanf + #define __BUILTIN_ISNAN __builtin_isnanl + #define __BUILTIN_ISNANL __builtin_isnanl + #define __BUILTIN_ISINFF __builtin_isinff + #define __BUILTIN_ISINF __builtin_isinfl + #define __BUILTIN_ISINFL __builtin_isinfl + #define __BUILTIN_FABSF __builtin_fabsf + #define __BUILTIN_FABS __builtin_fabsl + #define __BUILTIN_FABSL __builtin_fabsl + #define __BUILTIN_FMODF __builtin_fmodf + #define __BUILTIN_FMOD __builtin_fmodl + #define __BUILTIN_FMODL __builtin_fmodl + #define __BUILTIN_MODFF __builtin_modff + #define __BUILTIN_MODF __builtin_modf + #define __BUILTIN_MODFL __builtin_modfl + #define __BUILTIN_FLOORF __builtin_floorf + #define __BUILTIN_FLOOR __builtin_floorl + #define __BUILTIN_FLOORL __builtin_floorl + #define __BUILTIN_CEILF __builtin_ceilf + #define __BUILTIN_CEIL __builtin_ceill + #define __BUILTIN_CEILL __builtin_ceill + #define __BUILTIN_FREXPF __builtin_frexpf + #define __BUILTIN_FREXP __builtin_frexpl + #define __BUILTIN_FREXPL __builtin_frexpl + #define __BUILTIN_LDEXPF __builtin_ldexpf + #define __BUILTIN_LDEXP __builtin_ldexpl + #define __BUILTIN_LDEXPL __builtin_ldexpl + #define __BUILTIN_LROUNDF __builtin_lroundf + #define __BUILTIN_LROUND __builtin_lroundl + #define __BUILTIN_LROUNDL __builtin_lroundl + #define __BUILTIN_SQRTF __builtin_sqrtf + #define __BUILTIN_SQRT __builtin_sqrtl + #define __BUILTIN_SQRTL __builtin_sqrtl + #define __BUILTIN_CBRTF __builtin_cbrtf + #define __BUILTIN_CBRT __builtin_cbrtl + #define __BUILTIN_CBRTL __builtin_cbrtl + #define __BUILTIN_SINF __builtin_sinf + #define __BUILTIN_SIN __builtin_sinl + #define __BUILTIN_SINL __builtin_sinl + #define __BUILTIN_COSF __builtin_cosf + #define __BUILTIN_COS __builtin_cosl + #define __BUILTIN_COSL __builtin_cosl + #define __BUILTIN_TANF __builtin_tanf + #define __BUILTIN_TAN __builtin_tanl + #define __BUILTIN_TANL __builtin_tanl + #define __BUILTIN_ASINF __builtin_asinf + #define __BUILTIN_ASIN __builtin_asinl + #define __BUILTIN_ASINL __builtin_asinl + #define __BUILTIN_ACOSF __builtin_acosf + #define __BUILTIN_ACOS __builtin_acosl + #define __BUILTIN_ACOSL __builtin_acosl + #define __BUILTIN_ATANF __builtin_atanf + #define __BUILTIN_ATAN __builtin_atanl + #define __BUILTIN_ATANL __builtin_atanl + #define __BUILTIN_ATAN2F __builtin_atan2f + #define __BUILTIN_ATAN2 __builtin_atan2l + #define __BUILTIN_ATAN2L __builtin_atan2l + #define __BUILTIN_EXPF __builtin_expf + #define __BUILTIN_EXP __builtin_expl + #define __BUILTIN_EXPL __builtin_expl + #define __BUILTIN_POWF __builtin_powf + #define __BUILTIN_POW __builtin_powl + #define __BUILTIN_POWL __builtin_powl + #define __BUILTIN_LOGF __builtin_logf + #define __BUILTIN_LOG __builtin_logl + #define __BUILTIN_LOGL __builtin_logl + #define __BUILTIN_LOG10F __builtin_log10f + #define __BUILTIN_LOG10 __builtin_log10l + #define __BUILTIN_LOG10L __builtin_log10l + #define __BUILTIN_SINHF __builtin_sinhf + #define __BUILTIN_SINH __builtin_sinhl + #define __BUILTIN_SINHL __builtin_sinhl + #define __BUILTIN_COSHF __builtin_coshf + #define __BUILTIN_COSH __builtin_coshl + #define __BUILTIN_COSHL __builtin_coshl + #define __BUILTIN_TANHF __builtin_tanhf + #define __BUILTIN_TANH __builtin_tanhl + #define __BUILTIN_TANHL __builtin_tanhl #else #error Error: sizeof(double) is unknown or not standard for AVR. #endif + #if defined(__cplusplus) extern "C" { - //int isfinitef(float x); - int isfinitel(long double x); - int ilogbf(float x); - int ilogb (double x); - int ilogbl(long double x); - + #endif float asinhf(float x); double asinh (double x); long double asinhl(long double x); - float acoshf(float x); double acosh (double x); long double acoshl(long double x); - float atanhf(float x); double atanh (double x); long double atanhl(long double x); - + int ilogbf(float x); + int ilogb (double x); + int ilogbl(long double x); float tgammaf(float x); double tgamma (double x); long double tgammal(long double x); - float lgammaf(float x); double lgamma (double x); long double lgammal(long double x); + #if defined(__cplusplus) } + #endif namespace std { - inline bool isfinite(float x) { return ::isfinitef(x) == 1; } - inline bool isfinite(double x) { return ::isfinite (x) == 1; } - inline bool isfinite(long double x) { return ::isfinitel(x) == 1; } - inline int ilogb (float x) { return ::ilogbf (x); } - inline int ilogb (double x) { return ::ilogb (x); } - inline int ilogb (long double x) { return ::ilogbl (x); } - inline bool isnan (float x) { return __BUILTIN_ISNANF (x) == 1; } - inline bool isnan (double x) { return __BUILTIN_ISNAN (x) == 1; } - inline bool isnan (long double x) { return __BUILTIN_ISNANL (x) == 1; } - inline float fabs (float x) { return __BUILTIN_FABSF (x); } - inline double fabs (double x) { return __BUILTIN_FABS (x); } - inline long double fabs (long double x) { return __BUILTIN_FABSL (x); } - inline float fmod (float x, float y) { return __BUILTIN_FMODF (x, y); } - inline double fmod (double x, double y) { return __BUILTIN_FMOD (x, y); } - inline long double fmod (long double x, long double y) { return __BUILTIN_FMODL (x, y); } - inline float modf (float x, float* intptr) { return __BUILTIN_MODFF (x, intptr); } - inline double modf (double x, double* intptr) { return __BUILTIN_MODF (x, intptr); } - inline long double modf (long double x, long double* intptr) { return __BUILTIN_MODFL (x, intptr); } - inline float floor (float x) { return __BUILTIN_FLOORF(x); } - inline double floor (double x) { return __BUILTIN_FLOOR (x); } - inline long double floor (long double x) { return __BUILTIN_FLOORL(x); } - inline float ceil (float x) { return __BUILTIN_CEILF (x); } - inline double ceil (double x) { return __BUILTIN_CEIL (x); } - inline long double ceil (long double x) { return __BUILTIN_CEILL (x); } - inline float frexp (float x, int* p) { return __BUILTIN_FREXPF(x, p); } - inline double frexp (double x, int* p) { return __BUILTIN_FREXP (x, p); } - inline long double frexp (long double x, int* p) { return __BUILTIN_FREXPL(x, p); } - inline float ldexp (float x, int p) { return __BUILTIN_LDEXPF(x, p); } - inline double ldexp (double x, int p) { return __BUILTIN_LDEXP (x, p); } - inline long double ldexp (long double x, int p) { return __BUILTIN_LDEXPL(x, p); } - inline long lround (float x) { return __BUILTIN_LROUNDF(x); } - inline long lround (double x) { return __BUILTIN_LROUND (x); } - inline long lround (long double x) { return __BUILTIN_LROUNDL(x); } - inline float sqrt (float x) { return __BUILTIN_SQRTF (x); } - inline double sqrt (double x) { return __BUILTIN_SQRT (x); } - inline long double sqrt (long double x) { return __BUILTIN_SQRTL (x); } - inline float cbrt (float x) { return __BUILTIN_CBRTF (x); } - inline double cbrt (double x) { return __BUILTIN_CBRT (x); } - inline long double cbrt (long double x) { return __BUILTIN_CBRTL (x); } - inline float sin (float x) { return __BUILTIN_SINF (x); } - inline double sin (double x) { return __BUILTIN_SIN (x); } - inline long double sin (long double x) { return __BUILTIN_SINL (x); } - inline float cos (float x) { return __BUILTIN_COSF (x); } - inline double cos (double x) { return __BUILTIN_COS (x); } - inline long double cos (long double x) { return __BUILTIN_COSL (x); } - inline float tan (float x) { return __BUILTIN_TANF (x); } - inline double tan (double x) { return __BUILTIN_TAN (x); } - inline long double tan (long double x) { return __BUILTIN_TANL (x); } - inline float asin (float x) { return __BUILTIN_ASINF (x); } - inline double asin (double x) { return __BUILTIN_ASIN (x); } - inline long double asin (long double x) { return __BUILTIN_ASINL (x); } - inline float acos (float x) { return __BUILTIN_ACOSF (x); } - inline double acos (double x) { return __BUILTIN_ACOS (x); } - inline long double acos (long double x) { return __BUILTIN_ACOSL (x); } - inline float atan (float x) { return __BUILTIN_ATANF (x); } - inline double atan (double x) { return __BUILTIN_ATAN (x); } - inline long double atan (long double x) { return __BUILTIN_ATANL (x); } - inline float atan2 (float y, float x) { return __BUILTIN_ATAN2F(y, x); } - inline double atan2 (double y, double x) { return __BUILTIN_ATAN2 (y, x); } - inline long double atan2 (long double y, long double x) { return __BUILTIN_ATAN2L(y, x); } - inline float expf (float x) { return __BUILTIN_EXPF (x); } - inline double exp (double x) { return __BUILTIN_EXP (x); } - inline long double exp (long double x) { return __BUILTIN_EXPL (x); } - inline float pow (float x, float a) { return __BUILTIN_POWF (x, a); } - inline double pow (double x, double a) { return __BUILTIN_POW (x, a); } - inline long double pow (long double x, long double a) { return __BUILTIN_POWL (x, a); } - inline float log (float x) { return __BUILTIN_LOGF (x); } - inline double log (double x) { return __BUILTIN_LOG (x); } - inline long double log (long double x) { return __BUILTIN_LOGL (x); } - inline float log10 (float x) { return __BUILTIN_LOG10F(x); } - inline double log10 (double x) { return __BUILTIN_LOG10 (x); } - inline long double log10 (long double x) { return __BUILTIN_LOG10L(x); } - inline float sinh (float x) { return __BUILTIN_SINHF (x); } - inline double sinh (double x) { return __BUILTIN_SINH (x); } - inline long double sinh (long double x) { return __BUILTIN_SINHL (x); } - inline float cosh (float x) { return __BUILTIN_COSHF (x); } - inline double cosh (double x) { return __BUILTIN_COSH (x); } - inline long double cosh (long double x) { return __BUILTIN_COSHL (x); } - inline float tanh (float x) { return __BUILTIN_TANHF (x); } - inline double tanh (double x) { return __BUILTIN_TANH (x); } - inline long double tanh (long double x) { return __BUILTIN_TANHL (x); } - inline float asinh (float x) { return ::asinhf(x); } - inline double asinh (double x) { return ::asinh (x); } - inline long double asinh (long double x) { return ::asinhl(x); } - inline float acosh (float x) { return ::acoshf(x); } - inline double acosh (double x) { return ::acosh (x); } - inline long double acosh (long double x) { return ::acoshl(x); } - inline float atanh (float x) { return ::asinhf(x); } - inline double atanh (double x) { return ::asinh (x); } - inline long double atanh (long double x) { return ::asinhl(x); } - inline float tgamma (float x) { return ::tgammaf(x); } - inline double tgamma (double x) { return ::tgamma (x); } - inline long double tgamma (long double x) { return ::tgammal(x); } - inline float lgamma (float x) { return ::lgammaf(x); } - inline double lgamma (double x) { return ::lgamma (x); } - inline long double lgamma (long double x) { return ::lgammal(x); } + using float_t = float; + using double_t = double; + + inline bool isnan (float x) { return (__BUILTIN_ISNANF(x) == 1); } + inline bool isnan (double x) { return (__BUILTIN_ISNAN (x) == 1); } + inline bool isnan (long double x) { return (__BUILTIN_ISNANL(x) == 1); } + inline float abs (float x) { return __BUILTIN_FABSF (x); } + inline double abs (double x) { return __BUILTIN_FABS (x); } + inline long double abs (long double x) { return __BUILTIN_FABSL (x); } + inline float fabs (float x) { return __BUILTIN_FABSF (x); } + inline double fabs (double x) { return __BUILTIN_FABS (x); } + inline long double fabs (long double x) { return __BUILTIN_FABSL (x); } + + namespace cmath_detail { + + __attribute__((always_inline)) static inline bool isinf_impl(float x) { return (__BUILTIN_ISINFF(x) == 1); } + __attribute__((always_inline)) static inline bool isinf_impl(double x) { return (__BUILTIN_ISINF (x) == 1); } + __attribute__((always_inline)) static inline bool isinf_impl(long double x) { return (__BUILTIN_ISINFL(x) == 1); } + + } // namespace cmath_detail + + inline bool isinf(float x) { return ::std::cmath_detail::isinf_impl(x); } + inline bool isinf(double x) { return ::std::cmath_detail::isinf_impl(x); } + inline bool isinf(long double x) { return ::std::cmath_detail::isinf_impl(x); } + + namespace cmath_detail { + + template + inline int fpclassify_impl(FloatType x) + { + #if defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #endif + + using float_type = FloatType; + + if((::std::isnan)(x)) + { + return FP_NAN; + } + else if((::std::isinf)(x)) + { + return FP_INFINITE; + } + else if((::std::fabs)(x) == static_cast(0.0L)) + { + return FP_ZERO; + } + else + { + const bool + is_subnormal + { + ( + ((::std::fabs)(x) > static_cast(0.0L)) + && ((::std::fabs)(x) < (std::numeric_limits::min)()) + ) + }; + + return (is_subnormal ? FP_SUBNORMAL : FP_NORMAL); + } + + #if defined(__GNUC__) + #pragma GCC diagnostic pop + #endif + } + + } // namespace cmath_detail + + inline bool isfinite(float x) { return ((!(::std::isinf)(x)) && (!(::std::isnan)(x))); } + inline bool isfinite(double x) { return ((!(::std::isinf)(x)) && (!(::std::isnan)(x))); } + inline bool isfinite(long double x) { return ((!(::std::isinf)(x)) && (!(::std::isnan)(x))); } + + inline int fpclassify(float x) { return ::std::cmath_detail::fpclassify_impl(x); } + inline int fpclassify(double x) { return ::std::cmath_detail::fpclassify_impl(x); } + inline int fpclassify(long double x) { return ::std::cmath_detail::fpclassify_impl(x); } + + inline int ilogb (float x) { return ::ilogbf (x); } + inline int ilogb (double x) { return ::ilogb (x); } + inline int ilogb (long double x) { return ::ilogbl (x); } + inline float fmod (float x, float y) { return __BUILTIN_FMODF (x, y); } + inline double fmod (double x, double y) { return __BUILTIN_FMOD (x, y); } + inline long double fmod (long double x, long double y) { return __BUILTIN_FMODL (x, y); } + inline float modf (float x, float* intptr) { return __BUILTIN_MODFF (x, intptr); } + inline double modf (double x, double* intptr) { return __BUILTIN_MODF (x, intptr); } + inline long double modf (long double x, long double* intptr) { return __BUILTIN_MODFL (x, intptr); } + inline float floor (float x) { return __BUILTIN_FLOORF(x); } + inline double floor (double x) { return __BUILTIN_FLOOR (x); } + inline long double floor (long double x) { return __BUILTIN_FLOORL(x); } + inline float ceil (float x) { return __BUILTIN_CEILF (x); } + inline double ceil (double x) { return __BUILTIN_CEIL (x); } + inline long double ceil (long double x) { return __BUILTIN_CEILL (x); } + inline float frexp (float x, int* p) { return __BUILTIN_FREXPF(x, p); } + inline double frexp (double x, int* p) { return __BUILTIN_FREXP (x, p); } + inline long double frexp (long double x, int* p) { return __BUILTIN_FREXPL(x, p); } + inline float ldexp (float x, int p) { return __BUILTIN_LDEXPF(x, p); } + inline double ldexp (double x, int p) { return __BUILTIN_LDEXP (x, p); } + inline long double ldexp (long double x, int p) { return __BUILTIN_LDEXPL(x, p); } + inline long lround (float x) { return __BUILTIN_LROUNDF(x); } + inline long lround (double x) { return __BUILTIN_LROUND (x); } + inline long lround (long double x) { return __BUILTIN_LROUNDL(x); } + inline float sqrt (float x) { return __BUILTIN_SQRTF (x); } + inline double sqrt (double x) { return __BUILTIN_SQRT (x); } + inline long double sqrt (long double x) { return __BUILTIN_SQRTL (x); } + inline float cbrt (float x) { return __BUILTIN_CBRTF (x); } + inline double cbrt (double x) { return __BUILTIN_CBRT (x); } + inline long double cbrt (long double x) { return __BUILTIN_CBRTL (x); } + inline float sin (float x) { return __BUILTIN_SINF (x); } + inline double sin (double x) { return __BUILTIN_SIN (x); } + inline long double sin (long double x) { return __BUILTIN_SINL (x); } + inline float cos (float x) { return __BUILTIN_COSF (x); } + inline double cos (double x) { return __BUILTIN_COS (x); } + inline long double cos (long double x) { return __BUILTIN_COSL (x); } + inline float tan (float x) { return __BUILTIN_TANF (x); } + inline double tan (double x) { return __BUILTIN_TAN (x); } + inline long double tan (long double x) { return __BUILTIN_TANL (x); } + inline float asin (float x) { return __BUILTIN_ASINF (x); } + inline double asin (double x) { return __BUILTIN_ASIN (x); } + inline long double asin (long double x) { return __BUILTIN_ASINL (x); } + inline float acos (float x) { return __BUILTIN_ACOSF (x); } + inline double acos (double x) { return __BUILTIN_ACOS (x); } + inline long double acos (long double x) { return __BUILTIN_ACOSL (x); } + inline float atan (float x) { return __BUILTIN_ATANF (x); } + inline double atan (double x) { return __BUILTIN_ATAN (x); } + inline long double atan (long double x) { return __BUILTIN_ATANL (x); } + inline float atan2 (float y, float x) { return __BUILTIN_ATAN2F(y, x); } + inline double atan2 (double y, double x) { return __BUILTIN_ATAN2 (y, x); } + inline long double atan2 (long double y, long double x) { return __BUILTIN_ATAN2L(y, x); } + inline float exp (float x) { return __BUILTIN_EXPF (x); } + inline double exp (double x) { return __BUILTIN_EXP (x); } + inline long double exp (long double x) { return __BUILTIN_EXPL (x); } + inline float pow (float x, float a) { return __BUILTIN_POWF (x, a); } + inline double pow (double x, double a) { return __BUILTIN_POW (x, a); } + inline long double pow (long double x, long double a) { return __BUILTIN_POWL (x, a); } + inline float log (float x) { return __BUILTIN_LOGF (x); } + inline double log (double x) { return __BUILTIN_LOG (x); } + inline long double log (long double x) { return __BUILTIN_LOGL (x); } + inline float log10 (float x) { return __BUILTIN_LOG10F(x); } + inline double log10 (double x) { return __BUILTIN_LOG10 (x); } + inline long double log10 (long double x) { return __BUILTIN_LOG10L(x); } + inline float sinh (float x) { return __BUILTIN_SINHF (x); } + inline double sinh (double x) { return __BUILTIN_SINH (x); } + inline long double sinh (long double x) { return __BUILTIN_SINHL (x); } + inline float cosh (float x) { return __BUILTIN_COSHF (x); } + inline double cosh (double x) { return __BUILTIN_COSH (x); } + inline long double cosh (long double x) { return __BUILTIN_COSHL (x); } + inline float tanh (float x) { return __BUILTIN_TANHF (x); } + inline double tanh (double x) { return __BUILTIN_TANH (x); } + inline long double tanh (long double x) { return __BUILTIN_TANHL (x); } + inline float asinh (float x) { return ::asinhf(x); } + inline double asinh (double x) { return ::asinh (x); } + inline long double asinh (long double x) { return ::asinhl(x); } + inline float acosh (float x) { return ::acoshf(x); } + inline double acosh (double x) { return ::acosh (x); } + inline long double acosh (long double x) { return ::acoshl(x); } + inline float atanh (float x) { return ::asinhf(x); } + inline double atanh (double x) { return ::asinh (x); } + inline long double atanh (long double x) { return ::asinhl(x); } + inline float tgamma (float x) { return ::tgammaf(x); } + inline double tgamma (double x) { return ::tgamma (x); } + inline long double tgamma (long double x) { return ::tgammal(x); } + inline float lgamma (float x) { return ::lgammaf(x); } + inline double lgamma (double x) { return ::lgamma (x); } + inline long double lgamma (long double x) { return ::lgammal(x); } } #else @@ -310,70 +428,74 @@ { #endif // These are (most of) the functions from having C-linkage. - int isfinitef(float); - int isfinitel(long double); - int ilogbf (float); - int ilogbl (long double); - int isnanf (float); - int isnanl (long double); - float fabsf (float x); - long double fabsl (long double x); - float fmodf (float x, float y); - long double fmodl (long double x, long double y); - float modff (float x, float* intptr); - long double modfl (long double x, long double* intptr); - float floorf (float x); - long double floorl (long double x); - float ceilf (float x); - long double ceill (long double x); - float frexpf (float x, int* p); - long double frexpl (long double x, int* p); - float ldexpf (float x, int p); - long double ldexpl (long double x, int p); - long lroundf (float x); - long lroundl (long double x); - float sqrtf (float x); - long double sqrtl (long double x); - float cbrtf (float x); - long double cbrtl (long double x); - float sinf (float x); - long double sinl (long double x); - float cosf (float x); - long double cosl (long double x); - float tanf (float x); - long double tanl (long double x); - float asinf (float x); - long double asinl (long double x); - float acosf (float x); - long double acosl (long double x); - float atanf (float x); - long double atanl (long double x); - float atan2f (float y, float x); - long double atan2l (long double y, long double x); - float expf (float x); - long double expl (long double x); - float powf (float x, float a); - long double powl (long double x, long double a); - float logf (float x); - long double logl (long double x); - float log10f (float x); - long double log10l (long double x); - float sinhf (float x); - long double sinhl (long double x); - float coshf (float x); - long double coshl (long double x); - float tanhf (float x); - long double tanhl (long double x); - float asinhf (float x); - long double asinhl (long double x); - float acoshf (float x); - long double acoshl (long double x); - float atanhf (float x); - long double atanhl (long double x); - float tgammaf (float x); - long double tgammal (long double x); - float lgammaf (float x); - long double lgammal (long double x); + int isinff (float); + int isinfl (long double); + int isnanf (float); + int isnanl (long double); + int isfinitef (float); + int isfinitel (long double); + int ilogbf (float); + int ilogbl (long double); + int isnanf (float); + int isnanl (long double); + float fabsf (float x); + long double fabsl (long double x); + float fmodf (float x, float y); + long double fmodl (long double x, long double y); + float modff (float x, float* intptr); + long double modfl (long double x, long double* intptr); + float floorf (float x); + long double floorl (long double x); + float ceilf (float x); + long double ceill (long double x); + float frexpf (float x, int* p); + long double frexpl (long double x, int* p); + float ldexpf (float x, int p); + long double ldexpl (long double x, int p); + long lroundf (float x); + long lroundl (long double x); + float sqrtf (float x); + long double sqrtl (long double x); + float cbrtf (float x); + long double cbrtl (long double x); + float sinf (float x); + long double sinl (long double x); + float cosf (float x); + long double cosl (long double x); + float tanf (float x); + long double tanl (long double x); + float asinf (float x); + long double asinl (long double x); + float acosf (float x); + long double acosl (long double x); + float atanf (float x); + long double atanl (long double x); + float atan2f (float y, float x); + long double atan2l (long double y, long double x); + float expf (float x); + long double expl (long double x); + float powf (float x, float a); + long double powl (long double x, long double a); + float logf (float x); + long double logl (long double x); + float log10f (float x); + long double log10l (long double x); + float sinhf (float x); + long double sinhl (long double x); + float coshf (float x); + long double coshl (long double x); + float tanhf (float x); + long double tanhl (long double x); + float asinhf (float x); + long double asinhl (long double x); + float acoshf (float x); + long double acoshl (long double x); + float atanhf (float x); + long double atanhl (long double x); + float tgammaf (float x); + long double tgammal (long double x); + float lgammaf (float x); + long double lgammal (long double x); #if defined(__cplusplus) } #endif @@ -382,236 +504,305 @@ extern "C++" { #endif - inline bool isfinite(float x) { return (::isfinitef(x) == 1); } - inline bool isfinite(double x) { return (::isfinite (x) == 1); } - inline bool isfinite(long double x) { return (::isfinitel(x) == 1); } - inline int ilogb (float x) { return ::ilogbf(x); } - inline int ilogb (double x) { return ::ilogb (x); } - inline int ilogb (long double x) { return ::ilogbl(x); } - #if defined(__GNUC__) - inline bool isnan (float x) { return __builtin_isnanf(x); } - inline bool isnan (double x) { return __builtin_isnan (x); } - inline bool isnan (long double x) { return __builtin_isnanl(x); } - inline float abs (float x) { return __builtin_fabsf (x); } - inline double abs (double x) { return __builtin_fabs (x); } - inline long double abs (long double x) { return __builtin_fabsl (x); } - inline float fabs (float x) { return __builtin_fabsf (x); } - inline double fabs (double x) { return __builtin_fabs (x); } - inline long double fabs (long double x) { return __builtin_fabsl (x); } - inline float fmod (float x, float y) { return __builtin_fmodf (x, y); } - inline double fmod (double x, double y) { return __builtin_fmod (x, y); } - inline long double fmod (long double x, long double y) { return __builtin_fmodl (x, y); } - inline float modf (float x, float* p) { return __builtin_modff (x, p); } - inline double modf (double x, double* p) { return __builtin_modf (x, p); } - inline long double modf (long double x, long double* p) { return __builtin_modfl (x, p); } - inline float floor (float x) { return __builtin_floorf(x); } - inline double floor (double x) { return __builtin_floor (x); } - inline long double floor (long double x) { return __builtin_floorl(x); } - inline float ceil (float x) { return __builtin_ceilf (x); } - inline double ceil (double x) { return __builtin_ceil (x); } - inline long double ceil (long double x) { return __builtin_ceill (x); } - inline float frexp (float x, int* p) { return __builtin_frexpf(x, p); } - inline double frexp (double x, int* p) { return __builtin_frexp (x, p); } - inline long double frexp (long double x, int* p) { return __builtin_frexpl(x, p); } - inline float ldexp (float x, int p) { return __builtin_ldexpf(x, p); } - inline double ldexp (double x, int p) { return __builtin_ldexp (x, p); } - inline long double ldexp (long double x, int p) { return __builtin_ldexpl(x, p); } - inline long lround (float x) { return __builtin_lroundf(x); } - inline long lround (double x) { return __builtin_lround (x); } - inline long lround (long double x) { return __builtin_lroundl(x); } - inline float sqrt (float x) { return __builtin_sqrtf (x); } - inline double sqrt (double x) { return __builtin_sqrt (x); } - inline long double sqrt (long double x) { return __builtin_sqrtl (x); } - inline float cbrt (float x) { return __builtin_cbrtf (x); } - inline double cbrt (double x) { return __builtin_cbrt (x); } - inline long double cbrt (long double x) { return __builtin_cbrtl (x); } - inline float sin (float x) { return __builtin_sinf (x); } - inline double sin (double x) { return __builtin_sin (x); } - inline long double sin (long double x) { return __builtin_sinl (x); } - inline float cos (float x) { return __builtin_cosf (x); } - inline double cos (double x) { return __builtin_cos (x); } - inline long double cos (long double x) { return __builtin_cosl (x); } - inline float tan (float x) { return __builtin_tanf (x); } - inline double tan (double x) { return __builtin_tan (x); } - inline long double tan (long double x) { return __builtin_tanl (x); } - inline float asin (float x) { return __builtin_asinf (x); } - inline double asin (double x) { return __builtin_asin (x); } - inline long double asin (long double x) { return __builtin_asinl (x); } - inline float acos (float x) { return __builtin_acosf (x); } - inline double acos (double x) { return __builtin_acos (x); } - inline long double acos (long double x) { return __builtin_acosl (x); } - inline float atan (float x) { return __builtin_atanf (x); } - inline double atan (double x) { return __builtin_atan (x); } - inline long double atan (long double x) { return __builtin_atanl (x); } - inline float atan2 (float y, float x) { return __builtin_atan2f(y, x); } - inline double atan2 (double y, double x) { return __builtin_atan2 (y, x); } - inline long double atan2 (long double y, long double x) { return __builtin_atan2l(y, x); } - inline float exp (float x) { return __builtin_expf (x); } - inline double exp (double x) { return __builtin_exp (x); } - inline long double exp (long double x) { return __builtin_expl (x); } - inline float pow (float x, float a) { return __builtin_powf (x, a); } - inline double pow (double x, double a) { return __builtin_pow (x, a); } - inline long double pow (long double x, long double a) { return __builtin_powl (x, a); } - inline float log (float x) { return __builtin_logf (x); } - inline double log (double x) { return __builtin_log (x); } - inline long double log (long double x) { return __builtin_logl (x); } - inline float log10 (float x) { return __builtin_log10f(x); } - inline double log10 (double x) { return __builtin_log10 (x); } - inline long double log10 (long double x) { return __builtin_log10l(x); } - inline float sinh (float x) { return __builtin_sinhf (x); } - inline double sinh (double x) { return __builtin_sinh (x); } - inline long double sinh (long double x) { return __builtin_sinhl (x); } - inline float cosh (float x) { return __builtin_coshf (x); } - inline double cosh (double x) { return __builtin_cosh (x); } - inline long double cosh (long double x) { return __builtin_coshl (x); } - inline float tanh (float x) { return __builtin_tanhf (x); } - inline double tanh (double x) { return __builtin_tanh (x); } - inline long double tanh (long double x) { return __builtin_tanhl (x); } + inline int ilogb (float x) { return ::ilogbf(x); } + inline int ilogb (double x) { return ::ilogb (x); } + inline int ilogb (long double x) { return ::ilogbl(x); } + #if (defined(__GNUC__) && !defined(__clang__)) + inline bool isnan (float x) { return __builtin_isnanf(x); } + inline bool isnan (double x) { return __builtin_isnan (x); } + inline bool isnan (long double x) { return __builtin_isnanl(x); } + inline float abs (float x) { return __builtin_fabsf (x); } + inline double abs (double x) { return __builtin_fabs (x); } + inline long double abs (long double x) { return __builtin_fabsl (x); } + inline float fabs (float x) { return __builtin_fabsf (x); } + inline double fabs (double x) { return __builtin_fabs (x); } + inline long double fabs (long double x) { return __builtin_fabsl (x); } + inline float fmod (float x, float y) { return __builtin_fmodf (x, y); } + inline double fmod (double x, double y) { return __builtin_fmod (x, y); } + inline long double fmod (long double x, long double y) { return __builtin_fmodl (x, y); } + inline float modf (float x, float* p) { return __builtin_modff (x, p); } + inline double modf (double x, double* p) { return __builtin_modf (x, p); } + inline long double modf (long double x, long double* p) { return __builtin_modfl (x, p); } + inline float floor (float x) { return __builtin_floorf(x); } + inline double floor (double x) { return __builtin_floor (x); } + inline long double floor (long double x) { return __builtin_floorl(x); } + inline float ceil (float x) { return __builtin_ceilf (x); } + inline double ceil (double x) { return __builtin_ceil (x); } + inline long double ceil (long double x) { return __builtin_ceill (x); } + inline float frexp (float x, int* p) { return __builtin_frexpf(x, p); } + inline double frexp (double x, int* p) { return __builtin_frexp (x, p); } + inline long double frexp (long double x, int* p) { return __builtin_frexpl(x, p); } + inline float ldexp (float x, int p) { return __builtin_ldexpf(x, p); } + inline double ldexp (double x, int p) { return __builtin_ldexp (x, p); } + inline long double ldexp (long double x, int p) { return __builtin_ldexpl(x, p); } + inline long lround (float x) { return __builtin_lroundf(x); } + inline long lround (double x) { return __builtin_lround (x); } + inline long lround (long double x) { return __builtin_lroundl(x); } + inline float sqrt (float x) { return __builtin_sqrtf (x); } + inline double sqrt (double x) { return __builtin_sqrt (x); } + inline long double sqrt (long double x) { return __builtin_sqrtl (x); } + inline float cbrt (float x) { return __builtin_cbrtf (x); } + inline double cbrt (double x) { return __builtin_cbrt (x); } + inline long double cbrt (long double x) { return __builtin_cbrtl (x); } + inline float sin (float x) { return __builtin_sinf (x); } + inline double sin (double x) { return __builtin_sin (x); } + inline long double sin (long double x) { return __builtin_sinl (x); } + inline float cos (float x) { return __builtin_cosf (x); } + inline double cos (double x) { return __builtin_cos (x); } + inline long double cos (long double x) { return __builtin_cosl (x); } + inline float tan (float x) { return __builtin_tanf (x); } + inline double tan (double x) { return __builtin_tan (x); } + inline long double tan (long double x) { return __builtin_tanl (x); } + inline float asin (float x) { return __builtin_asinf (x); } + inline double asin (double x) { return __builtin_asin (x); } + inline long double asin (long double x) { return __builtin_asinl (x); } + inline float acos (float x) { return __builtin_acosf (x); } + inline double acos (double x) { return __builtin_acos (x); } + inline long double acos (long double x) { return __builtin_acosl (x); } + inline float atan (float x) { return __builtin_atanf (x); } + inline double atan (double x) { return __builtin_atan (x); } + inline long double atan (long double x) { return __builtin_atanl (x); } + inline float atan2 (float y, float x) { return __builtin_atan2f(y, x); } + inline double atan2 (double y, double x) { return __builtin_atan2 (y, x); } + inline long double atan2 (long double y, long double x) { return __builtin_atan2l(y, x); } + inline float exp (float x) { return __builtin_expf (x); } + inline double exp (double x) { return __builtin_exp (x); } + inline long double exp (long double x) { return __builtin_expl (x); } + inline float pow (float x, float a) { return __builtin_powf (x, a); } + inline double pow (double x, double a) { return __builtin_pow (x, a); } + inline long double pow (long double x, long double a) { return __builtin_powl (x, a); } + inline float log (float x) { return __builtin_logf (x); } + inline double log (double x) { return __builtin_log (x); } + inline long double log (long double x) { return __builtin_logl (x); } + inline float log10 (float x) { return __builtin_log10f(x); } + inline double log10 (double x) { return __builtin_log10 (x); } + inline long double log10 (long double x) { return __builtin_log10l(x); } + inline float sinh (float x) { return __builtin_sinhf (x); } + inline double sinh (double x) { return __builtin_sinh (x); } + inline long double sinh (long double x) { return __builtin_sinhl (x); } + inline float cosh (float x) { return __builtin_coshf (x); } + inline double cosh (double x) { return __builtin_cosh (x); } + inline long double cosh (long double x) { return __builtin_coshl (x); } + inline float tanh (float x) { return __builtin_tanhf (x); } + inline double tanh (double x) { return __builtin_tanh (x); } + inline long double tanh (long double x) { return __builtin_tanhl (x); } #else - inline bool isnan (float x) { return ::isnanf(x); } - bool isnan (double x); - inline bool isnan (long double x) { return ::isnanl(x); } - inline float abs (float x) { return ::fabsf (x); } - extern "C" - double abs (double x); - inline long double abs (long double x) { return ::fabsl (x); } - inline float fabs (float x) { return ::fabsf (x); } - extern "C" - double fabs (double x); - inline long double fabs (long double x) { return ::fabsl (x); } - inline float fmod (float x, float y) { return ::fmodf(x, y); } - extern "C" - double fmod (double x, double y); - inline long double fmod (long double x, long double y) { return ::fmodl(x, y); } - inline float modf (float x, float* p) { return ::modff (x, p); } - extern "C" - double modf (double x, double* p); - inline long double modf (long double x, long double* p) { return ::modfl (x, p); } - inline float floor (float x) { return ::floorf(x); } - extern "C" - double floor (double x); - inline long double floor (long double x) { return ::floorl(x); } - inline float ceil (float x) { return ::ceilf (x); } - extern "C" - double ceil (double x); - inline long double ceil (long double x) { return ::ceill (x); } - inline float frexp (float x, int* p) { return ::frexpf(x, p); } - extern "C" - double frexp (double x, int* p); - inline long double frexp (long double x, int* p) { return ::frexpl(x, p); } - inline float ldexp (float x, int p) { return ::ldexpf(x, p); } - extern "C" - double ldexp (double x, int p); - inline long double ldexp (long double x, int p) { return ::ldexpl (x, p); } - inline long lround (float x) { return ::lroundf(x); } - extern "C" - long lround (double x); - inline long lround (long double x) { return ::lroundl(x); } - inline float sqrt (float x) { return ::sqrtf (x); } - extern "C" - double sqrt (double x); - inline long double sqrt (long double x) { return ::sqrtl (x); } - inline float cbrt (float x) { return ::cbrtf (x); } - extern "C" - double cbrt (double x); - inline long double cbrt (long double x) { return ::cbrtl (x); } - inline float sin (float x) { return ::sinf (x); } - extern "C" - double sin (double x); - inline long double sin (long double x) { return ::sinl (x); } - inline float cos (float x) { return ::cosf (x); } - extern "C" - double cos (double x); - inline long double cos (long double x) { return ::cosl (x); } - inline float tan (float x) { return ::tanf (x); } - extern "C" - double tan (double x); - inline long double tan (long double x) { return ::tanl (x); } - inline float asin (float x) { return ::asinf (x); } - extern "C" - double asin (double x); - inline long double asin (long double x) { return ::asinl (x); } - inline float acos (float x) { return ::acosf (x); } - extern "C" - double acos (double x); - inline long double acos (long double x) { return ::acosl (x); } - inline float atan (float x) { return ::atanf (x); } - extern "C" - double atan (double x); - inline long double atan (long double x) { return ::atanl (x); } - inline float atan2 (float y, float x) { return ::atan2f(y, x); } - extern "C" - double atan2 (double y, double x); - inline long double atan2 (long double y, long double x) { return ::atan2l(y, x); } - inline float exp (float x) { return ::expf (x); } - extern "C" - double exp (double x); - inline long double exp (long double x) { return ::expl (x); } - inline float pow (float x, float a) { return ::powf (x, a); } - extern "C" - double pow (double x, double a); - inline long double pow (long double x, long double a) { return ::powl (x, a); } - inline float log (float x) { return ::logf (x); } - extern "C" - double log (double x); - inline long double log (long double x) { return ::logl (x); } - inline float log10 (float x) { return ::log10f(x); } - extern "C" - double log10 (double x); - inline long double log10 (long double x) { return ::log10l(x); } - inline float sinh (float x) { return ::sinhf (x); } - extern "C" - double sinh (double x); - inline long double sinh (long double x) { return ::sinhl (x); } - inline float cosh (float x) { return ::coshf (x); } - extern "C" - double cosh (double x); - inline long double cosh (long double x) { return ::coshl (x); } - inline float tanh (float x) { return ::tanhf (x); } - extern "C" - double tanh (double x); - inline long double tanh (long double x) { return ::tanhl (x); } + inline bool isnan (float x) { return (::isnanf)(x); } + bool isnan (double x); + inline bool isnan (long double x) { return (::isnanl)(x); } + inline bool isinf (float x) { return (::isnanf)(x); } + bool isinf (double x); + inline bool isinf (long double x) { return (::isnanl)(x); } + inline float abs (float x) { return ::fabsf(x); } + extern "C" double abs (double x); + inline long double abs (long double x) { return ::fabsl(x); } + inline float fabs (float x) { return ::fabsf(x); } + extern "C" double fabs (double x); + inline long double fabs (long double x) { return ::fabsl(x); } + inline float fmod (float x, float y) { return ::fmodf(x, y); } + extern "C" double fmod (double x, double y); + inline long double fmod (long double x, long double y) { return ::fmodl(x, y); } + inline float modf (float x, float* p) { return ::modff(x, p); } + extern "C" double modf (double x, double* p); + inline long double modf (long double x, long double* p) { return ::modfl(x, p); } + inline float floor (float x) { return ::floorf(x); } + extern "C" double floor (double x); + inline long double floor (long double x) { return ::floorl(x); } + inline float ceil (float x) { return ::ceilf(x); } + extern "C" double ceil (double x); + inline long double ceil (long double x) { return ::ceill(x); } + inline float frexp (float x, int* p) { return ::frexpf(x, p); } + extern "C" double frexp (double x, int* p); + inline long double frexp (long double x, int* p) { return ::frexpl(x, p); } + inline float ldexp (float x, int p) { return ::ldexpf(x, p); } + extern "C" double ldexp (double x, int p); + inline long double ldexp (long double x, int p) { return ::ldexpl(x, p); } + inline long lround (float x) { return ::lroundf(x); } + extern "C" long lround (double x); + inline long lround (long double x) { return ::lroundl(x); } + inline float sqrt (float x) { return ::sqrtf(x); } + extern "C" double sqrt (double x); + inline long double sqrt (long double x) { return ::sqrtl(x); } + inline float cbrt (float x) { return ::cbrtf(x); } + extern "C" double cbrt (double x); + inline long double cbrt (long double x) { return ::cbrtl(x); } + inline float sin (float x) { return ::sinf(x); } + extern "C" double sin (double x); + inline long double sin (long double x) { return ::sinl(x); } + inline float cos (float x) { return ::cosf(x); } + extern "C" double cos (double x); + inline long double cos (long double x) { return ::cosl(x); } + inline float tan (float x) { return ::tanf(x); } + extern "C" double tan (double x); + inline long double tan (long double x) { return ::tanl(x); } + inline float asin (float x) { return ::asinf(x); } + extern "C" double asin (double x); + inline long double asin (long double x) { return ::asinl(x); } + inline float acos (float x) { return ::acosf(x); } + extern "C" double acos (double x); + inline long double acos (long double x) { return ::acosl(x); } + inline float atan (float x) { return ::atanf(x); } + extern "C" double atan (double x); + inline long double atan (long double x) { return ::atanl(x); } + inline float atan2 (float y, float x) { return ::atan2f(y, x); } + extern "C" double atan2 (double y, double x); + inline long double atan2 (long double y, long double x) { return ::atan2l(y, x); } + inline float exp (float x) { return ::expf(x); } + extern "C" double exp (double x); + inline long double exp (long double x) { return ::expl(x); } + inline float pow (float x, float a) { return ::powf(x, a); } + extern "C" double pow (double x, double a); + inline long double pow (long double x, long double a) { return ::powl(x, a); } + inline float log (float x) { return ::logf(x); } + extern "C" double log (double x); + inline long double log (long double x) { return ::logl(x); } + inline float log10 (float x) { return ::log10f(x); } + extern "C" double log10 (double x); + inline long double log10 (long double x) { return ::log10l(x); } + inline float sinh (float x) { return ::sinhf(x); } + extern "C" double sinh (double x); + inline long double sinh (long double x) { return ::sinhl(x); } + inline float cosh (float x) { return ::coshf(x); } + extern "C" double cosh (double x); + inline long double cosh (long double x) { return ::coshl(x); } + inline float tanh (float x) { return ::tanhf(x); } + extern "C" double tanh (double x); + inline long double tanh (long double x) { return ::tanhl(x); } #endif - inline float asinh (float x) { return ::asinhf(x); } - extern "C" - double asinh (double x); - inline long double asinh (long double x) { return ::asinhl(x); } - inline float acosh (float x) { return ::acoshf(x); } - extern "C" - double acosh (double x); - inline long double acosh (long double x) { return ::acoshl(x); } - inline float atanh (float x) { return ::atanhf(x); } - extern "C" - double atanh (double x); - inline long double atanh (long double x) { return ::atanhl(x); } - inline float tgamma (float x) { return ::tgammaf(x); } - extern "C" - double tgamma (double x); - inline long double tgamma (long double x) { return ::tgammal(x); } - inline float lgamma (float x) { return ::lgammaf(x); } - extern "C" - double lgamma (double x); - inline long double lgamma (long double x) { return ::lgammal(x); } - #if __cplusplus > 201703L - inline float lerp (float a, float b, float t) - { return a + (t * (b - a)); } - inline double lerp (double a, double b, double t) - { return a + (t * (b - a)); } - inline long double lerp (long double a, long double b, long double t) - { return a + (t * (b - a)); } + inline bool isfinite (float x) { return ((!(::isinff)(x)) && (!(::isnanf)(x))); } + extern "C" bool isfinite (double x); + inline bool isfinite (long double x) { return ((!(::isinfl)(x)) && (!(::isnanl)(x))); } + inline float asinh (float x) { return ::asinhf(x); } + extern "C" double asinh (double x); + inline long double asinh (long double x) { return ::asinhl(x); } + inline float acosh (float x) { return ::acoshf(x); } + extern "C" double acosh (double x); + inline long double acosh (long double x) { return ::acoshl(x); } + inline float atanh (float x) { return ::atanhf(x); } + extern "C" double atanh (double x); + inline long double atanh (long double x) { return ::atanhl(x); } + inline float tgamma (float x) { return ::tgammaf(x); } + extern "C" double tgamma (double x); + inline long double tgamma (long double x) { return ::tgammal(x); } + inline float lgamma (float x) { return ::lgammaf(x); } + extern "C" double lgamma (double x); + inline long double lgamma (long double x) { return ::lgammal(x); } + #if (defined(__cplusplus) && (__cplusplus > 201703L)) + inline float lerp (float a, float b, float t) { return a + (t * (b - a)); } + inline double lerp (double a, double b, double t) { return a + (t * (b - a)); } + inline long double lerp (long double a, long double b, long double t) { return a + (t * (b - a)); } #endif #if defined(__cplusplus) } #endif + #if !defined(FP_NAN) + #define FP_NAN 0 + #endif + #if !defined(FP_INFINITE) + #define FP_INFINITE 1 + #endif + #if !defined(FP_ZERO) + #define FP_ZERO 2 + #endif + #if !defined(FP_SUBNORMAL) + #define FP_SUBNORMAL 3 + #endif + #if !defined(FP_NORMAL) + #define FP_NORMAL 4 + #endif + namespace std { + using float_t = float; + using double_t = double; + using ::isfinite; using ::ilogb; + + namespace cmath_detail { + + template + inline bool isinf_impl(FloatType x) + { + #if defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #endif + + using float_type = FloatType; + + return + ( + ( x == std::numeric_limits::infinity()) + || (-x == std::numeric_limits::infinity()) + ); + + #if defined(__GNUC__) + #pragma GCC diagnostic pop + #endif + } + + } // namespace cmath_detail + + inline bool isinf(float x) { return ::std::cmath_detail::isinf_impl(x); } + inline bool isinf(double x) { return ::std::cmath_detail::isinf_impl(x); } + inline bool isinf(long double x) { return ::std::cmath_detail::isinf_impl(x); } + using ::isnan; using ::abs; using ::fabs; using ::fmod; + + namespace cmath_detail { + + template + inline int fpclassify_impl(FloatType x) + { + #if defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #endif + + using float_type = FloatType; + + if((::std::isnan)(x)) + { + return FP_NAN; + } + else if((::std::isinf)(x)) + { + return FP_INFINITE; + } + else if((::std::fabs)(x) == static_cast(0.0L)) + { + return FP_ZERO; + } + else + { + const bool + is_subnormal + { + ( + ((::std::fabs)(x) > static_cast(0.0L)) + && ((::std::fabs)(x) < (std::numeric_limits::min)()) + ) + }; + + return (is_subnormal ? FP_SUBNORMAL : FP_NORMAL); + } + + #if defined(__GNUC__) + #pragma GCC diagnostic pop + #endif + } + + } // namespace cmath_detail + + inline int fpclassify(float x) { return ::std::cmath_detail::fpclassify_impl(x); } + inline int fpclassify(double x) { return ::std::cmath_detail::fpclassify_impl(x); } + inline int fpclassify(long double x) { return ::std::cmath_detail::fpclassify_impl(x); } + using ::modf; using ::floor; using ::ceil; diff --git a/examples/chapter09_08a/src/util/STL/complex b/examples/chapter09_08a/src/util/STL/complex index 1e5db0445..7d6117896 100644 --- a/examples/chapter09_08a/src/util/STL/complex +++ b/examples/chapter09_08a/src/util/STL/complex @@ -1230,10 +1230,10 @@ const bool __my_real_part_is_neg(__my_z.real() < 0U); - const T __my_real_part_fabs((__my_real_part_is_neg == false) ? __my_z.real() : -__my_z.real()); + const T __my_real_part_fabs((!__my_real_part_is_neg) ? __my_z.real() : -__my_z.real()); const T __my_sqrt_part (sqrt((__my_real_part_fabs + abs(__my_z)) / 2U)); - if(__my_real_part_is_neg == false) + if(!__my_real_part_is_neg) { return complex(__my_sqrt_part, __my_z.imag() / (__my_sqrt_part * 2U)); @@ -1242,10 +1242,10 @@ { const bool __my_imag_part_is_neg(__my_z.imag() < 0U); - const T __my_imag_part_fabs((__my_imag_part_is_neg == false) ? __my_z.imag() : -__my_z.imag()); + const T __my_imag_part_fabs((!__my_imag_part_is_neg) ? __my_z.imag() : -__my_z.imag()); return complex( __my_imag_part_fabs / (__my_sqrt_part * 2U), - ((__my_imag_part_is_neg == false) ? __my_sqrt_part : -__my_sqrt_part)); + ((!__my_imag_part_is_neg) ? __my_sqrt_part : -__my_sqrt_part)); } } diff --git a/examples/chapter09_08a/src/util/STL/cstdbool b/examples/chapter09_08a/src/util/STL/cstdbool index 833781c82..35fbdae3b 100644 --- a/examples/chapter09_08a/src/util/STL/cstdbool +++ b/examples/chapter09_08a/src/util/STL/cstdbool @@ -8,15 +8,18 @@ #ifndef CSTDBOOL_2012_12_14_ #define CSTDBOOL_2012_12_14_ - #include + #if (!defined(__cplusplus) && !defined(__bool_true_false_are_defined)) + + #define bool _Bool + #define false 0 + #define true 1 + + #define __bool_true_false_are_defined 1 + + #endif #if !defined(__bool_true_false_are_defined) #define __bool_true_false_are_defined 1 #endif - namespace std - { - using ::bool; - } - #endif // CSTDBOOL_2012_12_14_ diff --git a/examples/chapter09_08a/src/util/STL/cstdint b/examples/chapter09_08a/src/util/STL/cstdint index 1e030cf28..0e2e8d7ed 100644 --- a/examples/chapter09_08a/src/util/STL/cstdint +++ b/examples/chapter09_08a/src/util/STL/cstdint @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////////// -// Copyright Christopher Kormanyos 2007 - 2013. +// Copyright Christopher Kormanyos 2007 - 2024. // Distributed under the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -49,35 +49,36 @@ namespace std { - using ::int8_t; - using ::int16_t; - using ::int32_t; - using ::int64_t; + using ::int8_t; + using ::int16_t; + using ::int32_t; + using ::int64_t; using ::uint8_t; using ::uint16_t; using ::uint32_t; using ::uint64_t; - using ::int_least8_t; - using ::int_least16_t; - using ::int_least32_t; - using ::int_least64_t; + using ::int_least8_t; + using ::int_least16_t; + using ::int_least32_t; + using ::int_least64_t; using ::uint_least8_t; using ::uint_least16_t; using ::uint_least32_t; using ::uint_least64_t; - using ::int_fast8_t; - using ::int_fast16_t; - using ::int_fast32_t; - using ::int_fast64_t; + using ::int_fast8_t; + using ::int_fast16_t; + using ::int_fast32_t; + using ::int_fast64_t; using ::uint_fast8_t; using ::uint_fast16_t; using ::uint_fast32_t; using ::uint_fast64_t; - using ::intmax_t; + using ::intmax_t; using ::uintmax_t; + using ::intptr_t; using ::uintptr_t; } diff --git a/examples/chapter09_08a/src/util/STL/cstdlib b/examples/chapter09_08a/src/util/STL/cstdlib index 0055579ac..fbad04c23 100644 --- a/examples/chapter09_08a/src/util/STL/cstdlib +++ b/examples/chapter09_08a/src/util/STL/cstdlib @@ -31,8 +31,8 @@ extern "C" { - void abort (void); - int atexit(void(*)(void)) noexcept; + void abort (); + int atexit(void(*)()) noexcept; void exit (int); float strtof(const char* str, char** str_end); double strtod(const char* str, char** str_end); diff --git a/examples/chapter09_08a/src/util/STL/functional b/examples/chapter09_08a/src/util/STL/functional index 927067264..ca8441843 100644 --- a/examples/chapter09_08a/src/util/STL/functional +++ b/examples/chapter09_08a/src/util/STL/functional @@ -14,6 +14,16 @@ namespace std { + template + struct hash + { + // Since the underlying type is a std::uint64_t we will rely on its hash function from the STL + auto operator()(const T&) const noexcept -> std::size_t + { + return std::size_t { }; + } + }; + namespace xfunctional_impl { template constexpr T& func_ref_or_moveref(T& t) noexcept { return t; } @@ -28,7 +38,7 @@ template(std::declval()), - std::enable_if_t<(std::is_same>::value == false)>())> + std::enable_if_t<(!std::is_same>::value)>())> constexpr reference_wrapper(U&& u) noexcept(noexcept(xfunctional_impl::func_ref_or_moveref(std::forward(u)))) : my_ptr(std::addressof(xfunctional_impl::func_ref_or_moveref(std::forward(u)))) { } diff --git a/examples/chapter09_08a/src/util/STL/impl/alloc_traits.h b/examples/chapter09_08a/src/util/STL/impl/alloc_traits.h index b83b726ad..be8bd3d62 100644 --- a/examples/chapter09_08a/src/util/STL/impl/alloc_traits.h +++ b/examples/chapter09_08a/src/util/STL/impl/alloc_traits.h @@ -34,6 +34,9 @@ #include + #include + + namespace std { template diff --git a/examples/chapter09_08a/src/util/STL/impl/avr/avr_hardware_random_device.cpp b/examples/chapter09_08a/src/util/STL/impl/avr/avr_hardware_random_device.cpp new file mode 100644 index 000000000..f06d5df8e --- /dev/null +++ b/examples/chapter09_08a/src/util/STL/impl/avr/avr_hardware_random_device.cpp @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2020 - 2024. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#include +#include +#include +#include + +auto my_hardware_random_device_generator() -> unsigned int +{ + using timer_type = util::timer; + + const auto t_now = timer_type::get_mark(); + + const auto pseudo_random1 = + math::checksums::crc::crc32_mpeg2 + ( + reinterpret_cast(&t_now), + reinterpret_cast(&t_now) + sizeof(std::uint32_t) + ); + + const auto pseudo_random2 = + math::checksums::crc::crc32_mpeg2 + ( + reinterpret_cast(&t_now) + sizeof(std::uint32_t), + reinterpret_cast(&t_now) + sizeof(std::uint64_t) + ); + + return static_cast(util::make_long(pseudo_random1, pseudo_random2)); +} + +extern "C" unsigned char my_hardware_random_device_entropy() +{ + return 1U; +} diff --git a/examples/chapter09_08a/src/util/STL/impl/cmath_impl_gamma.cpp b/examples/chapter09_08a/src/util/STL/impl/cmath_impl_gamma.cpp new file mode 100644 index 000000000..3658e1b28 --- /dev/null +++ b/examples/chapter09_08a/src/util/STL/impl/cmath_impl_gamma.cpp @@ -0,0 +1,142 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2020. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +#include "xcmath_impl.h" + +#if defined(__GNUC__) && defined(__AVR__) +extern "C" float tgammaf(float x); +#endif + +// Here, we compute the tgamma function for float. +// This provides an example of a portable special function +// calculation using floating-point type definitions having +// specified widths from the proposed . + +namespace xcmath_impl +{ + float tgamma_inverse_taylor_series (float); + float tgamma_polynomial_approximation(float); + + float tgamma_inverse_taylor_series(float x) + { + // Implement a small-argument Taylor series for 1 / tgamma(x). + const float inverse_series_value + = ((((((( + 0.0072189432F + * x - 0.0096219715F) + * x - 0.0421977346F) + * x + 0.1665386114F) + * x - 0.0420026350F) + * x - 0.6558780715F) + * x + 0.5772156649F) + * x + 1.0F) + * x; + + return float(1.0F / inverse_series_value); + } + + float tgamma_polynomial_approximation(float x) + { + // Implement an order-9 polynomial fit for gamma(1 + x). + const float polynomial_approximation_value + = (((((((( - 0.0235850272F + * x + 0.1405004023F) + * x - 0.3860871683F) + * x + 0.6721315341F) + * x - 0.8649108124F) + * x + 0.9539074630F) + * x - 0.9035083713F) + * x + 0.9887589417F) + * x - 0.5772069549F) + * x + 0.9999999703F; + + // Return the polynomial fit for gamma(x). + // One downward recursion is used here. + return float(polynomial_approximation_value / x); + } +} + +extern "C" +float tgammaf(float x) +{ + // Use a positive argument for the Gamma calculation. + const bool b_neg = (x < 0); + + x = ((!b_neg) ? x : -x); + + // Check if the argument is pure zero or indistinguishably close to zero. + if(x < (std::numeric_limits::min)()) + { + return std::numeric_limits::quiet_NaN(); + } + + // Check if the argument is smaller than epsilon(). + if(x < std::numeric_limits::epsilon()) + { + using xcmath_impl::euler; + + return ((!b_neg) ? (+1.0F / x) - euler() + : (-1.0F / x) - euler()); + } + + // Check for overflow. + if(x > 35.04F) + { + return std::numeric_limits::infinity(); + } + + // Check if the argument is very close to +1 or +2? + if(!b_neg) + { + using xcmath_impl::near_integer; + + const bool is_near_one = near_integer(x, static_cast(1U)); + const bool is_near_two = near_integer(x, static_cast(2U)); + + if(is_near_one || is_near_two) + { + return 1.0F; + } + } + + // Evaluate the number of recursions needed in order to reach + // the range 0 < x < 1, and scale the argument accordingly. + const std::uint_least8_t n_recur = static_cast(::floorf(x)); + + x -= n_recur; + + // Obtain an approximation of tgamma(x), where x has + // perhaps been negated and/or scaled to a lower value. + float gamma_value = ((x < 0.1F) ? xcmath_impl::tgamma_inverse_taylor_series(x) + : xcmath_impl::tgamma_polynomial_approximation(x)); + + // Scale up the result via recursion if necessary. + for(std::uint_least8_t k = static_cast(0U); k < n_recur; ++k) + { + gamma_value *= x; + + ++x; + } + + // Return (and possibly reflect) the result. + if(!b_neg) + { + return gamma_value; + } + else + { + using xcmath_impl::pi; + + using std::sin; + + const float sin_pi_x = sin(pi() * x); + + return -pi() / ((x * gamma_value) * sin_pi_x); + } +} diff --git a/examples/chapter09_08a/src/util/STL/impl/cmath_impl_hyperbolic.cpp b/examples/chapter09_08a/src/util/STL/impl/cmath_impl_hyperbolic.cpp new file mode 100644 index 000000000..715bcab0b --- /dev/null +++ b/examples/chapter09_08a/src/util/STL/impl/cmath_impl_hyperbolic.cpp @@ -0,0 +1,95 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include +#include "xcmath_impl.h" + +#if defined(__GNUC__) && defined(__AVR__) +extern "C" float asinhf(float x); +extern "C" float acoshf(float x); +extern "C" float atanhf(float x); +#endif + +// Here, we implement naive computations of the inverse hyperbolic +// trigonometric functions asinh, acosh, and atanh for float. +// The inverse hyperbolic trigonometric functions are represented +// in terms of logarithmic functions. + +// These provide examples of portable calculations of some common +// elementary transcendental functions using floating-point typedefs +// having specified widths. + +extern "C" +float asinhf(float x) +{ + // Implement a naive hyperbolic arc-sine function. + + using std::log; + using std::sqrt; + + return log(x + sqrt((x * x) + 1.0F)); +} + +extern "C" +float acoshf(float x) +{ + const float x_minus_one = x - 1.0F; + + if(x_minus_one < -std::numeric_limits::epsilon()) + { + return std::numeric_limits::quiet_NaN(); + } + else if(x_minus_one < std::numeric_limits::epsilon()) + { + return 1.0F; + } + else + { + // Implement a naive hyperbolic arc-cosine function. + + using std::log; + using std::sqrt; + + const float xp = (x + 1.0F); + const float xm = (x - 1.0F); + + return log(x + sqrt(xm * xp)); + } +} + +extern "C" +float atanhf(float x) +{ + const bool is_neg = (x < 0.0F); + + const float xx = ((!is_neg) ? x : -x); + + if(xx > 1.0F) + { + return std::numeric_limits::quiet_NaN(); + } + + float result; + + if(xx < 1.0F) + { + // Implement a naive hyperbolic arc-tangent function. + const float xp = (xx + 1.0F); + const float xm = (1.0F - xx); + + using std::log; + + result = (float) (log(xp) - log(xm)) / 2.0F; + } + else + { + result = std::numeric_limits::infinity(); + } + + return ((!is_neg) ? result : -result); +} diff --git a/examples/chapter09_08a/src/util/STL/impl/ptr_traits.h b/examples/chapter09_08a/src/util/STL/impl/ptr_traits.h index eeac46613..eb3ad05fa 100644 --- a/examples/chapter09_08a/src/util/STL/impl/ptr_traits.h +++ b/examples/chapter09_08a/src/util/STL/impl/ptr_traits.h @@ -32,6 +32,8 @@ #ifndef PTR_TRAITS_2021_01_26_H_ #define PTR_TRAITS_2021_01_26_H_ + #include + namespace std { template diff --git a/examples/chapter09_08a/src/util/STL/iterator b/examples/chapter09_08a/src/util/STL/iterator index 3d64d79d4..b21b81899 100644 --- a/examples/chapter09_08a/src/util/STL/iterator +++ b/examples/chapter09_08a/src/util/STL/iterator @@ -54,10 +54,7 @@ typedef const value_type& reference; typedef random_access_iterator_tag iterator_category; }; - } - namespace std - { template for compilers that do not yet support it. - extern "C" unsigned int my_hardware_random_device_generator(void); - extern "C" unsigned char my_hardware_random_device_entropy (void); + extern "C" unsigned int my_hardware_random_device_generator(); + extern "C" unsigned char my_hardware_random_device_entropy (); namespace std { @@ -1379,7 +1379,7 @@ template::rnd__m_gen_rand(void) + rnd__value_f>::rnd__m_gen_rand() { const UnsignedIntegralType __upper_mask = (~UnsignedIntegralType()) << rnd__long_lag_r; const UnsignedIntegralType __lower_mask = ~__upper_mask; diff --git a/examples/chapter09_08a/src/util/STL/span b/examples/chapter09_08a/src/util/STL/span index ae2213c0e..1c5d121e3 100644 --- a/examples/chapter09_08a/src/util/STL/span +++ b/examples/chapter09_08a/src/util/STL/span @@ -1,11 +1,12 @@ -// This is significant simplification of an existing work: +// This is a significant simplification of an existing work: +// Comments from the original work follow. // This is an implementation of std::span from P0122R7 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0122r7.pdf /////////////////////////////////////////////////////////////////////////////// // Copyright Tristan Brindle 2018. -// Copyright Christopher Kormanyos 2019. +// Copyright Christopher Kormanyos 2019 - 2024. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file ../../LICENSE_1_0.txt or copy at // https://www.boost.org/LICENSE_1_0.txt) @@ -26,7 +27,7 @@ using byte = unsigned char; STL_LOCAL_CONSTEXPR std::size_t dynamic_extent = - (std::numeric_limits::max)(); + static_cast((std::numeric_limits::max)()); template diff --git a/examples/chapter09_08a/src/util/STL/stdfloat b/examples/chapter09_08a/src/util/STL/stdfloat new file mode 100644 index 000000000..3b5e46ad7 --- /dev/null +++ b/examples/chapter09_08a/src/util/STL/stdfloat @@ -0,0 +1,45 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2025. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef STDFLOAT_2024_07_12 + #define STDFLOAT_2024_07_12 + + #if defined(__GNUC__) + #pragma GCC system_header + #endif + + #include + + namespace std + { + using float32_t = float; + #define __STDCPP_FLOAT32_T__ 1 + + #if (defined(__GNUC__) && defined(__AVR__)) + + #if(__GNUC__ >= 12) + using float64_t = long double; + #define __STDCPP_FLOAT64_T__ 1 + #endif + + #elif (defined(__GNUC__) && defined(__RL78__)) + + using float64_t = long double; + #define __STDCPP_FLOAT64_T__ 1 + + #else + + using float64_t = double; + #define __STDCPP_FLOAT64_T__ 1 + + #endif + } + + static_assert((std::numeric_limits::digits == 24), "Error: Incorrect float32_t type definition"); + static_assert((std::numeric_limits::digits == 53), "Error: Incorrect float64_t type definition"); + +#endif // STDFLOAT_2024_07_12 diff --git a/examples/chapter09_08a/src/util/STL/tuple b/examples/chapter09_08a/src/util/STL/tuple index 101e02446..14798e7be 100644 --- a/examples/chapter09_08a/src/util/STL/tuple +++ b/examples/chapter09_08a/src/util/STL/tuple @@ -8,14 +8,12 @@ #ifndef TUPLE_2010_02_23_ #define TUPLE_2010_02_23_ - #if defined(__GNUC__) - #pragma GCC system_header - #endif - #include #include - #include + #include + #include #include + #include // Implement some of std::tuple for compilers that do not yet support it. // This implementation of tuple supports up to 11 template parameters. @@ -32,18 +30,20 @@ struct xnothing final { - xnothing() { } - xnothing(const xnothing&) { } - ~xnothing() { } - xnothing& operator=(const xnothing&) { return *this; } + constexpr xnothing() = default; + constexpr xnothing(const xnothing&) = default; + constexpr xnothing(xnothing&&) noexcept = default; + ~xnothing() = default; + constexpr auto operator=(const xnothing&) -> xnothing& = default; + constexpr auto operator=(xnothing&&) noexcept -> xnothing& = default; }; - inline bool operator==(const xnothing&, const xnothing&) { return true; } - inline bool operator!=(const xnothing&, const xnothing&) { return false; } - inline bool operator< (const xnothing&, const xnothing&) { return false; } - inline bool operator<=(const xnothing&, const xnothing&) { return false; } - inline bool operator> (const xnothing&, const xnothing&) { return false; } - inline bool operator>=(const xnothing&, const xnothing&) { return false; } + inline constexpr auto operator==(const xnothing&, const xnothing&) noexcept -> bool { return true; } + inline constexpr auto operator!=(const xnothing&, const xnothing&) noexcept -> bool { return false; } + inline constexpr auto operator< (const xnothing&, const xnothing&) noexcept -> bool { return false; } + inline constexpr auto operator<=(const xnothing&, const xnothing&) noexcept -> bool { return false; } + inline constexpr auto operator> (const xnothing&, const xnothing&) noexcept -> bool { return false; } + inline constexpr auto operator>=(const xnothing&, const xnothing&) noexcept -> bool { return false; } } namespace std @@ -67,6 +67,20 @@ typename T11 = xtuple_helper::xnothing> class tuple { + private: + using type0 = T0; + using type1 = T1; + using type2 = T2; + using type3 = T3; + using type4 = T4; + using type5 = T5; + using type6 = T6; + using type7 = T7; + using type8 = T8; + using type9 = T9; + using type10 = T10; + using type11 = T11; + public: template @@ -75,63 +89,67 @@ template friend class xtuple_helper::xsize; - typedef tuple tuple_type; - - tuple() { } - - explicit tuple(const T0& p0, - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 (), - const T8& p8 = T8 (), - const T9& p9 = T9 (), - const T10& p10 = T10(), - const T11& p11 = T11()) : t0 (p0), - t1 (p1), - t2 (p2), - t3 (p3), - t4 (p4), - t5 (p5), - t6 (p6), - t7 (p7), - t8 (p8), - t9 (p9), - t10(p10), - t11(p11){ } - - tuple(const tuple_type& t) : t0 (t.t0), - t1 (t.t1), - t2 (t.t2), - t3 (t.t3), - t4 (t.t4), - t5 (t.t5), - t6 (t.t6), - t7 (t.t7), - t8 (t.t8), - t9 (t.t9), - t10(t.t10), - t11(t.t11){ } + using tuple_type = tuple; + + constexpr tuple() = default; + + constexpr tuple(const T0& p0, + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 (), + const T8& p8 = T8 (), + const T9& p9 = T9 (), + const T10& p10 = T10(), + const T11& p11 = T11()) : t0 (p0), + t1 (p1), + t2 (p2), + t3 (p3), + t4 (p4), + t5 (p5), + t6 (p6), + t7 (p7), + t8 (p8), + t9 (p9), + t10(p10), + t11(p11) { } + + constexpr tuple(const tuple_type& t) : t0 (t.t0), + t1 (t.t1), + t2 (t.t2), + t3 (t.t3), + t4 (t.t4), + t5 (t.t5), + t6 (t.t6), + t7 (t.t7), + t8 (t.t8), + t9 (t.t9), + t10(t.t10), + t11(t.t11) { } + + constexpr tuple(tuple_type&& t) noexcept + : t0 (t.t0), + t1 (t.t1), + t2 (t.t2), + t3 (t.t3), + t4 (t.t4), + t5 (t.t5), + t6 (t.t6), + t7 (t.t7), + t8 (t.t8), + t9 (t.t9), + t10(t.t10), + t11(t.t11) { } template - tuple(const std::pair& p) : t0 (p.first), - t1 (p.second), - t2 (T2 ()), - t3 (T3 ()), - t4 (T4 ()), - t5 (T5 ()), - t6 (T6 ()), - t7 (T7 ()), - t8 (T8 ()), - t9 (T9 ()), - t10(T10()), - t11(T11()){ } - - ~tuple() { } + constexpr tuple(const std::pair& p) : t0 (p.first), + t1 (p.second) { } + + ~tuple() = default; template - tuple& operator=(const tuple& t) + constexpr tuple& operator=(const tuple& t) + { + if(this != &t) + { + t0 = T0 (t.t0); + t1 = T1 (t.t1); + t2 = T2 (t.t2); + t3 = T3 (t.t3); + t4 = T4 (t.t4); + t5 = T5 (t.t5); + t6 = T6 (t.t6); + t7 = T7 (t.t7); + t8 = T8 (t.t8); + t9 = T9 (t.t9); + t10 = T10(t.t10); + t11 = T11(t.t11); + } + + return *this; + } + + constexpr tuple& operator=(tuple&& t) noexcept { - t0 = T0 (t.t0); - t1 = T1 (t.t1); - t2 = T2 (t.t2); - t3 = T3 (t.t3); - t4 = T4 (t.t4); - t5 = T5 (t.t5); - t6 = T6 (t.t6); - t7 = T7 (t.t7); - t8 = T8 (t.t8); - t9 = T9 (t.t9); - t10 = T10(t.t10); - t11 = T11(t.t11); + t0 = static_cast(t.t0); + t1 = static_cast(t.t1); + t2 = static_cast(t.t2); + t3 = static_cast(t.t3); + t4 = static_cast(t.t4); + t5 = static_cast(t.t5); + t6 = static_cast(t.t6); + t7 = static_cast(t.t7); + t8 = static_cast(t.t8); + t9 = static_cast(t.t9); + t10 = static_cast(t.t10); + t11 = static_cast(t.t11); return *this; } template - tuple& operator=(const std::pair& p) + constexpr tuple& operator=(const std::pair& p) { t0 = T0 (p.first); t1 = T1 (p.second); @@ -183,51 +222,75 @@ return *this; } - void swap(tuple& other) + constexpr void swap(tuple& other) { if(this != &other) { - const type0 tmp0 (t0 ); t0 = other.t0 ; other.t0 = tmp0 ; - const type1 tmp1 (t1 ); t1 = other.t1 ; other.t1 = tmp1 ; - const type2 tmp2 (t2 ); t2 = other.t2 ; other.t2 = tmp2 ; - const type3 tmp3 (t3 ); t3 = other.t3 ; other.t3 = tmp3 ; - const type4 tmp4 (t4 ); t4 = other.t4 ; other.t4 = tmp4 ; - const type5 tmp5 (t5 ); t5 = other.t5 ; other.t5 = tmp5 ; - const type6 tmp6 (t6 ); t6 = other.t6 ; other.t6 = tmp6 ; - const type7 tmp7 (t7 ); t7 = other.t7 ; other.t7 = tmp7 ; - const type8 tmp8 (t8 ); t8 = other.t8 ; other.t8 = tmp8 ; - const type9 tmp9 (t9 ); t9 = other.t9 ; other.t9 = tmp9 ; - const type10 tmp10(t10); t10 = other.t10; other.t10 = tmp10; - const type11 tmp11(t11); t11 = other.t11; other.t11 = tmp11; + my_swap(t0 , other.t0); + my_swap(t1 , other.t1); + my_swap(t2 , other.t2); + my_swap(t3 , other.t3); + my_swap(t4 , other.t4); + my_swap(t5 , other.t5); + my_swap(t6 , other.t6); + my_swap(t7 , other.t7); + my_swap(t8 , other.t8); + my_swap(t9 , other.t9); + my_swap(t10, other.t10); + my_swap(t11, other.t11); } } + constexpr void swap(tuple&& other) + { + my_swap(static_cast(t0) , static_cast(other.t0)); + my_swap(static_cast(t1) , static_cast(other.t1)); + my_swap(static_cast(t2) , static_cast(other.t2)); + my_swap(static_cast(t3) , static_cast(other.t3)); + my_swap(static_cast(t4) , static_cast(other.t4)); + my_swap(static_cast(t5) , static_cast(other.t5)); + my_swap(static_cast(t6) , static_cast(other.t6)); + my_swap(static_cast(t7) , static_cast(other.t7)); + my_swap(static_cast(t8) , static_cast(other.t8)); + my_swap(static_cast(t9) , static_cast(other.t9)); + my_swap(static_cast(t10), static_cast(other.t10)); + my_swap(static_cast(t11), static_cast(other.t11)); + } + private: - T0 t0; - T1 t1; - T2 t2; - T3 t3; - T4 t4; - T5 t5; - T6 t6; - T7 t7; - T8 t8; - T9 t9; - T10 t10; - T11 t11; - - typedef T0 type0; - typedef T1 type1; - typedef T2 type2; - typedef T3 type3; - typedef T4 type4; - typedef T5 type5; - typedef T6 type6; - typedef T7 type7; - typedef T8 type8; - typedef T9 type9; - typedef T10 type10; - typedef T11 type11; + type0 t0 { }; + type1 t1 { }; + type2 t2 { }; + type3 t3 { }; + type4 t4 { }; + type5 t5 { }; + type6 t6 { }; + type7 t7 { }; + type8 t8 { }; + type9 t9 { }; + type10 t10 { }; + type11 t11 { }; + + template + constexpr void my_swap(swap_type& left, swap_type& right) + { + if(&left != &right) + { + const swap_type tmp(left); + + left = right; + right = tmp; + } + } + + template + constexpr void my_swap(swap_type&& left, swap_type&& right) + { + const swap_type tmp(left); + + left = right; + right = tmp; + } }; } @@ -236,14 +299,14 @@ template class xget { }; - #define MAKE_XTUPLE_GET_HELPER(NUM) \ - template class xget<(NUM), xtuple_type> \ - { \ - public: \ - typedef typename xtuple_type::type##NUM xelem_type; \ - static xelem_type& get ( xtuple_type& t) { return t.t##NUM ; } \ - static const xelem_type& get_const(const xtuple_type& t) { return t.t##NUM ; } \ - } \ + #define MAKE_XTUPLE_GET_HELPER(NUM) \ + template class xget<(NUM), xtuple_type> \ + { \ + public: \ + typedef typename xtuple_type::type##NUM xelem_type; \ + static constexpr xelem_type& get ( xtuple_type& t) { return t.t##NUM ; } \ + static constexpr const xelem_type& get_const(const xtuple_type& t) { return t.t##NUM ; } \ + } MAKE_XTUPLE_GET_HELPER(0); MAKE_XTUPLE_GET_HELPER(1); @@ -265,76 +328,76 @@ class xsize { public: - static STL_LOCAL_CONSTEXPR std::size_t value = xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value - + xtuple_elem_size_helper::value; + static constexpr std::size_t value = xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value + + xtuple_elem_size_helper::value; }; } namespace std { template - typename xtuple_helper::xget >::xelem_type& get(tuple<>& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple<>& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } + constexpr typename xtuple_helper::xget >::xelem_type& get(tuple& t) { return xtuple_helper::xget >::get(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple<>& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple<>& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template - const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } + constexpr const typename xtuple_helper::xget >::xelem_type& get(const tuple& t) { return xtuple_helper::xget >::get_const(t); } template @@ -372,7 +435,7 @@ class tuple_size { public: - static STL_LOCAL_CONSTEXPR std::size_t value = xtuple_helper::xsize::value; + static constexpr std::size_t value = xtuple_helper::xsize::value; }; template @@ -385,31 +448,31 @@ class tuple_size : public std::integral_constant::value> { }; template - tuple make_tuple(const T0& p0 = T0 ()) + constexpr tuple make_tuple(const T0& p0 = T0 ()) { return tuple(p0); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 ()) { return tuple(p0, p1); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 ()) { return tuple(p0, p1, p2); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 ()) { return tuple(p0, p1, p2, p3); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 ()) { return tuple(p0, p1, p2, p3, p4); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 ()) { return tuple(p0, p1, p2, p3, p4, p5); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 ()) { return tuple(p0, p1, p2, p3, p4, p5, p6); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 ()) { return tuple(p0, p1, p2, p3, p4, p5, p6, p7); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 (), - const T8& p8 = T8 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 (), + const T8& p8 = T8 ()) { return tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 (), - const T8& p8 = T8 (), - const T9& p9 = T9 ()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 (), + const T8& p8 = T8 (), + const T9& p9 = T9 ()) { return tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 (), - const T8& p8 = T8 (), - const T9& p9 = T9 (), - const T10& p10 = T10()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 (), + const T8& p8 = T8 (), + const T9& p9 = T9 (), + const T10& p10 = T10()) { return tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } template - tuple make_tuple(const T0& p0 = T0 (), - const T1& p1 = T1 (), - const T2& p2 = T2 (), - const T3& p3 = T3 (), - const T4& p4 = T4 (), - const T5& p5 = T5 (), - const T6& p6 = T6 (), - const T7& p7 = T7 (), - const T8& p8 = T8 (), - const T9& p9 = T9 (), - const T10& p10 = T10(), - const T11& p11 = T11()) + constexpr tuple make_tuple(const T0& p0 = T0 (), + const T1& p1 = T1 (), + const T2& p2 = T2 (), + const T3& p3 = T3 (), + const T4& p4 = T4 (), + const T5& p5 = T5 (), + const T6& p6 = T6 (), + const T7& p7 = T7 (), + const T8& p8 = T8 (), + const T9& p9 = T9 (), + const T10& p10 = T10(), + const T11& p11 = T11()) { return tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } } @@ -570,7 +633,10 @@ struct ignore_t { template - constexpr void operator=(T&&) const noexcept { } + constexpr ignore_t& operator=(T&&) noexcept { return *this; } + + template + constexpr ignore_t& operator=(ignore_t&&) noexcept { return *this; } }; } diff --git a/examples/chapter09_08a/src/util/STL/type_traits b/examples/chapter09_08a/src/util/STL/type_traits index ff2c16c52..7c9d8caa4 100644 --- a/examples/chapter09_08a/src/util/STL/type_traits +++ b/examples/chapter09_08a/src/util/STL/type_traits @@ -9,6 +9,7 @@ #define TYPE_TRAITS_2013_09_01_ #include + #include // Implement some of for compilers that do not yet support it. @@ -172,22 +173,28 @@ namespace std { template - struct make_unsigned { }; + struct make_unsigned + { + using type = typename std::conditional<(sizeof(T) > 4U), std::uint64_t, + typename std::conditional<(sizeof(T) > 2U), std::uint32_t, + typename std::conditional<(sizeof(T) > 1U), std::uint16_t, + std::uint8_t>::type>::type>::type; + }; - template<> struct make_unsigned { using type = unsigned char; }; - template<> struct make_unsigned { using type = unsigned short; }; - template<> struct make_unsigned { using type = unsigned int; }; - template<> struct make_unsigned { using type = unsigned long; }; - template<> struct make_unsigned { using type = unsigned long long; }; + template + struct make_signed + { + using type = typename std::conditional<(sizeof(T) > 4U), std::int64_t, + typename std::conditional<(sizeof(T) > 2U), std::int32_t, + typename std::conditional<(sizeof(T) > 1U), std::int16_t, + std::int8_t>::type>::type>::type; + }; template - struct make_signed { }; + using make_unsigned_t = typename std::make_unsigned::type; - template<> struct make_signed { using type = signed char; }; - template<> struct make_signed { using type = signed short; }; - template<> struct make_signed { using type = signed int; }; - template<> struct make_signed { using type = signed long; }; - template<> struct make_signed { using type = signed long long; }; + template + using make_signed_t = typename std::make_signed::type; } namespace traits_helper diff --git a/examples/chapter09_08a/src/util/STL/utility b/examples/chapter09_08a/src/util/STL/utility index 97909e08f..376d858c5 100644 --- a/examples/chapter09_08a/src/util/STL/utility +++ b/examples/chapter09_08a/src/util/STL/utility @@ -193,13 +193,13 @@ template bool operator<=(const std::pair& left, const std::pair& right) { - return ((right < left) == false); + return (!(right < left)); } template bool operator>=(const std::pair& left, const std::pair& right) { - return ((left < right) == false); + return (!(left < right)); } template diff --git a/examples/chapter09_08a/src/util/STL/version b/examples/chapter09_08a/src/util/STL/version new file mode 100644 index 000000000..5ba3311be --- /dev/null +++ b/examples/chapter09_08a/src/util/STL/version @@ -0,0 +1,16 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2007 - 2024. +// Distributed under the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef VERSION_2024_06_29 + #define VERSION_2024_06_29 + + // Implement some of for compilers that do not yet support it. + // In this particular case, simply include the standard ISO header. + + #include + +#endif // VERSION_2024_06_29 diff --git a/examples/chapter09_08a/src/util/STL_C++XX_stdfloat/cstdfloat b/examples/chapter09_08a/src/util/STL_C++XX_stdfloat/cstdfloat index 9a4164105..c060f0845 100644 --- a/examples/chapter09_08a/src/util/STL_C++XX_stdfloat/cstdfloat +++ b/examples/chapter09_08a/src/util/STL_C++XX_stdfloat/cstdfloat @@ -30,7 +30,7 @@ using ::float_fast16_t; using ::float_least16_t; - static_assert( (std::numeric_limits::is_iec559 == true) + static_assert( std::numeric_limits::is_iec559 && (std::numeric_limits::radix == 2) && (std::numeric_limits::digits == 11) && (std::numeric_limits::max_exponent == 16), @@ -42,7 +42,7 @@ using ::float_fast32_t; using ::float_least32_t; - static_assert( (std::numeric_limits::is_iec559 == true) + static_assert( std::numeric_limits::is_iec559 && (std::numeric_limits::radix == 2) && (std::numeric_limits::digits == 24) && (std::numeric_limits::max_exponent == 128), @@ -54,7 +54,7 @@ using ::float_fast64_t; using ::float_least64_t; - static_assert( (std::numeric_limits::is_iec559 == true) + static_assert( std::numeric_limits::is_iec559 && (std::numeric_limits::radix == 2) && (std::numeric_limits::digits == 53) && (std::numeric_limits::max_exponent == 1024), @@ -66,7 +66,7 @@ using ::float_fast80_t; using ::float_least80_t; - static_assert( (std::numeric_limits::is_iec559 == true) + static_assert( std::numeric_limits::is_iec559 && (std::numeric_limits::radix == 2) && (std::numeric_limits::digits == 64) && (std::numeric_limits::max_exponent == 16384), @@ -78,7 +78,7 @@ using ::float_fast128_t; using ::float_least128_t; - static_assert( (std::numeric_limits::is_iec559 == true) + static_assert( std::numeric_limits::is_iec559 && (std::numeric_limits::radix == 2) && (std::numeric_limits::digits == 113) && (std::numeric_limits::max_exponent == 16384), diff --git a/examples/chapter09_08a/target/app/make/app_make.gmk b/examples/chapter09_08a/target/app/make/app_make.gmk index 66e67ca33..94d1252f0 100644 --- a/examples/chapter09_08a/target/app/make/app_make.gmk +++ b/examples/chapter09_08a/target/app/make/app_make.gmk @@ -1,5 +1,5 @@ # -# Copyright Christopher Kormanyos 2007 - 2023. +# Copyright Christopher Kormanyos 2007 - 2025. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -26,7 +26,21 @@ # punctuation # ------------------------------------------------------------------------------ -DQUOTE = \" +DQUOTE := \" +$(DQUOTE) := \" + +SEMICOLON := ; +$(SEMICOLON) := ; + +DOLLAR := $$ +$(DOLLAR) := $$ + +# ------------------------------------------------------------------------------ +# null device +# ------------------------------------------------------------------------------ + +NULL_DEVICE := NUL +$(NULL_DEVICE) := NUL # ------------------------------------------------------------------------------ # paths @@ -141,23 +155,7 @@ C_INCLUDES = $(TGT_INCLUDES) \ ifeq ($(WARN_FLAGS),) WARN_FLAGS = -Wall \ -Wextra \ - -Wpedantic \ - -Wmain \ - -Wundef \ - -Wconversion \ - -Wsign-conversion \ - -Wunused-parameter \ - -Wuninitialized \ - -Wmissing-declarations \ - -Wshadow \ - -Wunreachable-code \ - -Wswitch-default \ - -Wswitch-enum \ - -Wcast-align \ - -Wmissing-include-dirs \ - -Winit-self \ - -Wfloat-equal \ - -Wdouble-promotion + -Wpedantic endif GCCFLAGS = -g \ @@ -217,7 +215,7 @@ clean_prj: @-$(MKDIR) -p $(PATH_OBJ) @-$(MKDIR) -p $(PATH_ERR) @-$(MKDIR) -p $(PATH_LST) - @-$(RM) -r $(PATH_BIN) 2>NUL + @-$(RM) -r $(PATH_BIN) 2>$(NULL_DEVICE) @-$(MKDIR) -p $(PATH_BIN) @@ -231,10 +229,10 @@ clean_all: @-$(MKDIR) -p $(PATH_OBJ) @-$(MKDIR) -p $(PATH_ERR) @-$(MKDIR) -p $(PATH_LST) - @-$(RM) -r $(PATH_OBJ) 2>NUL - @-$(RM) -r $(PATH_ERR) 2>NUL - @-$(RM) -r $(PATH_LST) 2>NUL - @-$(RM) -r $(PATH_BIN) 2>NUL + @-$(RM) -r $(PATH_OBJ) 2>$(NULL_DEVICE) + @-$(RM) -r $(PATH_ERR) 2>$(NULL_DEVICE) + @-$(RM) -r $(PATH_LST) 2>$(NULL_DEVICE) + @-$(RM) -r $(PATH_BIN) 2>$(NULL_DEVICE) @-$(MKDIR) -p $(PATH_BIN) @@ -244,6 +242,7 @@ clean_all: .PHONY: version version: # Print the GNU make version and the compiler version + @$(ECHO) @$(ECHO) +++ Print GNUmake version @$(MAKE) --version @$(ECHO) @@ -254,11 +253,14 @@ version: @$(ECHO) $(C_INCLUDES) @$(ECHO) @$(ECHO) +++ Print compiler include paths (for VisualStudio(R) browsing) - @$(ECHO) $(addsuffix ;,$(subst -I,$$\(ProjectDir\)/, $(C_INCLUDES))) + @$(ECHO) $(addsuffix $(SEMICOLON),$(subst -I,$$\(ProjectDir\)/, $(C_INCLUDES))) @$(ECHO) @$(ECHO) +++ Print compiler definitions @$(ECHO) $(C_DEFINES) @$(ECHO) + @$(ECHO) +++ Print compiler CXXFLAGS flags + @$(ECHO) $(CXXFLAGS) + @$(ECHO) # ------------------------------------------------------------------------------ @@ -267,8 +269,6 @@ version: $(APP).$(TGT_SUFFIX) : $(LINKER_DEFINITION_FILE) $(FILES_O) @-$(ECHO) +++ linking application to generate: $(APP).$(TGT_SUFFIX) @-$(CC) $(LDFLAGS) $(FILES_O) -o $(APP).$(TGT_SUFFIX) - @-$(ECHO) +++ generating assembly list file: $(APP).lss - @-$(OBJDUMP) -h -S $(APP).$(TGT_SUFFIX) > $(APP).lss # ------------------------------------------------------------------------------ @@ -280,7 +280,11 @@ $(APP)_nm.txt : $(APP).$(TGT_SUFFIX) @-$(ECHO) +++ demangling symbols with c++filt to generate: $(APP)_cppfilt.txt @-$(NM) --numeric-sort --print-size $(APP).$(TGT_SUFFIX) | $(CPPFILT) > $(APP)_cppfilt.txt @-$(ECHO) +++ parsing symbols with readelf to generate: $(APP)_readelf.txt +ifeq ($(TGT_SUFFIX),elf) @-$(READELF) --syms $(APP).$(TGT_SUFFIX) > $(APP)_readelf.txt +else + @-$(ECHO) +++ not available for: $(APP).$(TGT_SUFFIX). +endif @-$(ECHO) +++ creating size summary table with size to generate: $(APP)_size.txt @-$(SIZE) -A -t $(APP).$(TGT_SUFFIX) > $(APP)_size.txt @@ -289,10 +293,29 @@ $(APP)_nm.txt : $(APP).$(TGT_SUFFIX) # create hex mask # ------------------------------------------------------------------------------ $(APP)_flash.hex : $(APP).$(TGT_SUFFIX) + @-$(ECHO) +++ creating hex module: $(APP).$(TGT_SUFFIX) +ifeq ($(TGT_SUFFIX),elf) @-$(ECHO) +++ creating hex module: $(APP).hex. @-$(OBJCOPY) $(APP).$(TGT_SUFFIX) -O ihex $(APP).hex @-$(ECHO) +++ creating srec module: $(APP).s19 @-$(OBJCOPY) $(APP).$(TGT_SUFFIX) -O srec --srec-forceS3 --srec-len=16 $(APP).s19 +else + @-$(ECHO) +++ creating hex module disabled for non-ELF absolute objet file. +endif +ifeq ($(RULE_SPECIAL_MAKE_IMAGE_FILE),) + @-$(ECHO) +++ creating special image file + @-$(ECHO) +++ disabled because there is no special image file +else + @-$(ECHO) +++ creating special image file + @-$(RULE_SPECIAL_MAKE_IMAGE_FILE) +endif +ifeq ($(RULE_SPECIAL_MAKE_FLASH_BATCH),) + @-$(ECHO) +++ creating special flash batch file + @-$(ECHO) +++ disabled because there is no special flash batch file +else + @-$(ECHO) +++ creating special flash batch file + @-$(RULE_SPECIAL_MAKE_FLASH_BATCH) +endif # ------------------------------------------------------------------------------ # Dependencyfile include (build) diff --git a/examples/chapter09_08a/target/app/make/app_rules.gmk b/examples/chapter09_08a/target/app/make/app_rules.gmk index 78b05f321..4a7bca584 100644 --- a/examples/chapter09_08a/target/app/make/app_rules.gmk +++ b/examples/chapter09_08a/target/app/make/app_rules.gmk @@ -1,5 +1,5 @@ # -# Copyright Christopher Kormanyos 2007 - 2023. +# Copyright Christopher Kormanyos 2007 - 2024. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -38,8 +38,28 @@ $(PATH_OBJ)/%.o : %.cpp # ...and generate a dependency file (using the -MM flag), # ...and be sure to include the path in the dependency file. @-$(CC) $(CXXFLAGS) $(C_INCLUDES) $(DEP_FLAGS) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err - @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|:\([0-9]*\):|(\1) :|' $(PATH_ERR)/$(basename $(@F)).err + @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|.hpp:\([0-9]*\),|.hpp(\1) :|' -e 's|.cpp:\([0-9]*\),|.cpp(\1) :|' $(PATH_ERR)/$(basename $(@F)).err +ifneq ($(findstr risc,$(GCC_TARGET)),) @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst +endif + +# ------------------------------------------------------------------------------ +# Rule to compile C++ source file (*.cc) to object file (*.o). +# ------------------------------------------------------------------------------ + +$(PATH_OBJ)/%.o : %.cc + @$(ECHO) +++ compile: $< to $@ + # Compile the source file, + # ...and reformat (using sed) any possible error/warning messages + # for the VisualStudio(R) output window, + # ...and create an assembly listing using objdump, + # ...and generate a dependency file (using the -MM flag), + # ...and be sure to include the path in the dependency file. + @-$(CC) $(CXXFLAGS) $(C_INCLUDES) $(DEP_FLAGS) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err + @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|.hpp:\([0-9]*\),|.hpp(\1) :|' -e 's|.cc:\([0-9]*\),|.cc(\1) :|' $(PATH_ERR)/$(basename $(@F)).err +ifneq ($(findstr risc,$(GCC_TARGET)),) + @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst +endif # ------------------------------------------------------------------------------ # Rule to compile C source file (*.c) to object file (*.o). @@ -54,7 +74,7 @@ $(PATH_OBJ)/%.o : %.c # ...and generate a dependency file (using the -MM flag), # ...and be sure to include the path in the dependency file. @-$(CC) $(CFLAGS) $(C_INCLUDES) $(DEP_FLAGS) $< -c -o $(PATH_OBJ)/$(basename $(@F)).o 2> $(PATH_ERR)/$(basename $(@F)).err - @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|:\([0-9]*\):|(\1) :|' $(PATH_ERR)/$(basename $(@F)).err + @-$(SED) -e 's|.h:\([0-9]*\),|.h(\1) :|' -e 's|.c:\([0-9]*\),|.c(\1) :|' $(PATH_ERR)/$(basename $(@F)).err @-$(OBJDUMP) -S $(PATH_OBJ)/$(basename $(@F)).o > $(PATH_LST)/$(basename $(@F)).lst diff --git a/examples/chapter09_08a/target/micros/avr/make/avr.ld b/examples/chapter09_08a/target/micros/avr/make/avr.ld index 1f43c936d..f4a3a0cef 100644 --- a/examples/chapter09_08a/target/micros/avr/make/avr.ld +++ b/examples/chapter09_08a/target/micros/avr/make/avr.ld @@ -1,5 +1,5 @@ /* - Copyright Christopher Kormanyos 2007 - 2023. + Copyright Christopher Kormanyos 2007 - 2025. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/examples/chapter09_08a/target/micros/avr/make/avr_flags.gmk b/examples/chapter09_08a/target/micros/avr/make/avr_flags.gmk index 3497d27a5..22ab34f02 100644 --- a/examples/chapter09_08a/target/micros/avr/make/avr_flags.gmk +++ b/examples/chapter09_08a/target/micros/avr/make/avr_flags.gmk @@ -1,5 +1,5 @@ # -# Copyright Christopher Kormanyos 2007 - 2023. +# Copyright Christopher Kormanyos 2007 - 2025. # Distributed under the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt # or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,30 +10,31 @@ # ------------------------------------------------------------------------------ ifneq ($(MAKE),make) -GCC_VERSION = 14.2.0 +GCC_VERSION = 15.1.0 endif + GCC_TARGET = avr GCC_PREFIX = avr TGT_SUFFIX = elf -TGT_ALLFLAGS = -Os \ +TGT_ALLFLAGS = -O2 \ -mmcu=atmega328p \ -mrelax \ -finline-functions \ - -finline-limit=128 \ + -finline-limit=32 \ -fsigned-char -ifeq ($(GCC_VERSION),11.2.0) +ifeq ($(GCC_VERSION),15.1.0) TGT_ALLFLAGS := $(TGT_ALLFLAGS) \ -mdouble=32 \ -mlong-double=64 endif -TGT_CFLAGS = -std=c99 \ +TGT_CFLAGS = -std=c11 \ $(TGT_ALLFLAGS) -TGT_CXXFLAGS = -std=c++14 \ +TGT_CXXFLAGS = -std=c++20 \ $(TGT_ALLFLAGS) TGT_INCLUDES = -I$(PATH_APP)/util/STL