if condition and counter increment - if-statement

What wrong with this if condition?
if ((#rent_amt_h <> '0.000') or (#house_payment_amt_h <> '0.000') or (#insurance_amt_h <> '0.000')or (#property_taxes_amt_h <> '0.000') or (#gas_amt_u <> '0.000') or (#elec_amt_u <> '0.000') or (#otherfuel_amt_u <> '0.000') or (#Trash_Collection_amt_u <> '0.000') or (#Sewerage_amt_u <> '0.000') or (#Telephone_amt_u <> '0.000') or (#water_amt_u <> '0.000') or (#other_house_amt_h <> '0.000') or (#other_amt_u <> '0.000') or (#total_u <> '0.000'))
begin
SET #APPSHELTER_COUNT = (select Count(APP_ID) FROM ext_app_group_other_expenses (nolock) WHERE APP_ID = #App_Id )
end
else
begin
SET #APPSHELTER_COUNT = 0
end
It increments the #APPSHELTER_COUNT value, even the values in if condition are zero!. It never sets the value to 0?
Thanks for your help.

What language is that? Anyway, it feels like you are comparing numbers with strings. Try removing quotes around your zeros. For example #rent_amt_h <> 0 rather than #rent_amt_h <> '0.000'. Also, if that is some SQL, make sure you handle NULL correctly, because NULL != 0.

Related

How to detect index of a specific number in a std::integer_sequence?

I basically drafted compile time prime checking using this question as a reference:
Compile time prime checking
I have a IsPrime<3>::value available.
I want to design a find meta function that basically identifies if there is a prime in my integer sequence at compile time, if there is then returns the index else returns -1;
example
find<std::integer_sequence<4,6,8,3>>::value // 3
find<std::integer_sequence<4,6,8,27>>::value // -1
find<std::integer_sequence<4,6,8,3,5,27>>::value // 3(as index 3 is the first prime, we do not care about others)
I am unable to wrap my head around parameter pack, any good examples or proper solution with explanation would help a lot.
Thinking out loud something like below, but not able to wrap my head around, how to get the index and how to stop iterating once you find the first prime in the sequence
template<typename T... args>
struct find_prime{
static constexpr int value = is_prime<args>::value ? increement++ : is_prime<...>::args;
};
Sorry if this sounds like a dumb approach, unable to figure out how to iterate with index
This can be done with a recursive template. Recursion terminates early when a prime is found.
// Base failure case: our list is empty (or the specialization below would match)
template <int, int...>
struct find_prime_impl {
static constexpr int value = -1;
};
// Specialization for at least one item remaining. If it's prime, the current
// index is assigned to value; otherwise we recurse with an incremented index,
// and without the first item.
template <int Index, int Head, int... Tail>
struct find_prime_impl<Index, Head, Tail...> {
static constexpr int value = [] {
if constexpr (is_prime<Head>::value) {
return Index;
} else {
return find_prime_impl<Index + 1, Tail...>::value;
}
}();
};
// Calls the recursive template with the initial index 0.
template <int... Values>
struct find_prime : find_prime_impl<0, Values...> {};
The immediately-invoked lambda lets us use if constexpr which means that the compiler can skip instantiating the recursive use of find_prime_impl when the terminating case is met. The ternary operator does not "short-circuit" instantiation in this way and would still instantiate the entire recursive chain all the way down to find_prime_impl<Index>.
(Demo)
To directly use std::integer_sequence, tweak the implementation to expect it:
// Failure case when the type isn't std::integer_sequence
template <int, typename>
struct find_prime_impl {};
// Failure case when our list is empty (or the specialization below would match)
template <typename TInt, int Index>
struct find_prime_impl<Index, std::integer_sequence<TInt>> {
static constexpr int value = -1;
};
// Specialization for at least one item remaining. If it's prime, the current
// index is assigned to value; otherwise we recurse with an incremented index,
// and without the first item.
template <typename TInt, int Index, TInt Head, TInt... Tail>
struct find_prime_impl<Index, std::integer_sequence<TInt, Head, Tail...>> {
static constexpr int value = [] {
if constexpr (is_prime<Head>::value) {
return Index;
} else {
return find_prime_impl<
Index + 1,
std::integer_sequence<TInt, Tail...>
>::value;
}
}();
};
// Calls the recursive template with the initial index 0.
template <typename T>
struct find_prime : find_prime_impl<0, T> {};
Here is an example that works with significantly less code:
template <int ...Ints>
constexpr int find_prime() {
constexpr auto res = fp<Ints...>(std::make_index_sequence<sizeof...(Ints)>{});
return (res == sizeof...(Ints)) ? -1 : res;
}
template <int ...Ints, auto ...Indices>
constexpr int fp(std::index_sequence<Indices...>) {
return std::min({ (is_prime(Ints) ? Indices : sizeof...(Indices))... });
}
The idea is to bind each number to its index in the list and just return the smallest index from the list that is a prime. If all entries in the list of indices are the length of the list itself, the program shall return -1.

Why does if constexpr require an else to work?

I am trying to use if constexpr in the following way:
template<template <typename First, typename Second> class Trait,
typename First, typename Second, typename... Rest>
constexpr bool binaryTraitAre_impl()
{
if constexpr (sizeof... (Rest) == 0)
{
return Trait<First, Second>{}();
}
return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
}
Example use case:
static_assert(binaryTraitAre_impl<std::is_convertible,
int, int&,
int*, void*>());
But this fails to compile
clang:
error: no matching function for call to 'binaryTraitAre_impl'
return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc:
prog.cc: In instantiation of 'constexpr bool binaryTraitAre_impl() [with Trait = std::is_convertible; First = int*; Second = void*; Rest = {}]':
prog.cc:9:80: required from 'constexpr bool binaryTraitAre_impl() [with Trait = std::is_convertible; First = int; Second = int&; Rest = {int*, void*}]'
prog.cc:15:83: required from here
prog.cc:9:80: error: no matching function for call to 'binaryTraitAre_impl<template<class _From, class _To> struct std::is_convertible>()'
9 | return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
prog.cc:3:17: note: candidate: 'template<template<class First, class Second> class Trait, class First, class Second, class ... Rest> constexpr bool binaryTraitAre_impl()'
3 | constexpr bool binaryTraitAre_impl()
| ^~~~~~~~~~~~~~~~~~~
prog.cc:3:17: note: template argument deduction/substitution failed:
prog.cc:9:80: note: couldn't deduce template parameter 'First'
9 | return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
But I found the error goes away once I add else:
template<template <typename First, typename Second> class Trait,
typename First, typename Second, typename... Rest>
constexpr bool binaryTraitAre_impl()
{
if constexpr (sizeof... (Rest) == 0)
{
return Trait<First, Second>{}();
}
else
{
return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
}
}
live demo
What happened? Why can the compiler not infer the else in this case?
This is the excerpt from cppreference on constexpr if:
Constexpr If
The statement that begins with if constexpr is known as the constexpr if statement.
In a constexpr if statement, the value of condition must be a contextually converted constant expression of type bool. If the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded.
It is clear that only one of the two branches is discarded. In your case, the culprit code cannot be discarded because it's outside the else clause.
if constexpr when the clause is true doesn't eliminate code outside of the corresponding else block.
You could extend C++ to do that, but it quickly becomes a pain. Only the most trivial cases are obvious, and specifying what the trivial cases are is a pain. I mean do you cover:
if constexpr( blah ){
if (true) return 7;
}
? How about
if constexpr( blah ){
if (blah) return 7;
else exit(-1);
}
? Or
if constexpr( blah ){
if (blah) return 7;
else return false;
}
or
if constexpr( blah ){
if (blah) goto foo;
return false;
foo: return true;
}
or how about:
if constexpr( blah ){
std::size_t count = 0;
while (foo != 1 && (++count < (std::size_t)-1))
switch (foo%2) {
case 1: foo = 3*foo+1;
case 0: foo = foo/2;
}
}
if (count < (std::size_t)-1) return true;
}
? I can come up with a near continuum of cases that are slightly more or less "obvious" in their never-return. And the payoff? Not having an else. Lots of problems, little benefit.
Compilers have ad-hoc rules to detect unreachable code and the like. These don't have to be as formally specified as the standard, and they can differ from one compiler to another.
The standard, meanwhile, has to be the same for every compiler. And the rules for what is and isn't eliminated have to be identical.
The standard applies a simple rule; the if and else blocks are the only candidates for eliminatation.
So the standard doesn't do that. If you want code to be eliminated, put it in a if constexpr or else block of the if constexpr. Language development resources are better spent on things that have better yield and are less painful.

if constexpr and C4702 (and C4100, and C4715)

Is there a way to fix the following problem:
This code produces a C4702 warning 'unreachable code' (on VC++ 15.8 with /std:c++17)
template <typename T, typename VariantType>
inline bool MatchMonostate( VariantType& variant )
{
SUPPRESS_C4100( variant );
if constexpr ( std::is_same_v<T, std::monostate> )
{
variant = std::monostate();
return true;
}
return false; // !!! unreachable if the above is true !!! => C4702
}
to suppress the C4100 'unreferenced formal parameter' warning, I'm already using the trick
#define SUPPRESS_C4100(x) ((void)x)
The simple idea of adding
else
{
return false;
}
results in warning C4715 'not all control paths return a value' instead.
It's unreachable because for a given expansion of the template based on the template arguments the function will only ever pass the condition and return true or fail and return false. There is no case where it could go either way for the same type. It's essentially expanding to
if (true) {
return true;
}
return false; // Obviously will never happen
I'd rewrite it to only have a single return statement.
template <typename T, typename VariantType>
inline bool MatchMonostate( VariantType& variant )
{
SUPPRESS_C4100( variant );
bool retval = false;
if constexpr ( std::is_same_v<T, std::monostate> )
{
variant = std::monostate();
retval = true;
}
return retval;
}
Also, in the case where the condition is true variant is not unused. You may want to move that line that suppresses the warning (which basically turns into (void)variant) to an else statement.
As the direct answer to the direct question. On the subject of if constexpr. Consider this:
template <typename T, typename ... params >
inline bool match_monostate
(std::variant<params ...> & variant) noexcept
{
if constexpr (std::is_same_v<T, std::monostate>)
{
variant = std::monostate{} ;
// compiles only if called with variant
// whose one alternative is std::monostate
return true;
}
else {
return false;
}
}
Depending on the bool result of the if constexpr expression, compiler actually produces two functions. This version is produced when if constexpr() yields true:
template <typename T, typename ... params >
inline bool
match_monostate (std::variant<params ...> & variant) noexcept
{
variant = std::monostate{} ;
// compiles only if called with variant
// whose one alternative is std::monostate
return true;
}
This version is produced when if constexpr() yields false:
template <typename T, typename ... params >
inline bool
match_monostate (std::variant<params ...> & variant) noexcept
{
return false;
}
The second version might emit warnings about unused argument. But (it seems) not if using the latest versions of clang/gcc/msvc. For older compilers as "old123987" also pointed out one can add the standard attribute to the signature. Like so:
template <typename T, typename ... params >
inline bool
match_monostate ([[maybe_unused]] std::variant<params ...> & variant) ;
That will stop the warning emitting.

checking uniqueness of characters at compile time

Is it possible in C++11 (not later) to write a function that verifies the uniqueness of characters passed to it at compile time
verify('a');
verify('b');
verify('c');
verify('a'); //should cause compilation error
[Edit by MK to answer some questions]:
The calls are always in the same scope, right one after the other like above.
A macro solution would be acceptable too
Non-type template parameters are acceptable too
Not exactly what you asked for, but given your constraints (same scope and macro solution is acceptable) you can try something like this:
#define verify(x) class _tmp_##x {};
Example:
int main()
{
verify(a);
verify(b);
verify(a);
return 0;
}
Will fail compilation due to redefinition of local class _tmp_a.
template<std::size_t X>
struct line_t { enum{value=X}; constexpr line_t(){} };
template<std::size_t line, char c>
constexpr std::integral_constant<bool, false> use_flag(
std::integral_constant<char,c>, line_t<line>
) { return {}; }
#define FLAG_USE( C ) \
constexpr std::integral_constant<bool, true> use_flag( \
std::integral_constant<char,C>, line_t<__LINE__> \
) { return {}; }
template<char c, std::size_t line>
constexpr std::size_t count_uses( line_t<line> from, line_t<1> length ){
return use_flag( std::integral_constant<char, c>{}, from )();
}
template<char c, std::size_t line>
constexpr std::size_t count_uses( line_t<line> from, line_t<0> length ){
return 0;
}
template<char c, std::size_t f, std::size_t l>
constexpr std::size_t count_uses(line_t<f> from, line_t<l> length ){
return count_uses<c>( from, line_t< l/2 >{} )+ count_uses<c>( line_t< f+l/2>{}, line_t<(l+1)/2>{} );
}
#define UNIQUE(C) \
FLAG_USE(C) \
static_assert( count_uses<C>( line_t<0>{}, line_t<__LINE__+1>{} )==1, "too many" )
This should work in files of size 2^100s, until your compiler runs out of memory, as counting is log-depth recursion.
The type line_t enables deferred ADL lookup of use_flag until we invoke count_uses. We do a binary tree sum over every overload of use_flag, one per line per character in the file.
Live example.

C++ - Check if all template arguments are power of 2

I`am trying to find a simple way of checking if parameters passed as template arguments are all power of 2. I found a bithack on the website and I have this:
constexpr bool isPowerOf2(size_t value){
return !(value == 0) && !(value & (value - 1));
}
This works nice for single value but applying this to multiple arguments looks ugly.
static_assert(isPowerOf2(Arg1), "Argument must be a power of 2");
static_assert(isPowerOf2(Arg2), "Argument must be a power of 2");
static_assert(isPowerOf2(Arg3), "Argument must be a power of 2");
It would be better if I could make it look like arePowersOf2(Arg1, Arg2, Arg3), but im not really advanced in template magic. So my question: Is there an easy way of doing it? I would prefer constexpr C++11 solution.
You can write a conjunction trait which checks if all the bools in a parameter pack are true. This example uses #Columbo's bool_pack trick:
template <bool...> struct bool_pack{};
template <bool... bools>
struct conjunction : std::is_same<bool_pack<true, bools...>,
bool_pack<bools..., true>>
{};
template <size_t... Args>
constexpr bool arePowerOf2() {
return conjunction<isPowerOf2(Args)...>::value;
}
Then you would just call it like this:
arePowerOf2<Args...>();
arePowerOf2<Arg1, Arg2, Arg3>();
Live Demo
In C++1z you can use fold expressions for this:
template <size_t... Args>
constexpr bool arePowerOf2() {
return (... && isPowerOf2(Args));
}
C++1z will also get std::conjunction, which is just slightly different from the version above.
A pack of bools is an integer sequence of bools:
template<bool...Bs>using bools = std::integer_sequence<bool, Bs...>;
These help you create a sequence of true, true, true of a specified length:
template<std::size_t...Is>
constexpr bools<(Is,true)...> make_trues_f( std::index_sequence<Is...> ) {
return {};
}
template<std::size_t N>
using make_trues_t = decltype( all_true_f( std::make_index_sequence<N>{} ) );
template<class...Ts>
using make_trues_for_t = make_trues_t<sizeof...(Ts)>;
which gives you:
static_assert(
std::is_same<
bools<isPowerOf2(Args)...>,
make_trues_for_t<Args...>
>::value, "Argument must be a power of 2"
);
or
template<class...Args>
constexpr std::is_same<
bools<isPowerOf2(Args)...>,
make_trues<sizeof...(Args)>
>
all_power_of_2() { return {}; }
Me, I like returning types even from constexpr functions when I know the answer at a type-computation level.
As a bonus, the failed comparison is more clearly what is intended, instead of an off-by-one hack. The is_same compares a sequence of <true, true, false, true> to <true, true, true, true>, as compared to the off-by-one hack which compares <true, true, true, false, true> to <true, true, false, true, true>. In the first case, it is really clear from the type what went wrong -- the false -- especially when you spot that the right hand side is always a pack of only true.