问:
How to insert autogenerated ID in two columns in JPA/JAVA/Hibernate
I Generate id with autogenerator in JPA java in DAO class.
Because of the silly database architecture I need to generate the primary key and insert same id into two columns in same table

```<code>@Id
@GeneratedValue(generator = DataConstants.ABC)
@Column(name = "SYS_ID")
private Long Sysid;

@Column(name = "SYS_NUM")
private Long sysNum;
</code>```

Right now I have the DAO class as above which works fine and insert auto generated primary key in SYS_ID column.

One way to solve this is insert the data and get the sysid and then run Update on it which doesn;t seem feasible to me.

Any help would be appreciated

答:
I recently encountered a similar problem and eventually came up with the following solution: I use hibernate, panache, lombok for discription my entities:

Master.java

```<code>@Entity
@AllArgsConstructor
@NoArgsConstructor
@RegisterForReflection
@Table(name = "MASTER")
@FieldDefaults(level = AccessLevel.PUBLIC)
public class Master extends PanacheEntityBase {
    @Id
    @Column(name = "MASTERID", nullable = false)
    Long masterId;

    @Column(name = "DETAILID", nullable = false)
    Long detailId;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "master", cascade = {CascadeType.MERGE, CascadeType.PERSIST})
    Set<Detail> details = new HashSet<>(0);

    @Column(name = "DATECREATED", nullable = false)
    Date dateCreated;

    public static Master createMasterWithLoadId() {
        Query nativeQuery = Panache.getEntityManager().createNativeQuery("select MASTER_SEQ.nextval from dual");
        Master master = new Master();
        master.masterId = id;
        master.detailId = id;
        return master;
    }

     @PrePersist
     public void prePersist() {
        if (dateCreated == null) {
           dateCreated = clearTime(Calendar.getInstance()).getTime();
        }
     }

     private Calendar clearTime(Calendar cal) {
         cal.set(Calendar.HOUR_OF_DAY, 0);
         cal.set(Calendar.MINUTE, 0);
         cal.set(Calendar.SECOND, 0);
         cal.set(Calendar.MILLISECOND, 0);
         return cal;
     }
}
</code>```

Detail.java

```<code>@Entity
@NoArgsConstructor
@AllArgsConstructor
@RegisterForReflection
@IdClass(BatchContent.ContentId.class)
@Table(name = "DETAIL")
@FieldDefaults(level = AccessLevel.PUBLIC)
public class Detail extends PanacheEntityBase {
    @Id
    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.PERSIST})
    @JoinColumn(name = "detailId", nullable = false)
    Master master;

    @Id
    @Column(name = "one")
    Long one;

    @Id
    @Column(name = "two")
    Long two;

    @Getter
    @Setter
    @EqualsAndHashCode
    @NoArgsConstructor
    @AllArgsConstructor
    @RegisterForReflection
    @FieldDefaults(level = AccessLevel.PRIVATE)
    static class DetailId implements Serializable {

        Master master;

        Long one;

        Long two;

    }
}
</code>```

use:

```<code>Master master = Master.createMasterWithLoadId();
for (RequestDetail rDet : rDetails) {
    master.details.add(new Detail(master, rDet.getOne(), rDet.getTwo()));
}
master.persist();
</code>```

Body:
I Generate id with autogenerator in JPA java in DAO class.
Because of the silly database architecture I need to generate the primary key and insert same id into two columns in same table

@Id
@GeneratedValue(generator = DataConstants.ABC)
@Column(name = "SYS_ID")
private Long Sysid;

@Column(name = "SYS_NUM")
private Long sysNum;

Right now I have the DAO class as above which works fine and insert auto generated primary key in SYS_ID column.

One way to solve this is insert the data and get the sysid and then run Update on it which doesn;t seem feasible to me.

Any help would be appreciated

Body:
I recently encountered a similar problem and eventually came up with the following solution: I use hibernate, panache, lombok for discription my entities:

Master.java

@Entity
@AllArgsConstructor
@NoArgsConstructor
@RegisterForReflection
@Table(name = "MASTER")
@FieldDefaults(level = AccessLevel.PUBLIC)
public class Master extends PanacheEntityBase {
    @Id
    @Column(name = "MASTERID", nullable = false)
    Long masterId;

    @Column(name = "DETAILID", nullable = false)
    Long detailId;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "master", cascade = {CascadeType.MERGE, CascadeType.PERSIST})
    Set<Detail> details = new HashSet<>(0);

    @Column(name = "DATECREATED", nullable = false)
    Date dateCreated;

    public static Master createMasterWithLoadId() {
        Query nativeQuery = Panache.getEntityManager().createNativeQuery("select MASTER_SEQ.nextval from dual");
        Master master = new Master();
        master.masterId = id;
        master.detailId = id;
        return master;
    }

     @PrePersist
     public void prePersist() {
        if (dateCreated == null) {
           dateCreated = clearTime(Calendar.getInstance()).getTime();
        }
     }

     private Calendar clearTime(Calendar cal) {
         cal.set(Calendar.HOUR_OF_DAY, 0);
         cal.set(Calendar.MINUTE, 0);
         cal.set(Calendar.SECOND, 0);
         cal.set(Calendar.MILLISECOND, 0);
         return cal;
     }
}

Detail.java

@Entity
@NoArgsConstructor
@AllArgsConstructor
@RegisterForReflection
@IdClass(BatchContent.ContentId.class)
@Table(name = "DETAIL")
@FieldDefaults(level = AccessLevel.PUBLIC)
public class Detail extends PanacheEntityBase {
    @Id
    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.MERGE, CascadeType.PERSIST})
    @JoinColumn(name = "detailId", nullable = false)
    Master master;

    @Id
    @Column(name = "one")
    Long one;

    @Id
    @Column(name = "two")
    Long two;

    @Getter
    @Setter
    @EqualsAndHashCode
    @NoArgsConstructor
    @AllArgsConstructor
    @RegisterForReflection
    @FieldDefaults(level = AccessLevel.PRIVATE)
    static class DetailId implements Serializable {

        Master master;

        Long one;

        Long two;

    }
}

use:

Master master = Master.createMasterWithLoadId();
for (RequestDetail rDet : rDetails) {
    master.details.add(new Detail(master, rDet.getOne(), rDet.getTwo()));
}
master.persist();


来源: stackexchange

问:
Flutter - How to display webview inside application?
So i just starting to learn flutter and using its webview widget, but every time I open the route containing webview widget. Android always prompt me with open with webview browser tester instead of just displaying it inside my widget?

Here is my code.

```<code>import 'dart:async';

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class DetailLaporanR extends StatelessWidget {
  Completer <WebViewController> _c = Completer<WebViewController>();
  final globalScaff = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: globalScaff,
      appBar: AppBar(
        title: Text("Detail Laporan"),
      ),
      body: new WebView(
          initialUrl: "https://google.com",
          javaScriptMode: JavaScriptMode.unrestricted,
          onWebViewCreated: (WebViewController webViewController) {
            _c.complete(webViewController);
          },
        ),
      floatingActionButton: FloatingActionButton(
            onPressed: () {
              // verify and submit
              final snackBar = SnackBar(content: Text('Generating, Please Wait...'));
              // Find the Scaffold in the widget tree and use it to show a SnackBar.
              globalScaff.currentState.showSnackBar(snackBar);
            },
            child: Icon(Icons.cloud_download),
            backgroundColor: Colors.redAccent,
          ),
    );
  }
}
</code>```

答:
As per the docs on this package:

The plugin relies on Flutter's new mechanism for embedding Android and iOS views. As that mechanism is currently in a developers preview, this plugin should also be considered a developers preview.

https://pub.dev/documentation/webview_flutter/latest/

So it's not recommended to use in production as the api may change and relies on a feature in flutter which is not yet released in the stable versions.

ContentLicense: CC BY-SA 4.0

Body:
So i just starting to learn flutter and using its webview widget, but every time I open the route containing webview widget. Android always prompt me with open with webview browser tester instead of just displaying it inside my widget?

Here is my code.

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class DetailLaporanR extends StatelessWidget {
  Completer <WebViewController> _c = Completer<WebViewController>();
  final globalScaff = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: globalScaff,
      appBar: AppBar(
        title: Text("Detail Laporan"),
      ),
      body: new WebView(
          initialUrl: "https://google.com",
          javaScriptMode: JavaScriptMode.unrestricted,
          onWebViewCreated: (WebViewController webViewController) {
            _c.complete(webViewController);
          },
        ),
      floatingActionButton: FloatingActionButton(
            onPressed: () {
              // verify and submit
              final snackBar = SnackBar(content: Text('Generating, Please Wait...'));
              // Find the Scaffold in the widget tree and use it to show a SnackBar.
              globalScaff.currentState.showSnackBar(snackBar);
            },
            child: Icon(Icons.cloud_download),
            backgroundColor: Colors.redAccent,
          ),
    );
  }
}


问:
Laravel relations in multiple model with belongsToMany and hasMany
I am working on an eCommerce application.

I have 3 models. Product, Color, ProductImage.

The relation between Product and Color is: belongsToMany

<?php

