diff --git a/CMakeLists.txt b/CMakeLists.txt index 212281f68..3b290aa5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.24") endif() include(cmake/project_version.cmake) include(cmake/SlsAddFlag.cmake) +include(cmake/helpers.cmake) @@ -193,11 +194,9 @@ find_package(ClangFormat) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "No build type selected, default to Release") - set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (default Release)" FORCE) -endif() - +default_build_type("Release") +set_std_fs_lib() +message(STATUS "Extra linking to fs lib:${STD_FS_LIB}") #Enable LTO if available include(CheckIPOSupported) diff --git a/cmake/FindClangFormat.cmake b/cmake/FindClangFormat.cmake index 8e697896f..7b7fdd27f 100644 --- a/cmake/FindClangFormat.cmake +++ b/cmake/FindClangFormat.cmake @@ -25,7 +25,9 @@ mark_as_advanced( ClangFormat_BIN) if(ClangFormat_FOUND) - exec_program(${ClangFormat_BIN} ${CMAKE_CURRENT_SOURCE_DIR} ARGS --version OUTPUT_VARIABLE CLANG_VERSION_TEXT) + execute_process(COMMAND ${ClangFormat_BIN} --version + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT_VARIABLE CLANG_VERSION_TEXT) string(REGEX MATCH "([0-9]+)\\.[0-9]+\\.[0-9]+" CLANG_VERSION ${CLANG_VERSION_TEXT}) if((${CLANG_VERSION} GREATER "9") OR (${CLANG_VERSION} EQUAL "9")) # A CMake script to find all source files and setup clang-format targets for them diff --git a/cmake/helpers.cmake b/cmake/helpers.cmake new file mode 100644 index 000000000..2ddb9d057 --- /dev/null +++ b/cmake/helpers.cmake @@ -0,0 +1,46 @@ +function(default_build_type val) +if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "No build type selected, default to Release") + set(CMAKE_BUILD_TYPE ${val} CACHE STRING "Build type (default ${val})" FORCE) +endif() +endfunction() + +function(set_std_fs_lib) +# from pybind11 +# Check if we need to add -lstdc++fs or -lc++fs or nothing +if(DEFINED CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD LESS 17) + set(STD_FS_NO_LIB_NEEDED TRUE) +elseif(MSVC) + set(STD_FS_NO_LIB_NEEDED TRUE) +else() + file( + WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp + "#include \nint main(int argc, char ** argv) {\n std::filesystem::path p(argv[0]);\n return p.string().length();\n}" + ) + try_compile( + STD_FS_NO_LIB_NEEDED ${CMAKE_CURRENT_BINARY_DIR} + SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp + COMPILE_DEFINITIONS -std=c++17) + try_compile( + STD_FS_NEEDS_STDCXXFS ${CMAKE_CURRENT_BINARY_DIR} + SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp + COMPILE_DEFINITIONS -std=c++17 + LINK_LIBRARIES stdc++fs) + try_compile( + STD_FS_NEEDS_CXXFS ${CMAKE_CURRENT_BINARY_DIR} + SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp + COMPILE_DEFINITIONS -std=c++17 + LINK_LIBRARIES c++fs) +endif() + +if(${STD_FS_NEEDS_STDCXXFS}) + set(STD_FS_LIB stdc++fs PARENT_SCOPE) +elseif(${STD_FS_NEEDS_CXXFS}) + set(STD_FS_LIB c++fs PARENT_SCOPE) +elseif(${STD_FS_NO_LIB_NEEDED}) + set(STD_FS_LIB "" PARENT_SCOPE) +else() + message(WARNING "Unknown C++17 compiler - not passing -lstdc++fs") + set(STD_FS_LIB "") +endif() +endfunction() \ No newline at end of file diff --git a/docs/src/index.rst b/docs/src/index.rst index 206b08eef..6c3165a5a 100644 --- a/docs/src/index.rst +++ b/docs/src/index.rst @@ -81,8 +81,9 @@ Welcome to slsDetectorPackage's documentation! :caption: Receiver :maxdepth: 2 - receivers slsreceiver + receivers + .. toctree:: :caption: Receiver Files diff --git a/docs/src/receivers.rst b/docs/src/receivers.rst index 29937cf84..31ff8f734 100644 --- a/docs/src/receivers.rst +++ b/docs/src/receivers.rst @@ -1,25 +1,25 @@ -Receivers +Custom Receiver ================= -Receiver processes can be run on same or different machines as the client, receives the data from the detector (via UDP packets). -When using the slsReceiver/ slsMultiReceiver, they can be further configured by the client control software (via TCP/IP) to set file name, file path, progress of acquisition etc. +The receiver essentially listens to UDP data packets sent out by the detector. + +To know more about detector receiver setup in the config file, please check out :ref:`the detector-receiver UDP configuration in the config file` and the :ref:`detector udp format`. -To know more about detector receiver configuration, please check out :ref:`detector udp header and udp commands in the config file ` +| Please note the following when using a custom receiver: -Custom Receiver ----------------- +* **udp_dstmac** must be configured in the config file. This parameter is not required when using an in-built receiver. -| When using custom receiver with our package, ensure that **udp_dstmac** is also configured in the config file. This parameter is not required when using slsReceiver. +* Cannot use "auto" for **udp_dstip**. -| Cannot use "auto" for **udp_dstip**. +* No **rx_** commands in the config file. These commands are for configuring the slsReceiver. -| Also ensure that there are no **rx_** commands in the config file. These commands are for configuring the slsReceiver. + + +The main difference is the lack of **rx_** commands or file commands (eg. **f**write, **f**path) and the **udp_dstmac** is required in config file. Example of a custom receiver config file -* The main difference is the lack of **rx_** commands or file commands (eg. fwrite, fpath) and the udp_dstmac is required in config file. - .. code-block:: bash # detector hostname diff --git a/docs/src/serverupgrade.rst b/docs/src/serverupgrade.rst index c6fe1675a..a215da8ae 100644 --- a/docs/src/serverupgrade.rst +++ b/docs/src/serverupgrade.rst @@ -1,4 +1,5 @@ .. _Detector Server Upgrade: + Upgrade ======== diff --git a/docs/src/slsreceiver.rst b/docs/src/slsreceiver.rst index 0413eb10a..932c25a05 100644 --- a/docs/src/slsreceiver.rst +++ b/docs/src/slsreceiver.rst @@ -1,16 +1,55 @@ -slsReceiver/ slsMultiReceiver +In-built Receiver ================================ -| One has to start the slsReceiver before loading config file or using any receiver commands (prefix: **rx_** ) + +The receiver essentially listens to UDP data packets sent out by the detector. It's main features are: + +- **Listening**: Receives UDP data from the detector. +- **Writing to File**: Optionally writes received data to disk. +- **Streaming via ZMQ**: Optionally streams out the data using ZeroMQ. + +Each of these operations runs asynchronously and in parallel for each UDP port. + + +.. note :: + + * Can be run on the same or different machine as the client. + * Can be configured by the client. (set file name/ discard policy, get progress etc.) + * Has to be started before the client runs any receiver specific command. + + +Receiver Variants +----------------- +There are three main receiver types. How to start them is described :ref:`below`. + ++----------------------+--------------------+-----------------------------------------+--------------------------------+ +| Receiver Type | slsReceiver | slsMultiReceiver |slsFrameSynchronizer | ++======================+====================+=========================================+================================+ +| Modules Supported | 1 | Multiple | Multiple | ++----------------------+--------------------+-----------------------------------------+--------------------------------+ +| Internal Architecture| Threads per porttt | Multiple child processes of slsReceiver | Multi-threading of slsReceiver | ++----------------------+--------------------+-----------------------------------------+--------------------------------+ +| ZMQ Streaming | Disabled by default| Disabled by default | Enabled, not optional | ++----------------------+--------------------+-----------------------------------------+--------------------------------+ +| ZMQ Synchronization | No | No | Yes, across ports | ++----------------------+--------------------+-----------------------------------------+--------------------------------+ +| Image Reconstruction | No | No | No | ++----------------------+--------------------+-----------------------------------------+--------------------------------+ + + + + +.. _Starting up the Receiver: + +Starting up the Receiver +------------------------- For a Single Module .. code-block:: bash + + slsReceiver # default port 1954 - # default port 1954 - slsReceiver - - # custom port 2012 - slsReceiver -t2012 + slsReceiver -t2012 # custom port 2012 For Multiple Modules @@ -18,57 +57,66 @@ For Multiple Modules # each receiver (for each module) requires a unique tcp port (if all on same machine) - # using slsReceiver in multiple consoles + # option 1 (one for each module) slsReceiver slsReceiver -t1955 - # slsMultiReceiver [starting port] [number of receivers] + # option 2 slsMultiReceiver 2012 2 - # slsMultiReceiver [starting port] [number of receivers] [print each frame header for debugging] - slsMultiReceiver 2012 2 1 + # option 3 + slsFrameSynchronizer 2012 2 + Client Commands ----------------- -| One can remove **udp_dstmac** from the config file, as the slsReceiver fetches this from the **udp_ip**. +* Client commands to the receiver begin with **rx_** or **f_** (file commands). -| One can use "auto" for **udp_dstip** if one wants to use default ip of **rx_hostname**. +* **rx_hostname** has to be the first command to the receiver so the client knows which receiver process to communicate with. -| The first command to the receiver (**rx_** commands) should be **rx_hostname**. The following are the different ways to establish contact. +* Can use 'auto' for **udp_dstip** if using 1GbE interface or the :ref:`virtual simulators`. + + +To know more about detector receiver setup in the config file, please check out :ref:`the detector-receiver UDP configuration in the config file` and the :ref:`detector udp format`. + + +The following are the different ways to establish contact using **rx_hostname** command. .. code-block:: bash - # default receiver tcp port (1954) + # ---single module--- + + # default receiver port at 1954 + rx_hostname xxx + + # custom receiver port + rx_hostname xxx:1957 # option 1 + + rx_tcpport 1957 # option 2 rx_hostname xxx - # custom receiver port - rx_hostname xxx:1957 - # custom receiver port - rx_tcpport 1954 - rx_hostname xxx + # ---multi module--- - # multi modules with custom ports - rx_hostname xxx:1955+xxx:1956+ - - - # multi modules using increasing tcp ports when using multi detector command + # using increasing tcp ports rx_tcpport 1955 rx_hostname xxx - # or specify multi modules with custom ports on same rxr pc - 0:rx_tcpport 1954 + # custom ports + rx_hostname xxx:1955+xxx:1958+ # option 1 + + 0:rx_tcpport 1954 # option 2 1:rx_tcpport 1955 2:rx_tcpport 1956 rx_hostname xxx - # multi modules with custom ports on different rxr pc + # custom ports on different receiver machines 0:rx_tcpport 1954 0:rx_hostname xxx 1:rx_tcpport 1955 - 1:rx_hostname yyy + 1:rx_hostname yyyrxr | Example commands: @@ -91,6 +139,32 @@ Client Commands sls_detector_get -h rx_framescaught +Example of a config file using in-built receiver + +.. code-block:: bash + + # detector hostname + hostname bchip052+bchip053+ + + # udp destination port (receiver) + # sets increasing destination udp ports starting at 50004 + udp_dstport 50004 + + # udp destination ip (receiver) + 0:udp_dstip 10.0.1.100 + 1:udp_dstip 10.0.2.100 + + # udp source ip (same subnet as udp_dstip) + 0:udp_srcip 10.0.1.184 + 1:udp_srcip 10.0.2.184 + + # udp destination mac - not required (picked up from udp_dstip) + #udp_dstmac 22:47:d5:48:ad:ef + + # connects to receivers at increasing tcp port starting at 1954 + rx_hostname mpc3434 + # same as rx_hostname mpc3434:1954+mpc3434:1955+ + Performance diff --git a/docs/src/udpconfig.rst b/docs/src/udpconfig.rst index f3e56d82a..847b11899 100644 --- a/docs/src/udpconfig.rst +++ b/docs/src/udpconfig.rst @@ -1,4 +1,4 @@ -.. _detector udp header: +.. _detector udp header config: Config file diff --git a/docs/src/virtualserver.rst b/docs/src/virtualserver.rst index b96f285f8..239e51490 100644 --- a/docs/src/virtualserver.rst +++ b/docs/src/virtualserver.rst @@ -1,4 +1,5 @@ .. _Virtual Detector Servers: + Simulators =========== diff --git a/psi-pmodules/DetectorSoftware/slsDetectorPackage/files/variants b/psi-pmodules/DetectorSoftware/slsDetectorPackage/files/variants index c20d6f7e1..4a2904a5d 100644 --- a/psi-pmodules/DetectorSoftware/slsDetectorPackage/files/variants +++ b/psi-pmodules/DetectorSoftware/slsDetectorPackage/files/variants @@ -13,5 +13,5 @@ slsDetectorPackage/8.0.2_rh7 stable cmake/3.15.5 Qt/5.12.10 slsDetectorPackage/8.0.2_rh8 stable cmake/3.15.5 Qt/5.12.10 slsDetectorPackage/9.0.0_rh8 stable cmake/3.15.5 Qt/5.12.10 slsDetectorPackage/9.1.0_rh8 stable cmake/3.15.5 Qt/5.12.10 - +slsDetectorPackage/9.1.1_rh8 stable cmake/3.15.5 Qt/5.12.10 diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index 764bdadaa..e5f92d113 100755 Binary files a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer and b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer differ diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index d7f9e4f56..e7f914ca1 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -15,6 +15,7 @@ #include "loadPattern.h" #include +#include #include #include #include // usleep @@ -93,6 +94,10 @@ void basictests() { LOG(logINFOBLUE, ("********* Chip Test Board Virtual Server *********\n")); #else LOG(logINFOBLUE, ("************* Chip Test Board Server *************\n")); + initError = enableBlackfinAMCExternalAccessExtension(initErrorMessage); + if (initError == FAIL) { + return; + } initError = defineGPIOpins(initErrorMessage); if (initError == FAIL) { return; @@ -438,6 +443,32 @@ uint32_t getDetectorIP() { return res; } +int enableBlackfinAMCExternalAccessExtension(char *mess) { + unsigned int value; + const char *file_path = BFIN_AMC_ACCESS_EXTENSION_FNAME; + FILE *file = fopen(file_path, "r"); + if (!file) { + strcpy(mess, "Failed to enable blackfin AMC access extension. Could " + "not read EBIU_AMBCTL1\n"); + LOG(logERROR, (mess)); + return FAIL; + } + fscanf(file, "%x", &value); + fclose(file); + + value |= BFIN_AMC_ACCESS_EXTENSION_ENA_VAL; + file = fopen(file_path, "w"); + if (!file) { + strcpy(mess, "Failed to enable blackfin AMC access extension. Could " + "not write EBIU_AMBCTL1\n"); + LOG(logERROR, (mess)); + return FAIL; + } + fprintf(file, "0x%x", value); + fclose(file); + return OK; +} + /* initialization */ void initControlServer() { diff --git a/slsDetectorServers/slsDetectorServer/include/blackfin.h b/slsDetectorServers/slsDetectorServer/include/blackfin.h index fef76ad48..672f58c57 100644 --- a/slsDetectorServers/slsDetectorServer/include/blackfin.h +++ b/slsDetectorServers/slsDetectorServer/include/blackfin.h @@ -5,6 +5,23 @@ #include #include +/** enable support for ARDY signal on interface to FPGA + * needed to properly translate avalon_mm_waitrequest in the CTB firmware + * https://www.analog.com/media/en/dsp-documentation/processor-manuals/bf537_hwr_Rev3.2.pdf + * page 274 + * */ +#define BFIN_EBIU_AMBCTL1_B2_ARDY_ENA_OFST (0) +#define BFIN_EBIU_AMBCTL1_B2_ARDY_ENA_MSK \ + (1 << BFIN_EBIU_AMBCTL1_B2_ARDY_ENA_OFST) +#define BFIN_EBIU_AMBCTL1_B2_ARDY_POL_OFST (1) +#define BFIN_EBIU_AMBCTL1_B2_ARDY_POL_MSK \ + (1 << BFIN_EBIU_AMBCTL1_B2_ARDY_POL_OFST) + +#define BFIN_AMC_ACCESS_EXTENSION_ENA_VAL \ + (BFIN_EBIU_AMBCTL1_B2_ARDY_ENA_MSK | BFIN_EBIU_AMBCTL1_B2_ARDY_POL_MSK) +#define BFIN_AMC_ACCESS_EXTENSION_FNAME \ + "/sys/kernel/debug/blackfin/ebiu_amc/EBIU_AMBCTL1" + /** I2C defines */ #define I2C_CLOCK_MHZ (131.25) diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index f572252bd..8570456f3 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -113,6 +113,10 @@ void setModuleId(int modid); u_int64_t getDetectorMAC(); u_int32_t getDetectorIP(); +#if defined(CHIPTESTBOARDD) +int enableBlackfinAMCExternalAccessExtension(char *mess); +#endif + // initialization void initControlServer(); void initStopServer(); diff --git a/slsReceiverSoftware/src/DataProcessor.h b/slsReceiverSoftware/src/DataProcessor.h index e21d73c90..2f1c8f4ba 100644 --- a/slsReceiverSoftware/src/DataProcessor.h +++ b/slsReceiverSoftware/src/DataProcessor.h @@ -168,7 +168,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject { uint32_t streamingTimerInMs; uint32_t streamingStartFnum; uint32_t currentFreqCount{0}; - struct timespec timerbegin{}; + struct timespec timerbegin {}; bool framePadding; std::atomic startedFlag{false}; std::atomic firstIndex{0}; diff --git a/slsReceiverSoftware/src/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h index 7147d0e2c..34a329542 100644 --- a/slsReceiverSoftware/src/GeneralData.h +++ b/slsReceiverSoftware/src/GeneralData.h @@ -63,8 +63,8 @@ class GeneralData { slsDetectorDefs::frameDiscardPolicy frameDiscardMode{ slsDetectorDefs::NO_DISCARD}; - GeneralData() {}; - virtual ~GeneralData() {}; + GeneralData(){}; + virtual ~GeneralData(){}; // Returns the pixel depth in byte, 4 bits being 0.5 byte float GetPixelDepth() { return float(dynamicRange) / 8; } diff --git a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp index 7ad93b908..e8b586184 100644 --- a/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp +++ b/slsReceiverSoftware/tests/test-ArrangeDataBasedOnBitList.cpp @@ -47,8 +47,8 @@ class GeneralDataTest : public GeneralData { // dummy DataProcessor class for testing class DataProcessorTest : public DataProcessor { public: - DataProcessorTest() : DataProcessor(0) {}; - ~DataProcessorTest() {}; + DataProcessorTest() : DataProcessor(0){}; + ~DataProcessorTest(){}; void ArrangeDbitData(size_t &size, char *data) { DataProcessor::ArrangeDbitData(size, data); } diff --git a/slsSupportLib/CMakeLists.txt b/slsSupportLib/CMakeLists.txt index 02bf2e610..ee847a369 100755 --- a/slsSupportLib/CMakeLists.txt +++ b/slsSupportLib/CMakeLists.txt @@ -88,6 +88,7 @@ message(STATUS "RAPID: ${SLS_INTERNAL_RAPIDJSON_DIR}") target_link_libraries(slsSupportObject PUBLIC slsProjectOptions + ${STD_FS_LIB} # from helpers.cmake PRIVATE slsProjectWarnings diff --git a/slsSupportLib/include/sls/StaticVector.h b/slsSupportLib/include/sls/StaticVector.h index 3c671f80b..cf72aa05d 100644 --- a/slsSupportLib/include/sls/StaticVector.h +++ b/slsSupportLib/include/sls/StaticVector.h @@ -113,10 +113,10 @@ template class StaticVector { // auto begin() noexcept -> decltype(data_.begin()) { return data_.begin(); // } const_iterator begin() const noexcept { return data_.begin(); } - iterator end() noexcept { return &data_[current_size]; } - const_iterator end() const noexcept { return &data_[current_size]; } + iterator end() noexcept { return data_.begin()+current_size; } + const_iterator end() const noexcept { return data_.begin()+current_size; } const_iterator cbegin() const noexcept { return data_.cbegin(); } - const_iterator cend() const noexcept { return &data_[current_size]; } + const_iterator cend() const noexcept { return data_.cbegin()+current_size; } void size_check(size_type s) const { if (s > Capacity) { diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index d88a71ba8..0453a3846 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -10,3 +10,4 @@ #define APIXILINXCTB "0.0.0 0x250523" #define APIJUNGFRAU "0.0.0 0x250523" #define APIMYTHEN3 "0.0.0 0x250523" + diff --git a/slsSupportLib/tests/test-StaticVector.cpp b/slsSupportLib/tests/test-StaticVector.cpp index 6f9f5da50..2ff548fce 100644 --- a/slsSupportLib/tests/test-StaticVector.cpp +++ b/slsSupportLib/tests/test-StaticVector.cpp @@ -8,12 +8,15 @@ #include #include -namespace sls { + +using sls::StaticVector; TEST_CASE("StaticVector is a container") { - REQUIRE(is_container>::value == true); + REQUIRE(sls::is_container>::value == true); } + + TEST_CASE("Comparing StaticVector containers") { StaticVector a{0, 1, 2}; StaticVector b{0, 1, 2}; @@ -90,10 +93,17 @@ TEST_CASE("Copy construct from array") { REQUIRE(fcc == arr); } +TEST_CASE("Construct from a smaller StaticVector") { + StaticVector sv{1, 2, 3}; + StaticVector sv2{sv}; + REQUIRE(sv == sv2); +} + TEST_CASE("Free function and method gives the same iterators") { StaticVector fcc{1, 2, 3}; REQUIRE(std::begin(fcc) == fcc.begin()); } + SCENARIO("StaticVectors can be sized and resized", "[support]") { GIVEN("A default constructed container") { @@ -246,23 +256,23 @@ SCENARIO("Sorting, removing and other manipulation of a container", REQUIRE(a[3] == 90); } } - // WHEN("Sorting is done using free function for begin and end") { - // std::sort(begin(a), end(a)); - // THEN("it also works") { - // REQUIRE(a[0] == 12); - // REQUIRE(a[1] == 12); - // REQUIRE(a[2] == 14); - // REQUIRE(a[3] == 90); - // } - // } - // WHEN("Erasing elements of a certain value") { - // a.erase(std::remove(begin(a), end(a), 12)); - // THEN("all elements of that value are removed") { - // REQUIRE(a.size() == 2); - // REQUIRE(a[0] == 14); - // REQUIRE(a[1] == 90); - // } - // } + WHEN("Sorting is done using free function for begin and end") { + std::sort(std::begin(a), std::end(a)); + THEN("it also works") { + REQUIRE(a[0] == 12); + REQUIRE(a[1] == 12); + REQUIRE(a[2] == 14); + REQUIRE(a[3] == 90); + } + } + WHEN("Erasing elements of a certain value") { + a.erase(std::remove(std::begin(a), std::end(a), 12)); + THEN("all elements of that value are removed") { + REQUIRE(a.size() == 2); + REQUIRE(a[0] == 14); + REQUIRE(a[1] == 90); + } + } } } @@ -335,4 +345,3 @@ TEST_CASE("StaticVector stream") { REQUIRE(oss.str() == "[33, 85667, 2]"); } -} // namespace sls