A universal type for non-type template parameters for C++20 or later.

uninttp

A universal type for non-type template parameters for C++20 or later.

Installation:

uninttp (Universal Non-Type Template Parameters) is a header-only library, meaning you only need to include the required header(s) to start using it in your project/environment. In this case, simply cloning this repository and doing #include should suffice.

Usage:

Using uninttp's uninttp::uni_auto is pretty straightforward and is synonymous to auto in most of the cases: Demo

#include <uninttp/uni_auto.hpp>

using namespace uninttp;

template 

   constexpr 
   auto 
   add20() {
    
   return Value + 
   20;
}


   int 
   main() {
    
   static_assert(add20<
   20>() == 
   40); 
   // OK
}
  

And if you thought "Can't I just use something like template instead?", then you'd be absolutely correct. One can safely replace uni_auto with auto, at least for this example.

However, a template parameter declared with uni_auto can do much more than a template parameter declared with auto in the sense that you can also pass string literals and constexpr-marked arrays through it: Demo

); i++) std::cout << Array[i] << " "; std::cout << std::endl; // Index-based for loop (2nd version) for (std::size_t i = 0; i < uni_auto_len ; i++) std::cout << Array[i] << " "; std::cout << std::endl; } int main() { // Passing a string literal static_assert(std::string_view(shift<"foobar", 3>()) == "bar"); // OK // Passing an array marked as 'constexpr' constexpr int arr[] = { 1, 8, 9, 20 }; print_array (); // 1 8 9 20 // Passing an 'std::array' object print_array (); // 1 4 6 9 } ">
#include <uninttp/uni_auto.hpp>
#include <string_view>
#include <iostream>
#include <cstddef>
#include <array>

using namespace uninttp;

template 
      size_t X>

      constexpr 
      auto 
      shift() {
    
      return Value + X;
}


      template 
      

       void 
       print_array() {
    
       // Using range-based for loop
    
       for (
       auto 
       const& elem : Array)
        std::cout << elem << 
       " ";
    
    std::cout << std::endl;

    
       // Using iterators
    
       for (
       auto it = 
       std::begin(Array); it != 
       std::end(Array); ++it)
        std::cout << *it << 
       " ";
    
    std::cout << std::endl;

    
       // Index-based for loop (1st version)
    
       /* (The usage of 'uni_auto_v' is required here as the compiler cannot do implicit

               conversions in this context) */
    
       for (std::
       size_t i = 
       0; i < 
       std::size(uni_auto_v
       
        ); i++)
        std::cout << Array[i] << 
        " ";
    
    std::cout << std::endl;

    
        // Index-based for loop (2nd version)
    
        for (std::
        size_t i = 
        0; i < uni_auto_len
        
         ; i++)
        std::cout << Array[i] << 
         " ";
    
    std::cout << std::endl;
}


         int 
         main() {
    
         // Passing a string literal
    
         static_assert(
         std::string_view(shift<
         "foobar", 
         3>()) == 
         "bar"); 
         // OK

    
         // Passing an array marked as 'constexpr'
    
         constexpr 
         int arr[] = { 
         1, 
         8, 
         9, 
         20 };
    print_array
         
          ();                                             
          // 1 8 9 20

    
          // Passing an 'std::array' object
    print_array
          
           1, 
           4, 
           6, 
           9 }>(); 
           // 1 4 6 9 }
          
         
        
       
      
     

You can also use it with parameter packs, obviously: Demo

(); // 1 3.14159 6.3 foo } ">
#include <uninttp/uni_auto.hpp>
#include <iostream>

using namespace uninttp;

template 

   void 
   print() {
    ((std::cout << Values << 
   " "), ...) << std::endl;
}


   int 
   main() {
    print<
   1, 
   3.14159, 
   6.
   3f, 
   "foo">(); 
   // 1 3.14159 6.3 foo
}
  

You can also enforce a type by adding a constraint: Demo

(); // OK only_accepts_strings<123>(); // Error! Constraint not satisfied! } ">
#include <uninttp/uni_auto.hpp>
#include <type_traits>
#include <concepts>

using namespace uninttp;