namespace App\Entities\Product;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    /**
     * A product has many colors.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function colors()
    {
        return $this->belongsToMany(Color::class);
    }
}
```
<p>The relation between <code>Color</code> and <code>ProductImage</code> is: <strong>hasMany</strong></p>
<pre class="lang-php prettyprint-override"><code><?php

namespace App\Entities\Product;

use Illuminate\Database\Eloquent\Model;

class Color extends Model
{
    /**
     * A color has many images.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function images()
    {
        return $this->hasMany(ProductImage::class);
    }
}
</code>```

Question is how to make a relation between the Product and ProductImage model?

How to design the product_images table?

id, color_id, image

like this?

my use case is, I will make a slider on a single product page. There will be a Color select option. If a user selects a color, need to load product images associate with that selected color.

Appreciate your help :)

答:
If you need only productImages, you can use belongsToManyThrough. But if you need colors and productImages you can do it through the dot.

```<code>$product->load('colors.images');
</code>```

UPD
Read your description, in my point of view, table images should have two keys product_id and color_id. And then do something like this:

```<code>public function images()
{
    return $this->hasMany(ProductImage::class);
}

public function current_image(int $color_id)
{
    return $this->hasOne(ProductImage::class)->where('color_id', $color_id);
}
</code>```

Body:
I am working on an eCommerce application.

I have 3 models. Product, Color, ProductImage.

The relation between Product and Color is: belongsToMany

<?php

namespace App\Entities\Product;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    /**
     * A product has many colors.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function colors()
    {
        return $this->belongsToMany(Color::class);
    }
}

The relation between Color and ProductImage is: hasMany

<?php

namespace App\Entities\Product;

use Illuminate\Database\Eloquent\Model;

class Color extends Model
{
    /**
     * A color has many images.
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function images()
    {
        return $this->hasMany(ProductImage::class);
    }
}

Question is how to make a relation between the Product and ProductImage model?

How to design the product_images table?

id, color_id, image

like this?

my use case is, I will make a slider on a single product page. There will be a Color select option. If a user selects a color, need to load product images associate with that selected color.

Appreciate your help :)

Body:
If you need only productImages, you can use belongsToManyThrough. But if you need colors and productImages you can do it through the dot.

$product->load('colors.images');

UPD
Read your description, in my point of view, table images should have two keys product_id and color_id. And then do something like this:

public function images()
{
    return $this->hasMany(ProductImage::class);
}

public function current_image(int $color_id)
{
    return $this->hasOne(ProductImage::class)->where('color_id', $color_id);
}


问:
Problem related to programing STM32 microcontroller with CAN bus
I am new to STM32 microcontrollers and CAN bus communication protocol and I am working on programing an
STM32F103xx
microcontroller.
I want to use CAN bus for transmitting data to another microcontroller from the same family.

I set up all the necessary settings but when debugging the code it gets stuck in the transmitting pending function and doesn't transmit.
I want the data to be transmitted but it is not.

I don't believe I have a problem with my hardware.

PS:
I have tried both normal mode and LOOPBACK mode for CAN handler and they both didn't work.

```<code>int main(void)
{
    HAL_Init();

    SystemClock_Config();

    uint32_t BUTTON_0;
    uint32_t BUTTON_1;

    uint8_t Data_0[5] = "aaaaa";
    uint8_t Data_1[5] = "ZZZZZ";

    MX_GPIO_Init();
    MX_CAN_Init();

    if(HAL_CAN_Init(&hcan) != HAL_OK){
        Error_Handler();
    }

    if(HAL_CAN_Start(&hcan) != HAL_OK){
        Error_Handler();
    }

    while (1)
    {
        TxHeader.DLC   = 5;
        TxHeader.StdId = 0x65D;
        TxHeader.IDE   = CAN_ID_STD;
        TxHeader.RTR   = CAN_RTR_DATA;

        BUTTON_0 = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

        BUTTON_1 = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);

        if (BUTTON_0 == 0U){

            if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, Data_0, &TxMailbox) != HAL_OK ){
                Error_Handler();
            }

        }

        if (BUTTON_1 == 0U){

            if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, Data_1, &TxMailbox) != HAL_OK){
                Error_Handler();
            }

        }

        while (HAL_CAN_IsTxMessagePending(&hcan, TxMailbox));

        if (BUTTON_0 && BUTTON_1 == 0U){
            printf("Please Press a Button");
        }
    }
}
</code>```

答:
You are using
STM32CubeF1 HAL
libraries (probably through STM32CubeMX).
Please check the corresponding
User Manual
- section 9.2.1 recommends the following procedure:

Initialize the CAN low level resources by implementing the HAL_CAN_MspInit():

Enable the CAN interface clock using __HAL_RCC_CANx_CLK_ENABLE()

Configure CAN pins

Enable the clock for the CAN GPIOs

Configure CAN pins as alternate function open-drain

In case of using interrupts [...]

Initialize the CAN peripheral using HAL_CAN_Init() function.
  This function resorts to HAL_CAN_MspInit() for low-level initialization.

Configure the reception filters using the following configuration functions:

HAL_CAN_ConfigFilter()

Start the CAN module using HAL_CAN_Start() function.
  At this level the node is active on the bus:
  it receive messages, and can send messages.

To manage messages transmission, the following Tx control functions can be used:

HAL_CAN_AddTxMessage() to request transmission of a new message.

[...]

HAL_CAN_IsTxMessagePending() to check if a message is pending in a Tx mailbox.

[...]

When a message is received into the CAN Rx FIFOs,
  it can be retrieved using the HAL_CAN_GetRxMessage() function.
  The function HAL_CAN_GetRxFifoFillLevel() allows to know how many Rx message
  are stored in the Rx Fifo.

Calling the HAL_CAN_Stop() function stops the CAN module.

The deinitialization is achieved with HAL_CAN_DeInit() function.

[...]

Polling mode operation / Transmission:

Monitor the Tx mailboxes availability until at least one Tx mailbox is free,
  using HAL_CAN_GetTxMailboxesFreeLevel().

Then request transmission of a message using HAL_CAN_AddTxMessage().

Your code sample doesn't show the sub-functions called from main() so you have to check yourself :-) that

CAN/GPIO clocks have been enabled before the corresponding registers are assigned.

GPIO pins are configured as recommended.

Another thought - could it be that you have to check HAL_CAN_GetTxMailboxesFreeLevel() after starting the CAN, even before adding the first message for transmission?

Steps (2.), (4.), (5.) are already taken care of by your code, and
steps (3.), (6.), (7.), (8.) are not related to your problem (but only to reception / deinit).

If you don't want to do all the manual work yourself, you can also use one of the following tools as a starting point.
Both tools are far from perfect (and some of our StackOverflow peers disagree to recommend them at all), but often they already provide a basic structure with most of the relevant steps you need:

The firmware example collection (see their
Application Note
for details).

Code generator
STM32CubeMX

Body:
I am new to STM32 microcontrollers and CAN bus communication protocol and I am working on programing an
STM32F103xx
microcontroller.
I want to use CAN bus for transmitting data to another microcontroller from the same family.

I set up all the necessary settings but when debugging the code it gets stuck in the transmitting pending function and doesn't transmit.
I want the data to be transmitted but it is not.

I don't believe I have a problem with my hardware.

PS:
I have tried both normal mode and LOOPBACK mode for CAN handler and they both didn't work.

int main(void)
{
    HAL_Init();

    SystemClock_Config();

    uint32_t BUTTON_0;
    uint32_t BUTTON_1;

    uint8_t Data_0[5] = "aaaaa";
    uint8_t Data_1[5] = "ZZZZZ";

    MX_GPIO_Init();
    MX_CAN_Init();

    if(HAL_CAN_Init(&hcan) != HAL_OK){
        Error_Handler();
    }

    if(HAL_CAN_Start(&hcan) != HAL_OK){
        Error_Handler();
    }

    while (1)
    {
        TxHeader.DLC   = 5;
        TxHeader.StdId = 0x65D;
        TxHeader.IDE   = CAN_ID_STD;
        TxHeader.RTR   = CAN_RTR_DATA;

        BUTTON_0 = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);

        BUTTON_1 = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);

        if (BUTTON_0 == 0U){

            if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, Data_0, &TxMailbox) != HAL_OK ){
                Error_Handler();
            }

        }

        if (BUTTON_1 == 0U){

            if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, Data_1, &TxMailbox) != HAL_OK){
                Error_Handler();
            }

        }

        while (HAL_CAN_IsTxMessagePending(&hcan, TxMailbox));

        if (BUTTON_0 && BUTTON_1 == 0U){
            printf("Please Press a Button");
        }
    }
}


问:
Generate TYPECASE with macro in Common Lisp
I have a list of two element sublists which will change and grow in the course of the program. I want to write a macro which takes a key and generates a case dynamically like:

```<code>;; This is the List for saving CASE clauses
(setf l '((number 2) (symbol 3)))

;; and i want to have the following expansion
(typecase 'y
  (number 2)
  (symbol 3))
</code>```

I could have a macro which only refers to the global l:

```<code>(defmacro m (x)
  `(typecase ,x ,@l))
</code>```

which would expand correctly

```<code>(m 'y)  ;expands to (TYPECASE 'Y (number 2) (symbol 3))
</code>```

But how can i write the macro with a parameter for the list l so that it would work with other lists as well?

```<code>;; A macro which should generate the case based on the above list
(defmacro m (x l)
  `(typecase ,x ,@l))
</code>```

This doesn't work since l in the arguments list i a symbol and a call to (m 'y l) will expand to (TYPECASE 'Y . L).

Wanting to adhere to typecase mechanism, my workaround was as follows:

```<code>(setf types-x '(((integer 0 *) 38)
                ((eql neli) "Neli in X")
                (symbol 39))
            )
(setf types-y '(((eql neli) "Neli in Y")
                ((array bit *) "A Bit Vector")))

(defmacro m (x types-id)
  (case types-id
    (:x `(typecase ,x ,@types-x))
    (:y `(etypecase ,x ,@types-y))))

(m 'neli :x)                ;"Neli in X"
(m 'neli :y)                ;"Neli in Y"
(m 'foo :x)             ;39
</code>```

Any hints and comments is appreciated.

答:
The actual problem that you face is that if you do

```<code>(setf l '((number 2) (symbol 3)))
</code>```

already on toplevel, if you evaluate l, you don't come further than

```<code>((number 2) (symbol 3))
</code>```

So if you use l in a macro as an argument, you can't come further
than this. But what you need is to evaluate this form (modified after adding a typecase and an evaluated x upfront) once more within the macro.

This is, why @tfb suggested to write a function which actually evaluates the matching of the types specified in l.
So, we could regard his type-match function as a mini-interpreter for the type specifications given in l.

If you do a simple (defmacro m (x l) `(typecase ,x ,@l))
you face exactly that problem:

```<code>(macroexpand-1 '(m 1 l))
;; (typecase 1 . l)
</code>```

but what we need is that l once more evaluated.

```<code>(defmacro m (x l)
  `(typecase ,x ,@(eval l)))
</code>```

Which would give the actually desired result:

```<code>(macroexpand-1 '(m 1 l))
;; (TYPECASE 1 (NUMBER 2) (SYMBOL 3)) ;
;; T

;; and thus:
(m 1 l) ;; 2
</code>```

So far, it seems to work. But somewhere in the backhead it becomes itchy, because we know from books and community: "Don't use eval!! Eval in the code is evil!"

Trying around, you will find out when it will bite you very soon:

```<code># try this in a new session:

(defmacro m (x l) `(typecase ,x ,@(eval l)))
;; m

;; define `l` after definition of the macro works:
(setf l '((number 2) (symbol 3)))
;; ((NUMBER 2) (SYMBOL 3))

(m 1 l)
;; 2  ;; so our `eval` can handle definitions of `l` after macro was stated

(m '(1 2) l)
;; NIL

;; even redefining `l` works!
(setf l '((number 2) (symbol 3) (list 4)))
;; ((NUMBER 2) (SYMBOL 3) (LIST 4))

(m 1 l)
;; 2

(m '(1 2) l)
;; 4 ;; and it can handle re-definitions of `l` correctly.

;; however:
(let ((l '((number 2) (symbol 3)))) (m '(1 2) l))
;; 4 !!! this is clearly wrong! Expected is NIL!
;; so our `eval` in the macro cannot handle scoping correctly
;; which is a no-go for usage!

;; but after re-defining `l` globally to:
(setf l '((number 2) (symbol 3)))
;; ((NUMBER 2) (SYMBOL 3))

(m '(1 2) l)
;; NIL ;; it behaves correctly

(let ((lst '((number 2) (symbol 3) (list 4)))) (m '(1 2) lst))

;; *** - EVAL: variable LST has no value
;; so it becomes clear: `m` is looking in the scoping
;; where it was defined - the global scope (the parent scope of `m` when `m` was defined or within the scope of `m`).
</code>```

So the conclusion is:

The given macro with eval is NOT working correctly!!
Since it cannot handle local scoping.

So @tfb's answer - writing a mini-evaluator-function for l is the probably only way to handle this in a proper, safe, correct way.

Update

It seems to me that doing:

```<code>(defmacro m (x l)
  `(typecase ,x ,@l))

(defun m-fun (x l)
  (eval `(m ,x ,l)))

(m-fun ''y l) ;; 3
(m-fun 'y l)  ;; error since y unknown

(let ((l '((number 2) (symbol 3) (list 4))))
  (m-fun ''(1 2) l)) ;; => 4 since it is a list

(let ((l '((number 2) (symbol 3))))
  (m-fun ''(1 2) l)) ;; => NIL since it is a list

(let ((l '((number 2) (symbol 3))))
  (m-fun ''y l)) ;; => 3 since it is a symbol

(let ((n 12))
  (m-fun n l))  ;; => 2 since it is a number

;; to improve `m-fun`, one could define
(defun m-fun (x l)
  (eval `(m ',x ,l)))
;; then, one has not to do the strangely looking double quote
;; ''y but just one quote 'y.
(let ((l '((number 2) (symbol 3) (list 4))))
  (m-fun '(1 2) l)) ;; => 4 since it is a list
;; etc.
</code>```

at least hides the eval within a function.
And one does not have to use backquote in the main code.

Body:
I have a list of two element sublists which will change and grow in the course of the program. I want to write a macro which takes a key and generates a case dynamically like:

;; This is the List for saving CASE clauses
(setf l '((number 2) (symbol 3)))

;; and i want to have the following expansion
(typecase 'y
  (number 2)
  (symbol 3))

I could have a macro which only refers to the global l:

(defmacro m (x)
  `(typecase ,x ,@l))

which would expand correctly

(m 'y)  ;expands to (TYPECASE 'Y (number 2) (symbol 3))

But how can i write the macro with a parameter for the list l so that it would work with other lists as well?

;; A macro which should generate the case based on the above list
(defmacro m (x l)
  `(typecase ,x ,@l))

This doesn't work since l in the arguments list i a symbol and a call to (m 'y l) will expand to (TYPECASE 'Y . L).

Wanting to adhere to typecase mechanism, my workaround was as follows:

(setf types-x '(((integer 0 *) 38)
                ((eql neli) "Neli in X")
                (symbol 39))
            )
(setf types-y '(((eql neli) "Neli in Y")
                ((array bit *) "A Bit Vector")))

(defmacro m (x types-id)
  (case types-id
    (:x `(typecase ,x ,@types-x))
    (:y `(etypecase ,x ,@types-y))))

(m 'neli :x)                ;"Neli in X"
(m 'neli :y)                ;"Neli in Y"
(m 'foo :x)             ;39

Any hints and comments is appreciated.

Body:
The actual problem that you face is that if you do

(setf l '((number 2) (symbol 3)))

already on toplevel, if you evaluate l, you don't come further than

((number 2) (symbol 3))

So if you use l in a macro as an argument, you can't come further
than this. But what you need is to evaluate this form (modified after adding a typecase and an evaluated x upfront) once more within the macro.

This is, why @tfb suggested to write a function which actually evaluates the matching of the types specified in l.
So, we could regard his type-match function as a mini-interpreter for the type specifications given in l.

If you do a simple (defmacro m (x l) `(typecase ,x ,@l))
you face exactly that problem:

(macroexpand-1 '(m 1 l))
;; (typecase 1 . l)

but what we need is that l once more evaluated.

(defmacro m (x l)
  `(typecase ,x ,@(eval l)))

Which would give the actually desired result:

(macroexpand-1 '(m 1 l))
;; (TYPECASE 1 (NUMBER 2) (SYMBOL 3)) ;
;; T

;; and thus:
(m 1 l) ;; 2

So far, it seems to work. But somewhere in the backhead it becomes itchy, because we know from books and community: "Don't use eval!! Eval in the code is evil!"

Trying around, you will find out when it will bite you very soon:

# try this in a new session:

(defmacro m (x l) `(typecase ,x ,@(eval l)))
;; m

;; define `l` after definition of the macro works:
(setf l '((number 2) (symbol 3)))
;; ((NUMBER 2) (SYMBOL 3))

(m 1 l)
;; 2  ;; so our `eval` can handle definitions of `l` after macro was stated

(m '(1 2) l)
;; NIL

;; even redefining `l` works!
(setf l '((number 2) (symbol 3) (list 4)))
;; ((NUMBER 2) (SYMBOL 3) (LIST 4))

(m 1 l)
;; 2

(m '(1 2) l)
;; 4 ;; and it can handle re-definitions of `l` correctly.

;; however:
(let ((l '((number 2) (symbol 3)))) (m '(1 2) l))
;; 4 !!! this is clearly wrong! Expected is NIL!
;; so our `eval` in the macro cannot handle scoping correctly
;; which is a no-go for usage!

;; but after re-defining `l` globally to:
(setf l '((number 2) (symbol 3)))
;; ((NUMBER 2) (SYMBOL 3))

(m '(1 2) l)
;; NIL ;; it behaves correctly

(let ((lst '((number 2) (symbol 3) (list 4)))) (m '(1 2) lst))

;; *** - EVAL: variable LST has no value
;; so it becomes clear: `m` is looking in the scoping
;; where it was defined - the global scope (the parent scope of `m` when `m` was defined or within the scope of `m`).

So the conclusion is:

The given macro with eval is NOT working correctly!!
Since it cannot handle local scoping.

So @tfb's answer - writing a mini-evaluator-function for l is the probably only way to handle this in a proper, safe, correct way.

Update

It seems to me that doing:

(defmacro m (x l)
  `(typecase ,x ,@l))

(defun m-fun (x l)
  (eval `(m ,x ,l)))

(m-fun ''y l) ;; 3
(m-fun 'y l)  ;; error since y unknown

(let ((l '((number 2) (symbol 3) (list 4))))
  (m-fun ''(1 2) l)) ;; => 4 since it is a list

(let ((l '((number 2) (symbol 3))))
  (m-fun ''(1 2) l)) ;; => NIL since it is a list

(let ((l '((number 2) (symbol 3))))
  (m-fun ''y l)) ;; => 3 since it is a symbol

(let ((n 12))
  (m-fun n l))  ;; => 2 since it is a number

;; to improve `m-fun`, one could define
(defun m-fun (x l)
  (eval `(m ',x ,l)))
;; then, one has not to do the strangely looking double quote
;; ''y but just one quote 'y.
(let ((l '((number 2) (symbol 3) (list 4))))
  (m-fun '(1 2) l)) ;; => 4 since it is a list
;; etc.

at least hides the eval within a function.
And one does not have to use backquote in the main code.


问:
Why is %eax zeroed before a call to printf?
I am trying to pick up a little x86. I am compiling on a 64bit mac with gcc -S -O0.

Code in C:

```<code>printf("%d", 1);
</code>```

Output:

```<code>movl    $1, %esi
leaq    LC0(%rip), %rdi
movl    $0, %eax        ; WHY?
call    _printf
</code>```

I do not understand why %eax is cleared to 0 before 'printf' is called. Since printf returns the number of characters printed to %eax my best guess it is zeroed out to prepare it for printf but I would have assumed that printf would have to be responsible for getting it ready. Also, in contrast, if I call my own function int testproc(int p1), gcc sees no need to prepare %eax. So I wonder why gcc treats printf and testproc differently.

答:
In the x86_64 ABI, if a function has variable arguments then AL (which is part of EAX) is expected to hold the number of vector registers used to hold arguments to that function.

In your example:

```<code>printf("%d", 1);
</code>```

has an integer argument so there’s no need for a vector register, hence AL is set to 0.

On the other hand, if you change your example to:

```<code>printf("%f", 1.0f);
</code>```

then the floating-point literal is stored in a vector register and, correspondingly, AL is set to 1:

```<code>movsd   LC1(%rip), %xmm0
leaq    LC0(%rip), %rdi
movl    $1, %eax
call    _printf
</code>```

As expected:

```<code>printf("%f %f", 1.0f, 2.0f);
</code>```

will cause the compiler to set AL to 2 since there are two floating-point arguments:

```<code>movsd   LC0(%rip), %xmm0
movapd  %xmm0, %xmm1
movsd   LC2(%rip), %xmm0
leaq    LC1(%rip), %rdi
movl    $2, %eax
call    _printf
</code>```

As for your other questions:

puts is also zeroing out %eax right before the call though it only takes a single pointer. Why is this?

It shouldn’t. For instance:

```<code>#include <stdio.h>

void test(void) {
    puts("foo");
}
</code>```

when compiled with gcc -c -O0 -S, outputs:

```<code>pushq   %rbp
movq    %rsp, %rbp
leaq    LC0(%rip), %rdi
call    _puts
leave
ret
</code>```

and %eax is not zeroed out. However, if you remove #include <stdio.h> then the resulting assembly does zero out %eax right before calling puts():

```<code>pushq   %rbp
movq    %rsp, %rbp
leaq    LC0(%rip), %rdi
movl    $0, %eax
call    _puts
leave
ret
</code>```

The reason is related to your second question:

This also happens before any call to my own void proc() function (even with -O2 set), but it is not zeroed when calling a void proc2(int param) function.

If the compiler doesn't see the declaration of a function then it makes no assumptions about its parameters, and the function could well accept variable arguments. The same applies if you specify an empty parameter list (which you shouldn’t, and it’s marked as an obsolescent C feature by ISO/IEC). Since the compiler doesn’t have enough information about the function parameters, it zeroes out %eax before calling the function because it might be the case that the function is defined as having variable arguments.

For example:

```<code>#include <stdio.h>

void function() {
    puts("foo");
}

void test(void) {
    function();
}
</code>```

where function() has an empty parameter list, results in:

```<code>pushq   %rbp
movq    %rsp, %rbp
movl    $0, %eax
call    _function
leave
ret
</code>```

However, if you follow the recommend practice of specifying void when the function accepts no parameters, such as:

```<code>#include <stdio.h>

void function(void) {
    puts("foo");
}

void test(void) {
    function();
}
</code>```

then the compiler knows that function() doesn't accept arguments — in particular, it doesn’t accept variable arguments — and hence doesn’t clear %eax before calling that function:

```<code>pushq   %rbp
movq    %rsp, %rbp
call    _function
leave
ret
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am trying to pick up a little x86. I am compiling on a 64bit mac with gcc -S -O0.

Code in C:

printf("%d", 1);

Output:

movl    $1, %esi
leaq    LC0(%rip), %rdi
movl    $0, %eax        ; WHY?
call    _printf

I do not understand why %eax is cleared to 0 before 'printf' is called. Since printf returns the number of characters printed to %eax my best guess it is zeroed out to prepare it for printf but I would have assumed that printf would have to be responsible for getting it ready. Also, in contrast, if I call my own function int testproc(int p1), gcc sees no need to prepare %eax. So I wonder why gcc treats printf and testproc differently.

Body:
In the x86_64 ABI, if a function has variable arguments then AL (which is part of EAX) is expected to hold the number of vector registers used to hold arguments to that function.

In your example:

printf("%d", 1);

has an integer argument so there’s no need for a vector register, hence AL is set to 0.

On the other hand, if you change your example to:

printf("%f", 1.0f);

then the floating-point literal is stored in a vector register and, correspondingly, AL is set to 1:

movsd   LC1(%rip), %xmm0
leaq    LC0(%rip), %rdi
movl    $1, %eax
call    _printf

As expected:

printf("%f %f", 1.0f, 2.0f);

will cause the compiler to set AL to 2 since there are two floating-point arguments:

movsd   LC0(%rip), %xmm0
movapd  %xmm0, %xmm1
movsd   LC2(%rip), %xmm0
leaq    LC1(%rip), %rdi
movl    $2, %eax
call    _printf

As for your other questions:

puts is also zeroing out %eax right before the call though it only takes a single pointer. Why is this?

It shouldn’t. For instance:

#include <stdio.h>

void test(void) {
    puts("foo");
}

when compiled with gcc -c -O0 -S, outputs:

pushq   %rbp
movq    %rsp, %rbp
leaq    LC0(%rip), %rdi
call    _puts
leave
ret

and %eax is not zeroed out. However, if you remove #include <stdio.h> then the resulting assembly does zero out %eax right before calling puts():

pushq   %rbp
movq    %rsp, %rbp
leaq    LC0(%rip), %rdi
movl    $0, %eax
call    _puts
leave
ret

The reason is related to your second question:

This also happens before any call to my own void proc() function (even with -O2 set), but it is not zeroed when calling a void proc2(int param) function.

If the compiler doesn't see the declaration of a function then it makes no assumptions about its parameters, and the function could well accept variable arguments. The same applies if you specify an empty parameter list (which you shouldn’t, and it’s marked as an obsolescent C feature by ISO/IEC). Since the compiler doesn’t have enough information about the function parameters, it zeroes out %eax before calling the function because it might be the case that the function is defined as having variable arguments.

For example:

#include <stdio.h>

void function() {
    puts("foo");
}

void test(void) {
    function();
}

where function() has an empty parameter list, results in:

pushq   %rbp
movq    %rsp, %rbp
movl    $0, %eax
call    _function
leave
ret

However, if you follow the recommend practice of specifying void when the function accepts no parameters, such as:

#include <stdio.h>

void function(void) {
    puts("foo");
}

void test(void) {
    function();
}

then the compiler knows that function() doesn't accept arguments — in particular, it doesn’t accept variable arguments — and hence doesn’t clear %eax before calling that function:

pushq   %rbp
movq    %rsp, %rbp
call    _function
leave
ret


问:
Why does this wrapping allocator's constructor take in the wrong type during template substitution (perfect forwarding ctor)?
For some context, I'm writing an allocator that takes in a base allocator as a template type, and does nothing but forward the allocate() and deallocate() calls to the underlying allocator member. Creating std::vectors with this custom allocator works fine. I tried writing a make_shared wrapper that will use dummy_allocator<T, std::allocator<T>> by default but it wasn't successful. Here is a reproducible example:

```<code>#include <memory>
namespace test {

template<typename T, typename base_allocator=std::allocator<T>>
class dummy_allocator {
public:
    typedef typename std::allocator_traits<base_allocator>::size_type size_type;
    typedef typename std::allocator_traits<base_allocator>::difference_type difference_type;
    typedef typename std::allocator_traits<base_allocator>::pointer pointer;
    typedef typename std::allocator_traits<base_allocator>::const_pointer const_pointer;
    typedef typename std::allocator_traits<base_allocator>::value_type value_type;

    template<class U>
    struct rebind {
        typedef dummy_allocator<U,
                typename std::allocator_traits<base_allocator>::template rebind_alloc<U>> other;
    };

    template<typename... Args>
    dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}

    dummy_allocator(const dummy_allocator& a) = default;

    [[nodiscard]] T *allocate(std::size_t n) {
        T *p = alloc.allocate(n);
        return p;
    }

    void deallocate(T *p, std::size_t size) noexcept {
        alloc.deallocate(p, size);
    }

private:
    base_allocator alloc;
};

/// Allocate using a wrapped version of passed in allocator
template <typename T, typename Alloc, typename... Args>
std::shared_ptr<T> allocate_shared(const Alloc& alloc, Args&&... args) {
    auto dummy_alloc = dummy_allocator<T, Alloc>(alloc);
    return std::allocate_shared<T>(dummy_alloc, std::forward<Args>(args)...);
}

/// Create a shared pointer from a default stl allocator wrapped in profile allocator.
template <typename T, typename... Args>
std::shared_ptr<T> make_shared(Args&&... args) {
    return test::allocate_shared<T>(std::allocator<T>(), std::forward<Args>(args)...);
}

} // namespace test

int main() {
    auto ptr = test::make_shared<double>();
    return 0;
}
</code>```

When I ran the above code, the compiler generated some bizarre template substitution failure errors:

```<code>/usr/include/c++/10.1.0/bits/shared_ptr_base.h:679:43:   required from ‘std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = double; _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10.1.0/bits/shared_ptr_base.h:1371:71:   required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; _Tp = double; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10.1.0/bits/shared_ptr.h:408:59:   required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; _Tp = double]’
/usr/include/c++/10.1.0/bits/shared_ptr.h:859:14:   required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = double; _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}]’
/home/ray/home/testing/src/alloc.cpp:44:35:   required from ‘std::shared_ptr<_Tp> test::allocate_shared(const Alloc&, Args&& ...) [with T = double; Alloc = std::allocator<double>; Args = {}]’
/home/ray/home/testing/src/alloc.cpp:50:36:   required from ‘std::shared_ptr<_Tp> test::make_shared(Args&& ...) [with T = double; Args = {}]’
/home/ray/home/testing/src/alloc.cpp:86:46:   required from here
/home/ray/home/testing/src/alloc.cpp:25:82: error: no matching function for call to ‘std::allocator<std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic> >::allocator(const test::dummy_allocator<double, std::allocator<double> >&)’
   25 |     dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}
      |                                                                                ^
In file included from /usr/include/c++/10.1.0/list:61,
                 from /home/ray/home/testing/src/alloc.cpp:3:
/usr/include/c++/10.1.0/bits/allocator.h:157:2: note: candidate: ‘template<class _Tp1> constexpr std::allocator< <template-parameter-1-1> >::allocator(const std::allocator<_Tp1>&) [with _Tp1 = _Tp1; _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  157 |  allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
      |  ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:157:2: note:   template argument deduction/substitution failed:
/home/ray/home/testing/src/alloc.cpp:25:82: note:   ‘const test::dummy_allocator<double, std::allocator<double> >’ is not derived from ‘const std::allocator<_Up>’
   25 |     dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}
      |                                                                                ^
In file included from /usr/include/c++/10.1.0/list:61,
                 from /home/ray/home/testing/src/alloc.cpp:3:
/usr/include/c++/10.1.0/bits/allocator.h:147:7: note: candidate: ‘constexpr std::allocator< <template-parameter-1-1> >::allocator(const std::allocator< <template-parameter-1-1> >&) [with _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  147 |       allocator(const allocator& __a) _GLIBCXX_NOTHROW
      |       ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:147:34: note:   no known conversion for argument 1 from ‘const test::dummy_allocator<double, std::allocator<double> >’ to ‘const std::allocator<std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic> >&’
  147 |       allocator(const allocator& __a) _GLIBCXX_NOTHROW
      |                 ~~~~~~~~~~~~~~~~~^~~
/usr/include/c++/10.1.0/bits/allocator.h:144:7: note: candidate: ‘constexpr std::allocator< <template-parameter-1-1> >::allocator() [with _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  144 |       allocator() _GLIBCXX_NOTHROW { }
      |       ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:144:7: note:   candidate expects 0 arguments, 1 provided
... (The above error basically is repeated 2 more times)
</code>```

In particular, this error seemed representative of the problem occurring:

```<code>error: no matching function for call to ‘std::allocator<std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic> >::allocator(const test::dummy_allocator<double, std::allocator<double> >&)’
</code>```

Where it basically says "in the constructor of dummy_allocator, you can't pass in a dummy_allocator to the std::allocator's constructor". But I'm not doing that. In allocate_shared, I'm passing in the std::allocator into the dummy_allocator.

I've really scratched my head reading the compiler error but came to no conclusions on what I'm doing wrong. Any help would be greatly appreciated!

EDIT: I think I have a hunch that whatever magic shared_ptr is doing underneath, it's trying to do a copy constructor of my dummy_allocator, and perfect forwarding is capturing the copy construction instead an actual copy constructor. However, I have no idea how to solve this as it's a variadic template and I can't use std::is_same<Args, dummy_allocator> as a requires clause in the perfect forwarding constructor.

So as Daniel Langr has pointed out, just copy constructing the dummy_allocator will fail. I fixed that issue with the following requires clause:

```<code>...
    template <typename T1, typename ...TV>
    struct is_dummy : std::is_same<typename std::decay<T1>::type, dummy_allocator<T, base_allocator>>{
    };

    template<typename... Args>
    requires (!is_dummy<Args...>::value)
    dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}

    dummy_allocator() = default;
    dummy_allocator(const dummy_allocator& a) = default;
...

</code>```

However, that's not enough to fix the shared_ptr issue, where the error is a bit longer...*

So here is the error you get:

```<code>#include <memory>
namespace test {

template<typename T, typename base_allocator=std::allocator<T>>
class dummy_allocator {
public:
    /// Necessary for allocators, propagate exactly what the base_allocator
    /// wants.
    typedef typename std::allocator_traits<base_allocator>::size_type size_type;
    typedef typename std::allocator_traits<base_allocator>::difference_type difference_type;
    typedef typename std::allocator_traits<base_allocator>::pointer pointer;
    typedef typename std::allocator_traits<base_allocator>::const_pointer const_pointer;
    typedef typename std::allocator_traits<base_allocator>::value_type value_type;

    template<class U>
    struct rebind {
        typedef dummy_allocator<U,
                typename std::allocator_traits<base_allocator>::template rebind_alloc<U>> other;
    };

    template <typename T1, typename ...TV>
    struct is_dummy : std::is_same<typename std::decay<T1>::type, dummy_allocator<T, base_allocator>>{
    };

    template<typename... Args>
    requires (!is_dummy<Args...>::value)
    dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}

    dummy_allocator() = default;
    dummy_allocator(const dummy_allocator& a) = default;

    [[nodiscard]] T *allocate(std::size_t n) {
        T *p = alloc.allocate(n);
        return p;
    }

    void deallocate(T *p, std::size_t size) noexcept {
        alloc.deallocate(p, size);
    }

private:
    base_allocator alloc;
};

/// Allocate using a wrapped version of passed in allocator
template <typename T, typename Alloc, typename... Args>
auto allocate_shared(const Alloc& alloc, Args&&... args) {
    auto dummy_alloc = dummy_allocator<T, Alloc>(alloc);
    return std::allocate_shared<T>(dummy_alloc, std::forward<Args>(args)...);
}

/// Create a shared pointer from a default stl allocator wrapped in profile allocator.
template <typename T, typename... Args>
auto make_shared(Args&&... args) {
    return test::allocate_shared<T>(std::allocator<T>(), std::forward<Args>(args)...);
}

} // namespace test

int main() {
    // This will fail
    auto ptr = test::make_shared<double>();

    // This will now work
    auto dummy_alloc = test::dummy_allocator<int, std::allocator<int>>();
    auto dummy_alloc2 = test::dummy_allocator<int, std::allocator<int>>(dummy_alloc);
    return 0;
}
</code>```

The associated error:

```<code>/usr/include/c++/10.1.0/bits/shared_ptr_base.h:679:43:   required from ‘std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = double; _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10.1.0/bits/shared_ptr_base.h:1371:71:   required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; _Tp = double; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10.1.0/bits/shared_ptr.h:408:59:   required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; _Tp = double]’
/usr/include/c++/10.1.0/bits/shared_ptr.h:859:14:   required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = double; _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}]’
/home/ray/home/test/src/alloc.cpp:53:35:   required from ‘auto test::allocate_shared(const Alloc&, Args&& ...) [with T = double; Alloc = std::allocator<double>; Args = {}]’
/home/ray/home/test/src/alloc.cpp:59:36:   required from ‘auto test::make_shared(Args&& ...) [with T = double; Args = {}]’
/home/ray/home/test/src/alloc.cpp:95:46:   required from here
/home/ray/home/test/src/alloc.cpp:31:82: error: no matching function for call to ‘std::allocator<std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic> >::allocator(const test::dummy_allocator<double, std::allocator<double> >&)’
   31 |     dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}
      |                                                                                ^
In file included from /usr/include/c++/10.1.0/list:61,
                 from /home/ray/home/test/src/alloc.cpp:3:
/usr/include/c++/10.1.0/bits/allocator.h:157:2: note: candidate: ‘template<class _Tp1> constexpr std::allocator< <template-parameter-1-1> >::allocator(const std::allocator<_Tp1>&) [with _Tp1 = _Tp1; _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  157 |  allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
      |  ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:157:2: note:   template argument deduction/substitution failed:
/home/ray/home/test/src/alloc.cpp:31:82: note:   ‘const test::dummy_allocator<double, std::allocator<double> >’ is not derived from ‘const std::allocator<_Up>’
   31 |     dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}
      |                                                                                ^
In file included from /usr/include/c++/10.1.0/list:61,
                 from /home/ray/home/test/src/alloc.cpp:3:
/usr/include/c++/10.1.0/bits/allocator.h:147:7: note: candidate: ‘constexpr std::allocator< <template-parameter-1-1> >::allocator(const std::allocator< <template-parameter-1-1> >&) [with _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  147 |       allocator(const allocator& __a) _GLIBCXX_NOTHROW
      |       ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:147:34: note:   no known conversion for argument 1 from ‘const test::dummy_allocator<double, std::allocator<double> >’ to ‘const std::allocator<std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic> >&’
  147 |       allocator(const allocator& __a) _GLIBCXX_NOTHROW
      |                 ~~~~~~~~~~~~~~~~~^~~
/usr/include/c++/10.1.0/bits/allocator.h:144:7: note: candidate: ‘constexpr std::allocator< <template-parameter-1-1> >::allocator() [with _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  144 |       allocator() _GLIBCXX_NOTHROW { }
      |       ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:144:7: note:   candidate expects 0 arguments, 1 provided
</code>```

答:
@Evg's answer is correct in the implementation for making the arguments constructible, but it did not yet solve the problem of why I was getting the shared_ptr issue. I solved using his implementation because I felt like using is_constructible::value is the best way to approach it, but we need to add a constructor that allows for different types to rebind:

```<code>template<typename T, typename base_allocator=std::allocator<T>>
class dummy_allocator {
public:
    /// Necessary for allocators, propagate exactly what the base_allocator
    /// wants.
    typedef typename std::allocator_traits<base_allocator>::size_type size_type;
    typedef typename std::allocator_traits<base_allocator>::difference_type difference_type;
    typedef typename std::allocator_traits<base_allocator>::pointer pointer;
    typedef typename std::allocator_traits<base_allocator>::const_pointer const_pointer;
    typedef typename std::allocator_traits<base_allocator>::value_type value_type;

    template<class U>
    struct rebind {
        typedef dummy_allocator<U,
                typename std::allocator_traits<base_allocator>::template rebind_alloc<U>> other;
    };

    template <typename T1, typename ...TV>
    struct is_dummy : std::is_same<typename std::decay<T1>::type, dummy_allocator<T, base_allocator>>{
    };

    template<typename... Args>

    dummy_allocator(Args &&... args) requires (std::is_constructible_v<base_allocator, Args...>) : alloc(std::forward<Args>(args)...) {}

    template <typename U, typename A> friend class dummy_allocator;

    // Construct a dummy allocator from another dummy allocator with the same base_allocator but with different type.
    template <typename U>
    dummy_allocator(
            const dummy_allocator<U,
                    typename std::allocator_traits<base_allocator>::template rebind_alloc<U>>& other) noexcept :
            alloc(other.alloc) {}

    dummy_allocator() = default;
    dummy_allocator(const dummy_allocator& a) : alloc(a.alloc) {}

    [[nodiscard]] T *allocate(std::size_t n) {
        T *p = alloc.allocate(n);
        return p;
    }

    void deallocate(T *p, std::size_t size) noexcept {
        alloc.deallocate(p, size);
    }

private:
    base_allocator alloc;
};
</code>```

In particular, these lines here:

```<code>    template <typename U, typename A> friend class dummy_allocator;

    // Construct a dummy allocator from another dummy allocator with the same base_allocator but with different type.
    template <typename U>
    dummy_allocator(
            const dummy_allocator<U,
                    typename std::allocator_traits<base_allocator>::template rebind_alloc<U>>& other) noexcept :
            alloc(other.alloc) {}
</code>```

Because we need to have constructors between different underlying types for allocators.

Body:
For some context, I'm writing an allocator that takes in a base allocator as a template type, and does nothing but forward the allocate() and deallocate() calls to the underlying allocator member. Creating std::vectors with this custom allocator works fine. I tried writing a make_shared wrapper that will use dummy_allocator<T, std::allocator<T>> by default but it wasn't successful. Here is a reproducible example:

#include <memory>
namespace test {

template<typename T, typename base_allocator=std::allocator<T>>
class dummy_allocator {
public:
    typedef typename std::allocator_traits<base_allocator>::size_type size_type;
    typedef typename std::allocator_traits<base_allocator>::difference_type difference_type;
    typedef typename std::allocator_traits<base_allocator>::pointer pointer;
    typedef typename std::allocator_traits<base_allocator>::const_pointer const_pointer;
    typedef typename std::allocator_traits<base_allocator>::value_type value_type;

    template<class U>
    struct rebind {
        typedef dummy_allocator<U,
                typename std::allocator_traits<base_allocator>::template rebind_alloc> other;
    };

    template<typename... Args>
    dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}

    dummy_allocator(const dummy_allocator& a) = default;

    [[nodiscard]] T *allocate(std::size_t n) {
        T *p = alloc.allocate(n);
        return p;
    }

    void deallocate(T *p, std::size_t size) noexcept {
        alloc.deallocate(p, size);
    }

private:
    base_allocator alloc;
};

/// Allocate using a wrapped version of passed in allocator
template <typename T, typename Alloc, typename... Args>
std::shared_ptr<T> allocate_shared(const Alloc& alloc, Args&&... args) {
    auto dummy_alloc = dummy_allocator<T, Alloc>(alloc);
    return std::allocate_shared<T>(dummy_alloc, std::forward<Args>(args)...);
}

/// Create a shared pointer from a default stl allocator wrapped in profile allocator.
template <typename T, typename... Args>
std::shared_ptr<T> make_shared(Args&&... args) {
    return test::allocate_shared<T>(std::allocator<T>(), std::forward<Args>(args)...);
}

} // namespace test

int main() {
    auto ptr = test::make_shared<double>();
    return 0;
}

When I ran the above code, the compiler generated some bizarre template substitution failure errors:

/usr/include/c++/10.1.0/bits/shared_ptr_base.h:679:43:   required from ‘std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = double; _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10.1.0/bits/shared_ptr_base.h:1371:71:   required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; _Tp = double; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10.1.0/bits/shared_ptr.h:408:59:   required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; _Tp = double]’
/usr/include/c++/10.1.0/bits/shared_ptr.h:859:14:   required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = double; _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}]’
/home/ray/home/testing/src/alloc.cpp:44:35:   required from ‘std::shared_ptr<_Tp> test::allocate_shared(const Alloc&, Args&& ...) [with T = double; Alloc = std::allocator<double>; Args = {}]’
/home/ray/home/testing/src/alloc.cpp:50:36:   required from ‘std::shared_ptr<_Tp> test::make_shared(Args&& ...) [with T = double; Args = {}]’
/home/ray/home/testing/src/alloc.cpp:86:46:   required from here
/home/ray/home/testing/src/alloc.cpp:25:82: error: no matching function for call to ‘std::allocator<std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic> >::allocator(const test::dummy_allocator<double, std::allocator<double> >&)’
   25 |     dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}
      |                                                                                ^
In file included from /usr/include/c++/10.1.0/list:61,
                 from /home/ray/home/testing/src/alloc.cpp:3:
/usr/include/c++/10.1.0/bits/allocator.h:157:2: note: candidate: ‘template<class _Tp1> constexpr std::allocator< <template-parameter-1-1> >::allocator(const std::allocator<_Tp1>&) [with _Tp1 = _Tp1; _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  157 |  allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
      |  ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:157:2: note:   template argument deduction/substitution failed:
/home/ray/home/testing/src/alloc.cpp:25:82: note:   ‘const test::dummy_allocator<double, std::allocator<double> >’ is not derived from ‘const std::allocator<_Up>’
   25 |     dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}
      |                                                                                ^
In file included from /usr/include/c++/10.1.0/list:61,
                 from /home/ray/home/testing/src/alloc.cpp:3:
/usr/include/c++/10.1.0/bits/allocator.h:147:7: note: candidate: ‘constexpr std::allocator< <template-parameter-1-1> >::allocator(const std::allocator< <template-parameter-1-1> >&) [with _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  147 |       allocator(const allocator& __a) _GLIBCXX_NOTHROW
      |       ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:147:34: note:   no known conversion for argument 1 from ‘const test::dummy_allocator<double, std::allocator<double> >’ to ‘const std::allocator<std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic> >&’
  147 |       allocator(const allocator& __a) _GLIBCXX_NOTHROW
      |                 ~~~~~~~~~~~~~~~~~^~~
/usr/include/c++/10.1.0/bits/allocator.h:144:7: note: candidate: ‘constexpr std::allocator< <template-parameter-1-1> >::allocator() [with _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  144 |       allocator() _GLIBCXX_NOTHROW { }
      |       ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:144:7: note:   candidate expects 0 arguments, 1 provided
... (The above error basically is repeated 2 more times)

In particular, this error seemed representative of the problem occurring:

error: no matching function for call to ‘std::allocator<std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic> >::allocator(const test::dummy_allocator<double, std::allocator<double> >&)’

Where it basically says "in the constructor of dummy_allocator, you can't pass in a dummy_allocator to the std::allocator's constructor". But I'm not doing that. In allocate_shared, I'm passing in the std::allocator into the dummy_allocator.

I've really scratched my head reading the compiler error but came to no conclusions on what I'm doing wrong. Any help would be greatly appreciated!

EDIT: I think I have a hunch that whatever magic shared_ptr is doing underneath, it's trying to do a copy constructor of my dummy_allocator, and perfect forwarding is capturing the copy construction instead an actual copy constructor. However, I have no idea how to solve this as it's a variadic template and I can't use std::is_same<Args, dummy_allocator> as a requires clause in the perfect forwarding constructor.

So as Daniel Langr has pointed out, just copy constructing the dummy_allocator will fail. I fixed that issue with the following requires clause:

...
    template <typename T1, typename ...TV>
    struct is_dummy : std::is_same<typename std::decay<T1>::type, dummy_allocator<T, base_allocator>>{
    };

    template<typename... Args>
    requires (!is_dummy<Args...>::value)
    dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}

    dummy_allocator() = default;
    dummy_allocator(const dummy_allocator& a) = default;
...

However, that's not enough to fix the shared_ptr issue, where the error is a bit longer...*

So here is the error you get:

#include <memory>
namespace test {

template<typename T, typename base_allocator=std::allocator<T>>
class dummy_allocator {
public:
    /// Necessary for allocators, propagate exactly what the base_allocator
    /// wants.
    typedef typename std::allocator_traits<base_allocator>::size_type size_type;
    typedef typename std::allocator_traits<base_allocator>::difference_type difference_type;
    typedef typename std::allocator_traits<base_allocator>::pointer pointer;
    typedef typename std::allocator_traits<base_allocator>::const_pointer const_pointer;
    typedef typename std::allocator_traits<base_allocator>::value_type value_type;

    template<class U>
    struct rebind {
        typedef dummy_allocator<U,
                typename std::allocator_traits<base_allocator>::template rebind_alloc> other;
    };

    template <typename T1, typename ...TV>
    struct is_dummy : std::is_same<typename std::decay<T1>::type, dummy_allocator<T, base_allocator>>{
    };

    template<typename... Args>
    requires (!is_dummy<Args...>::value)
    dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}

    dummy_allocator() = default;
    dummy_allocator(const dummy_allocator& a) = default;

    [[nodiscard]] T *allocate(std::size_t n) {
        T *p = alloc.allocate(n);
        return p;
    }

    void deallocate(T *p, std::size_t size) noexcept {
        alloc.deallocate(p, size);
    }

private:
    base_allocator alloc;
};

/// Allocate using a wrapped version of passed in allocator
template <typename T, typename Alloc, typename... Args>
auto allocate_shared(const Alloc& alloc, Args&&... args) {
    auto dummy_alloc = dummy_allocator<T, Alloc>(alloc);
    return std::allocate_shared<T>(dummy_alloc, std::forward<Args>(args)...);
}

/// Create a shared pointer from a default stl allocator wrapped in profile allocator.
template <typename T, typename... Args>
auto make_shared(Args&&... args) {
    return test::allocate_shared<T>(std::allocator<T>(), std::forward<Args>(args)...);
}

} // namespace test

int main() {
    // This will fail
    auto ptr = test::make_shared<double>();

    // This will now work
    auto dummy_alloc = test::dummy_allocator<int, std::allocator<int>>();
    auto dummy_alloc2 = test::dummy_allocator<int, std::allocator<int>>(dummy_alloc);
    return 0;
}

The associated error:

/usr/include/c++/10.1.0/bits/shared_ptr_base.h:679:43:   required from ‘std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = double; _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10.1.0/bits/shared_ptr_base.h:1371:71:   required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; _Tp = double; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10.1.0/bits/shared_ptr.h:408:59:   required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}; _Tp = double]’
/usr/include/c++/10.1.0/bits/shared_ptr.h:859:14:   required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = double; _Alloc = test::dummy_allocator<double, std::allocator<double> >; _Args = {}]’
/home/ray/home/test/src/alloc.cpp:53:35:   required from ‘auto test::allocate_shared(const Alloc&, Args&& ...) [with T = double; Alloc = std::allocator<double>; Args = {}]’
/home/ray/home/test/src/alloc.cpp:59:36:   required from ‘auto test::make_shared(Args&& ...) [with T = double; Args = {}]’
/home/ray/home/test/src/alloc.cpp:95:46:   required from here
/home/ray/home/test/src/alloc.cpp:31:82: error: no matching function for call to ‘std::allocator<std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic> >::allocator(const test::dummy_allocator<double, std::allocator<double> >&)’
   31 |     dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}
      |                                                                                ^
In file included from /usr/include/c++/10.1.0/list:61,
                 from /home/ray/home/test/src/alloc.cpp:3:
/usr/include/c++/10.1.0/bits/allocator.h:157:2: note: candidate: ‘template<class _Tp1> constexpr std::allocator< <template-parameter-1-1> >::allocator(const std::allocator<_Tp1>&) [with _Tp1 = _Tp1; _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  157 |  allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
      |  ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:157:2: note:   template argument deduction/substitution failed:
/home/ray/home/test/src/alloc.cpp:31:82: note:   ‘const test::dummy_allocator<double, std::allocator<double> >’ is not derived from ‘const std::allocator<_Up>’
   31 |     dummy_allocator(Args &&... args) noexcept : alloc(std::forward<Args>(args)...) {}
      |                                                                                ^
In file included from /usr/include/c++/10.1.0/list:61,
                 from /home/ray/home/test/src/alloc.cpp:3:
/usr/include/c++/10.1.0/bits/allocator.h:147:7: note: candidate: ‘constexpr std::allocator< <template-parameter-1-1> >::allocator(const std::allocator< <template-parameter-1-1> >&) [with _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  147 |       allocator(const allocator& __a) _GLIBCXX_NOTHROW
      |       ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:147:34: note:   no known conversion for argument 1 from ‘const test::dummy_allocator<double, std::allocator<double> >’ to ‘const std::allocator<std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic> >&’
  147 |       allocator(const allocator& __a) _GLIBCXX_NOTHROW
      |                 ~~~~~~~~~~~~~~~~~^~~
/usr/include/c++/10.1.0/bits/allocator.h:144:7: note: candidate: ‘constexpr std::allocator< <template-parameter-1-1> >::allocator() [with _Tp = std::_Sp_counted_ptr_inplace<double, test::dummy_allocator<double, std::allocator<double> >, __gnu_cxx::_S_atomic>]’
  144 |       allocator() _GLIBCXX_NOTHROW { }
      |       ^~~~~~~~~
/usr/include/c++/10.1.0/bits/allocator.h:144:7: note:   candidate expects 0 arguments, 1 provided

Body:
@Evg's answer is correct in the implementation for making the arguments constructible, but it did not yet solve the problem of why I was getting the shared_ptr issue. I solved using his implementation because I felt like using is_constructible::value is the best way to approach it, but we need to add a constructor that allows for different types to rebind:

template<typename T, typename base_allocator=std::allocator<T>>
class dummy_allocator {
public:
    /// Necessary for allocators, propagate exactly what the base_allocator
    /// wants.
    typedef typename std::allocator_traits<base_allocator>::size_type size_type;
    typedef typename std::allocator_traits<base_allocator>::difference_type difference_type;
    typedef typename std::allocator_traits<base_allocator>::pointer pointer;
    typedef typename std::allocator_traits<base_allocator>::const_pointer const_pointer;
    typedef typename std::allocator_traits<base_allocator>::value_type value_type;

    template<class U>
    struct rebind {
        typedef dummy_allocator<U,
                typename std::allocator_traits<base_allocator>::template rebind_alloc<U>> other;
    };

    template <typename T1, typename ...TV>
    struct is_dummy : std::is_same<typename std::decay<T1>::type, dummy_allocator<T, base_allocator>>{
    };

    template<typename... Args>

    dummy_allocator(Args &&... args) requires (std::is_constructible_v<base_allocator, Args...>) : alloc(std::forward<Args>(args)...) {}

    template <typename U, typename A> friend class dummy_allocator;

    // Construct a dummy allocator from another dummy allocator with the same base_allocator but with different type.
    template <typename U>
    dummy_allocator(
            const dummy_allocator<U,
                    typename std::allocator_traits<base_allocator>::template rebind_alloc<U>>& other) noexcept :
            alloc(other.alloc) {}

    dummy_allocator() = default;
    dummy_allocator(const dummy_allocator& a) : alloc(a.alloc) {}

    [[nodiscard]] T *allocate(std::size_t n) {
        T *p = alloc.allocate(n);
        return p;
    }

    void deallocate(T *p, std::size_t size) noexcept {
        alloc.deallocate(p, size);
    }

private:
    base_allocator alloc;
};

In particular, these lines here:

    template <typename U, typename A> friend class dummy_allocator;

    // Construct a dummy allocator from another dummy allocator with the same base_allocator but with different type.
    template <typename U>
    dummy_allocator(
            const dummy_allocator<U,
                    typename std::allocator_traits<base_allocator>::template rebind_alloc<U>>& other) noexcept :
            alloc(other.alloc) {}

Because we need to have constructors between different underlying types for allocators.


问:
Django Annotate With Sum And Min/Max At The Same Time In Search Form
I have a page of courses which are search results of a course search form. In the current code below, it currently allows a user to type in the min and max views and return courses that contain that Course "views" criteria.

It incorrectly does this with the Course "views" field/column when it should be doing it on the Lesson "views" field/column

I want to annotate (or subquery?) the sum of all lesson views but make sure a user is able to find all courses with lesson views that fall under their min/max search critera? In other words, to have the user be able to filter and search via the search form by Courses with Lesson views between X min and Y max views and return all the courses that have that criteria. Or just search by courses with X min views only or Y max views only.

Valid annotate that gets the total sum of all lesson views in a course:

```<code>Course.objects.annotate(foobar=Sum("lesson__views")).order_by("foobar")
</code>```

Tried doing:

```<code>if min_views_query:
     qs = Course.objects.annotate(foobar=Sum(Min("lesson__views"))).order_by("foobar")
if max_views_query:
     qs = Course.objects.annotate(foobar=Sum(Max("lesson__views"))).order_by("foobar")
</code>```

Error:
django.core.exceptions.FieldError: Cannot compute Min('Sum'): 'Sum' is an aggregate

Code:

```<code>Courses Forms.py:

class CourseForm(forms.Form):
    min_views = forms.IntegerField(widget=forms.NumberInput(attrs={'class':'form-control', 'autocomplete':'off','id':'min_views', 'type':'number', 'min':'0', 'placeholder': '0'}), required=False, validators=[MinValueValidator(0), MaxValueValidator(99999999999999999999999999999999999)])
    max_views = forms.IntegerField(widget=forms.NumberInput(attrs={'class':'form-control', 'autocomplete':'off', 'id':'max_views', 'type':'number', 'min':'0', 'placeholder': '1000000'}), required=False, validators=[MinValueValidator(0), MaxValueValidator(99999999999999999999999999999999999)])

    def __init__(self, *args, **kwargs):
        super(CourseForm, self).__init__(*args, **kwargs)
        self.fields['min_views'].label = "Min Views:"
        self.fields['max_views'].label = "Max Views:"

Courses Views.py:

class CourseListView(ListView):
    model = Course
    def get_queryset(self):
        qs = super().get_queryset()
        self.form = form = CourseForm(self.request.GET)
        if form.is_valid():
                min_views_query = self.request.GET.get('min_views')
                max_views_query = self.request.GET.get('max_views')
                if min_views_query:
                    qs = qs.filter(views__gte=min_views_query)
                if max_views_query:
                    qs = qs.filter(views__lte=max_views_query)
                return qs

Courses Models.py:

class Course(models.Model):
    views = models.PositiveIntegerField(default=0)

    @property
    def total_lesson_views(self):
        lessons_dictionary = Lesson.objects.filter(course=self).aggregate(Sum('views'))
        return lessons_dictionary['views__sum']

class Lesson(models.Model):
    course = models.ForeignKey(Course, on_delete=models.SET_NULL, null=True)
    views = models.PositiveIntegerField(default=0)
</code>```

答:
If I understand correctly, you need this:

```<code>qs = Course.objects.annotate(Min("lesson__views"), Max("lesson_views")).\
    aggregate(Sum("lesson__views__min"), Sum("lesson__views__max"))
</code>```

That queryset should include two fields: lesson__views__min__sum and lesson__views__max__sum that you can use to filter.

If you already have views in your Lesson model, you can filter the Lessons from the Course model:

```<code>qs = Course.objects.filter(lesson__views__lt=top_limit,
                           lesson__views__gt=bottom__limit).\
                          distinct()
</code>```

This selects Lesson by their individual number of views, i.e. answers "Give me all Courses which includes at least one Lesson with its views between X and Y".

If you need to aggregate all Lesson views and then filter:

```<code>qs = Course.objects.annotate(Sum("lesson__views")).filter(
    lesson__views__sum__lt=top_limit,
    lesson__views__sum__gt=bottom_limit)
</code>```

This answers the question "Give me all Courses which the Sum of all the views of its Lessons combined are between X and Y".

Body:
I have a page of courses which are search results of a course search form. In the current code below, it currently allows a user to type in the min and max views and return courses that contain that Course "views" criteria.

It incorrectly does this with the Course "views" field/column when it should be doing it on the Lesson "views" field/column

I want to annotate (or subquery?) the sum of all lesson views but make sure a user is able to find all courses with lesson views that fall under their min/max search critera? In other words, to have the user be able to filter and search via the search form by Courses with Lesson views between X min and Y max views and return all the courses that have that criteria. Or just search by courses with X min views only or Y max views only.

Valid annotate that gets the total sum of all lesson views in a course:

Course.objects.annotate(foobar=Sum("lesson__views")).order_by("foobar")

Tried doing:

if min_views_query:
     qs = Course.objects.annotate(foobar=Sum(Min("lesson__views"))).order_by("foobar")
if max_views_query:
     qs = Course.objects.annotate(foobar=Sum(Max("lesson__views"))).order_by("foobar")

Error:
django.core.exceptions.FieldError: Cannot compute Min('Sum'): 'Sum' is an aggregate

Code:

Courses Forms.py:

class CourseForm(forms.Form):
    min_views = forms.IntegerField(widget=forms.NumberInput(attrs={'class':'form-control', 'autocomplete':'off','id':'min_views', 'type':'number', 'min':'0', 'placeholder': '0'}), required=False, validators=[MinValueValidator(0), MaxValueValidator(99999999999999999999999999999999999)])
    max_views = forms.IntegerField(widget=forms.NumberInput(attrs={'class':'form-control', 'autocomplete':'off', 'id':'max_views', 'type':'number', 'min':'0', 'placeholder': '1000000'}), required=False, validators=[MinValueValidator(0), MaxValueValidator(99999999999999999999999999999999999)])

    def __init__(self, *args, **kwargs):
        super(CourseForm, self).__init__(*args, **kwargs)
        self.fields['min_views'].label = "Min Views:"
        self.fields['max_views'].label = "Max Views:"

Courses Views.py:

class CourseListView(ListView):
    model = Course
    def get_queryset(self):
        qs = super().get_queryset()
        self.form = form = CourseForm(self.request.GET)
        if form.is_valid():
                min_views_query = self.request.GET.get('min_views')
                max_views_query = self.request.GET.get('max_views')
                if min_views_query:
                    qs = qs.filter(views__gte=min_views_query)
                if max_views_query:
                    qs = qs.filter(views__lte=max_views_query)
                return qs

Courses Models.py:

class Course(models.Model):
    views = models.PositiveIntegerField(default=0)

    @property
    def total_lesson_views(self):
        lessons_dictionary = Lesson.objects.filter(course=self).aggregate(Sum('views'))
        return lessons_dictionary['views__sum']

class Lesson(models.Model):
    course = models.ForeignKey(Course, on_delete=models.SET_NULL, null=True)
    views = models.PositiveIntegerField(default=0)

Body:
If I understand correctly, you need this:

qs = Course.objects.annotate(Min("lesson__views"), Max("lesson_views")).\
    aggregate(Sum("lesson__views__min"), Sum("lesson__views__max"))

That queryset should include two fields: lesson__views__min__sum and lesson__views__max__sum that you can use to filter.

If you already have views in your Lesson model, you can filter the Lessons from the Course model:

qs = Course.objects.filter(lesson__views__lt=top_limit,
                           lesson__views__gt=bottom__limit).\
                          distinct()

This selects Lesson by their individual number of views, i.e. answers "Give me all Courses which includes at least one Lesson with its views between X and Y".

If you need to aggregate all Lesson views and then filter:

qs = Course.objects.annotate(Sum("lesson__views")).filter(
    lesson__views__sum__lt=top_limit,
    lesson__views__sum__gt=bottom_limit)

This answers the question "Give me all Courses which the Sum of all the views of its Lessons combined are between X and Y".


问:
how to wait for input at end when running / debugging c++ in visual studio
I am looking to compete in the Google KickStart programming competition. I am using C++ in Visual Studio. (not visual studio code) Input parameters are given here as Console arguments, where they can be read with std::cin.

I want to paste the test input parameters into a text file and have the IDE pass them to the program as console arguments (held in the cin buffer). I have done this as defined here

But with this method the command line window will close immediately after the program finishes instead of asking for any key to be pressed. I have tried waiting for dummy input but this does not fix the closing error

答: Probably your linker settings are incorrect. As far as I'm concerned you should set up SubSystem to Console (/SUBSYSTEM:CONSOLE).(Properties -> Linker -> System -> SubSystem)


问:
Uploading to FTP from Node.js using jsftp
I'm trying to upload a file to FTP server from node js using jsftp

module.exports =   async function() {

    const jsftp = require("jsftp");
    console.log(__dirname)
    const ftp = new jsftp({
        host: "host.name",
        port: 990,
        user: "user",
        pass: "pass"
    });
    ftp.put('/path/to/file.xlsx', '/path/to/remote/file/qwer.xlsx', err => {
                console.log('in')
                if (!err) console.log("File transferred successfully!");
                else console.log(err)
              });
}
```

There are no errors in creating the ftp object. I'm getting a 200 response  but there's no file uploaded to the FTP server. If I make an error in the local path, I can see "Local file doesn't exist" error in the console. Otherwise, the "in" is not not printed at all.

I have no idea what's gong on here. Any help is appreciated!

答:
You need to read the file first. So, something like:-</p>

```<code>module.exports =   async function() {

    const jsftp = require("jsftp");
    const fs = require("fs");
    console.log(__dirname)
    const ftp = new jsftp({
        host: "host.name",
        port: 990,
        user: "user",
        pass: "pass"
    });
    fs.readFile(local, function(err, buffer) {
        if(err) {
            console.error(err);
            callback(err);
        }
        else {
            ftp.put('/path/to/file.xlsx', '/path/to/remote/file/qwer.xlsx', err => {
                console.log('in')
                if (!err){ console.log("File transferred successfully!")};
                else {console.log(err)}
            });
       }
    });
}
</code>```

Body:
I'm trying to upload a file to FTP server from node js using jsftp

module.exports =   async function() {

    const jsftp = require("jsftp");
    console.log(__dirname)
    const ftp = new jsftp({
        host: "host.name",
        port: 990,
        user: "user",
        pass: "pass"
    });
    ftp.put('/path/to/file.xlsx', '/path/to/remote/file/qwer.xlsx', err => {
                console.log('in')
                if (!err) console.log("File transferred successfully!");
                else console.log(err)
              });
}

There are no errors in creating the ftp object. I'm getting a 200 response  but there's no file uploaded to the FTP server. If I make an error in the local path, I can see "Local file doesn't exist" error in the console. Otherwise, the "in" is not not printed at all.

I have no idea what's gong on here. Any help is appreciated!

Body:
You need to read the file first. So, something like:-

module.exports =   async function() {

    const jsftp = require("jsftp");
    const fs = require("fs");
    console.log(__dirname)
    const ftp = new jsftp({
        host: "host.name",
        port: 990,
        user: "user",
        pass: "pass"
    });
    fs.readFile(local, function(err, buffer) {
        if(err) {
            console.error(err);
            callback(err);
        }
        else {
            ftp.put('/path/to/file.xlsx', '/path/to/remote/file/qwer.xlsx', err => {
                console.log('in')
                if (!err){ console.log("File transferred successfully!")};
                else {console.log(err)}
            });
       }
    });
}


问:
Wordpress - Limit get_pages to show 5 items
How can I limit the get_pages to only show 5 items?

I thought adding 'number' => 5 to the array would limit it to 5 but it doesn't show anything. Here's my code:

```<code><?php
$pages = get_pages(array('post_type' => 'page','sort_column' => 'menu_order','sort_order' => 'ASC','child_of' => 765));

foreach($pages as $post)
{
setup_postdata($post);
$fields = get_fields();
?>
        <p><?php echo $fields->start_date; ?> <a href="<?php echo get_page_link($post->ID) ?>"><?php echo substr($fields->event_title,0,24) . "..."; ?></a></p>
<?php
}

wp_reset_query();
?>
</code>```

答:
There seems to be an error with the number attribute in get_pages()

I got around it by using get_children:

```<code>$pages = get_children(array(
   'numberposts' =>1,
   'post_parent' => $heading_page->post_id
   ));
</code>```

and using post_parent instead of child_of.

Body:
How can I limit the get_pages to only show 5 items?

I thought adding 'number' => 5 to the array would limit it to 5 but it doesn't show anything. Here's my code:

<?php
$pages = get_pages(array('post_type' => 'page','sort_column' => 'menu_order','sort_order' => 'ASC','child_of' => 765));

foreach($pages as $post)
{
setup_postdata($post);
$fields = get_fields();
?>

<?php echo $fields->start_date; ?> <a href="<?php echo get_page_link($post->ID) ?>"><?php echo substr($fields->event_title,0,24) . "..."; ?>

<?php
}

wp_reset_query();
?>

Body:
There seems to be an error with the number attribute in get_pages()

I got around it by using get_children:

$pages = get_children(array(
   'numberposts' =>1,
   'post_parent' => $heading_page->post_id
   ));

and using post_parent instead of child_of.


问:
CAN bus sending data from two masters with equal balance
I have two master nodes connected to the same CAN bus, both send data to my PC.

first master ID = 0xFFA1
second master ID = 0xFFA2

Since the first master ID is lower than the second it takes control of the bus more than the second master. And this causes some delay in the data.

Is there a way to make load balancing between two nodes so that each node send an almost equal amount of messages.

I tried making the first node send data while switching between two IDs 0xFFA1 and 0xFFB2,
and the second node sends data with ID 0xFFB1. And it didn't help.

答:
There is no such thing as "masters" in CAN, nor in higher layer protocols like CANopen for that matter (a "master" in CANopen is just a supervisor node). Who gets to send what is defined by the CAN identifiers - CAN is primarily focusing on data, not nodes. What matters is what is sent, rather than who is sending/receiving, since every message is broadcasted.

It sounds as if you have 2 nodes that wildly spam the bus with identifier 0xFFA1 and 0xFFA2 messages, as fast as they are able, leading to 100% bus load. Then the node sending 0xFFA2 will "starve". Sending data "as fast as you are able" is never the correct way to use CAN.

Instead you need to define a higher layer protocol that dictates real-time characteristics. In control systems, this is most commonly done by having nodes send data at fixed intervals, such as once per 10ms or 100ms. This alone should fix your starvation problem.

If you want to prevent nodes from sending at the same time, then you could provide a means for them to synchronize. A trick used in CANopen and other protocols, is to have one node send out a "sync" message at given fixed time intervals.
 After reading this sync message, all nodes should act within x ms from receiving it.


问:
Use .join() with callback condition
Here is the situation, I'd like to join each elements of an array depending on a condition. I imagine something like a combinaison of join and reduce functions, e.g. :

const SEPARATOR =  ' ';
const array = ['I', 'am', 'coding'];

// my imaginary function (this does not work voluntarily, only for the example)
const output = array.join((previous, current) => {
    // when the function return true, it joins previous with current on the same index, else not
    return (previous + current).length < 6);
}, SEPARATOR);

console.log(output); // expected output : ['I am', 'coding']
```

To be clear, what I'm asking here is is there a way to achieve that with existing logic (for example, using a function similar to join) without recreating a whole logic.

FYI I found a similar question here but does not answer mine, since the goal was only to remove undefined values.

答:
It's generally a good idea to aim for clarity in your code. Even if your imaginary function existed, would a future developer - including Future You - be able to understand what it's doing?

Instead, be explicit, and break the problem down.

const SEPARATOR = ' ';
const THRESHOLD = 6;
const array = ['I', 'am', 'coding'];

const output = [];
let current = '';
array.forEach(item=>{
    if( current.length + SEPARATOR.length + item.length < THRESHOLD) {
        current += (current ? SEPARATOR : '') + item;
    }
    else {
        if( current) output.push(current);
        current = item;
    }
});
if( current) output.push(current);

console.log(output);```

Title: Use .join() with callback condition

Body:
Here is the situation, I'd like to join each elements of an array depending on a condition. I imagine something like a combinaison of join and reduce functions, e.g. :

const SEPARATOR =  ' ';
const array = ['I', 'am', 'coding'];

// my imaginary function (this does not work voluntarily, only for the example)
const output = array.join((previous, current) => {
    // when the function return true, it joins previous with current on the same index, else not
    return (previous + current).length < 6);
}, SEPARATOR);

console.log(output); // expected output : ['I am', 'coding']

To be clear, what I'm asking here is is there a way to achieve that with existing logic (for example, using a function similar to join) without recreating a whole logic.

FYI I found a similar question here but does not answer mine, since the goal was only to remove undefined values.


问:
How is the recursion of in-order, pre-order and post-order working in this Binary Search Tree (JavaScript) code?
I would like to visualize how the depth first traversal function work? I am learning recursion and I have understood that insert and the contains function. But I am unable to understand the flow of the program when it comes to depth first traversal? </p>

```<code>
 function bst(value){
 this.value = value;
 this.left = null;
 this.right = null;
 };

 bst.prototype.insert = function(value){

 if(value <= this.value){
   if(!this.left) this.left = new bst(value);
   else this.left.insert(value);
 }
 else if (value > this.value){
   if(!this.right) this.right = new bst(value);
   else this.right.insert(value);
 }
 };

 bst.prototype.contains = function(value){
   if (value === this.value) return true;
   if (value < this.value){
     if(!this.left) return false;
     else return this.left.contains(value);
   }
   if (value > this.value){
     if(!this.right) return false;
     else return this.right.contains(value);
   }
 };

 bst.prototype.depthFirstTraversal = function(iteratorFunc, order){
   if(order === 'pre-order') iteratorFunc(this.value);
   if(this.left) this.left.depthFirstTraversal(iteratorFunc, order);
   if(order === 'in-order') iteratorFunc(this.value);
   if(this.right)this.right.depthFirstTraversal(iteratorFunc, order);
   if(order === 'post-order') iteratorFunc(this.value);
 };

 function log(value){
 console.log(value);
 }
 var mybst = new bst(50);
 mybst.insert(40);
 mybst.insert(30);
 mybst.insert(60);
 mybst.insert(10);
 mybst.insert(70);
 mybst.insert(80);
 mybst.insert(55);
 console.log(mybst);
 console.log(mybst.contains(30));
 mybst.depthFirstTraversal(log, "in-order");

</code>```

答:
You could order the types to get the output in the wanted order:

```<code>order  nodes
-----  -----  -----  -----
in     left   root   right
pre    root   left   right
post   left   right   root
</code>```

function bst(value) {
  this.value = value;
  this.left = null;
  this.right = null;
};

bst.prototype.insert = function(value) {

  if (value <= this.value) {
    if (!this.left) this.left = new bst(value);
    else this.left.insert(value);
  } else if (value > this.value) {
    if (!this.right) this.right = new bst(value);
    else this.right.insert(value);
  }
};

bst.prototype.contains = function(value) {
  if (value === this.value) return true;
  if (value < this.value) {
    if (!this.left) return false;
    else return this.left.contains(value);
  }
  if (value > this.value) {
    if (!this.right) return false;
    else return this.right.contains(value);
  }
};

bst.prototype.depthFirstTraversal = function(iteratorFunc, order) {
  if (order === 'pre-order') iteratorFunc(this.value);

  if (this.left) this.left.depthFirstTraversal(iteratorFunc, order);

  if (order === 'in-order') iteratorFunc(this.value);

  if (this.right) this.right.depthFirstTraversal(iteratorFunc, order);

  if (order === 'post-order') iteratorFunc(this.value);
};

function log(value) {
  console.log(value);
}
var mybst = new bst(50);
mybst.insert(40);
mybst.insert(30);
mybst.insert(60);
mybst.insert(10);
mybst.insert(70);
mybst.insert(80);
mybst.insert(55);
//console.log(mybst);
//console.log(mybst.contains(30));

mybst.depthFirstTraversal(log, "in-order"); console.log('');
mybst.depthFirstTraversal(log, "pre-order"); console.log('');
mybst.depthFirstTraversal(log, "post-order");```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.as-console-wrapper { max-height: 100% !important; top: 0; }</code>```

Body:
I would like to visualize how the depth first traversal function work? I am learning recursion and I have understood that insert and the contains function. But I am unable to understand the flow of the program when it comes to depth first traversal?

 function bst(value){
 this.value = value;
 this.left = null;
 this.right = null;
 };

 bst.prototype.insert = function(value){

 if(value <= this.value){
   if(!this.left) this.left = new bst(value);
   else this.left.insert(value);
 }
 else if (value > this.value){
   if(!this.right) this.right = new bst(value);
   else this.right.insert(value);
 }
 };

 bst.prototype.contains = function(value){
   if (value === this.value) return true;
   if (value < this.value){
     if(!this.left) return false;
     else return this.left.contains(value);
   }
   if (value > this.value){
     if(!this.right) return false;
     else return this.right.contains(value);
   }
 };

 bst.prototype.depthFirstTraversal = function(iteratorFunc, order){
   if(order === 'pre-order') iteratorFunc(this.value);
   if(this.left) this.left.depthFirstTraversal(iteratorFunc, order);
   if(order === 'in-order') iteratorFunc(this.value);
   if(this.right)this.right.depthFirstTraversal(iteratorFunc, order);
   if(order === 'post-order') iteratorFunc(this.value);
 };

 function log(value){
 console.log(value);
 }
 var mybst = new bst(50);
 mybst.insert(40);
 mybst.insert(30);
 mybst.insert(60);
 mybst.insert(10);
 mybst.insert(70);
 mybst.insert(80);
 mybst.insert(55);
 console.log(mybst);
 console.log(mybst.contains(30));
 mybst.depthFirstTraversal(log, "in-order");

Body:
You could order the types to get the output in the wanted order:

order  nodes
-----  -----  -----  -----
in     left   root   right
pre    root   left   right
post   left   right   root

function bst(value) {
  this.value = value;
  this.left = null;
  this.right = null;
};

bst.prototype.insert = function(value) {

  if (value <= this.value) {
    if (!this.left) this.left = new bst(value);
    else this.left.insert(value);
  } else if (value > this.value) {
    if (!this.right) this.right = new bst(value);
    else this.right.insert(value);
  }
};

bst.prototype.contains = function(value) {
  if (value === this.value) return true;
  if (value < this.value) {
    if (!this.left) return false;
    else return this.left.contains(value);
  }
  if (value > this.value) {
    if (!this.right) return false;
    else return this.right.contains(value);
  }
};

bst.prototype.depthFirstTraversal = function(iteratorFunc, order) {
  if (order === 'pre-order') iteratorFunc(this.value);

  if (this.left) this.left.depthFirstTraversal(iteratorFunc, order);

  if (order === 'in-order') iteratorFunc(this.value);

  if (this.right) this.right.depthFirstTraversal(iteratorFunc, order);

  if (order === 'post-order') iteratorFunc(this.value);
};

function log(value) {
  console.log(value);
}
var mybst = new bst(50);
mybst.insert(40);
mybst.insert(30);
mybst.insert(60);
mybst.insert(10);
mybst.insert(70);
mybst.insert(80);
mybst.insert(55);
//console.log(mybst);
//console.log(mybst.contains(30));

mybst.depthFirstTraversal(log, "in-order"); console.log('');
mybst.depthFirstTraversal(log, "pre-order"); console.log('');
mybst.depthFirstTraversal(log, "post-order");

.as-console-wrapper { max-height: 100% !important; top: 0; }