diff --git a/Device/Beam/Beam.cpp b/Device/Beam/Beam.cpp
index a099fa54540ab3acc9f99e16446dd38b10c8607c..8e0dd8c84ee6ec046f5f19bb02cf205c126af5e7 100644
--- a/Device/Beam/Beam.cpp
+++ b/Device/Beam/Beam.cpp
@@ -37,7 +37,7 @@ Beam::Beam(double intensity, double wavelength, const Direction& direction)
     , m_alphaLimits(RealLimits::limited(-INCLINATION_LIMIT, INCLINATION_LIMIT))
 {
     setName("Beam");
-    checkLimits("Intensity", m_intensity, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("Intensity", m_intensity);
 
     checkLimits("Wavelength", m_wavelength, wavelengthLimits);
     checkLimits("InclinationAngle", m_alpha, m_alphaLimits);
diff --git a/Device/Pol/PolFilter.cpp b/Device/Pol/PolFilter.cpp
index 7f16b3152e7ef34cf68ed12904937c6d09fd0415..dc0de974ed34d27783cc829292d2638fd97338fe 100644
--- a/Device/Pol/PolFilter.cpp
+++ b/Device/Pol/PolFilter.cpp
@@ -19,7 +19,7 @@ PolFilter::PolFilter(R3 direction, double efficiency, double total_transmission)
     : m_direction(direction), m_efficiency(efficiency), m_total_transmission(total_transmission)
 {
     setName("Analyzer");
-    checkLimits("Transmission", m_total_transmission, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("Transmission", m_total_transmission);
 }
 
 PolFilter::PolFilter() : PolFilter({}, {}, 1.0) {}
diff --git a/Device/Resolution/ResolutionFunction2DGaussian.cpp b/Device/Resolution/ResolutionFunction2DGaussian.cpp
index 75e8ddb4a1f172008dd16fd87dbf776b08eaf137..e98c0f7e9e667b1cdba478dd4a37d6f20122c6db 100644
--- a/Device/Resolution/ResolutionFunction2DGaussian.cpp
+++ b/Device/Resolution/ResolutionFunction2DGaussian.cpp
@@ -20,8 +20,8 @@ ResolutionFunction2DGaussian::ResolutionFunction2DGaussian(double sigma_x, doubl
     : m_sigma_x(sigma_x), m_sigma_y(sigma_y)
 {
     setName("ResolutionFunction2D");
-    checkLimits("SigmaX", m_sigma_x, RealLimits::nonnegative());
-    checkLimits("SigmaY", m_sigma_y, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("SigmaX", m_sigma_x);
+    RealLimits::nonnegative().check("SigmaY", m_sigma_y);
 }
 
 double ResolutionFunction2DGaussian::evaluateCDF(double x, double y) const
diff --git a/Sample/Aggregate/IInterferenceFunction.cpp b/Sample/Aggregate/IInterferenceFunction.cpp
index d0555800eeb527822a0ff592eca6f13303217626..66df4fb23229ccf6c382ab6750a021187989eb5a 100644
--- a/Sample/Aggregate/IInterferenceFunction.cpp
+++ b/Sample/Aggregate/IInterferenceFunction.cpp
@@ -21,12 +21,12 @@ IInterferenceFunction::IInterferenceFunction(const NodeMeta& meta,
                                              const std::vector<double>& PValues)
     : ISampleNode(meta, PValues)
 {
-    checkLimits("PositionVariance", m_position_var, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("PositionVariance", m_position_var);
 }
 
 IInterferenceFunction::IInterferenceFunction(double position_var) : m_position_var(position_var)
 {
-    checkLimits("PositionVariance", m_position_var, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("PositionVariance", m_position_var);
 }
 
 // Default implementation of evaluate assumes no inner structure
diff --git a/Sample/Aggregate/InterferenceFunction1DLattice.cpp b/Sample/Aggregate/InterferenceFunction1DLattice.cpp
index 1eb54a8d4f8fe145af00ca39f8be225f273927f9..eb7606bdd0f6b9bb286ba17127cc270e69ab30c2 100644
--- a/Sample/Aggregate/InterferenceFunction1DLattice.cpp
+++ b/Sample/Aggregate/InterferenceFunction1DLattice.cpp
@@ -33,7 +33,7 @@ InterferenceFunction1DLattice::InterferenceFunction1DLattice(double length, doub
     : IInterferenceFunction(0), m_length(length), m_xi(xi), m_na{0}
 {
     setName("Interference1DLattice");
-    checkLimits("Length", m_length, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("Length", m_length);
 }
 
 InterferenceFunction1DLattice::~InterferenceFunction1DLattice() = default;
diff --git a/Sample/Aggregate/InterferenceFunction2DParaCrystal.cpp b/Sample/Aggregate/InterferenceFunction2DParaCrystal.cpp
index 06ade4cfefd741c2f8e09500d43e3c4c2d1bc726..760c0693376d11648ff52696a4c937bf265084af 100644
--- a/Sample/Aggregate/InterferenceFunction2DParaCrystal.cpp
+++ b/Sample/Aggregate/InterferenceFunction2DParaCrystal.cpp
@@ -27,9 +27,9 @@ InterferenceFunction2DParaCrystal::InterferenceFunction2DParaCrystal(const Latti
     m_lattice.reset(lattice.clone());
     registerChild(m_lattice.get());
     setDomainSizes(domain_size_1, domain_size_2);
-    checkLimits("DampingLength", m_damping_length, RealLimits::nonnegative());
-    checkLimits("DomainSize1", m_domain_sizes[0], RealLimits::nonnegative());
-    checkLimits("DomainSize2", m_domain_sizes[1], RealLimits::nonnegative());
+    RealLimits::nonnegative().check("DampingLength", m_damping_length);
+    RealLimits::nonnegative().check("DomainSize1", m_domain_sizes[0]);
+    RealLimits::nonnegative().check("DomainSize2", m_domain_sizes[1]);
 }
 
 InterferenceFunction2DParaCrystal::~InterferenceFunction2DParaCrystal() = default;
diff --git a/Sample/Aggregate/InterferenceFunctionHardDisk.cpp b/Sample/Aggregate/InterferenceFunctionHardDisk.cpp
index 37fc5363e5c081650fc232204ace833d947470f1..ecd84ae0db51e9d8d91502a42e7fea8368a21ae4 100644
--- a/Sample/Aggregate/InterferenceFunctionHardDisk.cpp
+++ b/Sample/Aggregate/InterferenceFunctionHardDisk.cpp
@@ -55,8 +55,8 @@ InterferenceFunctionHardDisk::InterferenceFunctionHardDisk(double radius, double
         throw std::runtime_error("InterferenceFunctionHardDisk::validateParameters: "
                                  "radius and density must be positive and packing ratio between "
                                  "0 and 0.65");
-    checkLimits("Radius", m_radius, RealLimits::nonnegative());
-    checkLimits("TotalParticleDensity", m_density, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("Radius", m_radius);
+    RealLimits::nonnegative().check("TotalParticleDensity", m_density);
 }
 
 InterferenceFunctionHardDisk* InterferenceFunctionHardDisk::clone() const
diff --git a/Sample/Aggregate/InterferenceFunctionRadialParaCrystal.cpp b/Sample/Aggregate/InterferenceFunctionRadialParaCrystal.cpp
index 04889e1c1721df94e54bb8678390042cd936ea50..27f33fe4705f4a1785e717af4716f7afd060f68f 100644
--- a/Sample/Aggregate/InterferenceFunctionRadialParaCrystal.cpp
+++ b/Sample/Aggregate/InterferenceFunctionRadialParaCrystal.cpp
@@ -32,10 +32,10 @@ InterferenceFunctionRadialParaCrystal::InterferenceFunctionRadialParaCrystal(dou
     if (m_damping_length == 0.0)
         m_use_damping_length = false;
 
-    checkLimits("PeakDistance", m_peak_distance, RealLimits::nonnegative());
-    checkLimits("DampingLength", m_damping_length, RealLimits::nonnegative());
-    checkLimits("SizeSpaceCoupling", m_kappa, RealLimits::nonnegative());
-    checkLimits("DomainSize", m_domain_size, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("PeakDistance", m_peak_distance);
+    RealLimits::nonnegative().check("DampingLength", m_damping_length);
+    RealLimits::nonnegative().check("SizeSpaceCoupling", m_kappa);
+    RealLimits::nonnegative().check("DomainSize", m_domain_size);
 }
 
 InterferenceFunctionRadialParaCrystal* InterferenceFunctionRadialParaCrystal::clone() const
diff --git a/Sample/Aggregate/InterferenceFunctionTwin.cpp b/Sample/Aggregate/InterferenceFunctionTwin.cpp
index 8537c8cd2ce0224336b7fd5bbd9b684fd5b64f3f..892383d608a1378f373518d6d14211bfb16269f5 100644
--- a/Sample/Aggregate/InterferenceFunctionTwin.cpp
+++ b/Sample/Aggregate/InterferenceFunctionTwin.cpp
@@ -28,8 +28,8 @@ InterferenceFunctionTwin::InterferenceFunctionTwin(const R3& direction, double m
         throw std::runtime_error(
             "InterferenceFunctionTwin::validateParameters: mean distance, standard deviation and "
             "length of direction vector should be positive");
-    checkLimits("Mean", m_distance, RealLimits::nonnegative());
-    checkLimits("StdDev", m_std_dev, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("Mean", m_distance);
+    RealLimits::nonnegative().check("StdDev", m_std_dev);
 }
 
 InterferenceFunctionTwin* InterferenceFunctionTwin::clone() const
diff --git a/Sample/Interface/LayerRoughness.cpp b/Sample/Interface/LayerRoughness.cpp
index c7fe6da1a71f156671e8fad4f5056a0b2d1731da..1ea5f8ec36ad1fa8f40ef0769ac20acf2c75b89b 100644
--- a/Sample/Interface/LayerRoughness.cpp
+++ b/Sample/Interface/LayerRoughness.cpp
@@ -26,7 +26,7 @@ LayerRoughness::LayerRoughness(double sigma, double hurstParameter, double later
     : m_sigma(sigma), m_hurstParameter(hurstParameter), m_lateralCorrLength(lateralCorrLength)
 {
     setName("LayerBasicRoughness");
-    checkLimits("CorrelationLength", m_lateralCorrLength, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("CorrelationLength", m_lateralCorrLength);
 }
 
 LayerRoughness::LayerRoughness() : LayerRoughness(0, 0, 0) {}
diff --git a/Sample/Lattice/Lattice2D.cpp b/Sample/Lattice/Lattice2D.cpp
index 97829ce51e3091a6495c87421e7c3be6773549f8..fcd988b968011eb7419e37cd0bd8a0e2a7a58db6 100644
--- a/Sample/Lattice/Lattice2D.cpp
+++ b/Sample/Lattice/Lattice2D.cpp
@@ -67,8 +67,8 @@ BasicLattice2D::BasicLattice2D(double length1, double length2, double angle, dou
             "negative or zero.");
 
     setName("BasicLattice2D");
-    checkLimits("LatticeLength1", m_length1, RealLimits::positive());
-    checkLimits("LatticeLength2", m_length2, RealLimits::positive());
+    RealLimits::positive().check("LatticeLength1", m_length1);
+    RealLimits::positive().check("LatticeLength2", m_length2);
 }
 
 BasicLattice2D* BasicLattice2D::clone() const
@@ -93,7 +93,7 @@ SquareLattice2D::SquareLattice2D(double length, double xi) : Lattice2D(xi), m_le
             "negative or zero.");
 
     setName("SquareLattice2D");
-    checkLimits("LatticeLength", m_length, RealLimits::positive());
+    RealLimits::positive().check("LatticeLength", m_length);
 }
 
 SquareLattice2D* SquareLattice2D::clone() const
@@ -122,7 +122,7 @@ HexagonalLattice2D::HexagonalLattice2D(double length, double xi) : Lattice2D(xi)
                                  "Lattice length can't be negative or zero.");
 
     setName("HexagonalLattice2D");
-    checkLimits("LatticeLength", m_length, RealLimits::positive());
+    RealLimits::positive().check("LatticeLength", m_length);
 }
 
 HexagonalLattice2D* HexagonalLattice2D::clone() const
diff --git a/Sample/Multilayer/MultiLayer.cpp b/Sample/Multilayer/MultiLayer.cpp
index 0ae143d44fdcba38d796dd892638866234b9f8b5..956c76ec7886b791c34a51f77f5eafd596da3443 100644
--- a/Sample/Multilayer/MultiLayer.cpp
+++ b/Sample/Multilayer/MultiLayer.cpp
@@ -25,7 +25,7 @@
 MultiLayer::MultiLayer() : m_crossCorrLength(0)
 {
     setName("MultiLayer");
-    checkLimits("CrossCorrelationLength", m_crossCorrLength, RealLimits::nonnegative());
+    RealLimits::nonnegative().check("CrossCorrelationLength", m_crossCorrLength);
 }
 
 MultiLayer::~MultiLayer() = default;
diff --git a/Tests/Unit/Param/IParameterizedTest.cpp b/Tests/Unit/Param/IParameterizedTest.cpp
index 5a25f4e1404d326b6e29b6d85cec8ae3fd54a08a..a8c3e93d560584949d22a2619e8fdbdea6c32b42 100644
--- a/Tests/Unit/Param/IParameterizedTest.cpp
+++ b/Tests/Unit/Param/IParameterizedTest.cpp
@@ -3,19 +3,12 @@
 #include "Tests/GTestWrapper/google_test.h"
 #include <stdexcept>
 
-class IParametricTest : public ::testing::Test {
-protected:
-    class TestClass : public IParametric {
-    public:
-        using IParametric::checkLimits; // make it public
-    };
-};
+class IParametricTest : public ::testing::Test {};
 
 TEST_F(IParametricTest, checkLimits)
 {
     // this checks only the function if IParametricTest::checkLimits() in principle. More
     // tests regarding RealLimits shall be done in dedicated RealLimits unit tests
-    TestClass t;
-    EXPECT_NO_THROW(t.checkLimits("A", 0, RealLimits::nonnegative()));
-    EXPECT_THROW(t.checkLimits("A", 0, RealLimits::positive()), std::runtime_error);
+    EXPECT_NO_THROW(RealLimits::nonnegative().check("A", 0));
+    EXPECT_THROW(RealLimits::positive().check("A", 0), std::runtime_error);
 }