template 

   /* You need to use 'uni_auto_t
    
     ' to fetch the underlying type held by the value,
    

      and since the type returned is in the form of a reference to an array,

      you would need to decay it to a pointer type in order to do a proper comparison */

   requires (std::same_as
   
    decay_t<
    uni_auto_t
    
     >, 
     const 
     char*>)
void only_accepts_strings() {}


     int 
     main() {
    only_accepts_strings<
     "foobar">(); 
     // OK
    only_accepts_strings<
     123>();      
     // Error! Constraint not satisfied!
}
    
   
  

The above can also be modified to work with std::array, here's an example.

Note: One can also "exploit" the above combination of constraints and uni_auto to achieve a sort of "function overloading through template parameters" mechanism: Demo

requires (std::same_as >, int>) void do_something() { std::cout << "An integer was passed" << std::endl; } int main() { do_something<"foobar">(); // A string was passed do_something<123>(); // An integer was passed // do_something<12.3>(); // Error! } ">
#include <uninttp/uni_auto.hpp>
#include <type_traits>
#include <concepts>
#include <iostream>

using namespace uninttp;

template 

       requires (std::same_as
       
        decay_t<
        uni_auto_t
        
         >, 
         const 
         char*>)
void do_something() {
    std::cout << 
         "A string was passed" << std::endl;
}


         template 
         

          requires (std::same_as
          
           decay_t<
           uni_auto_t
           
            >, 
            int>) void do_something() { std::cout << 
            "An integer was passed" << std::endl; } 
            int 
            main() { do_something<
            "foobar">(); 
            // A string was passed do_something<
            123>(); 
            // An integer was passed 
            // do_something<12.3>(); // Error! }
           
          
         
        
       
      

Example using std::array

Unsurprisingly, one can pass trivial structs through uni_auto as well: Demo

#include <uninttp/uni_auto.hpp>

using namespace uninttp;

struct X {
    int val{6};
};

struct Y {
    int val{7};
};

template 

   constexpr 
   auto 
   mul() {
    
   return A.
   val * B.
   val;
}


   int 
   main() {
    
   static_assert(mul
   
    () == 
    42); 
    // OK
}
   
  

You can also pass lambdas and compile-time functor objects through uni_auto as well: Demo

#include <uninttp/uni_auto.hpp>

using namespace uninttp;

template 

   constexpr 
   auto 
   call() {
    
   return 
   F();
}


   struct 
   Funct {
    
   constexpr 
   auto 
   operator()() 
   const {
        
   return 
   86;
    }
};


   int 
   main() {
    
   static_assert(call<[] { 
   return 
   69; }>() == 
   69); 
   // OK
    
   static_assert(call
   
    () == 
    86);           
    // OK
}
   
  

All the examples shown have used function templates to demonstrate the capability of uni_auto. However, it can readily be used in any context.

Cheat sheet:

Description
uninttp::uni_auto_t Gives the type of the underlying value held by the uni_auto class object passed to it.
uninttp::uni_auto_v Effectively extracts the underlying value held by the uni_auto class object passed to it.
uninttp::uni_auto_len As the name suggests, it returns the length/size of the array held by uni_auto (if any).
Equivalent to: std::size(uni_auto_v ) .

Limitations:

There are two drawbacks to using uni_auto:

  1. The datatype of the value held by a uni_auto object cannot be fetched using decltype(X) as is done with auto-template parameters. Instead, one would have to use uni_auto_t instead:
    template 
         1.89>
    
         void 
         fun() {
        
         static_assert(std::same_as<
         uni_auto_t
         
          , 
          double>); 
          // OK
    }
    
          // ...
         
        
  2. There may be some cases where conversion operator of the uni_auto object doesn't get invoked. In such a scenario, one would need to explicitly notify the compiler to extract the value out of the uni_auto object using uni_auto_v:
    template 
         42>
    
         void 
         fun() {
        
         constexpr 
         auto answer = uni_auto_v
         
          ;
        
          /* You can also write the above line as follows:
    
                 constexpr int answer = X; */
        
          static_assert(std::same_as<
          decltype(answer), 
          int>); 
          // OK
    }
    
          // ...
         
        

Tell uninttp that you'd like to use std::array instead of normal C-style arrays:

It is completely up to the choice of the user to choose between working with C-style arrays or std::array, the former is used by uninttp by default. In order to use the latter, one needs to define UNINTTP_USE_STD_ARRAY before including any of uninttp's header(s):

#define UNINTTP_USE_STD_ARRAY
#include <uninttp/uni_auto.hpp>

// Now 'uninttp::uni_auto' and co. will use 'std::array' instead of C-Style arrays to store their value(s)...

Playground:

If you'd like to play around with uni_auto yourself, here you go!

Similar Resources

This library support run-time type casting faster than dynamic_cast ( similar to unreal engine's CastTo )

This library support run-time type casting faster than dynamic_cast ( similar to unreal engine's CastTo )

Fast Runtime Type Casting This library give you C++ Fast Runtime Type Casting faster than dynamic_cast ( similar to Unreal Engine's CastTo, IsChildOf

Jun 11, 2022

Strong typedef - A class template that creates a new type that is distinct from the underlying type, but convertible to and from it

jss::strong_typedef Tag, ValueType, Properties... This is an implementation of a C++17 class template that provides a wrapper type that is convertib

Aug 11, 2022

A simple PoC to demonstrate that is possible to write Non writable memory and execute Non executable memory on Windows

WindowsPermsPoC A simple PoC to demonstrate that is possible to write Non writable memory and execute Non executable memory on Windows You can build i

Jul 21, 2022

Blend between two non-concentric non-circular cones for use in a Pose Space system

Blend between two non-concentric non-circular cones for use in a Pose Space system

BlurRelax Why does maya not have a smooth or relax deformer? They've got brushes, sure, but no deformers. This one is pretty fast. I've got it working

Dec 27, 2021

ring-span lite - A C++yy-like ring_span type for C++98, C++11 and later in a single-file header-only library

ring-span lite: A circular buffer view for C++98 and later Contents Example usage In a nutshell Dependencies Installation Synopsis Reported to work wi

Aug 23, 2022

variant lite - A C++17-like variant, a type-safe union for C++98, C++11 and later in a single-file header-only library

variant lite: A single-file header-only version of a C++17-like variant, a type-safe union for C++98, C++11 and later Contents Example usage In a nuts

Sep 22, 2022

ring-span lite - A C++yy-like ring_span type for C++98, C++11 and later in a single-file header-only library

ring-span lite: A circular buffer view for C++98 and later Contents Example usage In a nutshell Dependencies Installation Synopsis Reported to work wi

Aug 23, 2022

Examples for individual ROS2 functionalities inc. Subscribers, Publishers, Timers, Services, Parameters. ...

ROS2 examples This example package is meant to explore the possibilities of ROS2 from the point of view of current ROS1 features and how the ROS1 feat

Sep 3, 2022

This package estimates the calibration parameters that transforms the camera frame (parent) into the lidar frame (child)

This package estimates the calibration parameters that transforms the camera frame (parent) into the lidar frame (child)

Camera-LiDAR Calibration This package estimates the calibration parameters that transforms the camera frame (parent) into the lidar frame (child). We

Sep 21, 2022

Two alphanumeric LCDs and 2 LED bars to show and manage some in-flight parameters

Two alphanumeric LCDs and 2 LED bars to show and manage some in-flight parameters

FS2020-LCD-Panel with Arduino Two alphanumeric LCDs and 2 LED bars to show and manage some in-flight parameters for FS2020. In this project you can pl

Sep 24, 2022

C-function for traversing files/directories effectively and calling a given function with each encountered file and a void-pointer as parameters

C-function for traversing files/directories effectively and calling a given function with each encountered file and a void-pointer as parameters

Jun 27, 2022

ROS package to calibrate the extrinsic parameters between LiDAR and Camera.

ROS package to calibrate the extrinsic parameters between LiDAR and Camera.

lidar_camera_calibrator lidar_camera_calibrator is a semi-automatic, high-precision, feature-based camera and LIDAR extrinsic calibration tool. In gen

Sep 1, 2022

This is a C plus plus coding template for Compitative programming. This template is very optimized for the Online Judgment

C-plusplus-compitative-Programming-Template Tech We Used C++ Features Easy to compile Easy debug facility Analysised and optimized base template Steps

Jan 27, 2022

FSD-Template - A template UE4.25 project for BP modding.

FSD-Template Project generated by Archengius' UE4 Template Generator. Reflected C++ classes generated by CheatingMuppet & Archengius' UE4SS UHT Genera

Aug 3, 2022

OpenGL Template Engine - a C++ OpenGL graphics engine which aimed to be a simple startup template for 3D OpenGL projects.

OpenGL Template Engine - a C++ OpenGL graphics engine which aimed to be a simple startup template for 3D OpenGL projects.

OpenGL Template Engine is a C++ OpenGL graphics engine which aimed to be a simple startup template for 3D OpenGL projects. This is the template I personally use for my own projects and provides me with the general OpenGL 3D render setup with model import and UI.

May 16, 2022

A type safe SQL template library for C++

sqlpp11 A type safe embedded domain specific language for SQL queries and results in C++ Documentation is found in the wiki So what is this about? SQL

Sep 16, 2022

Cross-platform STL-styled and STL-compatible library with implementing containers, ranges, iterators, type traits and other tools; actors system; type-safe config interface.

Yato A small repository where I'm gatherting useful snippets and abstractions for C++ development. Yato includes 3 main modules: multidimensional cont

Jul 22, 2022
Universal configuration library parser

LIBUCL Table of Contents generated with DocToc Introduction Basic structure Improvements to the json notation General syntax sugar Automatic arrays cr

Sep 24, 2022
Sqrt OS is a simulation of an OS scheduler and memory manager using different scheduling algorithms including Highest Priority First (non-preemptive), Shortest Remaining Time Next, and Round Robin.
Sqrt OS is a simulation of an OS scheduler and memory manager using different scheduling algorithms including Highest Priority First (non-preemptive), Shortest Remaining Time Next, and Round Robin.

A CPU scheduler determines an order for the execution of its scheduled processes; it decides which process will run according to a certain data structure that keeps track of the processes in the system and their status. A process, upon creation, has one of the three states: Running, Ready, Blocked (doing I/O, using other resources than CPU or waiting on unavailable resource).

Apr 15, 2022
Read Non-Rectangular Text Data
Read Non-Rectangular Text Data

meltr The goal of ‘meltr’ is to provide a fast and friendly way to read non-rectangular data (like ragged forms of ‘csv’, ‘tsv’, and ‘fwf’). Standard

Sep 11, 2022
A non-linear trajectory optimization library developed by Optimus Ride, Inc

A non-linear trajectory optimization library developed by Optimus Ride, Inc. This library implements a C++ version of the original open-source ALTRO solver developed by the Robotic Exploration Lab at Stanford and Carnegie Mellon Universities, also available open-source as an official Julia package.

Sep 7, 2022
Extension to Keyboard.h to allow non-US keyboards and Unicode characters

KeyboardUTF8 This Arduino library adds a mapping layer on top of the Keyboard library (for Leonardo/Micro/Due) to allow non-US keyboards and 'typing'

Sep 4, 2022
Sorting routine implementations in "template" C

sort.h Overview sort.h is an implementation of a ton of sorting algorithms in C with a user-defined type that is provided at include time. This means

Aug 27, 2022
A Template Engine for Modern C++

Inja is a template engine for modern C++, loosely inspired by jinja for python. It has an easy and yet powerful template syntax with all variables, lo

Sep 18, 2022
Windows kernel hacking framework, driver template, hypervisor and API written on C++

Windows kernel hacking framework, driver template, hypervisor and API written on C++

Sep 23, 2022
Minimal, type safe printf replacement library for C++

tinyformat.h A minimal type safe printf() replacement tinyformat.h is a type safe printf replacement library in a single C++ header file. If you've ev

Sep 2, 2022
A header only C++ library that provides type safety and user defined literals for physical units

SI - Type safety for physical units A header only c++ library that provides type safety and user defined literals for handling pyhsical values defined

Sep 20, 2022